|
1 // This component and the accompanying materials are made available |
|
2 // under the terms of the License "Eclipse Public License v1.0" |
|
3 // which accompanies this distribution, and is available |
|
4 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
5 // |
|
6 // Initial Contributors: |
|
7 // lukasz.forynski@gmail.com |
|
8 // |
|
9 // Contributors: |
|
10 // |
|
11 // Description: |
|
12 // omap3530/beagle_drivers/byd_touch/common/controller.cpp |
|
13 // |
|
14 #include <drivers/iic.h> |
|
15 #include <drivers/iic_channel.h> |
|
16 #include <assp/omap3530_assp/omap3530_gpio.h> |
|
17 #include "controller.h" |
|
18 |
|
19 //#define VERBOSE_DEBUG |
|
20 #ifdef VERBOSE_DEBUG |
|
21 #define LOG_FUNCTION_CALL Kern::Printf("%s()", __FUNCTION__) |
|
22 #else |
|
23 #define LOG_FUNCTION_CALL |
|
24 #endif |
|
25 |
|
26 TTouchControllerInterface::TTouchControllerInterface() : |
|
27 iSpiTransactionHeader(KHeader), |
|
28 iSpiTxTransfer(TIicBusTransfer::EMasterWrite, KBufGranulatity, &iSpiWriteBuffer), |
|
29 iSpiRxTransfer(TIicBusTransfer::EMasterRead, KBufGranulatity, &iSpiReadBuffer), |
|
30 iSpiTransaction(&iSpiTransactionHeader, &iSpiTxTransfer) |
|
31 { |
|
32 // after all above - make the transaction full duplex using the Rx buffer |
|
33 iSpiTransaction.SetFullDuplexTrans(&iSpiRxTransfer); |
|
34 |
|
35 // set buffer length only once.. |
|
36 iSpiWriteBuffer.SetLength(iSpiWriteBuffer.MaxLength()); |
|
37 iSpiReadBuffer.SetLength(iSpiReadBuffer.MaxLength()); |
|
38 |
|
39 // and set SPI addressing / bus configuration |
|
40 iSpiBusId = 0; |
|
41 SET_BUS_TYPE(iSpiBusId, DIicBusChannel::ESpi); |
|
42 SET_CHAN_NUM(iSpiBusId, KSpiModule); |
|
43 SET_SLAVE_ADDR(iSpiBusId, KSpiSlaveAddr); |
|
44 } |
|
45 |
|
46 TInt TTouchControllerInterface::Read(TUint8 aRegAddress, TUint8& aValue) |
|
47 { |
|
48 LOG_FUNCTION_CALL; |
|
49 iSpiWriteBuffer[0] = KReadCommand; |
|
50 iSpiWriteBuffer[1] = aRegAddress; |
|
51 iSpiWriteBuffer[2] = 0; // TODO - might not be needed.. |
|
52 #ifdef VERBOSE_DEBUG |
|
53 for (int i = 0; i <KSpiPacketLength; i++) |
|
54 Kern::Printf("R0[i]: %d", iSpiReadBuffer[1]); |
|
55 #endif |
|
56 TInt r = IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction); |
|
57 if(r == KErrNone) |
|
58 { |
|
59 aValue = iSpiReadBuffer[2]; |
|
60 } |
|
61 #ifdef VERBOSE_DEBUG |
|
62 for (int i = 0; i <KSpiPacketLength; i++) |
|
63 Kern::Printf("R1[i]: %d", iSpiReadBuffer[1]); |
|
64 #endif |
|
65 return r; |
|
66 } |
|
67 |
|
68 TInt TTouchControllerInterface::Write(TUint8 aRegAddress, TUint8 aValue) |
|
69 { |
|
70 LOG_FUNCTION_CALL; |
|
71 iSpiWriteBuffer[0] = KWriteCommand; |
|
72 iSpiWriteBuffer[1] = aRegAddress; |
|
73 iSpiWriteBuffer[2] = aValue; |
|
74 |
|
75 #ifdef VERBOSE_DEBUG |
|
76 for (int i = 0; i < 3; i++) |
|
77 Kern::Printf("WR0[i]: %d", iSpiWriteBuffer[i]); |
|
78 |
|
79 for (int i = 0; i <KSpiPacketLength; i++) |
|
80 Kern::Printf("W0[i]: %d", iSpiReadBuffer[1]); |
|
81 #endif |
|
82 TInt r = IicBus::QueueTransaction(iSpiBusId, &iSpiTransaction); |
|
83 |
|
84 #ifdef VERBOSE_DEBUG |
|
85 for (int i = 0; i <KSpiPacketLength; i++) |
|
86 Kern::Printf("W1[i]: %d", iSpiReadBuffer[1]); |
|
87 #endif |
|
88 return r; |
|
89 } |
|
90 |
|
91 // Touch controller |
|
92 TouchController::TouchController() : |
|
93 iCallback(NULL) |
|
94 { |
|
95 } |
|
96 |
|
97 TouchController::TouchController(TVoidCallback aCallback) : |
|
98 iCallback(aCallback) |
|
99 { |
|
100 } |
|
101 |
|
102 TInt TouchController::HardReset() |
|
103 { |
|
104 LOG_FUNCTION_CALL; |
|
105 TInt r = GPIO::SetPinMode(KResetPin, GPIO::EEnabled); |
|
106 if(r == KErrNone) |
|
107 { |
|
108 r = GPIO::SetPinDirection(KResetPin, GPIO::EOutput); |
|
109 if(r == KErrNone) |
|
110 { |
|
111 // GPIO::SetOutputState(KResetPin, GPIO::ELow); |
|
112 GPIO::SetOutputState(KResetPin, GPIO::EHigh); |
|
113 // GPIO::SetOutputState(KResetPin, GPIO::ELow); |
|
114 |
|
115 Kern::NanoWait(25000); // should be > 10us |
|
116 // GPIO::SetOutputState(KResetPin, GPIO::EHigh); |
|
117 GPIO::SetOutputState(KResetPin, GPIO::ELow); |
|
118 |
|
119 } |
|
120 } |
|
121 // Kern::NanoWait(1000000); |
|
122 // SoftReset(); |
|
123 // Kern::NanoWait(1000000); |
|
124 |
|
125 iInterface.Write(KMasterReadStartAddr, X1_H); |
|
126 return r; |
|
127 } |
|
128 TInt TouchController::SoftReset() |
|
129 { |
|
130 LOG_FUNCTION_CALL; |
|
131 for(TInt i = 0; i<4; i++) |
|
132 { |
|
133 iCtrlRegsCache[i] = 0; |
|
134 } |
|
135 return iInterface.Write(KControl_0, KControl_0_SWRST); |
|
136 } |
|
137 |
|
138 TInt TouchController::SetTouchMode(TTouchMode aMode) |
|
139 { |
|
140 LOG_FUNCTION_CALL; |
|
141 iCtrlRegsCache[0] &= ~KControl_0_MODE_MASK; // clear all mode bits |
|
142 switch(aMode) |
|
143 { |
|
144 case ESingle: |
|
145 iCtrlRegsCache[0] |= KControl_0_MODE_SINGLE; |
|
146 break; |
|
147 case EMulti: |
|
148 iCtrlRegsCache[0] |= KControl_0_MODE_MULTI; |
|
149 break; |
|
150 case EGesture: |
|
151 iCtrlRegsCache[0] |= KControl_0_MODE_GESTURE; |
|
152 break; |
|
153 } |
|
154 |
|
155 return iInterface.Write(KControl_0, iCtrlRegsCache[0]); |
|
156 } |
|
157 |
|
158 |
|
159 TInt TouchController::SetResolution(TResolution aResolution) |
|
160 { |
|
161 LOG_FUNCTION_CALL; |
|
162 iCtrlRegsCache[0] &= ~KControl_0_RM_12; // clear all mode bits |
|
163 if(aResolution == ERes12Bits) |
|
164 { |
|
165 iCtrlRegsCache[0] |= KControl_0_RM_12; // set bit |
|
166 } |
|
167 return iInterface.Write(KControl_0, iCtrlRegsCache[0]); |
|
168 } |
|
169 |
|
170 |
|
171 TInt TouchController::SetLongerSamplingRate(TUint aRate) |
|
172 { |
|
173 LOG_FUNCTION_CALL; |
|
174 iCtrlRegsCache[0] &= ~KControl_0_LST_MASK; // clear bits.. |
|
175 iCtrlRegsCache[0] |= aRate & KControl_0_LST_MASK; // set new value.. |
|
176 return iInterface.Write(KControl_0, iCtrlRegsCache[0]); |
|
177 } |
|
178 |
|
179 |
|
180 TInt TouchController::SetIrqActiveTime(TUint aIrqActiveTime) |
|
181 { |
|
182 LOG_FUNCTION_CALL; |
|
183 iCtrlRegsCache[1] &= ~KControl_1_PAT_MASK; // clear bits.. |
|
184 iCtrlRegsCache[1] |= (aIrqActiveTime << KControl_1_PAT_SHIFT) & KControl_1_PAT_MASK; // set new value.. |
|
185 return iInterface.Write(KControl_1, iCtrlRegsCache[1]); |
|
186 } |
|
187 |
|
188 |
|
189 TInt TouchController::SetPanelVoltageStabTime(TUint aVoltageStabilizationTime) |
|
190 { |
|
191 LOG_FUNCTION_CALL; |
|
192 iCtrlRegsCache[1] &= ~KControl_1_PVT_MASK; // clear bits.. |
|
193 iCtrlRegsCache[1] |= (aVoltageStabilizationTime << KControl_1_PVT_SHIFT) & KControl_1_PVT_MASK; // set new value.. |
|
194 return iInterface.Write(KControl_1, iCtrlRegsCache[1]); |
|
195 } |
|
196 |
|
197 |
|
198 TInt TouchController::SetNumberOfColumns(TUint aNumberOfColumns) |
|
199 { |
|
200 LOG_FUNCTION_CALL; |
|
201 iCtrlRegsCache[2] &= ~KControl_2_C_MASK; // clear bits.. |
|
202 iCtrlRegsCache[2] |= (aNumberOfColumns << KControl_2_C_SHIFT) & KControl_2_C_MASK; |
|
203 return iInterface.Write(KControl_2, iCtrlRegsCache[2]); |
|
204 } |
|
205 |
|
206 TInt TouchController::SetNumberOfRows(TUint aNumberOfRows) |
|
207 { |
|
208 LOG_FUNCTION_CALL; |
|
209 iCtrlRegsCache[3] &= ~KControl_3_R_SHIFT; // clear bits.. |
|
210 iCtrlRegsCache[3] |= (aNumberOfRows << KControl_3_R_SHIFT) & KControl_3_R_MASK; // set new value.. |
|
211 return iInterface.Write(KControl_3, iCtrlRegsCache[3]); |
|
212 } |
|
213 |
|
214 TInt TouchController::EnableWindowMode(TPoint aStart, TPoint aStop) |
|
215 { |
|
216 LOG_FUNCTION_CALL; |
|
217 |
|
218 TBool error_occured = EFalse; |
|
219 // setup window points |
|
220 TInt r = iInterface.Write(KWindowXStart_Msb, (TUint8)(aStart.iX >> 8)); |
|
221 if(r != KErrNone) |
|
222 error_occured = ETrue; |
|
223 |
|
224 r = iInterface.Write(KWindowXStart_Lsb, (TUint8)(aStart.iX)); |
|
225 if(r != KErrNone) |
|
226 error_occured = ETrue; |
|
227 |
|
228 r = iInterface.Write(KWindowYStart_Msb, (TUint8)(aStart.iY >> 8)); |
|
229 if(r != KErrNone) |
|
230 error_occured = ETrue; |
|
231 |
|
232 r = iInterface.Write(KWindowYStart_Lsb, (TUint8)(aStart.iY)); |
|
233 if(r != KErrNone) |
|
234 error_occured = ETrue; |
|
235 |
|
236 r = iInterface.Write(KWindowXStop_Msb, (TUint8)(aStop.iX >> 8)); |
|
237 if(r != KErrNone) |
|
238 error_occured = ETrue; |
|
239 |
|
240 r = iInterface.Write(KWindowXStop_Lsb, (TUint8)(aStop.iX)); |
|
241 if(r != KErrNone) |
|
242 error_occured = ETrue; |
|
243 |
|
244 r = iInterface.Write(KWindowYStop_Msb, (TUint8)(aStop.iY >> 8)); |
|
245 if(r != KErrNone) |
|
246 error_occured = ETrue; |
|
247 |
|
248 r = iInterface.Write(KWindowYStop_Lsb, (TUint8)(aStop.iY)); |
|
249 if(r != KErrNone) |
|
250 error_occured = ETrue; |
|
251 |
|
252 // enable mode |
|
253 if(!error_occured) |
|
254 { |
|
255 iCtrlRegsCache[1] |= ~KControl_1_WS; // set enable bit.. |
|
256 r = iInterface.Write(KControl_1, iCtrlRegsCache[1]); |
|
257 } |
|
258 else |
|
259 { |
|
260 r = KErrGeneral; |
|
261 } |
|
262 return r; |
|
263 } |
|
264 |
|
265 TInt TouchController::DisableWindowMode() |
|
266 { |
|
267 LOG_FUNCTION_CALL; |
|
268 iCtrlRegsCache[1] &= ~KControl_1_WS; // clear enable bit.. |
|
269 return iInterface.Write(KControl_1, iCtrlRegsCache[1]); |
|
270 } |
|
271 |
|
272 TInt TouchController::NumOfTouches() |
|
273 { |
|
274 TUint8 val = 0; |
|
275 return iInterface.Read(KTouchNumberAndType, val); |
|
276 } |
|
277 |
|
278 TInt TouchController::GetMeasurements(TPoint* aPoints, TInt& aNumPoints) |
|
279 { |
|
280 LOG_FUNCTION_CALL; |
|
281 TInt r = KErrArgument; |
|
282 TInt num_points = 0; |
|
283 if(aPoints) |
|
284 { |
|
285 // check how many points is there to read.. |
|
286 TUint8 val = 0; |
|
287 r = iInterface.Read(KTouchNumberAndType, val); |
|
288 |
|
289 //Kern::Printf("KTouchNumberAndType %x", val); |
|
290 // if in multi mode - read all received, but only up to one otherwise.. |
|
291 num_points = val & (val & KTouchNumberAndType_MULTI ? KTouchNumberAndType_TouchNMask : 1); |
|
292 |
|
293 // setup the transaction: |
|
294 for (TInt i = 0; i < num_points; i++) // if anything was touched at all.. |
|
295 { |
|
296 // get X coordinate |
|
297 r = iInterface.Read(X1_H + (i << 2), val); |
|
298 if (r != KErrNone) |
|
299 break; |
|
300 |
|
301 aPoints[i].iX = TInt(val << 8); |
|
302 |
|
303 r = iInterface.Read(X1_L + (i << 2) , val); |
|
304 if (r != KErrNone) |
|
305 break; |
|
306 |
|
307 aPoints[i].iX |= TInt(val); |
|
308 |
|
309 // get Y coordinate |
|
310 r = iInterface.Read(Y1_H + (i << 2), val); |
|
311 if (r != KErrNone) |
|
312 break; |
|
313 |
|
314 aPoints[i].iY = TInt(val << 8); |
|
315 |
|
316 r = iInterface.Read(Y1_L + (i << 2) , val); |
|
317 if (r != KErrNone) |
|
318 break; |
|
319 |
|
320 aPoints[i].iY |= TInt(val); |
|
321 } |
|
322 } |
|
323 |
|
324 // update number of points |
|
325 if (r != KErrNone) |
|
326 { |
|
327 aNumPoints = 0; |
|
328 } |
|
329 else |
|
330 { |
|
331 aNumPoints = num_points; |
|
332 } |
|
333 return r; |
|
334 } |
|
335 |