1 | //========================================================================== |
---|
2 | // |
---|
3 | // ads7846.c |
---|
4 | // |
---|
5 | // Author(s): Michael Kelly - Cogent Computer Systems, Inc. |
---|
6 | // Date: 03/06/03 |
---|
7 | // Description: ADS7846 Interface routines for CSB740 |
---|
8 | // Modified from MC9328mxl version to use SPI1 |
---|
9 | // |
---|
10 | //========================================================================== |
---|
11 | |
---|
12 | #include "config.h" |
---|
13 | #include "cpuio.h" |
---|
14 | #include "genlib.h" |
---|
15 | #include "stddefs.h" |
---|
16 | #include "omap3530.h" |
---|
17 | #include "cpu_gpio.h" |
---|
18 | #include "ads7846.h" |
---|
19 | #include "cli.h" |
---|
20 | #include "umongpio.h" |
---|
21 | |
---|
22 | //-------------------------------------------------------------------------- |
---|
23 | // function prototypes |
---|
24 | // |
---|
25 | int ads_init(void); |
---|
26 | int ads_rd(uchar ads_ctl); |
---|
27 | |
---|
28 | extern void udelay(int delay); |
---|
29 | |
---|
30 | //-------------------------------------------------------------------------- |
---|
31 | // ads_init() |
---|
32 | // |
---|
33 | // This routine sets up the OMAP3530 SPI3 port in Microwire mode |
---|
34 | // (8 bit control, 16 bit data, 24 bit total). It also turns on |
---|
35 | // the ADS7843 pen interrupt via a dummy read. Note that we assume |
---|
36 | // that PERCLK2 is 12Mhz (HCLK/4). We are using CS0 on SPI3. |
---|
37 | // |
---|
38 | int ads_init() |
---|
39 | { |
---|
40 | volatile uchar temp; |
---|
41 | |
---|
42 | |
---|
43 | SPI3_REG(SPI_CH0_CTRL) = 0x00; // Disable SPI3 Channel 0 |
---|
44 | |
---|
45 | SPI3_REG(SPI_CH0_CONF) = SPI_CH_CONF_CLKG |
---|
46 | | SPI_CH_CONF_DPE0 // no transmission on SPI3_MISO |
---|
47 | | SPI_CH_CONF_WL(7) // 8-bit data mode |
---|
48 | | SPI_CH_CONF_EPOL // CS is active low |
---|
49 | // | SPI_CH_CONF_SB_POL // |
---|
50 | // | SPI_CH_CONF_SBE // |
---|
51 | | SPI_CH_CONF_CLKD(9); // divide by 512 = 93Khz |
---|
52 | // | SPI_CH_CONF_PHA; // Data is latched on even numbered edges |
---|
53 | // | SPI_CH_CONF_POL; // SPI clock is active low |
---|
54 | |
---|
55 | SPI3_REG(SPI_MODULCTRL) = 0x0; // Functional mode, Master, and auto CS generation |
---|
56 | |
---|
57 | SPI3_REG(SPI_CH0_CTRL) = 0x01; // Enable SPI3 Channel 0 |
---|
58 | |
---|
59 | // enable the ADS7846 so it can generate a touch interrupt. |
---|
60 | // this consists of reading any channel, but setting the |
---|
61 | // power down mode in the control byte to 00b. note we |
---|
62 | // flush the returned data |
---|
63 | //ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_ADD_DFR_X); |
---|
64 | ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_8BIT | ADS7846E_ADD_DFR_Y); |
---|
65 | // ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_ADD_DFR_Y); |
---|
66 | temp = SPI3_REG(SPI_RXD0); |
---|
67 | |
---|
68 | return 0; |
---|
69 | } |
---|
70 | |
---|
71 | //-------------------------------------------------------------------------- |
---|
72 | int ads_rd(uchar ads_ctl) |
---|
73 | { |
---|
74 | int timeout = 100; |
---|
75 | volatile uchar temp0, temp1; |
---|
76 | |
---|
77 | // the OMAP3530 only handles up to 16-bits per transfer |
---|
78 | // so we send 8-bits at a time to get our total of 24 |
---|
79 | |
---|
80 | // SPI3_REG(SPI_TXD0) = ads_ctl; |
---|
81 | // udelay(10); |
---|
82 | // while (!(SPI3_REG(SPI_IRQSTATUS) & SPI_TX0_EMPTY)); |
---|
83 | // while (!(SPI3_REG(SPI_IRQSTATUS) & SPI_RX0_FULL)); |
---|
84 | // temp0 = SPI3_REG(SPI_RXD0); |
---|
85 | // |
---|
86 | // SPI3_REG(SPI_TXD0) = 0; |
---|
87 | // udelay(10); |
---|
88 | // while (!(SPI3_REG(SPI_IRQSTATUS) & SPI_TX0_EMPTY)); |
---|
89 | // while (!(SPI3_REG(SPI_IRQSTATUS) & SPI_RX0_FULL)); |
---|
90 | // temp0 = SPI3_REG(SPI_RXD0); |
---|
91 | // |
---|
92 | // SPI3_REG(SPI_TXD0) = 0; |
---|
93 | // udelay(10); |
---|
94 | // while (!(SPI3_REG(SPI_IRQSTATUS) & SPI_TX0_EMPTY)); |
---|
95 | // while (!(SPI3_REG(SPI_IRQSTATUS) & SPI_RX0_FULL)); |
---|
96 | // temp1 = SPI3_REG(SPI_RXD0); |
---|
97 | |
---|
98 | SPI3_REG(SPI_TXD0) = ads_ctl; |
---|
99 | udelay(10); |
---|
100 | while (!(SPI3_REG(SPI_CH0_STAT) & SPI_CH_TX0_EMPTY)); |
---|
101 | while (!(SPI3_REG(SPI_CH0_STAT) & SPI_CH_RX0_FULL)); |
---|
102 | temp0 = SPI3_REG(SPI_RXD0); |
---|
103 | |
---|
104 | SPI3_REG(SPI_TXD0) = 0; |
---|
105 | udelay(10); |
---|
106 | while (!(SPI3_REG(SPI_CH0_STAT) & SPI_CH_TX0_EMPTY)); |
---|
107 | while (!(SPI3_REG(SPI_CH0_STAT) & SPI_CH_RX0_FULL)); |
---|
108 | temp0 = SPI3_REG(SPI_RXD0); |
---|
109 | |
---|
110 | // SPI3_REG(SPI_TXD0) = 0; |
---|
111 | // udelay(10); |
---|
112 | // while (!(SPI3_REG(SPI_CH0_STAT) & SPI_CH_TX0_EMPTY)); |
---|
113 | // while (!(SPI3_REG(SPI_CH0_STAT) & SPI_CH_RX0_FULL)); |
---|
114 | // temp1 = SPI3_REG(SPI_RXD0); |
---|
115 | temp1 = 0; |
---|
116 | return ((temp0 << 8) | temp1); |
---|
117 | } |
---|
118 | |
---|
119 | //-------------------------------------------------------------------------- |
---|
120 | char *adsHelp[] = { |
---|
121 | "Screen touch demo using ADS7846 and OMAP3530 SPI port.", |
---|
122 | "", |
---|
123 | 0 |
---|
124 | }; |
---|
125 | |
---|
126 | int ads(int argc, char *argv[]) |
---|
127 | { |
---|
128 | uchar c; |
---|
129 | int pen, i; |
---|
130 | int average_x, average_y; |
---|
131 | |
---|
132 | // init the SPI and ADS7846 |
---|
133 | if (ads_init() == -1) |
---|
134 | { |
---|
135 | printf("Error intializing ADS7846!\n"); |
---|
136 | return (CMD_FAILURE); |
---|
137 | } |
---|
138 | |
---|
139 | printf("Waiting for Touch (Press \'X\' to end test)...\n"); |
---|
140 | |
---|
141 | pen = 0; |
---|
142 | while (1) |
---|
143 | { |
---|
144 | if (gotachar()) |
---|
145 | { |
---|
146 | c = getchar(); |
---|
147 | if ((c == 'X') || (c == 'x')) goto done; |
---|
148 | } |
---|
149 | if (GPIO_tst(PIRQ) == 0) |
---|
150 | { |
---|
151 | printf("Pen Down....\n"); |
---|
152 | pen = 1; |
---|
153 | while(GPIO_tst(PIRQ) == 0) // keep reading until touch goes away |
---|
154 | { |
---|
155 | average_x = 0; |
---|
156 | average_y = 0; |
---|
157 | |
---|
158 | // display every 256 samples (less if pen is down a short time) |
---|
159 | for (i = 0; i < 256 ; i++) |
---|
160 | { |
---|
161 | // average_x += ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_ADD_DFR_X); |
---|
162 | // average_y += ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_ADD_DFR_Y); |
---|
163 | average_x += ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_8BIT | ADS7846E_ADD_DFR_X); |
---|
164 | average_y += ads_rd(ADS7846E_S | ADS7846E_PD_ADC | ADS7846E_8BIT | ADS7846E_ADD_DFR_Y); |
---|
165 | } |
---|
166 | printf("X = %04d, Y = %04d\n", average_x/i, average_y/i); |
---|
167 | |
---|
168 | } // while pen is down |
---|
169 | } |
---|
170 | if (pen) |
---|
171 | { |
---|
172 | printf("Pen Up....\n"); |
---|
173 | pen = 0; |
---|
174 | } |
---|
175 | |
---|
176 | } |
---|
177 | |
---|
178 | done: |
---|
179 | return(CMD_SUCCESS); |
---|
180 | } |
---|