Developing a Linux driver for a chip with I2C registers: Difference between revisions
(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…') |
mNo edit summary |
||
(4 intermediate revisions by 3 users not shown) | |||
Line 1: | Line 1: | ||
<seo title="Developing a Linux driver for a chip with I2C registers | I2C Linux" titlemode="replace" keywords="GStreamer, Linux SDK, Linux BSP, Embedded Linux, Device Drivers, Nvidia, Xilinx, TI, NXP, Freescale, Embedded Linux driver development, Linux Software development, Embedded Linux SDK, Embedded Linux Application development, GStreamer Multimedia Framework." description="Learn how to develop a linux driver for a chip with i2c registers today. This comprehensive RidgeRun Developer document contains all the necessary steps required."></seo> | |||
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. | 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. | ||
Line 17: | Line 19: | ||
# 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 | 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 36: | ||
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 () | |||
{ | |||
# 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 | |||
} | |||
</pre> | |||
And now to read the X and Y locations is easy | And now to read the X and Y locations is easy | ||
Line 72: | Line 77: | ||
Overall, I found the i2c-tools very helpful in validating I understand how to interact with the chip registers properly. | Overall, I found the i2c-tools very helpful in validating I understand how to interact with the chip registers properly. | ||
[[Category:Whitepaper]] | [[Category:Whitepaper]][[Category:HowTo]] |
Latest revision as of 18:37, 6 April 2018
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.