ECE497 Project: TSC2046 Kernel Driver
Embedded Linux Class by Mark A. Yoder
Team members: Alexander Hirschfeld
Contents
Executive Summary
The TSC2046 Touch Screen Control chip is the driving ic for for the screen package distributed for Rose-Hulman's ECE497 class. This driver has few native drivers for Linux, and this project seeks to create one.
Installation Instructions
- Dependencies
- linux-headers-`uname –r`
To install this kernel driver
- Clone this git repo:
git clone https://github.com/d-qoi/TSC2046_kernel_driver
- CD into the directory
cd TSC2046_kernel_driver
- Type make to build the kernel.
make
- Install the kernel module.
./on.sh
- To remove the module
./off.sh
User Instructions
This module uses SPI1.2 on the beagle bone blue, and GP1_3. These can be changed in the on.sh script. The `mode` and `SER` parameters can be changed in the on.sh script as well. The Temperature and Battery files will return incorrect values unless SER is set to 1.
Folder where all of the values from the touch screen can be read.
/dev/firmware/TSC2046/device
- battery
- An input on the chip is a batter voltage sensor
- Reading this file return 0x00 unless a batter has been attached to the sensor input on this chip
- The embedded one on the 2.4in TFT display we used in class doesn't use this feature.
- Writing is disabled for this file
- diffs
- reading this file returns the value difference between when the screen was touched, and when the touch was lifted.
- example
x <val> y <val> z1 <val> z2 <val> time <val>
- oneshot
- Writing the ADC settings to this file (single int between 0 and 7, larger will just take first 3 bits)
- Reading will cause a spi_write_then_read allowing for multiple values to be received by setting the command once.
- Example input:
sudo sh -c "echo 1 > oneshot" # will create command to read y axis from touch screen.
- Example output:
command 0x90 data 0x7f80
- PD_select
- Writing to this will set the PD bits of this chip, check the datasheet for a description of what these bits do.
- Reading will return the PD bits.
- It takes any other command to update the bits on the chip
- Reads in an unsigned char, only uses first two bits. (0-3)
- temperature
- There is a temperature sensor on the TSC2046 chip
- reading this file will return the value read from that sensor.
- writing is not allowed for this file
- vals
- Reading this file will return the absolute value read in from the touchscreen, as well as whether or not the touch screen is being touched.
x 0 y 0 z1 0 z2 0 active 0
- Writing is not allowed for this file.
Highlights
For some reason, while developing this, there were a lot of kernel panics that caused the beaglebone to lock up completely. These were interesting as the beaglebone would not log the error, it would just hard lock.
This has been fixed, it was due to tracking both rising and falling edges of a signal for interrupts. It was switched to just tracking the falling edge.
Theory of Operation
The Chip runs on an SPI bus, so it is a simple matter of sending the right commands and writing the output of the chip to the right location. If this is to control a mouse, then it will need to write to that part of the kernel.
Work Breakdown
The first thing I did was figure out how to let the user access values from the kernel space. This was accomplished using sysfs and kobjects. I followed this article on how to use these libraries. http://opensourceforu.com/2015/05/talking-to-the-kernel-through-sysfs/
Next was actually using the SPI bus. This wasn't too difficult after the initial configuration, spi_write_then_read is synchronous, and will sleep till it has an opportunity to use the SPI bus, allowing this module to be used in conjunction with other modules that use the SPI bus.
Looping in the interrupt handler is generally frowned upon, so I used a Workqueue to spin up a thread to handle continuously reading from the TSC2046 chip. This handled creating threads, cleaning up threads, and ensuring that only one loop was running at a time.
Passing parameters into this Module was done through the moduleparams library. There are 5 params passed in, the touchIRQ GPIO pin, the SPI bus, the SPI chip select, the mode (8 bit or 12 bit ADC), and the SER (single or dual channel sampling for the touch screen)
Future Work
The module still causes kernel panics, and I am not sure why. No longer panics. Interrupt handler only tracks Falling edge, not both rising and falling.
The readings from the touch screen are not consistent when there is no movement, that should be fixed, it may be a hardware issue from my TSC2046.
Conclusions
This was an interesting project. I have learned quite a bit about creating drivers for SPI devices and about kernel development.