diff options
Diffstat (limited to 'firmware/drivers/tsc2100.c')
-rw-r--r-- | firmware/drivers/tsc2100.c | 78 |
1 files changed, 62 insertions, 16 deletions
diff --git a/firmware/drivers/tsc2100.c b/firmware/drivers/tsc2100.c index 14b56b76c9..271a557822 100644 --- a/firmware/drivers/tsc2100.c +++ b/firmware/drivers/tsc2100.c | |||
@@ -27,6 +27,10 @@ | |||
27 | 27 | ||
28 | /* adc_data contains the last readings from the tsc2100 */ | 28 | /* adc_data contains the last readings from the tsc2100 */ |
29 | static short adc_data[10]; | 29 | static short adc_data[10]; |
30 | static short adc_status; | ||
31 | static long adc_last_read=0; | ||
32 | static long adc_last_touch_read=0; | ||
33 | static long adc_last_volt_read=0; | ||
30 | 34 | ||
31 | void tsc2100_read_data(void) | 35 | void tsc2100_read_data(void) |
32 | { | 36 | { |
@@ -36,7 +40,11 @@ void tsc2100_read_data(void) | |||
36 | unsigned char out[] = {command >> 8, command & 0xff}; | 40 | unsigned char out[] = {command >> 8, command & 0xff}; |
37 | unsigned char *p_adc_data=(unsigned char *)&adc_data; | 41 | unsigned char *p_adc_data=(unsigned char *)&adc_data; |
38 | 42 | ||
39 | spi_block_transfer(SPI_target_TSC2100, | 43 | adc_status|=tsc2100_readreg(TSSTAT_PAGE, TSSTAT_ADDRESS); |
44 | |||
45 | adc_last_read=current_tick; | ||
46 | |||
47 | spi_block_transfer(SPI_target_TSC2100, false, | ||
40 | out, sizeof(out), (char *)adc_data, sizeof(adc_data)); | 48 | out, sizeof(out), (char *)adc_data, sizeof(adc_data)); |
41 | 49 | ||
42 | for(i=0; i<sizeof(adc_data); i+=2) | 50 | for(i=0; i<sizeof(adc_data); i+=2) |
@@ -44,28 +52,55 @@ void tsc2100_read_data(void) | |||
44 | } | 52 | } |
45 | 53 | ||
46 | /* Read X, Y, Z1, Z2 touchscreen coordinates. */ | 54 | /* Read X, Y, Z1, Z2 touchscreen coordinates. */ |
47 | void tsc2100_read_touch(short *x, short* y, short *z1, short *z2) | 55 | bool tsc2100_read_touch(short *x, short* y, short *z1, short *z2) |
48 | { | 56 | { |
49 | *x = adc_data[0]; | 57 | /* Note: This could cause problems if the current tick is not reset in ~1.3 |
50 | *y = adc_data[1]; | 58 | * years. Noting this in the event that a suspend/resume function |
51 | *z1 = adc_data[2]; | 59 | * is added. |
52 | *z2 = adc_data[3]; | 60 | */ |
61 | if( (adc_status&(3<<9)) && (adc_last_read - adc_last_touch_read>=0) ) { | ||
62 | *x = adc_data[0]; | ||
63 | *y = adc_data[1]; | ||
64 | *z1 = adc_data[2]; | ||
65 | *z2 = adc_data[3]; | ||
66 | |||
67 | adc_status&=~(3<<9); | ||
68 | |||
69 | adc_last_touch_read=current_tick; | ||
70 | |||
71 | return true; | ||
72 | } else { | ||
73 | return false; | ||
74 | } | ||
53 | } | 75 | } |
54 | 76 | ||
55 | void tsc2100_read_volt(short *bat1, short *bat2, short *aux) | 77 | bool tsc2100_read_volt(short *bat1, short *bat2, short *aux) |
56 | { | 78 | { |
57 | *bat1 = adc_data[5]; | 79 | if( (adc_status&(7<<4)) && TIME_BEFORE(adc_last_volt_read, adc_last_read)) { |
58 | *bat2 = adc_data[6]; | 80 | *bat1 = adc_data[5]; |
59 | *aux = adc_data[7]; | 81 | *bat2 = adc_data[6]; |
82 | *aux = adc_data[7]; | ||
83 | |||
84 | adc_status&=~(7<<4); | ||
85 | adc_last_volt_read=current_tick; | ||
86 | return true; | ||
87 | } else { | ||
88 | return false; | ||
89 | } | ||
60 | } | 90 | } |
61 | 91 | ||
62 | void tsc2100_set_mode(unsigned char scan_mode) | 92 | void tsc2100_set_mode(bool poweron, unsigned char scan_mode) |
63 | { | 93 | { |
64 | short tsadc=(scan_mode<<TSADC_ADSCM_SHIFT)| /* mode */ | 94 | short tsadc=(scan_mode<<TSADC_ADSCM_SHIFT)| /* mode */ |
65 | (0x3<<TSADC_RESOL_SHIFT)| /* 12 bit resolution */ | 95 | (0x3<<TSADC_RESOL_SHIFT)| /* 12 bit resolution */ |
66 | (0x2<<TSADC_ADCR_SHIFT )| /* 2 MHz internal clock */ | 96 | (0x2<<TSADC_ADCR_SHIFT )| /* 2 MHz internal clock */ |
67 | (0x2<<TSADC_PVSTC_SHIFT); | 97 | (0x2<<TSADC_PVSTC_SHIFT); |
68 | 98 | ||
99 | if(!poweron) | ||
100 | { | ||
101 | tsadc|=TSADC_ADST; | ||
102 | } | ||
103 | |||
69 | if(scan_mode<6) | 104 | if(scan_mode<6) |
70 | tsadc|=TSADC_PSTCM; | 105 | tsadc|=TSADC_PSTCM; |
71 | 106 | ||
@@ -75,12 +110,15 @@ void tsc2100_set_mode(unsigned char scan_mode) | |||
75 | void tsc2100_adc_init(void) | 110 | void tsc2100_adc_init(void) |
76 | { | 111 | { |
77 | /* Set the TSC2100 to read touchscreen */ | 112 | /* Set the TSC2100 to read touchscreen */ |
78 | tsc2100_set_mode(0x01); | 113 | tsc2100_set_mode(true, 0x01); |
79 | 114 | ||
80 | tsc2100_writereg(TSSTAT_PAGE, TSSTAT_ADDRESS, | 115 | tsc2100_writereg(TSSTAT_PAGE, TSSTAT_ADDRESS, |
81 | (0x1<<TSSTAT_PINTDAV_SHIFT) /* Data available only */ | 116 | (0x1<<TSSTAT_PINTDAV_SHIFT) /* Data available only */ |
82 | ); | 117 | ); |
83 | 118 | ||
119 | /* An additional 2 mA can be saved here by powering down vref between | ||
120 | * conversions, but it adds a click to the audio on the M:Robe 500 | ||
121 | */ | ||
84 | tsc2100_writereg(TSREF_PAGE, TSREF_ADDRESS, | 122 | tsc2100_writereg(TSREF_PAGE, TSREF_ADDRESS, |
85 | TSREF_VREFM|TSREF_IREFV); | 123 | TSREF_VREFM|TSREF_IREFV); |
86 | } | 124 | } |
@@ -90,7 +128,7 @@ short tsc2100_readreg(int page, int address) | |||
90 | unsigned short command = 0x8000|(page << 11)|(address << 5); | 128 | unsigned short command = 0x8000|(page << 11)|(address << 5); |
91 | unsigned char out[] = {command >> 8, command & 0xff}; | 129 | unsigned char out[] = {command >> 8, command & 0xff}; |
92 | unsigned char in[2]; | 130 | unsigned char in[2]; |
93 | spi_block_transfer(SPI_target_TSC2100, | 131 | spi_block_transfer(SPI_target_TSC2100, false, |
94 | out, sizeof(out), in, sizeof(in)); | 132 | out, sizeof(out), in, sizeof(in)); |
95 | return (in[0]<<8)|in[1]; | 133 | return (in[0]<<8)|in[1]; |
96 | } | 134 | } |
@@ -101,7 +139,7 @@ void tsc2100_writereg(int page, int address, short value) | |||
101 | unsigned short command = (page << 11)|(address << 5); | 139 | unsigned short command = (page << 11)|(address << 5); |
102 | unsigned char out[4] = {command >> 8, command & 0xff, | 140 | unsigned char out[4] = {command >> 8, command & 0xff, |
103 | value >> 8, value & 0xff}; | 141 | value >> 8, value & 0xff}; |
104 | spi_block_transfer(SPI_target_TSC2100, | 142 | spi_block_transfer(SPI_target_TSC2100, false, |
105 | out, sizeof(out), NULL, 0); | 143 | out, sizeof(out), NULL, 0); |
106 | } | 144 | } |
107 | 145 | ||
@@ -111,3 +149,11 @@ void tsc2100_keyclick(void) | |||
111 | //short val = 0xC410; | 149 | //short val = 0xC410; |
112 | tsc2100_writereg(TSAC2_PAGE, TSAC2_ADDRESS, tsc2100_readreg(TSAC2_PAGE, TSAC2_ADDRESS)&0x8000); | 150 | tsc2100_writereg(TSAC2_PAGE, TSAC2_ADDRESS, tsc2100_readreg(TSAC2_PAGE, TSAC2_ADDRESS)&0x8000); |
113 | } | 151 | } |
152 | |||
153 | #ifdef HAVE_HARDWARE_BEEP | ||
154 | |||
155 | void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude) | ||
156 | { | ||
157 | tsc2100_keyclick(); | ||
158 | } | ||
159 | #endif | ||