This library supports the internal QEI hardware of the LPC1768. WARNING: requires modification of the mbed module.

Dependents:   Bracky-MPU6050-DMP mbed__motor_QEIHWv2_interupt_timer_sy_2017_RD_ver020 realtimeMM_V3 realtimeMM_V3 ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers qeihw.cpp Source File

qeihw.cpp

Go to the documentation of this file.
00001  /* mbed Library - QEI driver for LP1768 hardware
00002  * Copyright (c) 2010, hball
00003  * released under MIT license http://mbed.org/licence/mit
00004  */
00005  
00006 /***********************************************************************//**
00007  * @file        qeihw.cpp
00008  * @brief       Driver file for the QEI hardware. Requires connection to
00009  *              internal mbed circuit nodes. Adapted from the CMSIS
00010  *              driver, lpc17xx_qei.c, v 2.0
00011  * @version     0.1
00012  * @date        28 Dec 2010
00013  * @author      hb
00014  **************************************************************************/
00015 #include "mbed.h"
00016 #include "qeihw.h"
00017 
00018 QEIHW *QEIHW::instance;
00019 
00020 /*********************************************************************//**
00021  * @brief        Create a QEI object and configure it.
00022  * @param _dirinv Direction invert. When = 1, complements the QEICONF register DIR bit
00023  * @param _sigmode Signal mode. When = 0, PhA and PhB are quadrature inputs. When = 1, PhA is direction and PhB is clock
00024  * @param _capmode Capture mode. When = 0, count PhA edges only (2X mode). Whe = 1, count PhB edges also (4X mode).
00025  * @param _invinx Invert index. When = 1, inverts the sense of the index signal
00026  * @return        None
00027  **********************************************************************/
00028 QEIHW::QEIHW(uint32_t _dirinv, uint32_t _sigmode, uint32_t _capmode, uint32_t _invinx)
00029 {
00030     /* Set up clock and power for QEI module */
00031     LPC_SC->PCONP |= PCONP_QEI_ENABLE;
00032 
00033     /* The clock for theQEI module is set to FCCLK  */
00034     LPC_SC->PCLKSEL1 = LPC_SC->PCLKSEL1 & ~(3UL<<0) | ((PCLKSEL_CCLK_DIV_1 & 3)<<0); 
00035 
00036     /* Assign the pins. They are hard-coded, not user-selected. The index
00037      * pin is assigned, even though it is not easily accessed on the mbed.
00038      * As it may be unconnected, it is given a pull-up resistor to minimize
00039      * power drain.
00040      */
00041     // MCI0 (PhA)
00042     LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI0_MASK) | PINSEL3_MCI0 ;
00043     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI0_MASK) | PINMODE3_MCI0;
00044 
00045     // MCI1 (PhB)
00046     LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI1_MASK) | PINSEL3_MCI1 ;
00047     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI1_MASK) | PINMODE3_MCI1;
00048 
00049     // MCI2 (Index)
00050     LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI2_MASK) | PINSEL3_MCI2 ;
00051     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_MCI2;
00052     
00053     // Initialize all remaining values in QEI peripheral
00054     LPC_QEI->QEICON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI;
00055     LPC_QEI->QEIMAXPOS = 0xFFFFFFFF;                          // Default value
00056     LPC_QEI->CMPOS0 = 0x00;
00057     LPC_QEI->CMPOS1 = 0x00;
00058     LPC_QEI->CMPOS2 = 0x00;
00059     LPC_QEI->INXCMP = 0x00;
00060     LPC_QEI->QEILOAD = 0x00;
00061     LPC_QEI->VELCOMP = 0x00;
00062     LPC_QEI->FILTER = 200000;       // Default for mechanical switches.
00063 
00064     // Set QEI configuration value corresponding to the call parameters
00065     LPC_QEI->QEICONF = (
00066         ((_dirinv << 0) & 1) | \
00067         ((_sigmode << 1) & 2) | \
00068         ((_capmode << 2) & 4) | \
00069         ((_invinx <<3) & 8) );
00070        
00071     // Mask all int sources   
00072     LPC_QEI->QEIIEC = QEI_IECLR_BITMASK;    // Set the "clear" bits for all sources in the IE clear register              
00073 
00074     // Clear any pending ints    
00075     LPC_QEI->QEICLR = QEI_INTCLR_BITMASK;   // Set the "clear" bits for for all sources in the Interrupt clear register             
00076     
00077     /* preemption = 1, sub-priority = 1 */
00078     NVIC_SetPriority(QEI_IRQn, ((0x01<<3)|0x01));
00079 
00080     //* Attach IRQ
00081     instance = this;
00082     NVIC_SetVector(QEI_IRQn, (uint32_t)&_Qeiisr);
00083 
00084     /* Enable interrupt for QEI  */
00085     NVIC_EnableIRQ(QEI_IRQn);                       
00086   
00087 }
00088 
00089 /*********************************************************************//**
00090  * @brief        Resets value for each type of QEI value, such as velocity,
00091  *                 counter, position, etc..
00092  * @param[in]    ulResetType        QEI Reset Type, should be one of the following:
00093  *                                 - QEI_RESET_POS: Reset Position Counter
00094  *                                 - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal
00095  *                                 - QEI_RESET_VEL: Reset Velocity
00096  *                                 - QEI_RESET_IDX: Reset Index Counter
00097  * @return        None
00098  **********************************************************************/
00099 void QEIHW::Reset(uint32_t ulResetType)
00100 {
00101     LPC_QEI->QEICON = ulResetType;
00102 }
00103 
00104 /*********************************************************************//**
00105  * @brief        De-initializes the QEI peripheral registers to their
00106  *                  default reset values.
00107  *
00108  * @return         None
00109  **********************************************************************/
00110 void QEIHW::DeInit()
00111 {
00112     /* Turn off clock and power for QEI module */
00113     LPC_SC->PCONP &= PCONP_QEI_DISABLE;
00114 
00115     /* Return pins to their default assignment (PINSEL = 0, PINMODE = PULLDOWN) */
00116     // MCI0 (PhA) -> LED-2 (p1.20)
00117     LPC_PINCON->PINSEL3 &= PINSEL3_MCI0_MASK;
00118     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI0_MASK) | PINMODE3_GPIO1p20;
00119 
00120     // MCI1 (PhB) -> LED-4 (p1.23)
00121     LPC_PINCON->PINSEL3 &= PINSEL3_MCI1_MASK;
00122     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI1_MASK) | PINMODE3_GPIO1p23;
00123 
00124     // MCI2 (Index) -> p1.24
00125     LPC_PINCON->PINSEL3 &= PINSEL3_MCI2_MASK;
00126     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_GPIO1p24;
00127 }
00128 
00129 /*********************************************************************//**
00130  * @brief        Report direction (QEISTAT bit DIR)
00131  *                             
00132  * @return       State of the DIR bit (SET or RESET)
00133  **********************************************************************/
00134 FlagStatus QEIHW::Direction()
00135 {
00136     return ((LPC_QEI->QEISTAT & QEI_STATUS_DIR) ? SET : RESET);
00137 }
00138 
00139 /*********************************************************************//**
00140  * @brief        Get current position value in QEI peripheral
00141  * 
00142  * @return        Current position value of QEI peripheral
00143  **********************************************************************/
00144 uint32_t QEIHW::GetPosition()
00145 {
00146     return (LPC_QEI->QEIPOS);
00147 }
00148 
00149 /*********************************************************************//**
00150  * @brief        Set max position value for QEI peripheral
00151  *
00152  * @param[in]    ulMaxPos    Max position value to set
00153  * @return        None
00154  **********************************************************************/
00155 void QEIHW::SetMaxPosition(uint32_t ulMaxPos)
00156 {
00157     LPC_QEI->QEIMAXPOS = ulMaxPos;
00158 }
00159 
00160 /*********************************************************************//**
00161  * @brief        Set position compare value for QEI peripheral
00162  * @param[in]    QEIx        QEI peripheral, should be LPC_QEI
00163  * @param[in]    bPosCompCh    Compare Position channel, should be:
00164  *                             - QEI_COMPPOS_CH_0: QEI compare position channel 0
00165  *                             - QEI_COMPPOS_CH_1: QEI compare position channel 1
00166  *                             - QEI_COMPPOS_CH_2: QEI compare position channel 2
00167  * @param[in]    ulPosComp    Compare Position value to set
00168  * @return        None
00169  **********************************************************************/
00170 void QEIHW::SetPositionComp( uint8_t bPosCompCh, uint32_t ulPosComp)
00171 {
00172     uint32_t *tmp;
00173 
00174     tmp = (uint32_t *) (&(LPC_QEI->CMPOS0) + bPosCompCh * 4);
00175     *tmp = ulPosComp;
00176 }
00177 
00178 /*********************************************************************//**
00179  * @brief        Get current index counter of QEI peripheral
00180  *
00181  * @return        Current value of QEI index counter
00182  **********************************************************************/
00183 uint32_t QEIHW::GetIndex()
00184 {
00185     return (LPC_QEI->INXCNT);
00186 }
00187 
00188 /*********************************************************************//**
00189  * @brief        Set value for index compare in QEI peripheral
00190  * @param[in]    ulIndexComp        Compare Index Value to set
00191  * @return        None
00192  **********************************************************************/
00193 void QEIHW::SetIndexComp( uint32_t ulIndexComp)
00194 {
00195     LPC_QEI->INXCMP = ulIndexComp;
00196 }
00197 
00198 /*********************************************************************//**
00199  * @brief        Set Velocity timer reload value
00200  *
00201  * @param[in]    ulReloadValue    Velocity timer reload count
00202  * @return        None
00203  **********************************************************************/
00204 void QEIHW::SetVelocityTimerReload( uint32_t ulReloadValue)
00205 {   
00206          LPC_QEI->QEILOAD = ulReloadValue;
00207 }
00208 
00209 /*********************************************************************//**
00210  * @brief        Set Velocity timer reload value in microseconds
00211  *
00212  * @param[in]    ulReloadValue    Velocity timer reload count
00213  * @return        None
00214  **********************************************************************/
00215 void QEIHW::SetVelocityTimerReload_us( uint32_t ulReloadValue)
00216 {
00217     int div;
00218 
00219     //Work out CCLK
00220     uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
00221     uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1;
00222     uint32_t cclkdiv = LPC_SC->CCLKCFG + 1;
00223     uint32_t Fcco = (2 * m * XTAL_FREQ) / n;
00224     uint32_t cclk = Fcco / cclkdiv;
00225     
00226 
00227     
00228 //    div = CLKPWR_GetPCLKSEL(ClkType);
00229     div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK;
00230     switch (div)
00231     {
00232     case 0:
00233         div = 4;
00234         break;
00235 
00236     case 1:
00237         div = 1;
00238         break;
00239 
00240     case 2:
00241         div = 2;
00242         break;
00243 
00244     case 3:
00245         div = 8;
00246         break;
00247     }
00248     cclk /=div;
00249     cclk =((uint64_t)cclk / (1000000/ulReloadValue)) - 1;
00250     LPC_QEI->QEILOAD = (uint32_t) cclk;
00251 }
00252 
00253 /*********************************************************************//**
00254  * @brief        Get current timer counter in QEI peripheral
00255  * 
00256  * @return        Current timer counter in QEI peripheral
00257  **********************************************************************/
00258 uint32_t QEIHW::GetTimer()
00259 {
00260     return (LPC_QEI->QEITIME);
00261 }
00262 
00263 /*********************************************************************//**
00264  * @brief        Get current velocity pulse counter in current time period
00265  * 
00266  * @return        Current velocity pulse counter value
00267  **********************************************************************/
00268 uint32_t QEIHW::GetVelocity()
00269 {
00270     return (LPC_QEI->QEIVEL);
00271 }
00272 
00273 /*********************************************************************//**
00274  * @brief        Get the most recently captured velocity of the QEI. When
00275  *                 the Velocity timer in QEI is over-flow, the current velocity
00276  *                 value will be loaded into Velocity Capture register.
00277  * 
00278  * @return        The most recently measured velocity value
00279  **********************************************************************/
00280 uint32_t QEIHW::GetVelocityCap()
00281 {
00282     return (LPC_QEI->QEICAP);
00283 }
00284 
00285 /*********************************************************************//**
00286  * @brief        Set Velocity Compare value for QEI peripheral
00287  *
00288  * @param[in]    ulVelComp        Compare Velocity value to set
00289  * @return        None
00290  **********************************************************************/
00291 void QEIHW::SetVelocityComp( uint32_t ulVelComp)
00292 {
00293     LPC_QEI->VELCOMP = ulVelComp;
00294 }
00295 
00296 /*********************************************************************//**
00297  * @brief        Set value of sampling count for the digital filter in
00298  *                 QEI peripheral
00299  * 
00300  * @param[in]    ulSamplingPulse    Value of sampling count to set
00301  * @return        None
00302  **********************************************************************/
00303 void QEIHW::SetDigiFilter( uint32_t ulSamplingPulse)
00304 {
00305     LPC_QEI->FILTER = ulSamplingPulse;
00306 }
00307 
00308 /*********************************************************************//**
00309  * @brief        Check whether if specified interrupt flag status in QEI
00310  *                 peripheral is set or not
00311  * 
00312  * @param[in]    ulIntType        Interrupt Flag Status type, should be:
00313                                 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
00314                                 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
00315                                 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
00316                                 - QEI_INTFLAG_DIR_Int: Change of direction interrupt
00317                                 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
00318                                 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
00319                                 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
00320                                                         current position interrupt
00321                                 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
00322                                                         current position interrupt
00323                                 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
00324                                                         current position interrupt
00325                                 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
00326                                                         index count interrupt
00327                                 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
00328                                 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
00329                                 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
00330  * @return        New State of specified interrupt flag status (SET or RESET)
00331  **********************************************************************/
00332 FlagStatus QEIHW::GetIntStatus( uint32_t ulIntType)
00333 {
00334     return((LPC_QEI->QEIINTSTAT & ulIntType) ? SET : RESET);
00335 }
00336 
00337 /*********************************************************************//**
00338  * @brief        Enable/Disable specified interrupt in QEI peripheral
00339  * 
00340  * @param[in]    ulIntType        Interrupt Flag Status type, should be:
00341  *                                - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
00342  *                                - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
00343  *                                - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
00344  *                                - QEI_INTFLAG_DIR_Int: Change of direction interrupt
00345  *                                - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
00346  *                                - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
00347  *                                - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
00348  *                                                        current position interrupt
00349  *                                - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
00350  *                                                        current position interrupt
00351  *                                - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
00352  *                                                        current position interrupt
00353  *                                - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
00354  *                                                        index count interrupt
00355  *                                - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
00356  *                                - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
00357  *                                - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
00358  * @param[in]    NewState        New function state, should be:
00359  *                                - DISABLE
00360  *                                - ENABLE
00361  * @return        None
00362  **********************************************************************/
00363 void QEIHW::IntCmd( uint32_t ulIntType, FunctionalState NewState)
00364 {
00365     if (NewState == ENABLE) {
00366         LPC_QEI->QEIIES = ulIntType;
00367     } else {
00368         LPC_QEI->QEIIEC = ulIntType;
00369     }
00370 }
00371 
00372 /*********************************************************************//**
00373  * @brief       Assert specified interrupt in QEI peripheral
00374  * 
00375  * @param[in]    ulIntType        Interrupt Flag Status type, should be:
00376                                 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
00377                                 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
00378                                 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
00379                                 - QEI_INTFLAG_DIR_Int: Change of direction interrupt
00380                                 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
00381                                 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
00382                                 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
00383                                                         current position interrupt
00384                                 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
00385                                                         current position interrupt
00386                                 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
00387                                                         current position interrupt
00388                                 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
00389                                                         index count interrupt
00390                                 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
00391                                 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
00392                                 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
00393  * @return        None
00394  **********************************************************************/
00395 void QEIHW::IntSet( uint32_t ulIntType)
00396 {
00397     LPC_QEI->QEISET = ulIntType;
00398 }
00399 
00400 /*********************************************************************//**
00401  * @brief       De-assert specified interrupt (pending) in QEI peripheral
00402  * 
00403  * @param[in]    ulIntType        Interrupt Flag Status type, should be:
00404                                 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
00405                                 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
00406                                 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
00407                                 - QEI_INTFLAG_DIR_Int: Change of direction interrupt
00408                                 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
00409                                 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
00410                                 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
00411                                                         current position interrupt
00412                                 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
00413                                                         current position interrupt
00414                                 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
00415                                                         current position interrupt
00416                                 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
00417                                                         index count interrupt
00418                                 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
00419                                 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
00420                                 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
00421  * @return        None
00422  **********************************************************************/
00423 void QEIHW::IntClear( uint32_t ulIntType)
00424 {
00425     LPC_QEI->QEICLR = ulIntType;
00426 }
00427 
00428 /*********************************************************************//**
00429  * @brief        Calculates the actual velocity in RPM passed via velocity
00430  *                 capture value and Pulse Per Revolution (of the encoder) value
00431  *                 parameter input.
00432  * 
00433  * @param[in]    ulVelCapValue    Velocity capture input value that can
00434  *                                 be got from QEI_GetVelocityCap() function
00435  * @param[in]    ulPPR            Pulse per round of encoder
00436  * @return        The actual value of velocity in RPM (Revolutions per minute)
00437  **********************************************************************/
00438 uint32_t QEIHW::CalculateRPM( uint32_t ulVelCapValue, uint32_t ulPPR)
00439 {
00440     uint64_t rpm, Load, edges;
00441     int div;
00442     
00443     // Get current Clock rate for timer input
00444     //Work out CCLK
00445     uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
00446     uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1;
00447     uint32_t cclkdiv = LPC_SC->CCLKCFG + 1;
00448     uint32_t Fcco = (2 * m * XTAL_FREQ) / n;
00449     uint32_t cclk = Fcco / cclkdiv;
00450     
00451 //    div = CLKPWR_GetPCLKSEL(ClkType);
00452     div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK;
00453     switch (div)
00454     {
00455     case 0:
00456         div = 4;
00457         break;
00458 
00459     case 1:
00460         div = 1;
00461         break;
00462 
00463     case 2:
00464         div = 2;
00465         break;
00466 
00467     case 3:
00468         div = 8;
00469         break;
00470     }
00471     cclk /= div;
00472     
00473     // Get Timer load value (velocity capture period)
00474     Load  = (uint64_t)(LPC_QEI->QEILOAD + 1);
00475     // Get Edge
00476     edges = (uint64_t)((LPC_QEI->QEICONF & QEI_CONF_CAPMODE) ? 4 : 2);
00477     // Calculate RPM
00478     rpm = ((( uint64_t)cclk * ulVelCapValue * 60) / (Load * ulPPR * edges));
00479 
00480     return (uint32_t)(rpm);
00481 }
00482 
00483 /*********************************************************************//**
00484  * @brief        Append interrupt handler for specific QEI interrupt source
00485  * 
00486  * @param[in]    ulISRType        Interrupt Flag Status type, should be:
00487  *                                - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
00488  *                                - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
00489  *                                - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
00490  *                                - QEI_INTFLAG_DIR_Int: Change of direction interrupt
00491  *                                - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
00492  *                                - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
00493  *                                - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
00494  *                                                        current position interrupt
00495  *                                - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
00496  *                                                        current position interrupt
00497  *                                - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
00498  *                                                        current position interrupt
00499  *                                - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
00500  *                                                        index count interrupt
00501  *                                - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
00502  *                                - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
00503  *                                - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
00504  *                                 
00505  * @return       none
00506  **********************************************************************/
00507 void QEIHW::AppendISR(uint32_t ulISRType, void(*fptr)(void)) {
00508     int i;
00509     
00510     for(i = 0; i < 13; i++) {
00511         if( ulISRType == (1UL << i) ) {
00512             _qei_isr[i] = fptr;
00513             break;
00514         }
00515     }
00516     return;
00517 }
00518 
00519 /*********************************************************************//**
00520  * @brief        Unappend interrupt handler for specific QEI interrupt source
00521  * 
00522  * @param[in]    ulISRType        Interrupt Flag Status type, should be:
00523  *                                - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
00524  *                                - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
00525  *                                - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
00526  *                                - QEI_INTFLAG_DIR_Int: Change of direction interrupt
00527  *                                - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
00528  *                                - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
00529  *                                - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
00530  *                                                        current position interrupt
00531  *                                - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
00532  *                                                        current position interrupt
00533  *                                - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
00534  *                                                        current position interrupt
00535  *                                - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
00536  *                                                        index count interrupt
00537  *                                - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
00538  *                                - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
00539  *                                - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
00540  *                                 
00541  * @return       none
00542  **********************************************************************/
00543 void QEIHW::UnAppendISR(uint32_t ulISRType) {
00544     int i;
00545     
00546     for(i = 0; i < 13; i++) {
00547         if( ulISRType == (1UL << i) ) {
00548             _qei_isr[i] = NULL;
00549             break;
00550         }
00551     }
00552     return;
00553 }
00554 
00555 
00556 void QEIHW::_Qeiisr(void)
00557 {
00558     instance->Qeiisr();
00559 }
00560 
00561 /*********************************************************************//**
00562  * @brief        QEI interrupt service dispatcher. 
00563  * 
00564  * @param[in]    none
00565  *                                 
00566  * @return       none
00567  **********************************************************************/
00568 void QEIHW::Qeiisr(void)  
00569 {
00570     int32_t i;
00571 
00572     //User defined interrupt handlers. Check all possible sources, dispatch to corresponding non-null service routines.
00573     for(i = 0; i < 13; i++) {
00574         if(LPC_QEI->QEIINTSTAT & ((uint32_t)(1<<i)) ) {
00575             if (_qei_isr[i] != NULL) {
00576                 _qei_isr[i]();
00577             }
00578         }
00579     }
00580     return;
00581 }
00582