「タッチスクリーン」の編集履歴(バックアップ)一覧に戻る
タッチスクリーン - (2007/06/27 (水) 22:31:13) の編集履歴(バックアップ)
TI社の TSC2046 コントローラが入ってます。
ARM7 の SPI ポートに繋がってます。
News at 9.
コマンドフォーマット:
bit |
名前 |
説明 |
7 |
S |
スタートビット |
6..4 |
A2..A0 |
チャンネルセレクト |
3 |
Mode |
12 bit/8 bit コンバーションモード |
2 |
SER/DFR |
読み込みタイプ |
1..0 |
PD1..PD0 |
パワーダウンモード |
パワーダウンモード:
PD1 |
PD0 |
/PENIRQ |
説明 |
0 |
0 |
Enabled |
Power-down between conversions |
0 |
1 |
Disabled |
Voltage reference off, ADC on |
1 |
0 |
Enabled |
Voltage reference on, ADC off |
1 |
1 |
Disabled |
Device always powered. Voltage reference on, ADC on |
/PENIRQ は、R2_CR の bit 6 に繋がれています。
The DS has wired an external VREF of 3.3 V to the TSC, instead of using the internal 2.5 VREF. This impacts the temperature calculations below, and converting any reading into an actual voltage.
便利なコマンド:
定数 |
値 |
説明 |
TSC_MEASURE_TEMP1 |
0x84 |
Measures temperature diode 1 |
TSC_MEASURE_Y |
0x94 |
Measures Y position |
TSC_MEASURE_BATTERY |
0xA4 |
Does not work on DS, VBAT is grounded |
TSC_MEASURE_Z1 |
0xB4 |
Measures cross-panel position 1 |
TSC_MEASURE_Z2 |
0xC4 |
Measures cross-panel position 2 |
TSC_MEASURE_X |
0xD4 |
Measures X position |
TSC_MEASURE_AUX |
0xE4 |
Measures ?, its non-zero, but I don't know what |
TSC_MEASURE_TEMP2 |
0xF4 |
Measures temperature diode 2 |
12-bit の、測定サイクルは 3バイトの SPI 転送 から成っている。
- 最初の転送:コマンド転送と意味の無いデータが戻ってくる
- 2回目の転送:戻り値 0 、測定値 (11)..測定値 (5)
- 3回目の転送: 測定値を返す (4..0) 000
測定用の TSC 入力のコード例:
BlockingWriteSPI(command);
data = BlockingWriteSPI(0);
data = (data << 5) | (BlockingWriteSPI(0) >> 3);
温度計算:
Temperature diode two has a 91 times larger current, and the absolute temperature can be calculated based on the measurements of the two sensors. I'll present a fixed point algorithm for computing the temperature in degrees C (see the TSC 2046 datasheet for the original equation).
temperature(deg C) = 8490 * (V_I91 - V_I1) - 273*4096; (in 20.12 fixed point)
タッチスクリーンセンサの読み込み (SPI)
uint16 touchRead(uint32 command) {
uint16 result;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);
// コマンド書き込みと完了待ち
SERIAL_CR = SERIAL_ENABLE | 0x800 | 0x201;
SERIAL_DATA = command;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);
// 2回目のコマンド書き込みとデータの一部取得
SERIAL_DATA = 0;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);
result = SERIAL_DATA;
// 残りのデータの取得 (最後の転送)
SERIAL_CR = SERIAL_ENABLE | 0x201;
SERIAL_DATA = 0;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);
// 結果を返す
return ((result & 0x7F) << 5) | (SERIAL_DATA >> 3);
}
Todo: figure out what bit 11, bit 9, and bit 0 are doing (bit 0 is probably the CR select, since the firmware reads have this bit cleared)
Position calculation
#define SCREEN_WIDTH 256
#define SCREEN_HEIGHT 192
// ピクセル位置の2箇所を取得するためのレジスタ。クリック位置の調整用に2箇所を取得する
#define TOUCH_CNTRL_X1 (*(vu8*)0x027FFCDC)
#define TOUCH_CNTRL_Y1 (*(vu8*)0x027FFCDD)
#define TOUCH_CNTRL_X2 (*(vu8*)0x027FFCE2)
#define TOUCH_CNTRL_Y2 (*(vu8*)0x027FFCE3)
// タッチスクリーン用レジスタの位置の宣言
#define TOUCH_CAL_X1 (*(vu16*)0x027FFCD8)
#define TOUCH_CAL_Y1 (*(vu16*)0x027FFCDA)
#define TOUCH_CAL_X2 (*(vu16*)0x027FFCDE)
#define TOUCH_CAL_Y2 (*(vu16*)0x027FFCE0)
// タッチスクリーン位置からピクセル位置へはリニアマッピングを使う
// いくつかの変数の準備
static int16 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
static int16 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
static int16 CNTRL_WIDTH = TOUCH_CNTRL_X2 - TOUCH_CNTRL_X1;
static int16 CNTRL_HEIGHT = TOUCH_CNTRL_Y2 - TOUCH_CNTRL_Y1;
// ピクセルポジションの取得
int16 x = (IPC->touchX - (int16) TOUCH_CAL_X1) * CNTRL_WIDTH / TOUCH_WIDTH + (int16) TOUCH_CNTRL_X1;
int16 y = (IPC->touchY - (int16) TOUCH_CAL_Y1) * CNTRL_HEIGHT / TOUCH_HEIGHT + (int16) TOUCH_CNTRL_Y1;