Developing a Linux driver for a chip with I2C registers

From RidgeRun Developer Connection

(Difference between revisions)
Jump to:navigation, search
(Created page with '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…')
(Changed register 7 value from 0x0F as documented incorrectly in to 2009 version of the spect to 0x0E as documented in the aug 2011 version of the spec)
(One intermediate revision not shown)
Line 17: Line 17:
  # step 1 - enable the ADC, select TSC input to ADC
  # step 1 - enable the ADC, select TSC input to ADC
-
  i2cset -y 1 0x48 0x07 0x8F
+
  i2cset -y 1 0x48 0x07 0x0E
   
   
  # step 2 - set tsc mode to detect touch
  # step 2 - set tsc mode to detect touch
Line 34: Line 34:
There is a series of steps request to read the X and Y locations, so I wrote a simple shell script
There is a series of steps request to read the X and Y locations, so I wrote a simple shell script
-
 
+
<pre>
-
tsc_read ()
+
tsc_read ()
-
{
+
{
-
    # first parameter is ASCII charcter between 0 .. 7
+
  # first parameter is ASCII charcter between 0 .. 7
-
    tsc_mode=$1
+
  tsc_mode=$1
-
    # set the tsc mode
+
  #enable the ADC and set it to use all TSC functions
-
    i2cset -y 1 0x48 0x08 0x8$tsc_mode
+
  i2cset -y -f 1 0x48 0x07 0x9E
-
    # start the conversion on ADC input TSC
+
  # set the tsc mode
-
    i2cset -y 1 0x48 0x07 0xCF
+
  i2cset -y -f 1 0x48 0x08 0x0$tsc_mode
-
    # verify we are done (shell script should be slow enough)
+
  # start the conversion on ADC input TSC
-
    # check that bit 5 is set
+
  i2cset -y -f 1 0x48 0x07 0xDE
-
    i2cget -y 1 0x48 0x07
+
  # verify we are done (shell script should be slow enough)
-
    # read the A/D converted value
+
  # check that bit 5 is set
-
    i2cget -y 1 0x48 0x0A
+
  i2cget -y -f 1 0x48 0x07
-
    i2cget -y 1 0x48 0x09
+
  # read the A/D converted value
-
}
+
  i2cget -y -f 1 0x48 0x0A
 +
  i2cget -y -f 1 0x48 0x09
 +
}
 +
</pre>
And now to read the X and Y locations is easy
And now to read the X and Y locations is easy

Revision as of 14:51, 26 August 2011

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: -- -- -- -- -- -- -- --

UU means a chip was detects and since the datasheet said my chip had address 0×48, I was seeing a response I expected.

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 0x0E

# 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
   #enable the ADC and set it to use all TSC functions
   i2cset -y -f 1 0x48 0x07 0x9E
   # set the tsc mode
   i2cset -y -f 1 0x48 0x08 0x0$tsc_mode
   # start the conversion on ADC input TSC
   i2cset -y -f 1 0x48 0x07 0xDE
   # verify we are done (shell script should be slow enough)
   # check that bit 5 is set
   i2cget -y -f 1 0x48 0x07
   # read the A/D converted value
   i2cget -y -f 1 0x48 0x0A
   i2cget -y -f 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.

Navigation
Toolbox