Introduction ============ This is a small group of Linux utilities for the Atmel AT91SAM9G25 and AT91SAM9G20 microcontroller units (MCUs). The utilities target The Aria G25 and the FoxG20 boards from Acme Systems and will most likely work on other boards based on the same MCUs. Some of the utilities have the same names as those from the earlier FoxLX board from Acme System; that board was based on the Etrax LX processor from Axis communications. These utilities mainly work with individual GPIO lines and may be extended to other protocols that can be implemented by "bit banging" GPIO lines. These include I2C (a.k.a. TWI), "one wire" (known as "w1" by the Linux kernel) from Dallas Semiconductor (now Maxim), and the two wire protocol for the SHT-71 . Summary ======= In the following list those files without the ".txt" extension are the names of executables. In most cases the source code for the executable is in a file of the same name with the ".c" extension. ariag25_gpio.txt notes about the GPIO lines on the G25 with some information specific to the Aria G25 devmem2 read or write to memory address (useful for controlling memory mapped IO used by the G25+G20) N.B. no longer installed since clashes with Ubuntu package of same name; can be made be hand foxg20_gpio.txt notes about the GPIO lines on the G20 foxg20_pwm.txt notes about PWM generation on the G20 foxg20_serial.txt notes about the serial ports on the G20 foxg20_pc4.txt notes about FoxG20 push button foxg20_pc7.txt notes about FoxG20 red LED g20gpio_status fetch PIO status values for given GPIO line g25gpio_status install creates this name as hard link to previous g20gpio_set set PIO attributes on given GPIO line g25gpio_set install creates this name as hard link to previous g20tc_freq generate squarish waves with TC3, TC4 or TC5 (G20) g25tc_freq also controls mark:space and much longer periods gpio_ioctl access and test a GPIO line using /dev/gpio device gpio_sysfs access and test a GPIO line using sysfs interface hex2tty command/response tester for serial lines i2c_bbtest I2C master using user space GPIO bit banging i2c_devtest I2C master using kernel /dev/i2c- device is_ariag25 script helper to distinguish target: at91sam9g25 is_arm script helper to distinguish target: has _EABI_ is_foxg20 script helper to distinguish target: at91sam9g20 is_foxglx script helper to distinguish target: has __CRIS__ is_sama5d3 script helper to distinguish target: sama5d3 family mem2io read or write multiple 32 bit values from memory. Can also delay between writes readbits mimics utility for the FoxLX (Phrozen distribution) setbits mimics utility for the FoxLX (Phrozen distribution) w1_bbtest one wire protocol bit banging user space utility Build system ============ Since the previous version of this package, the build has been changed to run native. That is, build on an Aria G25 or a FoxG20 (both ARM based system) rather than cross build on a i386 based system like a laptop. For system that don't have much RAM (e.g. a FoxG20) configuring a swap partition on secondary storage (e.g. microSD card) will probably be necessary. Assumimg a Debian 6 based system, making sure it is up to date may be useful. That can be done with these two commands: # apt-get update # apt-get dist-upgrade To compile and build utilities (e.g. with "./configure ; make") load the (pseudo) package: # apt-get install build-essential To run the "./build_debian" script to generate a deb binary package that can be installed on other ARM systems; this pakage is required: # apt-get install debhelper This package doesn't use libusb but if it did (use version 1.0) then these packages would be needed: # apt-get install libusb-1.0-0 # apt-get install libusb-1.0-0-dev Other "-dev" packages may be needed for some peripherals. The classic build and install sequence is: # ./configure ; make ; make install where that last item will cause executables to be placed in the /usr/local/bin directory. To place them in the /usr/bin directory then change the first item to: # ./configure --prefix=/usr Cross building on an i386 based system (e.g. an laptop running Ubuntu 12.04) is getting more and more fiddly. The process was described in an earlier version of this package (with the older name: fg20_utils version 0.94). That is based on the emdebian project some of whose components have not been updated for a long while. This package can still be cross built with this invocation: # cp Makefile.cross Makefile ; ./build_debian Documentation ============= Read the code (and send corrections to me please). There is a usage information in each utility accessed with the '-h' option. With some utilities '-hh', '-e' or '-ee' provide extra information (e.g. g20gpio_status and g25gpio_status). gpio_sysfs and gpio_ioctl ========================= These two utilities have almost identical functionality. They differ in the way the access the gpio lines at the kernel interface. gpio_sysfs uses the sysfs gpio interface documented in the /Documentation/gpio.txt file in a section titled "Sysfs Interface for Userspace". gpio_ioctl uses ioctls on the /dev/gpio device node and is discussed in the next section. Note that gpio_sysfs can work with both the G25 and G20. However at this time gpio_ioctl only works on the G20 since it depends on the gpio_dev kernel driver which has not been ported to the G25 (and may not be done). Both utilities can toggle the specified gpio line times with a delay between each transition (see the '-t', '-n' and '-d' options). The high state may be as a result of an external or internal pull-up resistor (default action) or may be driven high when the '-f' option is used. The accuracy of the delay depends on several factors (e.g. whether a tickless kernel is used) but it most certainly will not be accurate down to the microsecond level. The gpio_sysfs has an extra '-c' option to count rising, falling or both edges on a gpio line for a given duration (default 1 second). See the gpio.txt kernel documentation file, specifically about the "edge" file. The PIO unit in the AT91SAM9G20 only supports an input change interrupt (rather than separate rising and falling edge interrupts). Hence the "edge" file only supports 'none' and 'both'. The use of poll() from the user space to detect a level change is quite bizarre and curious readers are encouraged to read the code for the process_count() function in gpio_sysfs.c . This problem goes away in the G25. Recent "device-tree" Linux kernels (e.g. lk 3.7) have changed the GPIO kernel pin number ordering. In the past it started at 32 (for PA0) to allow other interrupt number to use the numbers 0 to 31. Those two numbering systems have been decoupled so GPIO kernel pin numbers now start at 0 (for PA0). This can be detected at run time by the presence or absence of this directory: /sys/class/gpio/gpiochip0 . If it is present PA0 is GPIO kernel pin number 0. gpio_ioctl and the gpio_dev driver ================================== The gpio_ioctl utility uses the gpio_dev driver originally written by John Crispin and extended by me to work with recent Linux kernels. One of the joys of being a Linux driver maintainer is finding out that some kernel big name has changed an internal kernel API and broken your driver. Seems as though the gpio_dev driver was thrown out of the Linux mainline (around lk 2.6.28 ?) possibly for using ioctls (hated by the management) and replaced by the inferior sysfs gpio interface. Recent versions of the Debian and OpenWRT distributions for the FoxG20 have accepted my patch to re-add the gpio_dev driver. If it is present in a kernel then the /dev/gpio device node should be present. If it is not present then this patch: http://sg.danny.cz/foxg20/gpio_dev2632rev2.patch may be apply against a lk 2.6.32 kernel. The gpio_dev driver also needs to be selected in the kernel config (e.g. 'make menuconfig') and I usually build it in rather than make it a module. In response to a question about the speed of GPIO lines, I added some extra ioctls to gpio_dev (GPIO_SPARE1 to SPARE4) to drill down through kernel APIs to the lowest C level to determine if it made a difference to the maximum GPIO line toggle speed (and it did). The gpio_dev driver header and source file extensions can be seen in this tarball: http://sg.danny.cz/foxg20/gpio_dev_r2t1.tgz Since the extra code is meant to be used with a 'scope for timing I'm not sure it is useful extension to the gpio_dev driver in that form. Currently the gpio_dev driver has not been ported to the lk 3.7 series as used by the Aria G25. g20gpio_status ============== The kernel generic interfaces to GPIO lines (e.g. as used by gpio_sysfs) on the AT91SAM9G20 overlook some of the more subtle features of these lines. Information about these fine details can be found in the AT91SAM9G20 preliminary manual in the section titled: "Parallel Input Output Controller (PIO)". Examples of the details is whether or not an internal pullup resistor is connected and whether a line is "open drain" (a.k.a. open collector in the past). [I2C (a.k.a. TWI) requires SDA and SCL to be "open drain", hence the need to an external pull-up reistor.] g20gpio_status print out values from the PIO status registers corresponding to the given line. An output like "psr=0" indicates that the bit corresponding to the given GPIO line in the PIO_PSR memory-mapped IO area (PIO_PSR is 32 bits wide) is 0. This means the line is in peripheral mode and "absr=" should be checked to see if that is peripheral A (which is absr=0) or peripheral B (which is absr=1). When GPIO lines don't behave as expected it might be an idea to use g20gpio_status to determine if there are any abnormal settings. The g20gpio_status utility has been updated to work both with the AT91SAM9G20 and the AT91SAM9G25. When the utility is installed a "hard link" is formed from the name "g25gpio_status" to the g20gpio_status executable. The utility can detect what name is was invoked by and set the G20 or G25 mode as appropriate. Command line option '-0' and '-5' can also be used to force G20 or G25 mode. New features include a status summary of a whole bank (e.g. '-s -pb' to show all lines in bank B) and more help and enumerations of each lines peripheral functions (see '-h', '-hh', '-e' and '-ee'). g20gpio_set =========== This utility allows most of the attributes shown in g20gpio_status to be changed (set or cleared). This bypasses the Linux kernel and goes directly to the PIO unit on the AT91SAM9G20 MCU in the FoxG20. So care should be taken when changing settings also accessed by the kernel interfaces. The g20gpio_set utility has been updated to work both with the AT91SAM9G20 and the AT91SAM9G25. When the utility is installed a "hard link" is formed from the name "g25gpio_set" to the g20gpio_set executable. The utility can detect what name is was invoked by and set the G20 or G25 mode as appropriate. Command line option '-0' and '-5' can also be used to force G20 or G25 mode. Note that the PIO macrocell in the G25 has many more features than in the G20 (e.g. optional pull-downs, more interrupt modes, more peripheral modes (up to 4 for each line), and debouncing inputs. Debouncing is actually a slow speed glitch filter. hext2tty ======== The serial tty interface is still quite commonly used both directly (RS-232 voltage levels or TTL levels (5, 3.3 or 1.8 volts)) or tunnelled over something like USB so many peripherals still use it. Being old means that it has very stable (if a bit messy) kernel/user_space interfaces. hext2tty supports command/response testing of serial tty based devices. Commands are given in ASCII hex and any responses are printed in ASCII hex. It has lots of serial line "knobs" (e.g. for RTS/CTS hardware handshake). I2C === Wikipedia has an excellent introduction to the I2C protocol. Atmel call I2C the "Two Wire Interface" (TWI) due to former licensing issues with the term I2C. Since 1st October 2006 no licensing fee was required to implement I2C so it has been appearing in many low speed sensors designed since that date. For example the Sensirion SHT71 temperature and humidity sensor had its own I2C variant. Recently that company released the SHT21 which has a real I2C interface. For Linux documentation on I2C look in the kernel source Documentation/i2c directory. In there they seem to stress the importance of SMbus which is an I2C derivative (subset) and big on PC and laptop motherboards. As far as I can see I2C (or TWI) rules in the embedded space. From my investigations the FoxG20 can talk (as "master") to I2C devices ("slaves") one of two ways: a) via the kernel I2C-dev pass-through driver b) bit banging GPIO lines directly in the user space The a) can be further sub-divided: a1) using the i2c-gpio bit banging kernel driver a2) using the i2c-at91 driver The FoxG20 distros that I have looked at use a1) with SDA on PA23 (J6.32) and SCL on PA24 (J6.31). The Linux kernel source claims that the i2c-at91 is broken but it works with the AT91SAM9G20 (see below). Lack of error processing can put the silicon in a bad state. Then there is option b), basically do it yourself (DIY) from the user space. I2C is a great little protocol in which the clock can run down to DC (very ... slow), so a user space program getting scheduled out for 50 milliseconds is not a problem. [When you try to do the same thing with the one-wire protocol then it breaks due to its strict timing requirements.] The DIY advantages are that any spare GPIO lines can be used and more than one pair can be used [compared with a1) which is only set up for one pair and a2) that the silicon restricts to one pair (on the PA23 and PA24 gpio lines)]. The i2c_bbtest utility in this package implements option b) and pretty well "just works". In a similar fashion to hex2tty, i2c_bbtest is meant to exercise devices that have a command/response structure. Notice the '-w ' option: since the timing of an I2C slave device's response is controlled by the master end, the slave may not be finished processing the command it has been given when the master asks for a response. Clock stretching (see I2C descriptions) is one possible delaying mechanism by a slave but what I have seen is a NACK on the attempted read operation to fetch the response. And the slave continues to NACK until it is ready to respond. I2C advice ========== For those who really want to use the kernel I2C possibilities, my advice is to try and get i2c_bbtest working first. Pick two GPIO lines and test that they can be changed via the sysfs interface (e.g. with the gpio_sysfs utility and a multimeter). Don't forget the pull-up resistors on both SDA and SCL (4.7 kilo-ohm should be fine). The pull-ups should be to 3.3 volts unless the PC* gpio lines are being used, in that case the pull-up should be to 1.8 volts. Check the voltage levels are acceptable to the I2C slave device. For example if the I2C slave device is 5 volt then its Vih (voltage in, high) is critical. If it is less that 3.2 or 3.1 volts then a bi-directional level shifter may be needed. Linux /dev/i2c-0 ================ This is the device node in Linux that is most likely to be accessed if a user space program is trying to access an I2C device (slave) via option a1) or a2) described in the "I2C" section above. The a1) driver stack (within the kernel) is: i2c_dev i2c_core i2c_gpio [Underscores and hyphens seem to be interchangeable in various tools.] The i2c_algo_bit module/driver will also be present and can be considered as a helper. If all of these drivers are build as modules then they should be visible with the lsmod command. Using the convention common in other Linux subsystems, the driver at the top of the stack is closest to the user/kernel interface and the one at the bottom of the stack is closest to the hardware. The i2c_dev driver can be thought of as owning the /dev/i2c-0 character device node. The a2) driver stack is: i2c_dev i2c_core i2c_at91 The i2c_devtest utility in this package essentially "talks to" the i2c_dev driver via the /dev/i2c-0 character device node. Where possible it has the same options as the i2c_bbtest utility. The i2c-at91.c driver ===================== The interested reader can use google to find out why the driver has been marked as broken. To make it "unbroken" some kernel source hacking is required: visit the /drivers/i2c/busses directory and modify Kconfig. I usually take a copy of a file that I change first: cp -p Kconfig Kconfig2632 Then remove the "&& BROKEN" as shown in this patch: --- Kconfig2632 2009-12-18 17:27:07.000000000 -0500 +++ Kconfig 2010-01-21 00:28:07.000000000 -0500 @@ -279,7 +279,7 @@ config I2C_AT91 tristate "Atmel AT91 I2C Two-Wire interface (TWI)" - depends on ARCH_AT91 && EXPERIMENTAL && BROKEN + depends on ARCH_AT91 && EXPERIMENTAL help This supports the use of the I2C interface on Atmel AT91 processors. Then run 'make menuconfig' in the top level linux source directory and select device_drivers|I2C_support|hardware_bus_support and the Atmel AT91 entry should be there. Select it as a module and deselect the GPIO based bitbanging I2C a few entries down. The i2c-at91 driver (found in drivers/i2c/busses/i2c-at91.c) has problems with AT91SAM9G20. Hard to know whether those who marked it is broken in the Linux kernel looked at recent members of the AT91 family. Anyway the driver in lk 2.6.32 is not a great example of the art as it has no error checking. I made some changes and they can be found here as a patch against lk 2.6.32 : http://sg.danny.cz/foxg20/i2c-at91_2632dpg1.patch Since the patch changes only one file (i2c-at91.c) here is that file: http://sg.danny.cz/foxg20/i2c-at91.c The clock rate of the SCL line is adjustable via the 'clockrate' module parameter. Due to limitations of the clock divider, frequencies from 4000 to 400000 Hz are accepted. The clock rate can be changed on the fly with a command like: echo 25000 > /sys/module/i2c_at91/parameters/clockrate [sysfs does have some uses.] Note that I2C NACKs appear as errno=EREMOTEIO to ioctl(I2C_RDWR). Linux kernel 3.7.0 and new i2c-at91 driver ========================================== In the lk 3.7 series a new i2c-at91 driver by Nikolaus Voss was introduced into the mainline kernel. This new driver (it was proposed over a year ago) should be used in preference to the original "broken" driver together with the author's patches to improve it. The old driver and the author's patches to it are discussed in the previous section. The new driver does not have any clock speed selection (at the moment). The clock frequency is fixed at 100 kHz which all I2C (TWI) devices should accept. See the /Documentation/i2c directory for Linux specific documentation. If the kernel is built with CONFIG_I2C_CHARDEV (and CONFIG_I2C_AT91 to get this driver) then device nodes like /dev/i2c-0 and /dev/i2c-1 should appear. Then user space programs can use code shown in the "dev-interface" file in the Documentation/i2c directory to control I2C devices. devmem2 and mem2io ================== The devmem2 program allows memory locations to be read and written. The helps access the memory-mapped IO locations in the G20 and G25 MCUs. It was written by Jan-Derk Bakker in 2000. A copy of that source is in this directory. The author has added a similar program called mem2io which a few extra features like the ability to read from a script file and change multiple locations in one invocation. Both devmem2 and mem2io were built and installed in earlier versions of this package. However recently a Ubuntu server based system for ARM was found to have the devmem2 program installed from its own package. [Debian 6 does not have a devmem2 package in its standard repositories and devmem2 is flagged as a "requested package" so it may appear in the future.] So to avoid clashes in the future, the devmem2 program is no longer built or installed. It can still be made "by hand" with 'make devmem2'. The mem2io program can be used as a replacement but it has a slightly different command line syntax. Douglas Gilbert dgilbert@interlog.com 8th August 2013