Sunday, 22 September 2013

Final Report

This will be my last report as Google Summer of Code is officially wrapping up at noon tomorrow. The report will give a rundown of everything I've done during the summer and list my future plans.

Code merged into mainline Minix:
Documentation:
Videos:
Blog Highlights:
Future (Post-GSoC) Plans:
  • Finish porting the frame buffer driver to AM335X.
  • pkgsrc for Minix/arm.
  • Helping test release candidates.
I really enjoyed my work this summer. The project wouldn't have been nearly as successful as it turned out to be if it weren't for the following people and organizations: BeagleBoard.org, Minix, Google, Jason Kridner, Kees Jongenburger, Frans Meulenbroeks, Ben Gras, David van Moolenbroek, and Lionel Sambuc.

Thursday, 19 September 2013

Project Results Video Posted

I just uploaded a YouTube video summarizing the results of my project. The video is embedded below and also viewable at the following URL: http://youtu.be/dxjaFsWYkAM

Wednesday, 18 September 2013

Soft Pencils Down

This past Monday marked the "Soft Pencils Down" date for Google Summer of Code. This week is "a week to scrub code, write tests, improve documentation, etc.", so that's what I've been doing.

Today I committed 4 patches to mainline Minix: tda19988: add missing blockdriver_announce() call, bmp085: remove duplicate code, libi2cdriver: add functions for IC register access, i2c: increase read/write timeout. They're mostly clean-up and refactoring. The net result is 390 fewer lines of code and improved reliability.

This week I wrote and executed a test plan for everything I've developed this summer (and more!). It can be found here, on the Minix wiki. Later today I'll be reviewing all of the other documentation I wrote this summer to ensure that it's complete, accurate, and up to date. Following that, I'll be working on a final summary video and a final report.

Sunday, 15 September 2013

Report 13 (September 9 - September 15)

This is Report #13. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:
  • Rebased against mainline Minix
  • Continued working on porting the frame buffer driver to the AM335X. It can turn on the display and back-light and do the initialization steps, but currently it's only displaying 1 non-black pixel. More debugging work remains.
Issues / Concerns / Challenges:
  • The frame buffer driver is more challenging than I first thought. Additionally, the test program which draws raccoons on the frame buffer doesn't support 24-bit color which is needed for the LCD I'm testing with. Since there is only 1 week left and it's supposed to be for clean-up/documentation, I'm deferring the rest of the work on the frame buffer driver until after the clean-up / documentation is done.
Plan for next week:
  • Code clean-up. Think about what can be improved and do it.
    • libi2cdriver: Add common reg_read()/reg_write() functions for accessing registers on ICs.
    • TDA19988: Add a call to blockdriver_announce().
  • Review and test all code. Make sure everything still works as expected.
  • Go over documentation. Make sure it's up to date, accurate, and complete.
  • Create a final summary video for the project.
  • Revisit the frame buffer driver.

Tuesday, 10 September 2013

Building a custom FreeBSD SD card image for the BeagleBone

In an effort to figure out the clocking for the LCD controller on the AM335X, I built a custom FreeBSD SD card image for the BeagleBone. I thought I'd share the steps I used to build the image as it isn't totally trivial. Though, the crochet-freebsd scripts really do help a lot.

The best host for cross building a FreeBSD image is FreeBSD. Since my main box runs Gentoo Linux, I decided to setup a FreeBSD virtual machine under QEMU with the latest version of FreeBSD. Here are the steps to fetch the ISO, create a disk image for the virtual machine, and run the installer:

wget -O freebsd.iso ftp://ftp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/9.2/FreeBSD-9.2-RC3-i386-disc1.iso

qemu-img create freebsd.img 32G


qemu-kvm -localtime -net user -net nic -m 2048 -cdrom freebsd.iso \
    -hda freebsd.img -boot d


There isn't a whole lot to configure during the installation. The defaults should be fine. I chose the sshd option as it allowed me to easily transfer the image off of the VM later on. Once the installation of FreeBSD is complete, you can start QEMU with this command:

qemu-kvm -rtc base=utc -net user,hostfwd=tcp::2222-:22 \
    -net nic -m 2048 -hda freebsd.img


Log in to the virtual machine and install the dependencies (subversion, git, bash, gmake, and gsed). Then use subversion to checkout the latest sources. Finally build an ARM cross compiler:

pkg_add -r subversion git bash gmake gsed

rm -rf /usr/src && svn co http://svn.freebsd.org/base/head /usr/src


cd /usr/src && make XDEV=arm XDEV_ARCH=armv6 xdev


The next step is to get a copy of crochet-freebsd and u-boot.

cd ~ && git clone git://github.com/kientzle/crochet-freebsd.git

