NDS > Ecran Tactile

NDS

It's a TI TSC2046 controller, hooked up to the ARM7 SPI port. News at 9.

Command Format:

bitnamedescription
7SStart bit
6..4A2..A0Channel select
3Mode12 bit/8 bit conversion mode
2SER/DFRread type
1..0PD1..PD0power-down mode

Power down mode:

PD1PD0/PENIRQDescription
00EnabledPower-down between conversions
01DisabledVoltage reference off, ADC on
10EnabledVoltage reference on, ADC off
11DisabledDevice always powered. Voltage reference on, ADC on

/PENIRQ is wired to bit 6 of R2_CR

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.

Useful commands:

ConstantValueNotes
TSC_MEASURE_TEMP10x84Measures temperature diode 1
TSC_MEASURE_Y0x94Measures Y position
TSC_MEASURE_BATTERY0xA4Does not work on DS, VBAT is grounded
TSC_MEASURE_Z10xB4Measures cross-panel position 1
TSC_MEASURE_Z20xC4Measures cross-panel position 2
TSC_MEASURE_X0xD4Measures X position
TSC_MEASURE_AUX0xE4Measures ?, its non-zero, but I don't know what
TSC_MEASURE_TEMP20xF4Measures temperature diode 2

A 12-bit measurment cycle consists of 3 SPI byte transfers:

Thus, pseudocode for measuring a TSC input is:

 
BlockingWriteSPI(command);
data = BlockingWriteSPI(0);
data = (data << 5) | (BlockingWriteSPI(0) >> 3);

Temperature calculation:

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)
 
uint16 touchRead(uint32 command) {
uint16 result;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);

// Write the command and wait for it to complete
SERIAL_CR = SERIAL_ENABLE | 0x800 | 0x201;
SERIAL_DATA = command;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);

// Write the second command and clock in part of the data
SERIAL_DATA = 0;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);
result = SERIAL_DATA;

// Clock in the rest of the data (last transfer)
SERIAL_CR = SERIAL_ENABLE | 0x201;
SERIAL_DATA = 0;
while (SERIAL_CR & SERIAL_BUSY) swiDelay(1);

// Return the result
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

 
//header
#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 s32 TOUCH_WIDTH = TOUCH_CAL_X2 - TOUCH_CAL_X1;
static s32 TOUCH_HEIGHT = TOUCH_CAL_Y2 - TOUCH_CAL_Y1;
static s32 TOUCH_OFFSET_X = ( ((SCREEN_WIDTH -60) * TOUCH_CAL_X1) / TOUCH_WIDTH ) - 28;
static s32 TOUCH_OFFSET_Y = ( ((SCREEN_HEIGHT-60) * TOUCH_CAL_Y1) / TOUCH_HEIGHT ) - 28;

//code
s32 x = ( ((SCREEN_WIDTH -60) * IPC->touchX) / TOUCH_WIDTH ) - TOUCH_OFFSET_X;
s32 y = ( ((SCREEN_HEIGHT-60) * IPC->touchY) / TOUCH_HEIGHT ) - TOUCH_OFFSET_Y;
x = min(max(x, 0), SCREEN_WIDTH-1);
y = min(max(y, 0), SCREEN_HEIGHT-1);

Accueil Mode d'emploi Derniers changements Toutes les pages