summaryrefslogtreecommitdiff
path: root/firmware/drivers/tsc2100.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/tsc2100.c')
-rw-r--r--firmware/drivers/tsc2100.c78
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 */
29static short adc_data[10]; 29static short adc_data[10];
30static short adc_status;
31static long adc_last_read=0;
32static long adc_last_touch_read=0;
33static long adc_last_volt_read=0;
30 34
31void tsc2100_read_data(void) 35void 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. */
47void tsc2100_read_touch(short *x, short* y, short *z1, short *z2) 55bool 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
55void tsc2100_read_volt(short *bat1, short *bat2, short *aux) 77bool 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
62void tsc2100_set_mode(unsigned char scan_mode) 92void 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)
75void tsc2100_adc_init(void) 110void 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
155void pcmbuf_beep(unsigned int frequency, size_t duration, int amplitude)
156{
157 tsc2100_keyclick();
158}
159#endif