cd crochet-freebsd && ftp ftp://ftp.denx.de/pub/u-boot/u-boot-2013.04.tar.bz2


tar xf u-boot-2013.04.tar.bz2


Finally, run the crochet.sh script to build the image.

sh crochet.sh -b BeagleBone

The build will take a while, especially in a VM. When it's done, there will be an SD card image under the work directory. Insert an SD card and be sure to unmount any partitions that were auto-mounted. On my Linux host, I ran these two commands to fetch the image off of the VM and write it to the SD card.

scp -P 2222 root@localhost:/root/crochet-freebsd/work/*.img .

dd if=FreeBSD-armv6-BEAGLEBONE.img of=/dev/sdb bs=1M oflag=direct





That's it. Just put the card into the BeagleBone and apply power. It should boot up to a login prompt. At the prompt you can log in as root (no password).

Sunday, 8 September 2013

Report 12 (September 2 - September 8)

This is Report #12. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:
  • Rebased against mainline Minix.
  • Finished porting the GPIO driver to the AM335X (demo video).
  • Code merged into mainline Minix this week:
  • Continued working on porting the fb driver to the AM335X.
Issues / Concerns / Challenges:
  • Figuring out all of the clocking for the AM335X LCDC peripheral has been very challenging, especially determining the relationship between the functional clock, module clock, Display PLL, and pixel clock and their respective divisors and multipliers. There is a BSD licensed LCDC driver in FreeBSD that I may either re-use or add some debugging output to which would enable me to see all of the various clock values and multipliers/divisors in a working configuration.
Plan for next week:

Wednesday, 4 September 2013

Support for AM335X GPIO merged in mainline Minix

The changes to Minix's GPIO library that I've been working on were merged today (commit). The changes enable the use of GPIO on the BeagleBone and BeagleBone Black through the gpio file system which is sort of similar to the gpio-sysfs interface on Linux. I posted a demo video of the code in action earlier this week.

Monday, 2 September 2013

BeagleBone Black GPIO Demo Video Posted

I just uploaded a YouTube video showing off the Minix GPIO driver I ported to the AM335X. The video is embedded below and also viewable at the following URL: http://youtu.be/Me5AUs-uMbM


Sunday, 1 September 2013

Report 11 (August 26 - September 1)

This is Report #11. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:
 Issues / Concerns / Challenges:
  • With the gpio driver, I'm running into the limit of allowed interrupts per driver. Specifying the 6 dm37xx interrupt numbers and 8 am335x interrupt numbers in the system configuration file puts it over the limit of 8. The likely fix is to increase the per driver interrupt limit, but I'm still exploring other possible solutions.
Plan for next week:
  • Finish testing the gpio driver, resolve interrupt limit mentioned above, and submit to mainline Minix.
  • Continue working on the frame buffer driver.

Saturday, 31 August 2013

padconf code merged

Earlier this week, the padconf changes I was working on were merged into mainline Minix (commit). The change adds a kernel call to allow userspace drivers to dynamically change the padconf at runtime. A kernel call was needed because on the AM335X, writes to the padconf registers must be done in privileged mode.

Tuesday, 27 August 2013

New Documentation Posted and Plans for the rest of GSoC

I spent part of my day today writing documentation for the Minix wiki. The new stuff includes a user guide for the BeagleBone Weather Cape, a developer guide with instructions for supporting new capes, and a developer guide for the I2C /dev interface.

If you remember my preliminary timeline, you know that I'm a bit ahead of where I planned to be at this time. There are still a few more weeks left in Google Summer of Code; the firm pencils down date isn't until September 23. Before it's over, I plan to accomplish a few more tasks...
  • libpadconf support for am335x - when developing the i2c bus driver, I found out the hard way that access to the padconf (i.e. pinmux) registers on the am335x has to be done privileged mode. As a work-around I did the configuration in the kernel at boot. I will be cleaning that up by adding a kernel call to allow the pins to be configured by user space drivers at runtime.
  • frame buffer support for BeagleBone Black - the frame buffer driver currently only supports the BealgeBoard-xM. Since I developed the Minix TDA19988 HDMI Transmitter driver and worked on part of the frame buffer driver previously, it shouldn't be too hard for me to add support for the BeagleBone Black.
  • final week tasks - in the last week I plan to read through all of the code I developed this summer, see if anything can be improved, test everything, review the documentation to make sure it's up to date and accurate, and produce a final report and summary video.

weatherstation code merged

As part of adding support for using the BeagleBone Weather Cape in Minix, I ported the weatherstation application. The task mostly involved removing the node.js and socket.io code and replacing it with a JSON interface. I also added a loading spinner using spin.js and changed the units of pressure from mbar to hPa. Lastly, I updated to the latest versions of jQuery and Processing.js.

Since Minix doesn't have a web server in the base system, I developed a tiny web server in Lua that implements just enough to serve the static content and generate JSON. I'm elated that this project affords me the opportunity to work at all layers of the software stack, from device drivers to web servers to HTML5 and javascript.

Yesterday, I recorded a video demo of the application in action. The code was also merged into the Minix base system yesterday. Here's the commit. To use the weatherstation app, you just have to plug the board into a network (doesn't have to be Internet connected), configure the NIC with `netconf`, attach the cape, and boot the system. The cape will be automatically detected, the right drivers will be loaded, and the web server will be started. In the coming days I will be writing more formal setup instructions on the Minix wiki.

Monday, 26 August 2013

BeagleBone Weather Cape Demo Video Posted

I just uploaded a YouTube video showing off the Weather Cape drivers I developed along with the weatherstation application I ported from bonescript. The video is embedded below and also viewable at the following URL: http://youtu.be/QJEtuusBPak




Sunday, 25 August 2013

Report 10 (August 19 - August 25)

This is Report #10. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:

 Issues / Concerns / Challenges:

  • None this week :)
Plan for next week:
  • Develop a script to read from the sensors and output JSON.
  • Integrate the weather station demo and make it trivial to setup and use.
  • Write more documentation.
    • How to use the Minix I2C /dev interface.
    • How to develop support for additional capes.
    • How to use the BeagleBone Weather Cape in Minix.

Friday, 23 August 2013

BeagleBone Weather Cape Drivers Merged into Mainline Minix

I received a BeagleBone Weather Cape earlier this week. A cape is an expansion board for the BeagleBone and BeagleBone Black. The weather cape provides sensors for temperature, ambient light, humidity, and pressure. Combined with a BeagleBone, it allows anyone to create an Internet connected weather station.

I've been working hard on drivers to support the devices on the cape in Minix. I developed drivers for the SHT21, BMP085, and TSL2550. The other active device on the board, a CAT24C256 EEPROM, was already supported from my prior work. I also updated Minix's eepromread utility. It works sort of like Linux's i2cdump, but it is also aware of a few EEPROM formats. It has a mode where it can parse and display data fields as label:value pairs. Using the updated eepromread utility, I enhanced the rc script to detect attached capes and run cape specific start-up scripts at boot which load the proper drivers.


Here are the commits:
To sum it up, all of the devices on the Weather Cape are now supported in Minix. If the cape is attached, the drivers are automatically started at boot. To get the sensor values, you just read from the device files of each device. The format should be simple to parse; it's fixed width and also has a delimiter (':'). Here's an example usage:

# cat /dev/sht21b3s40
TEMPERATURE     : 29.126
HUMIDITY        : 45.818
# cat /dev/bmp085b3s77
TEMPERATURE     : 28.5
PRESSURE        : 100432
# cat /dev/tsl2550b3s39
ILLUMINANCE     : 830


Temperature is in Celsius (C), relative humidity is a percentage (%), pressure is in pascals (Pa), and ambient light is in lux (lx). There is a small difference in temperature between the two temperature sensors. I hypothesize the difference is due to some slight heating by the BeagleBone. I got the same results when I tried the board under Linux.

My next steps will be to get a demo application working and properly integrated. I'm hoping to modify the bonescript Weather Station demo (src) to work under Minix. I plan to make a small CGI application / script to expose the sensor values via JSON. Then, I will modify the web interface to make use of the data.

Sunday, 18 August 2013

Report 9 (August 12 - August 18)

This is Report #9. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:

  • Rebased against mainline Minix
  • Cleaned up the I2C bus driver based on comments from one of my mentors, Kees. The changes have been merged (commit).
  • Documented EDID Reading and the RTC device protocol on the Minix wiki (here and here).
  • Developed a driver for the TSL2550 Ambient Light Sensor that comes on the WeatherCape. The code is written, and I will test it when I pick up the hardware (either tomorrow or the following day).
  • Began developing a driver for the SHT21 Humidity and Temperature Sensor IC for the WeatherCape.

Issues / Concerns / Challenges:

  • None this week :)

Plan for next week:

  • Test the TSL2550 driver.
  • Finish the SHT21 driver.
  • Develop a BMP085 driver.

Sunday, 11 August 2013

Report 8 (August 5 - August 11)

This is Report #8. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:


Issues / Concerns / Challenges:

  • None this week :)

Plan for next week:

  • Write documentation for the Minix wiki about how EDID reading and the real time clock work.
  • Begin developing drivers for the devices on the WeatherCape: TSL2550, SHT21, and BMP085.


Friday, 9 August 2013

TPS65950 driver Merged

This week I developed a driver for the TPS65950 Power Management and System Companion Device commonly found on the BeagleBoard-xM. I implemented a basic I2C driver for the chip with support for the real-time clock peripheral. The code was merged today. Here are the commits:

Thursday, 8 August 2013

Real-time Clock Demo Video Posted

I just uploaded a YouTube video showing off the code I developed last week to control the real-time clock on the BeagleBone Black. The video is embedded below and also viewable at the following URL: http://youtu.be/rBakaxAGRS0


 

Monday, 5 August 2013

Merge Monday

Lots of code got merged into the main Minix git repository today, including 6 patches from my Google Summer of Code project for BeagleBoard.org. Included in the commits are support for the real-time clock on the AM335X, a driver for the TPS65217 Power Management IC, support for powering off the BeagleBone / BeagleBone Black, and support for rebooting the AM335X and DM37XX. Here's the full list of commits:

In other news, an ethernet driver developed by JPEmbedded for the lan8710a was also merged today; BeagleBone and BeagleBone Black users finally have networking support (configuration instructions here). Since it isn't always clear what features are supported on which boards, I made a Feature Matrix on the Minix Wiki.

Sunday, 4 August 2013

Report 7 (July 29 - August 4)

This is Report #7. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:


Issues / Concerns / Challenges:

  • None this week :)

Plan for next week:

  • Submit changes for merging into mainline Minix:
    • frame buffer driver enhancements.
    • am335x rtc driver.
    • tps65217 driver.
    • other changes related to power-off.
    • reboot support for am335x/dm37xx.
  • Begin working on a driver for the power management chip on the BeagleBoard-xM (TPS65950).


Friday, 2 August 2013

PMIC Power-Off Demo Video Posted

I just uploaded a YouTube video showing off the code I developed this week to safely power-off the BeagleBone Black when the power button is pressed. It also works on the original BeagleBone when you run `shutdown -p`. The video is embedded below and also viewable at the following URL: http://youtu.be/x51NWpnesqQ




Wednesday, 31 July 2013

Software Power-Off of the AM335X with the TPS65217 PMIC

The BeagleBone Black is powered by the AM335X ARM Cortex-A8 Processor. The board provides a push button near the Ethernet connector for powering off and powering on the board. The AM335X works in concert with the TPS65217C Power Management IC (PMIC) and the operating system to do a proper shutdown when the button is pressed. By proper shutdown, I mean the file systems are sync()'d and services are shutdown cleanly. As part of my Google Summer of Code project, I've been implementing this functionality in Minix. I've got the basics working (clean shutdown and power off when the power button is pressed), but a lot of clean-up, re-factoring, and testing remains before I can think about submitting it for inclusion in Minix. The dance between the PMIC and SoC is interesting, so I thought I'd share how it works while it's fresh in my head.

There's a bit of setup to get this to work. It requires drivers for the SoC's I2C controller and RTC. A driver for the PMIC (an i2c slave) is also needed. First, the push button interrupt in the TPS65217C needs to be unmasked, and the driver for the TPS65217C needs to handle interrupts from the NNMI pin (irq 7). That pin signals the AM335X to let it know that there is an interrupt pending on the TPS65217C. This gets notifications about the button press to the TPS65217C driver. With just that part functional, you can do safe shutdowns of the operating system when the user presses the button.

Powering off the board takes a few more steps. The TPS65217C driver also has to set the OFF bit in the STATUS register. This enables power-off when the AM335X signals a power off by toggling the PWR_EN pin. Toggling the pin is done by setting the POWER_EN bit in RTC_PMIC, setting the time to power off the chip in the RTC's ALARM2 registers, enabling the the ALARM2 interrupt in the RTC_INTERRUPTS_REG register, and waiting for the alarm to go off which will automatically toggle the pin to alert the PMIC to power down the board. Finally, the PMIC will sense the toggle and cut the power. The user can press the power button again to boot the system.

TDA19988 Driver merged into mainline Minix

Just a quick note to mention that the driver I developed for the TDA19988 HDMI Transmitter was merged into the main Minix repository earlier in the week. The commit is here. The driver enables EDID reading on the BeagleBone Black. When the frame buffer driver is ported to the BeagleBone Black, it will be able to use the EDID from the TDA19988 to configure the display properly.

While the TDA19988 driver is meant to be accessed directly by the frame buffer driver, it can be tested from the shell by creating a block device file with an unused major number and doing a read with the dd command. Below is the output from one of my test runs showing the exact commands:

# cd /dev
# mknod tda19988 b 32 0
# chmod 600 tda19988
# /bin/service down tda19988.1.3470
# /bin/service up /usr/sbin/tda19988 -label tda19988.1.3470 \
 -dev /dev/tda19988 \
 -args 'cec_bus=1 cec_address=0x34 hdmi_bus=1 hdmi_address=0x70'
# dd if=/dev/tda19988 of=/root/edid.dat count=1 bs=128
1+0 records in
1+0 records out
# hexdump -C /root/edid.dat
00000000  00 ff ff ff ff ff ff 00  05 e3 02 19 56 04 00 00  |............V...|
00000010  24 10 01 03 81 29 1a 78  2a d7 a5 a2 59 4a 96 24  |$....).x*...YJ.$|
00000020  14 50 54 bf ef 00 81 80  71 4f 81 40 95 0f 01 01  |.PT.....qO.@....|
00000030  01 01 01 01 95 00 30 2a  a0 d0 51 84 22 30 50 98  |......0*..Q."0P.|
00000040  36 00 9a 01 11 00 00 1e  00 00 00 ff 00 39 33 31  |6............931|
00000050  36 39 43 41 30 30 31 31  31 30 00 00 00 fd 00 32  |69CA001110.....2|
00000060  4c 1e 53 0e 00 0a 20 20  20 20 20 20 00 00 00 fc  |L.S...      ....|
00000070  00 47 31 39 4c 57 6b 0a  20 20 20 20 20 20 00 95  |.G19LWk.      ..|
00000080
# /bin/service down tda19988.1.3470
# rm tda19988


If you try this at home, you'll need a display connected to your BeagleBone Black for this to work. The hexdump should begin with the EDID magic number: 00 ff ff ff ff ff ff 00. The checksum algorithm is: sum the bytes, (sum & 0xff) should equal 0.

Monday, 29 July 2013

Looking for beta testers who have a BeagleBoard-xM

I've been working on enhancements to Minix's frame buffer driver that allow it to detect the supported resolutions of the connected display via EDID (extended display identification data) and automatically configure the frame buffer driver with a resolution that works well with the display and the board. I'm looking for some people to help test my code as I only have 1 physical monitor to test with in addition to the Linaro QEMU simulator. If you'd like to help, please read on.

Note, this only works with the BeagleBoard-xM. The BeagleBone isn't supported by the frame buffer driver yet.

Test Instructions

  1. Connect a display to your BeagleBoard-xM. It should work with most HDMI/DVI displays.
  2. Boot a BeagleBoard-xM with my patches. Steps to obtain, build, and boot my code are provided here: http://minix-i2c.blogspot.ca/2013/06/minix-on-beagleboard-xm.html
  3. Log in as root and run the splash program
    1. # splash
  4. Observe the screen. If it worked, you should see some raccoons ( like this photo ). To stop the splash program, use Ctrl+C.

If it works

Please e-mail me at linuxgeek@gmail.com to let me know. If you can, also include a description of your display (make, model, etc).


If it doesn't work

Please e-mail me at linuxgeek@gmail.com with your display's EDID. Here are the steps to get the EDID:

  1. Read the EDID and store the contents in a file
    1. # dd if=/dev/eepromb3s50 of=/root/eeprom.dat count=1 bs=128
  2. E-mail me the data. You can either send me that file as an attachment (it should be on the 2nd partition of the SD card) or copy and paste the output of `hexdump -C /root/eeprom.dat` into the e-mail body.
Thanks,
Thomas

Sunday, 28 July 2013

Report 6 (July 22 - July 28)

This is Report #6. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:

  • Rebased against mainline Minix
  • EEPROM driver enhancements (merged):
    • 4x speed-up for reads of 128 bytes or more.
    • Support for the 1 byte addressing scheme used in smaller EEPROMs. Previously, just the 2 byte (page + address) scheme, used by the CAT24C256 EEPROM, was supported.
  • Imported EDID validation, parsing, and printing code from NetBSD and got it compiling on Minix.
  • Committed small EDID man page fixes to NetBSD.
  • Began enhancing the frame buffer driver:
    • Added code to request and retrieve the EDID. Tested on BeagleBoard-xM. (blog post).
    • Began working on code to apply the settings. Works on my monitor (photo) and in Linaro QEMU.
    • Wrote a function to choose a resolution supported by both the SoC and the display.
  • Made a small fix to the frame buffer demo program to dynamically get the screen resolution from the frame buffer driver.
  • Continued work on the TDA19988 driver. EDID reading is buggy. It only works intermittently, and when it does work, it is only reading the last 32 bytes.

Issues / Concerns / Challenges:

  • None this week :)

Plan for next week:

  • Finish the frame buffer driver enhancements.
    • Code clean-up and more testing.
    • Maybe try to recruit some people to help test it with different monitors.
    • Submit changes for merging into mainline Minix.
  • Debug the TDA19988 driver, clean up the code a bit, and submit to mainline.
  • Begin working on a driver for the power management chip (TPS65217C).

Friday, 26 July 2013

EDID Reading

I haven't posted in a while, so here's a little bit of a brain dump about EDID on Beagle hardware with some sample debugging output from the BeagleBoard-xM towards the end.

Lately, I've been working on implementing support in Minix for reading Extended Display Identification Data (EDID). EDID contains information about your monitor (resolution, etc). The data resides on a chip in your monitor. It's read using I2C (well, technically I think it's DDC, but it's on the I2C bus). The general idea is that the frame buffer driver will query the EDID and configure itself with the optimal resolution, sync rates, etc. On the BeagleBoard-xM, the EDID is at slave address 0x50 on the third I2C bus. For the original BeagleBone (White), the EDID is at slave address 0x50 on the second I2C bus, assuming you're using the DVI cape. The programming for doing the reading is rather simple, it's done the same way as reading from an EEPROM: write 0x00 with a STOP and then do a 128 byte read.

For the BeagleBone Black, it's a lot more complicated. EDID reading goes through the TDA19988. The TDA19988 has two slave addresses (0x34 for CEC and 0x70 for HDMI). When the chip powers up, the HDMI interface is disabled by default. You have to enable it through the CEC interface. Then you need to setup interrupts, send a read request, poll a status register waiting for the interrupt to fire, and then you can read the EDID. Last week I got the point where my TDA19988 driver can detect if a monitor is connected, enable the HDMI interface, and read the TDA19988 revision information through the HDMI interface. I've written the code for the rest, but I'm waiting on a cable to fully test it (my uHDMI to VGA adapter doesn't support EDID -- I double checked in Linux); I should have the cable this weekend.

I did manage to get the right HDMI to DVI cable to do some testing of my work in progress code on the BeagleBoard-xM. Below is a screen dump of the debug output. I start the EEPROM driver for slave address 0x50 on I2C bus 3, I start the frame buffer driver with arguments to point it at the EEPROM driver, and then I run a program which feeds the frame buffer driver some images to display. You'll see that when the frame buffer init code runs, it looks up the EEPROM driver and requests the data. Then the frame buffer driver validates, parses, and displays the EDID. I'm using the NetBSD EDID code for that last part. I committed some EDID documentation fixes back to NetBSD.

# cd /dev && MAKEDEV eepromb3s50
# service up /usr/sbin/cat24c256 -dev /dev/eepromb3s50 -label cat24c256.3.50 -args 'bus=3 address=0x50'
# service up /usr/sbin/fb -dev /dev/fb0 -args edid.0=cat24c256.3.50
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+67(fb_edid_args_parse):Found key:edid.0 value:cat24c256.3.50
framebuffer fresh: pid 140
# splash
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+154(fb_edid_read):Contacting cat24c256.3.50 to get EDID.
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+123(do_read):REP=0
edid(debug):/home/tcort/repos/i2c/src/drivers/fb/fb_edid.c+178(fb_edid_read):EDID Retrieved and Parsed OK
fb(debug):/home/tcort/repos/i2c/src/drivers/fb/arch/earm/fb_arch.c+311(arch_fb_init):Configuring Settings based on EDID...
fb(debug):/home/tcort/repos/i2c/src/drivers/fb/arch/earm/fb_arch.c+142(configure_with_edid):--- EDID - START ---
Vendor: [AOC] AOC
Product: [1902] G19LWk
Serial number: 93169CA001110
Manufactured 2006 Week 36
EDID Version 1.3
EDID Comment: 
Video Input: 81
Digital (DFP 1.x compatible)
Gamma: 2.20
Max Size: 41 cm x 26 cm
Features: 2a
DPMS active-off
RGB
Preferred timing
Chroma Info:
Red X: 0.635
Red Y: 0.635
Grn X: 0.290
Grn Y: 0.588
Blu X: 0.142
Blu Y: 0.080
Wht X: 0.313
Wht Y: 0.329
Range:
Horizontal: 30 - 83 kHz
Vertical: 50 - 76 Hz
Max Dot Clock: 140 MHz
Video modes:
720x400 @ 70Hz (28320 738 846 900 412 414 449 -H +V)
640x480 @ 60Hz (25175 656 752 800 490 492 525 -H -V)
640x480 @ 73Hz (31500 664 704 832 489 492 520 -H -V)
640x480 @ 75Hz (31500 656 720 840 481 484 500 -H -V)
800x600 @ 56Hz (36000 824 896 1024 601 603 625 +H +V)
800x600 @ 60Hz (40000 840 968 1056 601 605 628 +H +V)
800x600 @ 72Hz (50000 856 976 1040 637 643 666 +H +V)
800x600 @ 75Hz (49500 816 896 1056 601 604 625 +H +V)
832x624 @ 75Hz (57284 864 928 1152 625 628 667 -H -V)
1024x768 @ 60Hz (65000 1048 1184 1344 771 777 806 -H -V)
1024x768 @ 70Hz (75000 1048 1184 1328 771 777 806 -H -V)
1024x768 @ 75Hz (78750 1040 1136 1312 769 772 800 +H +V)
1280x1024 @ 75Hz (135000 1296 1440 1688 1025 1028 1066 +H +V)
1280x1024 @ 60Hz (108000 1328 1440 1688 1025 1028 1066 +H +V)
1152x864 @ 75Hz (108000 1216 1344 1600 865 868 900 +H +V)
1280x960 @ 60Hz (108000 1376 1488 1800 961 964 1000 +H +V)
1440x900 @ 75Hz (136492 1536 1688 1936 901 904 940 +H +V)
1440x900 @ 60Hz (106470 1520 1672 1904 901 904 932 +H +V)
1440x900 @ 61Hz (108000 1520 1672 1904 903 909 934 +H +V)
Preferred mode: 1440x900 @ 61Hz
fb(debug):/home/tcort/repos/i2c/src/drivers/fb/arch/earm/fb_arch.c+144(configure_with_edid):--- EDID - END ---

Now that the frame buffer driver can get the EDID, the next step is to actually configure the frame buffer driver using the EDID information. This will be a bit of a learning, but I'm looking forward to learning the details of graphics drivers like what a "horizontal front porch" is. Another next step is testing the TDA19988 driver. I'll let you know how it goes in my report on Sunday.

Sunday, 21 July 2013

Report 5 (July 15 - July 21)

This is Report #5. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:


Issues / Concerns / Challenges:

  • None this week :)

Plan for next week:

  • EDID reading in the TDA19988 driver. Subtasks: enabling DDC, enabling interrupts, setting up the read, and reading the data.
  • Begin frame buffer driver enhancements to use EDID to configure the driver properly.

Wednesday, 17 July 2013

Everything you ever wanted to know about Minix I2C (and more!)

I just finished posting the last of 3 new pages to the Minix wiki documenting the I2C subsystem on Minix, the I2C driver interface, and I2C device driver development. Without further adieu, here are the links:

  • I2C Subsystem Internals - this page explains how the I2C subsystem works, how device files are named/numbered, what interfaces are provided, userland tools, and much more.
  • I2C Driver Protocol - this page specifies the interface between I2C device drivers and the I2C bus drivers. It explains what Minix IPC message types are accepted by the I2C bus drivers, the fields in the messages, and the possible reply codes. Pretty technical stuff.
  •  I2C Device Driver Programming - this is a step by step guide walking you through creating a new Minix device driver from scratch for an I2C device. I'm hoping it compliments the general Device Driver Programming guide (not written by me) and inspires/helps future Minix developers. At the very least, it will act as a checklist and provide skeleton for future I2C drivers that I develop.
During the rest of this week I will be continuing work on the TDA19988 driver. The main focus of that project is to read the Extended Display Identification Data (EDID). EDID contains the information about the monitor that's connected to the BeagleBone (resolution, etc). I'll be using that data later on to configure the frame buffer driver properly. I've got a stub for that driver built. Now I just have to read the documentation and figure out how to access the EDID.

Sunday, 14 July 2013

Report 4 (July 8 - July 14)

This is Report #4. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:

  • Contributed i2cscan enhancements back to NetBSD. Commits: i2cscan.c, i2cscan.8
  • Finished the CAT24C256 Driver (EEPROM).
  • Resolved the pinmux issue I had last week. See my blog post for details.
  • General code clean-up and testing.
  • Documented the Minix I2C device driver interface to the I2C bus driver. Text here. Will post to the wiki when code is merged.
  • Documented the Minix I2C internals. Text here. Will post to the wiki when code is merged.

Issues / Concerns / Challenges:

  • None this week :)

Plan for next week:

  • Minor fix needed to allow the i2c device drivers to survive the i2c bus driver restarting.
  • Submit what I've done so far into the code review / continuous integration pipeline for inclusion in mainline Minix. This includes the pinmux work around, i2c bus driver, i2cscan utility, libi2cdriver, cat24c256 driver, eepromread utility.
  • Start working on a driver for reading the extended display identification data (EDID) via the TDA19988.
  • As I work on the TDA19988 driver, I'll also document how to write a Minix I2C driver using the i2cdriver library I developed previously.
  • If things go really well, begin frame buffer driver enhancements to use EDID to configure the driver properly.

Friday, 12 July 2013

pinmux issue resolved

Just a quickie update to say that I have overcome an issue I had last week. In my last report, I wrote that I had an issue configuring the I2C pins for the third I2C bus on the BeagleBone Black (AM335X). The root cause was that writes to the control module registers on the Cortex-A8 must be done in privileged mode and my driver runs in user space. I moved the pin configuration into the kernel and it executes as part of the arm specific initialization now. Now that the pins are getting setup properly, my driver works for the third I2C bus. Here's the output of my eepromread utility reading an EEPROM I attached to the third I2C bus:



This change is just a temporary fix until another developer gets a chance to create a pinmux server. With Minix being a microkernel based operating system, we try to keep the amount of code in the kernel to a minimum.

Sunday, 7 July 2013

Report 3 (July 1 - July 7)

This is Report #3. I plan to post these every Sunday. They will give a rundown of what I've done during the week, list any problems I had, and what I plan to do the following week. I'll be posting the reports both to the beagle-gsoc Google Group and to my blog.

Completed this week:
  • Rebased against mainline Minix.
  • Finished a simple I2C EEPROM test program that uses the /dev interface to write to specific locations in the EEPROM and read back what it wrote.
  • Did some testing, but I ran into an issue with the third i2c bus on the BBB (see "Issues" section below for details).
  • Enhanced i2cscan to support scanning using only the 1 byte read method (i.e. make it work similar to i2cdetect -r). Submitted patches upstream to NetBSD.
  • Defined an interface for accessing the i2c bus from other drivers and implemented it.
  • Created libi2cdriver and wrote common routines that would have been repeated in most i2c device drivers.
  • Updated the rc script to start the i2c bus drivers at boot and start the the proper i2c device drivers for the board it's being run on (BBB, BB, xM).
  • Started work on a CAT24C256 Driver (EEPROM). Implemented reading from specific locations on the chip.
  • Wrote a couple of blog posts: Using i2c-tools with Angstrom Linux on the BeagleBone Black, BeagleBone debugging with OpenOCD
Issues / Concerns / Challenges:
  • I spent well over 15 hours trying to figure out why my i2c bus code worked great for the first two I2C buses but not for the 3rd I2C bus. I got some tips in #beagle-gsoc from the group and from my mentors. Eventually, one of my mentors, Kees, figured out that the pinmux settings were not being applied. It turns out that writes to the control module need to be done in privileged mode. Since my code runs in userspace, writes to the control registers weren't having an affect. It seems that the only reason the first two buses worked was because they were left over from u-boot's pinmuxing.
Plan for next week:
  • Follow up with upstream on the patches to NetBSD's i2cscan program.
  • Finish the CAT24C256 Driver (EEPROM) by implementing writing to specific locations on the chip and developing an interface.
  • See how I can help the Minix team get the pinmux library working.
  • Code clean-up / testing / review.
  • If all goes well and time permits, submit what I've done so far to mainline Minix and write some documentation.
  • Begin working on a driver for reading extended display identification data.

Thursday, 4 July 2013

BeagleBone debugging with OpenOCD

The original BeagleBone (White) comes with a built-in JTAG emulator which allows you to debug your code without needing to go out and buy an expensive JTAG debugger. There's a neat tool called OpenOCD which, among many other things, can be used to debug code on your BeagleBone. I found that the few guides and tutorials available didn't work for me when I was trying to get it going, so I'm posting what I did in hopes that it'll help someone else and save them some time.

I did this on Gentoo Linux using OpenOCD 0.6.1, but similar steps should apply elsewhere. The first step is to install OpenOCD as well as usbutils. You'll need OpenOCD built with usb and ftd2xx support. In Gentoo, there are USE flags for this (USE="usb ftd2xx"). Connect your BeagleBone to your computer via USB, and then run `lsusb` as root. You should find a "Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC" in the list (ID: 0403:6010). If you don't, then the driver isn't installed properly.

The next part is to configure OpenOCD. This is where I ran into problems. There is a default configuration script for the BeagleBone called ti_beaglebone.cfg. You specify it when you run OpenOCD like this `openocd -s /usr/share/openocd/scripts -f board/ti_beaglebone.cfg`. The '-s' is to specify the base of the scripts directory.


Unfortunately, as you can see above, the default script doesn't work out of the box. It prompts you to add a line for your device with this message: "Error: please add "ft2232_device_desc <string>" or "ft2232_serial <string>" to your .cfg file". It wasn't 100% clear how to find out the serial number or device description so I experimented. I found that if you put in a bogus serial number, it will list the available serial numbers. I added the following line to /usr/share/openocd/scripts/board/ti_beaglebone.cfg:
ft2232_serial "XXX"
Then I ran openocd...


From that list I found the serial number "TIWKAE5U A". I edited /usr/share/openocd/scripts/board/ti_beaglebone.cfg again with that serial number and executed `openocd -s /usr/share/openocd/scripts -f board/ti_beaglebone.cfg` again. This time it worked.


Once the OpenOCD server is up, you can connect to it via telnet on port 4444. From there you can issue commands. In the example below I display the value of the I2C revision of the first I2C controller.