00001 /************************************************************************* 00002 * © 2011 Microchip Technology Inc. 00003 * 00004 * Project Name: mTouch CVD Framework v1.1 00005 * FileName: mTouchCVD.c 00006 * Dependencies: mTouchCVD.h 00007 * Processor: See documentation for supported PIC® microcontrollers 00008 * Compiler: HI-TECH Ver. 9.81 or later 00009 * IDE: MPLAB® IDE v8.50 (or later) or MPLAB® X 00010 * Hardware: 00011 * Company: 00012 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00013 * Description: mTouch CVD Framework filtering and decoding modules 00014 * - No application code should be implemented in this 00015 * or any other mTouch framework file. This will allow 00016 * for better customer support and easier upgrades to 00017 * later firmware versions. Use the main.c and user- 00018 * generated files to implement your application. 00019 * - See the documentation located in the docs/ folder 00020 * for a more information about how the framework is 00021 * implemented. 00022 *************************************************************************/ 00023 /************************************************************************** 00024 * MICROCHIP SOFTWARE NOTICE AND DISCLAIMER: You may use this software, and 00025 * any derivatives created by any person or entity by or on your behalf, 00026 * exclusively with Microchip's products in accordance with applicable 00027 * software license terms and conditions, a copy of which is provided for 00028 * your referencein accompanying documentation. Microchip and its licensors 00029 * retain all ownership and intellectual property rights in the 00030 * accompanying software and in all derivatives hereto. 00031 * 00032 * This software and any accompanying information is for suggestion only. 00033 * It does not modify Microchip's standard warranty for its products. You 00034 * agree that you are solely responsible for testing the software and 00035 * determining its suitability. Microchip has no obligation to modify, 00036 * test, certify, or support the software. 00037 * 00038 * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER 00039 * EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED 00040 * WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A 00041 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE, ITS INTERACTION WITH 00042 * MICROCHIP'S PRODUCTS, COMBINATION WITH ANY OTHER PRODUCTS, OR USE IN ANY 00043 * APPLICATION. 00044 * 00045 * IN NO EVENT, WILL MICROCHIP BE LIABLE, WHETHER IN CONTRACT, WARRANTY, 00046 * TORT (INCLUDING NEGLIGENCE OR BREACH OF STATUTORY DUTY), STRICT 00047 * LIABILITY, INDEMNITY, CONTRIBUTION, OR OTHERWISE, FOR ANY INDIRECT, 00048 * SPECIAL, PUNITIVE, EXEMPLARY, INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, 00049 * FOR COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, 00050 * HOWSOEVER CAUSED, EVEN IF MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY 00051 * OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT ALLOWABLE BY LAW, 00052 * MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS 00053 * SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID 00054 * DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. 00055 * 00056 * MICROCHIP PROVIDES THIS SOFTWARE CONDITIONALLY UPON YOUR ACCEPTANCE OF 00057 * THESE TERMS. 00058 *************************************************************************/ 00064 00065 // INCLUDES 00067 #include "includes/mTouchCVD.h" 00068 00070 // GLOBAL VARIABLES 00072 00078 unsigned char ButtonState [CVD_NUMBER_SENSORS]; 00079 unsigned int Average [CVD_NUMBER_SENSORS]; 00080 00081 00082 // LOCAL VARIABLES 00084 00089 #if defined(AVG_ENABLE) 00090 unsigned int AverageCount [CVD_NUMBER_SENSORS]; 00091 #endif 00092 00093 #if defined(BUTTON_TIMEOUT) 00094 #if BUTTON_TIMEOUT > 0 00095 unsigned char PressTimer [CVD_NUMBER_SENSORS]; 00096 #endif 00097 #endif 00098 00099 unsigned char DebounceCount [CVD_NUMBER_SENSORS]; 00100 unsigned int initCounter; 00101 00102 00103 // CREATE THRESHOLD CONSTANT ARRAY // 00104 //============================================================// 00112 const unsigned int pressThreshold[] = PRESS_THRESHOLD_INIT; 00113 const unsigned int releaseThreshold[] = RELEASE_THRESHOLD_INIT; 00114 00115 00116 //************************************************************************* 00117 // mTouchCVD_Init() - mTouch Framework's Initialization Routine 00118 //************************************************************************* 00132 void mTouchCVD_Init(void) 00133 { 00134 00138 for (unsigned char i = 0; i < CVD_NUMBER_SENSORS; i++) 00139 { 00140 ButtonState [i] = CVD_INITIALIZING; 00141 DebounceCount [i] = 0; 00142 00143 #if defined(BUTTON_TIMEOUT) 00144 #if BUTTON_TIMEOUT > 0 00145 PressTimer [i] = 0; 00146 #endif 00147 #endif 00148 00149 sensor_data [i] = 0x47F; 00150 } 00151 00153 initCounter = POWER_UP_SAMPLES; 00154 00156 CVD_SET_ADC_CLK(); 00157 00159 CVD_Filter_Init(); 00160 00162 #if defined(CVD_DEBUG) && (CVD_DEBUG == 1) 00163 mTouchCVD_Comm_Init(); 00164 #endif 00165 00167 CVD_SET_TMR0IE(); 00168 CVD_SET_GIE(); 00169 00171 00176 00177 } 00179 00180 //************************************************************************* 00181 // CVD_Filter_Init() - Filtering Module's Initialization Routine 00182 //************************************************************************* 00190 void CVD_Filter_Init(void) 00191 { 00195 #if defined(AVG_ENABLE) 00196 for (unsigned char i = 0; i < CVD_NUMBER_SENSORS; i++) 00197 { 00198 Average[i] = 0; 00199 AverageCount[i] = 0; 00200 } 00201 #endif 00202 00204 } 00205 00206 //************************************************************************* 00207 // CVD_Decode() - Decoding Module's Service Routine 00208 //************************************************************************* 00218 void CVD_Decode(void) 00219 { 00224 signed int delta; 00225 00226 #if defined(CVD_DEBUG) && (CVD_DEBUG == 1) 00227 unsigned char areInitialized = 1; 00228 #endif 00229 00230 //#if defined(_PIC14) 00231 GIE = 0; // If non-enhanced core is used, prevent stack overflow by disabling 00232 // interrupts during decoding. 00233 //#endif 00234 00235 // For each active sensor... 00236 for(unsigned char i = 0; i < CVD_NUMBER_SENSORS; i++) 00237 { 00243 delta = CVDGetSensor(i) - CVD_GetAverage(i); 00244 00245 // If a negative shift is detected, clear delta value. 00246 if (delta < 0) 00247 { 00248 delta = 0; // Shifts should increase. 00249 // Setting to 0 helps to prevent triggering 00250 // on negative spikes. 00251 } 00252 00256 switch(CVD_GetButtonState(i)) // Begin state machine 00257 { 00269 case CVD_INITIALIZING: 00270 { 00271 if (--initCounter == 0) // If initialization delay has elapsed 00272 { 00273 // State Transition -> Released 00274 initCounter = 1; // Sets the initCounter variable so that 00275 // all future sensors will be immediately 00276 // transitioned to 'released'. 00277 00278 CVD_SetButtonState(CVD_RELEASED,i); // Sensor is now released and stable 00279 DebounceCount[i] = 0; // Initialize sensor's debounce counter 00280 Average[i] = CVDGetSensor(i); // Initialize sensor's average 00281 } 00282 else // If initialization delay is not complete 00283 { 00284 #if defined(CVD_DEBUG) && (CVD_DEBUG == 1) // (Only if CVD_DEBUG is enabled) 00285 areInitialized = 0; // Disable data transfer until initialized 00286 #endif 00287 Average[i] = CVDGetSensor(i); // Initialize sensor's average 00288 } 00289 break; 00290 } 00291 00310 case CVD_RELEASED: // Sensor is released and stable 00311 { 00312 00313 if(delta > pressThreshold[i]) // If reading has crossed the press threshold 00314 { 00315 if (++DebounceCount[i] > DEBOUNCE_COUNT_PRESS) // Increment the debounce counter 00316 { // and check if it has crossed its limit 00317 // State Transition -> Pressed 00318 CVD_SetButtonState(CVD_PRESSED, i); // Sensor is now pressed 00319 DebounceCount[i] = DEBOUNCE_COUNT_RELEASE; // Initialize the pressed state's debounce variable 00320 00321 #if defined(BUTTON_TIMEOUT) // If the press timer is enabled 00322 #if BUTTON_TIMEOUT > 0 00323 PressTimer[i] = BUTTON_TIMEOUT; // Initialize the press timer counter 00324 #endif 00325 #endif 00326 } 00327 } 00328 else // If the reading has not crossed the press threshold 00329 { 00330 DebounceCount[i] = 0; // Reset the debounce variable 00331 CVD_Filter_UpdateAverage(CVDGetSensor(i), i); // Update the average 00332 } 00333 break; 00334 00335 } 00336 00357 case CVD_PRESSED: 00358 { 00359 00360 #if defined(BUTTON_TIMEOUT) // (Only if the press timer has been enabled) 00361 #if BUTTON_TIMEOUT > 0 00362 00363 if (--PressTimer[i] <= 0) // Decrement the press timer counter 00364 { // and check if it has reached 0. 00365 // State Transition -> Released 00366 CVD_SetButtonState(CVD_RELEASED, i); // Sensor is now released 00367 DebounceCount[i] = 0; // Initialize the debounce counter for the CVD_PRESSED state 00368 Average[i] = CVDGetSensor(i); // Re-initialize the average to the current reading value 00369 break; 00370 } 00371 00372 #endif 00373 #endif 00374 00375 00376 if(delta < releaseThreshold[i]) // If the reading has crossed the release threshold 00377 { 00378 if (--DebounceCount[i] == 0) // Decrement the debounce counter 00379 { // and check if it has reached 0. 00380 CVD_SetButtonState(CVD_RELEASED, i); // Sensor is now released 00381 } 00382 } 00383 else // If the reading has not crossed the release threshold 00384 { 00385 DebounceCount[i] = DEBOUNCE_COUNT_RELEASE; // Reset the debounce counter 00386 } 00387 break; 00388 } 00389 00390 default: break; 00391 00392 } // End state machine switch command 00393 } // End for loop iterating over each sensor 00394 00398 #if defined(CVD_DEBUG) && (CVD_DEBUG == 1) // (Only if debugging communications are enabled) 00399 if (areInitialized) // Only trasmit data if all sensors are initialized 00400 { 00401 send_Data(); // Transmit data packet using mTouch Communication module 00402 } 00403 #endif 00404 00405 //#if defined(_PIC14) 00406 GIE = 1; // If non-enhanced core is used, re-enable interrupts. 00407 //#endif 00408 00410 } 00411 00412 //************************************************************************* 00413 // CVD_Filter_UpdateAverage() - Filtering Module 00414 //************************************************************************* 00427 void CVD_Filter_UpdateAverage(unsigned int reading, unsigned char index) 00428 { 00448 #if NEGATIVE_CAPACITANCE == 1 00449 if ((signed int)(reading - Average[index]) < 0) // If there was a negative shift 00450 { 00451 AverageCount[index] = AVG_RATE; // Set the average counter to allow an immediate average update 00452 } 00453 #elif NEGATIVE_CAPACITANCE == 2 00454 if ((signed int)(reading - Average[index]) < 0) // If there was a negative shift 00455 { 00456 Average[index] = reading; // Re-initialize the average to the current reading value 00457 return; // and return from the function - not performing the update algorithm 00458 } 00459 #endif 00460 00461 if (++AverageCount[index] >= AVG_RATE) // If the average counter has been exceeded 00462 { 00463 AverageCount[index] = 0; // Reset the average counter 00464 00465 #if (AVG_UPDATE == 2) // Calculate average update 00466 00467 // avg = (avg + reading) / 2 00468 Average[index] += reading; 00469 Average[index] >>= 1; 00470 00471 #elif (AVG_UPDATE == 4) 00472 00473 // avg = avg - (25% * avg) + (25% * reading) 00474 Average[index] -= (unsigned int)(Average[index] >> 2); 00475 Average[index] += (unsigned int)(reading >> 2); 00476 00477 #elif (AVG_UPDATE == 8) 00478 00479 // avg = avg - (12.5% * avg) + (12.5% * reading) 00480 Average[index] -= (unsigned int)(Average[index] >> 3); 00481 Average[index] += (unsigned int)(reading >> 3); 00482 00483 #elif (AVG_UPDATE == 16) 00484 00485 // avg = avg - (6.25% * avg) + (6.25% * reading) 00486 Average[index] -= (unsigned int)(Average[index] >> 4); 00487 Average[index] += (unsigned int)(reading >> 4); 00488 00489 #endif 00490 } 00492 } 00493 00494 00495