Archive

Archive for the ‘Uncategorized’ Category

AM35x Evaluation SDK available!

May 26th, 2010

We are glad to make available our evaluation SDK for the AM35x EVM board.

RidgeRun SDK offers an integrated build system for this platform, with a proved solution for reliable product development and deployment, integrating the greatest of open source software and our know-how for TI SoCs.

Our Professional SDK includes support for advanced 3D User interfaces with QT and Clutter.

Check our download center.

Sitara ,

Introducing RidgeRun YouTube Channel

March 18th, 2010
Comments Off

We are happy to introduce our own YouTube Channel.

This channel will be used to post videos on trainings, or demos we have. You can see, we already have some videos showing GStreamer daemon technology.

Enjoy.

Uncategorized

Introducing RidgeRun Developer Connection

March 18th, 2010
Comments Off

We are happy to introduce our new RidgeRun Developer Connection site.

This wiki will provide updated documentation, whitepapers, release notes, regarding using RidgeRun technologies. We also use it as the basis for documenting some of our research and development projects, allowing people to try out the latest we are working on (if you are brave enough!).

The wiki is open only to RidgeRun developers for editing at this point, but we hope that will change on the future as the sites matures. If you feel you can contribute, let us know and we can provide you editing access.

Uncategorized

Debugging with the aid of a CPU register dump

November 25th, 2009
Comments Off

I was testing the new DM6446 SPI support I had added to u-boot when I got a data abort.

U-Boot > sspi 0 32 abcd
data abort
pc : [<810a3674>] lr : [<810a3638>]
sp : 8104fe3c ip : 00000d39 fp : 00000001
r10: 00000002 r9 : 00000000 r8 : 8104ffdc
r7 : 000f4240 r6 : 00000000 r5 : 00000000 r4 : 810602b8
r3 : 00000001 r2 : 01c66800 r1 : 00000019 r0 : 810602b8
Flags: NzCv IRQs off FIQs off Mode SVC_32
Resetting CPU …

Egads, what should I do with that information? Actually, it is really rather easy to figure out what line of source code caused the problem. Here are the steps I used.

First, look in u-boot.map where you found the u-boot.bin that you loaded into your target hardware. Search for the library with the address closest (but lower) to the address shown in the dump for the pc (program counter) register – 0×810a3674 in my case. Note that the PC was incremented by 4, so the address of interest is at 0×810a3670

from u-boot.map:

.text 0×810a3428 0×25c drivers/spi/libspi.a

This is the collection of object files in an archive (the .a file) from the drivers/spi directory.

Since the PC address when the data abort occurred is 0×810a3670, and libspi.a starts 0×810a3428, the problem occurred 0×248 offset inside libspi.a.

Second, use objdump to see what is 0×248 bytes from the start of the libspi.a.

arm-linux-gnueabi-objdump -dS drivers/spi/libspi.a

which produces, in part

static inline void spi_out32(u32 addr, u32 data)
{
__raw_writel(data,addr);
244: e5832000 str r2, [r3]

/* Take SPI module out of reset */
spi_set_bits(SPI_GCR0, 1);

/* Take SPI module out of reset */
spi_set_bits(SPI_GCR0, 1);

return &spi_bus->slave;
}
248: e8bd84f0 pop {r4, r5, r6, r7, sl, pc}

the source code objdump added to the assembly listing isn’t exactly right (because I have compiler optimization enabled), but you can see the problem is near the return from the spi_setup_slave() function that caused the data abort.

Hmm, turns out it was one instruction before – at offset 0×244 – there is more instruction pipelining that I realized, the causing the value of PC to be incremented for two instructions before the data abort occurred.

In look at the inline function

static inline void spi_set_bits(u32 addr, u32 bits)
{
u32 v = spi_in32(addr);
v |= bits;
spi_out32(v, addr);
}

I see I have the arguments backwards in the spi_out32 call. Changing the line to:

spi_out32(addr,v );

fixed the problem.

I hope this simple example shows how with the aid of a symbol (map) file and using objdump, you can use the PC address where the problem occurred to quickly locate the line of offending code.

Uncategorized

Developing a Linux driver for a chip with I2C registers

November 20th, 2009
Comments Off

In the past I have always hauled around a simple i2c Linux app I wrote so I could read and write I2C registers when I tried to make sense of some confusing datasheet. This was in the dark ages before there was a standard I2C sub-system in Linux.

Recently while working on a touch screen driver for the TI TPS65070 chip (the combo analog chip for the way cool OMAP-L138 SoC), I came across i2c-tools from the folks over at lm-sensors. After a quick port to the SDK framework, I ran the i2cdetect tool and got the output:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- 08 -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- UU -- -- -- -- -- -- --
20: -- 21 -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- 48 -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- UU -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

A number (like 21 or 48) means a chip was detects and since the datasheet said my chip had address 0×48, I was seeing a response I expected. UU means a driver is controlling the chip at that I2C address. You can see the I2C address <--> driver mapping using

ls /sys/bus/i2c/drivers/*

Next, I read the TPS65070 datasheet to see how to configure the chip to post an interrupt when the screen was touched. I needed to set a couple of I2C registers and for this simple test, I poll once a second.

# step 1 - enable the ADC, select TSC input to ADC
i2cset -y 1 0x48 0x07 0x8F

# step 2 - set tsc mode to detect touch
i2cset -y 1 0x48 0x08 0x05

# step 3 - poll tsc interrupt (bit 3) until it is set
while sleep 1 ; do i2cget -y 1 0x48 0x02 ; done

Example output:

0x00
0x00
0x08
0x00
0x00

As soon as I read the I2C interrupt register, the interrupt is cleared.

There is a series of steps request to read the X and Y locations, so I wrote a simple shell script

tsc_read ()
{
    # first parameter is ASCII charcter between 0 .. 7
    tsc_mode=$1
    # set the tsc mode
    i2cset -y 1 0x48 0x08 0x8$tsc_mode
    # start the conversion on ADC input TSC
    i2cset -y 1 0x48 0x07 0xCF
    # verify we are done (shell script should be slow enough)
    # check that bit 5 is set
    i2cget -y 1 0x48 0x07
    # read the A/D converted value
    i2cget -y 1 0x48 0x0A
    i2cget -y 1 0x48 0x09
}

And now to read the X and Y locations is easy

# step 4 - read X position
tsc_read 0

# step 5 -read Y position
tsc_read 1

Example output:

# tsc_read 0
0xaf
0x01
0xf6
# tsc_read 1
0xaf
0x01
0x83

meaning on a 10 bit A/D scale 0×000 … 0×3FF (x,y) = (0×1F6, 0×183)

Overall, I found the i2c-tools very helpful in validating I understand how to interact with the chip registers properly.

Uncategorized

Blog moved to wordpress!

December 17th, 2008
Comments Off

I have to admit that when you write software for embedded systems you don’t have much time left for editing your website (and I don’t have dedicated guys to do it). So I’m really happy to be moving the blog to wordpress.

You see, sometimes we have so much fun with new technologies here at RidgeRun, that is nice from once in a while to keep our customers, partners and friends up to date with what we are doing.

Hope to update the site more often now.

Uncategorized