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

Committer:
hexley
Date:
Sat Dec 11 01:34:35 2010 +0000
Revision:
0:20a27391f6dc
Child:
2:53f8ae2cf502
Initial release

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hexley 0:20a27391f6dc 1 /* mbed Library - QEI driver for LP1768 hardware
hexley 0:20a27391f6dc 2 * Copyright (c) 2010, hball
hexley 0:20a27391f6dc 3 * released under MIT license http://mbed.org/licence/mit
hexley 0:20a27391f6dc 4 */
hexley 0:20a27391f6dc 5
hexley 0:20a27391f6dc 6 /***********************************************************************//**
hexley 0:20a27391f6dc 7 * @file qeihw.cpp
hexley 0:20a27391f6dc 8 * @brief Driver file for the QEI hardware. Requires connection to
hexley 0:20a27391f6dc 9 * internal mbed circuit nodes. Adapted from the CMSIS
hexley 0:20a27391f6dc 10 * driver, lpc17xx_qei.c, v 2.0
hexley 0:20a27391f6dc 11 * @version 0.0
hexley 0:20a27391f6dc 12 * @date 10 Dec 2010
hexley 0:20a27391f6dc 13 * @author hb
hexley 0:20a27391f6dc 14 **************************************************************************/
hexley 0:20a27391f6dc 15 #include "mbed.h"
hexley 0:20a27391f6dc 16 #include "qeihw.h"
hexley 0:20a27391f6dc 17
hexley 0:20a27391f6dc 18 QEIHW *QEIHW::instance;
hexley 0:20a27391f6dc 19
hexley 0:20a27391f6dc 20 /*********************************************************************//**
hexley 0:20a27391f6dc 21 * @brief Create a QEI object and configure it.
hexley 0:20a27391f6dc 22 * @param _dirinv Direction invert. When = 1, complements the QEICONF register DIR bit
hexley 0:20a27391f6dc 23 * @param _sigmode Signal mode. When = 0, PhA and PhB are quadrature inputs. When = 1, PhA is direction and PhB is clock
hexley 0:20a27391f6dc 24 * @param _capmode Capture mode. When = 0, count PhA edges only (2X mode). Whe = 1, count PhB edges also (4X mode).
hexley 0:20a27391f6dc 25 * @param _invinx Invert index. When = 1, inverts the sense of the index signal
hexley 0:20a27391f6dc 26 * @return None
hexley 0:20a27391f6dc 27 **********************************************************************/
hexley 0:20a27391f6dc 28 QEIHW::QEIHW(uint32_t _dirinv, uint32_t _sigmode, uint32_t _capmode, uint32_t _invinx)
hexley 0:20a27391f6dc 29 {
hexley 0:20a27391f6dc 30 /* Set up clock and power for QEI module */
hexley 0:20a27391f6dc 31 LPC_SC->PCONP |= PCONP_QEI_ENABLE;
hexley 0:20a27391f6dc 32
hexley 0:20a27391f6dc 33 /* The clock for theQEI module is set to FCCLK */
hexley 0:20a27391f6dc 34 LPC_SC->PCLKSEL1 = LPC_SC->PCLKSEL1 & ~(3UL<<0) | ((PCLKSEL_CCLK_DIV_1 & 3)<<0);
hexley 0:20a27391f6dc 35
hexley 0:20a27391f6dc 36 /* Assign the pins. They are hard-coded, not user-selected. The index
hexley 0:20a27391f6dc 37 * pin is assigned, even though it is not easily accessed on the mbed.
hexley 0:20a27391f6dc 38 * As it may be unconnected, it is given a pull-up resistor to minimize
hexley 0:20a27391f6dc 39 * power drain.
hexley 0:20a27391f6dc 40 */
hexley 0:20a27391f6dc 41 // MCI0 (PhA)
hexley 0:20a27391f6dc 42 LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI0_MASK) | PINSEL3_MCI0 ;
hexley 0:20a27391f6dc 43 LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI0_MASK) | PINMODE3_MCI0;
hexley 0:20a27391f6dc 44
hexley 0:20a27391f6dc 45 // MCI1 (PhB)
hexley 0:20a27391f6dc 46 LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI1_MASK) | PINSEL3_MCI1 ;
hexley 0:20a27391f6dc 47 LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI1_MASK) | PINMODE3_MCI1;
hexley 0:20a27391f6dc 48
hexley 0:20a27391f6dc 49 // MCI2 (Index)
hexley 0:20a27391f6dc 50 LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI2_MASK) | PINSEL3_MCI2 ;
hexley 0:20a27391f6dc 51 LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_MCI2;
hexley 0:20a27391f6dc 52
hexley 0:20a27391f6dc 53 // Initialize all remaining values in QEI peripheral
hexley 0:20a27391f6dc 54 LPC_QEI->QEICON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI;
hexley 0:20a27391f6dc 55 LPC_QEI->QEIMAXPOS = 0xFFFFFFFF; // Default value
hexley 0:20a27391f6dc 56 LPC_QEI->CMPOS0 = 0x00;
hexley 0:20a27391f6dc 57 LPC_QEI->CMPOS1 = 0x00;
hexley 0:20a27391f6dc 58 LPC_QEI->CMPOS2 = 0x00;
hexley 0:20a27391f6dc 59 LPC_QEI->INXCMP = 0x00;
hexley 0:20a27391f6dc 60 LPC_QEI->QEILOAD = 0x00;
hexley 0:20a27391f6dc 61 LPC_QEI->VELCOMP = 0x00;
hexley 0:20a27391f6dc 62 LPC_QEI->FILTER = 200000; // Default for mechanical switches.
hexley 0:20a27391f6dc 63
hexley 0:20a27391f6dc 64 // Set QEI configuration value corresponding to the call parameters
hexley 0:20a27391f6dc 65 LPC_QEI->QEICONF = (
hexley 0:20a27391f6dc 66 ((_dirinv << 0) & 1) | \
hexley 0:20a27391f6dc 67 ((_sigmode << 1) & 2) | \
hexley 0:20a27391f6dc 68 ((_capmode << 2) & 4) | \
hexley 0:20a27391f6dc 69 ((_invinx <<3) & 8) );
hexley 0:20a27391f6dc 70
hexley 0:20a27391f6dc 71 // Mask all int sources
hexley 0:20a27391f6dc 72 LPC_QEI->QEIIEC = QEI_IECLR_BITMASK; // Set the "clear" bits for all sources in the IE clear register
hexley 0:20a27391f6dc 73
hexley 0:20a27391f6dc 74 // Clear any pending ints
hexley 0:20a27391f6dc 75 LPC_QEI->QEICLR = QEI_INTCLR_BITMASK; // Set the "clear" bits for for all sources in the Interrupt clear register
hexley 0:20a27391f6dc 76
hexley 0:20a27391f6dc 77 /* preemption = 1, sub-priority = 1 */
hexley 0:20a27391f6dc 78 NVIC_SetPriority(QEI_IRQn, ((0x01<<3)|0x01));
hexley 0:20a27391f6dc 79
hexley 0:20a27391f6dc 80 //* Attach IRQ
hexley 0:20a27391f6dc 81 instance = this;
hexley 0:20a27391f6dc 82 NVIC_SetVector(QEI_IRQn, (uint32_t)&_Qeiisr);
hexley 0:20a27391f6dc 83
hexley 0:20a27391f6dc 84 /* Enable interrupt for QEI */
hexley 0:20a27391f6dc 85 NVIC_EnableIRQ(QEI_IRQn);
hexley 0:20a27391f6dc 86
hexley 0:20a27391f6dc 87 }
hexley 0:20a27391f6dc 88
hexley 0:20a27391f6dc 89 /*********************************************************************//**
hexley 0:20a27391f6dc 90 * @brief Resets value for each type of QEI value, such as velocity,
hexley 0:20a27391f6dc 91 * counter, position, etc..
hexley 0:20a27391f6dc 92 * @param[in] ulResetType QEI Reset Type, should be one of the following:
hexley 0:20a27391f6dc 93 * - QEI_RESET_POS: Reset Position Counter
hexley 0:20a27391f6dc 94 * - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal
hexley 0:20a27391f6dc 95 * - QEI_RESET_VEL: Reset Velocity
hexley 0:20a27391f6dc 96 * - QEI_RESET_IDX: Reset Index Counter
hexley 0:20a27391f6dc 97 * @return None
hexley 0:20a27391f6dc 98 **********************************************************************/
hexley 0:20a27391f6dc 99 void QEIHW::Reset(uint32_t ulResetType)
hexley 0:20a27391f6dc 100 {
hexley 0:20a27391f6dc 101 LPC_QEI->QEICON = ulResetType;
hexley 0:20a27391f6dc 102 }
hexley 0:20a27391f6dc 103
hexley 0:20a27391f6dc 104 /*********************************************************************//**
hexley 0:20a27391f6dc 105 * @brief De-initializes the QEI peripheral registers to their
hexley 0:20a27391f6dc 106 * default reset values.
hexley 0:20a27391f6dc 107 *
hexley 0:20a27391f6dc 108 * @return None
hexley 0:20a27391f6dc 109 **********************************************************************/
hexley 0:20a27391f6dc 110 void QEIHW::DeInit()
hexley 0:20a27391f6dc 111 {
hexley 0:20a27391f6dc 112 /* Turn off clock and power for QEI module */
hexley 0:20a27391f6dc 113 LPC_SC->PCONP &= PCONP_QEI_DISABLE;
hexley 0:20a27391f6dc 114
hexley 0:20a27391f6dc 115 /* Return pins to their default assignment (PINSEL = 0, PINMODE = PULLDOWN) */
hexley 0:20a27391f6dc 116 // MCI0 (PhA) -> LED-2 (p1.20)
hexley 0:20a27391f6dc 117 LPC_PINCON->PINSEL3 &= PINSEL3_MCI0_MASK;
hexley 0:20a27391f6dc 118 LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI0_MASK) | PINMODE3_GPIO1p20;
hexley 0:20a27391f6dc 119
hexley 0:20a27391f6dc 120 // MCI1 (PhB) -> LED-4 (p1.23)
hexley 0:20a27391f6dc 121 LPC_PINCON->PINSEL3 &= PINSEL3_MCI1_MASK;
hexley 0:20a27391f6dc 122 LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI1_MASK) | PINMODE3_GPIO1p23;
hexley 0:20a27391f6dc 123
hexley 0:20a27391f6dc 124 // MCI2 (Index) -> p1.24
hexley 0:20a27391f6dc 125 LPC_PINCON->PINSEL3 &= PINSEL3_MCI2_MASK;
hexley 0:20a27391f6dc 126 LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_GPIO1p24;
hexley 0:20a27391f6dc 127 }
hexley 0:20a27391f6dc 128
hexley 0:20a27391f6dc 129 /*********************************************************************//**
hexley 0:20a27391f6dc 130 * @brief Report direction (QEISTAT bit DIR)
hexley 0:20a27391f6dc 131 *
hexley 0:20a27391f6dc 132 * @return State of the DIR bit (SET or RESET)
hexley 0:20a27391f6dc 133 **********************************************************************/
hexley 0:20a27391f6dc 134 FlagStatus QEIHW::Direction()
hexley 0:20a27391f6dc 135 {
hexley 0:20a27391f6dc 136 return ((LPC_QEI->QEISTAT & QEI_STATUS_DIR) ? SET : RESET);
hexley 0:20a27391f6dc 137 }
hexley 0:20a27391f6dc 138
hexley 0:20a27391f6dc 139 /*********************************************************************//**
hexley 0:20a27391f6dc 140 * @brief Get current position value in QEI peripheral
hexley 0:20a27391f6dc 141 *
hexley 0:20a27391f6dc 142 * @return Current position value of QEI peripheral
hexley 0:20a27391f6dc 143 **********************************************************************/
hexley 0:20a27391f6dc 144 uint32_t QEIHW::GetPosition()
hexley 0:20a27391f6dc 145 {
hexley 0:20a27391f6dc 146 return (LPC_QEI->QEIPOS);
hexley 0:20a27391f6dc 147 }
hexley 0:20a27391f6dc 148
hexley 0:20a27391f6dc 149 /*********************************************************************//**
hexley 0:20a27391f6dc 150 * @brief Set max position value for QEI peripheral
hexley 0:20a27391f6dc 151 *
hexley 0:20a27391f6dc 152 * @param[in] ulMaxPos Max position value to set
hexley 0:20a27391f6dc 153 * @return None
hexley 0:20a27391f6dc 154 **********************************************************************/
hexley 0:20a27391f6dc 155 void QEIHW::SetMaxPosition(uint32_t ulMaxPos)
hexley 0:20a27391f6dc 156 {
hexley 0:20a27391f6dc 157 LPC_QEI->QEIMAXPOS = ulMaxPos;
hexley 0:20a27391f6dc 158 }
hexley 0:20a27391f6dc 159
hexley 0:20a27391f6dc 160 /*********************************************************************//**
hexley 0:20a27391f6dc 161 * @brief Set position compare value for QEI peripheral
hexley 0:20a27391f6dc 162 * @param[in] QEIx QEI peripheral, should be LPC_QEI
hexley 0:20a27391f6dc 163 * @param[in] bPosCompCh Compare Position channel, should be:
hexley 0:20a27391f6dc 164 * - QEI_COMPPOS_CH_0: QEI compare position channel 0
hexley 0:20a27391f6dc 165 * - QEI_COMPPOS_CH_1: QEI compare position channel 1
hexley 0:20a27391f6dc 166 * - QEI_COMPPOS_CH_2: QEI compare position channel 2
hexley 0:20a27391f6dc 167 * @param[in] ulPosComp Compare Position value to set
hexley 0:20a27391f6dc 168 * @return None
hexley 0:20a27391f6dc 169 **********************************************************************/
hexley 0:20a27391f6dc 170 void QEIHW::SetPositionComp( uint8_t bPosCompCh, uint32_t ulPosComp)
hexley 0:20a27391f6dc 171 {
hexley 0:20a27391f6dc 172 uint32_t *tmp;
hexley 0:20a27391f6dc 173
hexley 0:20a27391f6dc 174 tmp = (uint32_t *) (&(LPC_QEI->CMPOS0) + bPosCompCh * 4);
hexley 0:20a27391f6dc 175 *tmp = ulPosComp;
hexley 0:20a27391f6dc 176 }
hexley 0:20a27391f6dc 177
hexley 0:20a27391f6dc 178 /*********************************************************************//**
hexley 0:20a27391f6dc 179 * @brief Get current index counter of QEI peripheral
hexley 0:20a27391f6dc 180 *
hexley 0:20a27391f6dc 181 * @return Current value of QEI index counter
hexley 0:20a27391f6dc 182 **********************************************************************/
hexley 0:20a27391f6dc 183 uint32_t QEIHW::GetIndex()
hexley 0:20a27391f6dc 184 {
hexley 0:20a27391f6dc 185 return (LPC_QEI->INXCNT);
hexley 0:20a27391f6dc 186 }
hexley 0:20a27391f6dc 187
hexley 0:20a27391f6dc 188 /*********************************************************************//**
hexley 0:20a27391f6dc 189 * @brief Set value for index compare in QEI peripheral
hexley 0:20a27391f6dc 190 * @param[in] ulIndexComp Compare Index Value to set
hexley 0:20a27391f6dc 191 * @return None
hexley 0:20a27391f6dc 192 **********************************************************************/
hexley 0:20a27391f6dc 193 void QEIHW::SetIndexComp( uint32_t ulIndexComp)
hexley 0:20a27391f6dc 194 {
hexley 0:20a27391f6dc 195 LPC_QEI->INXCMP = ulIndexComp;
hexley 0:20a27391f6dc 196 }
hexley 0:20a27391f6dc 197
hexley 0:20a27391f6dc 198 /*********************************************************************//**
hexley 0:20a27391f6dc 199 * @brief Set Velocity timer reload value
hexley 0:20a27391f6dc 200 *
hexley 0:20a27391f6dc 201 * @param[in] ulReloadValue Velocity timer reload count
hexley 0:20a27391f6dc 202 * @return None
hexley 0:20a27391f6dc 203 **********************************************************************/
hexley 0:20a27391f6dc 204 void QEIHW::SetVelocityTimerReload( uint32_t ulReloadValue)
hexley 0:20a27391f6dc 205 {
hexley 0:20a27391f6dc 206 LPC_QEI->QEILOAD = ulReloadValue;
hexley 0:20a27391f6dc 207 }
hexley 0:20a27391f6dc 208
hexley 0:20a27391f6dc 209 /*********************************************************************//**
hexley 0:20a27391f6dc 210 * @brief Set Velocity timer reload value in microseconds
hexley 0:20a27391f6dc 211 *
hexley 0:20a27391f6dc 212 * @param[in] ulReloadValue Velocity timer reload count
hexley 0:20a27391f6dc 213 * @return None
hexley 0:20a27391f6dc 214 **********************************************************************/
hexley 0:20a27391f6dc 215 void QEIHW::SetVelocityTimerReload_us( uint32_t ulReloadValue)
hexley 0:20a27391f6dc 216 {
hexley 0:20a27391f6dc 217 int div;
hexley 0:20a27391f6dc 218
hexley 0:20a27391f6dc 219 //Work out CCLK
hexley 0:20a27391f6dc 220 uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
hexley 0:20a27391f6dc 221 uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1;
hexley 0:20a27391f6dc 222 uint32_t cclkdiv = LPC_SC->CCLKCFG + 1;
hexley 0:20a27391f6dc 223 uint32_t Fcco = (2 * m * XTAL_FREQ) / n;
hexley 0:20a27391f6dc 224 uint32_t cclk = Fcco / cclkdiv;
hexley 0:20a27391f6dc 225
hexley 0:20a27391f6dc 226
hexley 0:20a27391f6dc 227
hexley 0:20a27391f6dc 228 // div = CLKPWR_GetPCLKSEL(ClkType);
hexley 0:20a27391f6dc 229 div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK;
hexley 0:20a27391f6dc 230 switch (div)
hexley 0:20a27391f6dc 231 {
hexley 0:20a27391f6dc 232 case 0:
hexley 0:20a27391f6dc 233 div = 4;
hexley 0:20a27391f6dc 234 break;
hexley 0:20a27391f6dc 235
hexley 0:20a27391f6dc 236 case 1:
hexley 0:20a27391f6dc 237 div = 1;
hexley 0:20a27391f6dc 238 break;
hexley 0:20a27391f6dc 239
hexley 0:20a27391f6dc 240 case 2:
hexley 0:20a27391f6dc 241 div = 2;
hexley 0:20a27391f6dc 242 break;
hexley 0:20a27391f6dc 243
hexley 0:20a27391f6dc 244 case 3:
hexley 0:20a27391f6dc 245 div = 8;
hexley 0:20a27391f6dc 246 break;
hexley 0:20a27391f6dc 247 }
hexley 0:20a27391f6dc 248 LPC_QEI->QEILOAD = cclk;
hexley 0:20a27391f6dc 249 }
hexley 0:20a27391f6dc 250
hexley 0:20a27391f6dc 251 /*********************************************************************//**
hexley 0:20a27391f6dc 252 * @brief Get current timer counter in QEI peripheral
hexley 0:20a27391f6dc 253 *
hexley 0:20a27391f6dc 254 * @return Current timer counter in QEI peripheral
hexley 0:20a27391f6dc 255 **********************************************************************/
hexley 0:20a27391f6dc 256 uint32_t QEIHW::GetTimer()
hexley 0:20a27391f6dc 257 {
hexley 0:20a27391f6dc 258 return (LPC_QEI->QEITIME);
hexley 0:20a27391f6dc 259 }
hexley 0:20a27391f6dc 260
hexley 0:20a27391f6dc 261 /*********************************************************************//**
hexley 0:20a27391f6dc 262 * @brief Get current velocity pulse counter in current time period
hexley 0:20a27391f6dc 263 *
hexley 0:20a27391f6dc 264 * @return Current velocity pulse counter value
hexley 0:20a27391f6dc 265 **********************************************************************/
hexley 0:20a27391f6dc 266 uint32_t QEIHW::GetVelocity()
hexley 0:20a27391f6dc 267 {
hexley 0:20a27391f6dc 268 return (LPC_QEI->QEIVEL);
hexley 0:20a27391f6dc 269 }
hexley 0:20a27391f6dc 270
hexley 0:20a27391f6dc 271 /*********************************************************************//**
hexley 0:20a27391f6dc 272 * @brief Get the most recently captured velocity of the QEI. When
hexley 0:20a27391f6dc 273 * the Velocity timer in QEI is over-flow, the current velocity
hexley 0:20a27391f6dc 274 * value will be loaded into Velocity Capture register.
hexley 0:20a27391f6dc 275 *
hexley 0:20a27391f6dc 276 * @return The most recently measured velocity value
hexley 0:20a27391f6dc 277 **********************************************************************/
hexley 0:20a27391f6dc 278 uint32_t QEIHW::GetVelocityCap()
hexley 0:20a27391f6dc 279 {
hexley 0:20a27391f6dc 280 return (LPC_QEI->QEICAP);
hexley 0:20a27391f6dc 281 }
hexley 0:20a27391f6dc 282
hexley 0:20a27391f6dc 283 /*********************************************************************//**
hexley 0:20a27391f6dc 284 * @brief Set Velocity Compare value for QEI peripheral
hexley 0:20a27391f6dc 285 *
hexley 0:20a27391f6dc 286 * @param[in] ulVelComp Compare Velocity value to set
hexley 0:20a27391f6dc 287 * @return None
hexley 0:20a27391f6dc 288 **********************************************************************/
hexley 0:20a27391f6dc 289 void QEIHW::SetVelocityComp( uint32_t ulVelComp)
hexley 0:20a27391f6dc 290 {
hexley 0:20a27391f6dc 291 LPC_QEI->VELCOMP = ulVelComp;
hexley 0:20a27391f6dc 292 }
hexley 0:20a27391f6dc 293
hexley 0:20a27391f6dc 294 /*********************************************************************//**
hexley 0:20a27391f6dc 295 * @brief Set value of sampling count for the digital filter in
hexley 0:20a27391f6dc 296 * QEI peripheral
hexley 0:20a27391f6dc 297 *
hexley 0:20a27391f6dc 298 * @param[in] ulSamplingPulse Value of sampling count to set
hexley 0:20a27391f6dc 299 * @return None
hexley 0:20a27391f6dc 300 **********************************************************************/
hexley 0:20a27391f6dc 301 void QEIHW::SetDigiFilter( uint32_t ulSamplingPulse)
hexley 0:20a27391f6dc 302 {
hexley 0:20a27391f6dc 303 LPC_QEI->FILTER = ulSamplingPulse;
hexley 0:20a27391f6dc 304 }
hexley 0:20a27391f6dc 305
hexley 0:20a27391f6dc 306 /*********************************************************************//**
hexley 0:20a27391f6dc 307 * @brief Check whether if specified interrupt flag status in QEI
hexley 0:20a27391f6dc 308 * peripheral is set or not
hexley 0:20a27391f6dc 309 *
hexley 0:20a27391f6dc 310 * @param[in] ulIntType Interrupt Flag Status type, should be:
hexley 0:20a27391f6dc 311 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
hexley 0:20a27391f6dc 312 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
hexley 0:20a27391f6dc 313 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
hexley 0:20a27391f6dc 314 - QEI_INTFLAG_DIR_Int: Change of direction interrupt
hexley 0:20a27391f6dc 315 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
hexley 0:20a27391f6dc 316 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
hexley 0:20a27391f6dc 317 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
hexley 0:20a27391f6dc 318 current position interrupt
hexley 0:20a27391f6dc 319 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
hexley 0:20a27391f6dc 320 current position interrupt
hexley 0:20a27391f6dc 321 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
hexley 0:20a27391f6dc 322 current position interrupt
hexley 0:20a27391f6dc 323 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
hexley 0:20a27391f6dc 324 index count interrupt
hexley 0:20a27391f6dc 325 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
hexley 0:20a27391f6dc 326 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
hexley 0:20a27391f6dc 327 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
hexley 0:20a27391f6dc 328 * @return New State of specified interrupt flag status (SET or RESET)
hexley 0:20a27391f6dc 329 **********************************************************************/
hexley 0:20a27391f6dc 330 FlagStatus QEIHW::GetIntStatus( uint32_t ulIntType)
hexley 0:20a27391f6dc 331 {
hexley 0:20a27391f6dc 332 return((LPC_QEI->QEIINTSTAT & ulIntType) ? SET : RESET);
hexley 0:20a27391f6dc 333 }
hexley 0:20a27391f6dc 334
hexley 0:20a27391f6dc 335 /*********************************************************************//**
hexley 0:20a27391f6dc 336 * @brief Enable/Disable specified interrupt in QEI peripheral
hexley 0:20a27391f6dc 337 *
hexley 0:20a27391f6dc 338 * @param[in] ulIntType Interrupt Flag Status type, should be:
hexley 0:20a27391f6dc 339 * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
hexley 0:20a27391f6dc 340 * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
hexley 0:20a27391f6dc 341 * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
hexley 0:20a27391f6dc 342 * - QEI_INTFLAG_DIR_Int: Change of direction interrupt
hexley 0:20a27391f6dc 343 * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
hexley 0:20a27391f6dc 344 * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
hexley 0:20a27391f6dc 345 * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
hexley 0:20a27391f6dc 346 * current position interrupt
hexley 0:20a27391f6dc 347 * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
hexley 0:20a27391f6dc 348 * current position interrupt
hexley 0:20a27391f6dc 349 * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
hexley 0:20a27391f6dc 350 * current position interrupt
hexley 0:20a27391f6dc 351 * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
hexley 0:20a27391f6dc 352 * index count interrupt
hexley 0:20a27391f6dc 353 * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
hexley 0:20a27391f6dc 354 * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
hexley 0:20a27391f6dc 355 * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
hexley 0:20a27391f6dc 356 * @param[in] NewState New function state, should be:
hexley 0:20a27391f6dc 357 * - DISABLE
hexley 0:20a27391f6dc 358 * - ENABLE
hexley 0:20a27391f6dc 359 * @return None
hexley 0:20a27391f6dc 360 **********************************************************************/
hexley 0:20a27391f6dc 361 void QEIHW::IntCmd( uint32_t ulIntType, FunctionalState NewState)
hexley 0:20a27391f6dc 362 {
hexley 0:20a27391f6dc 363 if (NewState == ENABLE) {
hexley 0:20a27391f6dc 364 LPC_QEI->QEIIES = ulIntType;
hexley 0:20a27391f6dc 365 } else {
hexley 0:20a27391f6dc 366 LPC_QEI->QEIIEC = ulIntType;
hexley 0:20a27391f6dc 367 }
hexley 0:20a27391f6dc 368 }
hexley 0:20a27391f6dc 369
hexley 0:20a27391f6dc 370 /*********************************************************************//**
hexley 0:20a27391f6dc 371 * @brief Assert specified interrupt in QEI peripheral
hexley 0:20a27391f6dc 372 *
hexley 0:20a27391f6dc 373 * @param[in] ulIntType Interrupt Flag Status type, should be:
hexley 0:20a27391f6dc 374 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
hexley 0:20a27391f6dc 375 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
hexley 0:20a27391f6dc 376 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
hexley 0:20a27391f6dc 377 - QEI_INTFLAG_DIR_Int: Change of direction interrupt
hexley 0:20a27391f6dc 378 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
hexley 0:20a27391f6dc 379 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
hexley 0:20a27391f6dc 380 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
hexley 0:20a27391f6dc 381 current position interrupt
hexley 0:20a27391f6dc 382 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
hexley 0:20a27391f6dc 383 current position interrupt
hexley 0:20a27391f6dc 384 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
hexley 0:20a27391f6dc 385 current position interrupt
hexley 0:20a27391f6dc 386 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
hexley 0:20a27391f6dc 387 index count interrupt
hexley 0:20a27391f6dc 388 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
hexley 0:20a27391f6dc 389 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
hexley 0:20a27391f6dc 390 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
hexley 0:20a27391f6dc 391 * @return None
hexley 0:20a27391f6dc 392 **********************************************************************/
hexley 0:20a27391f6dc 393 void QEIHW::IntSet( uint32_t ulIntType)
hexley 0:20a27391f6dc 394 {
hexley 0:20a27391f6dc 395 LPC_QEI->QEISET = ulIntType;
hexley 0:20a27391f6dc 396 }
hexley 0:20a27391f6dc 397
hexley 0:20a27391f6dc 398 /*********************************************************************//**
hexley 0:20a27391f6dc 399 * @brief De-assert specified interrupt (pending) in QEI peripheral
hexley 0:20a27391f6dc 400 *
hexley 0:20a27391f6dc 401 * @param[in] ulIntType Interrupt Flag Status type, should be:
hexley 0:20a27391f6dc 402 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
hexley 0:20a27391f6dc 403 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
hexley 0:20a27391f6dc 404 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
hexley 0:20a27391f6dc 405 - QEI_INTFLAG_DIR_Int: Change of direction interrupt
hexley 0:20a27391f6dc 406 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
hexley 0:20a27391f6dc 407 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
hexley 0:20a27391f6dc 408 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
hexley 0:20a27391f6dc 409 current position interrupt
hexley 0:20a27391f6dc 410 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
hexley 0:20a27391f6dc 411 current position interrupt
hexley 0:20a27391f6dc 412 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
hexley 0:20a27391f6dc 413 current position interrupt
hexley 0:20a27391f6dc 414 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
hexley 0:20a27391f6dc 415 index count interrupt
hexley 0:20a27391f6dc 416 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
hexley 0:20a27391f6dc 417 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
hexley 0:20a27391f6dc 418 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
hexley 0:20a27391f6dc 419 * @return None
hexley 0:20a27391f6dc 420 **********************************************************************/
hexley 0:20a27391f6dc 421 void QEIHW::IntClear( uint32_t ulIntType)
hexley 0:20a27391f6dc 422 {
hexley 0:20a27391f6dc 423 LPC_QEI->QEICLR = ulIntType;
hexley 0:20a27391f6dc 424 }
hexley 0:20a27391f6dc 425
hexley 0:20a27391f6dc 426 /*********************************************************************//**
hexley 0:20a27391f6dc 427 * @brief Calculates the actual velocity in RPM passed via velocity
hexley 0:20a27391f6dc 428 * capture value and Pulse Per Revolution (of the encoder) value
hexley 0:20a27391f6dc 429 * parameter input.
hexley 0:20a27391f6dc 430 *
hexley 0:20a27391f6dc 431 * @param[in] ulVelCapValue Velocity capture input value that can
hexley 0:20a27391f6dc 432 * be got from QEI_GetVelocityCap() function
hexley 0:20a27391f6dc 433 * @param[in] ulPPR Pulse per round of encoder
hexley 0:20a27391f6dc 434 * @return The actual value of velocity in RPM (Revolutions per minute)
hexley 0:20a27391f6dc 435 **********************************************************************/
hexley 0:20a27391f6dc 436 uint32_t QEIHW::CalculateRPM( uint32_t ulVelCapValue, uint32_t ulPPR)
hexley 0:20a27391f6dc 437 {
hexley 0:20a27391f6dc 438 uint64_t rpm, Load, edges;
hexley 0:20a27391f6dc 439 int div;
hexley 0:20a27391f6dc 440
hexley 0:20a27391f6dc 441 // Get current Clock rate for timer input
hexley 0:20a27391f6dc 442 //Work out CCLK
hexley 0:20a27391f6dc 443 uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
hexley 0:20a27391f6dc 444 uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1;
hexley 0:20a27391f6dc 445 uint32_t cclkdiv = LPC_SC->CCLKCFG + 1;
hexley 0:20a27391f6dc 446 uint32_t Fcco = (2 * m * XTAL_FREQ) / n;
hexley 0:20a27391f6dc 447 uint32_t cclk = Fcco / cclkdiv;
hexley 0:20a27391f6dc 448
hexley 0:20a27391f6dc 449 // div = CLKPWR_GetPCLKSEL(ClkType);
hexley 0:20a27391f6dc 450 div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK;
hexley 0:20a27391f6dc 451 switch (div)
hexley 0:20a27391f6dc 452 {
hexley 0:20a27391f6dc 453 case 0:
hexley 0:20a27391f6dc 454 div = 4;
hexley 0:20a27391f6dc 455 break;
hexley 0:20a27391f6dc 456
hexley 0:20a27391f6dc 457 case 1:
hexley 0:20a27391f6dc 458 div = 1;
hexley 0:20a27391f6dc 459 break;
hexley 0:20a27391f6dc 460
hexley 0:20a27391f6dc 461 case 2:
hexley 0:20a27391f6dc 462 div = 2;
hexley 0:20a27391f6dc 463 break;
hexley 0:20a27391f6dc 464
hexley 0:20a27391f6dc 465 case 3:
hexley 0:20a27391f6dc 466 div = 8;
hexley 0:20a27391f6dc 467 break;
hexley 0:20a27391f6dc 468 }
hexley 0:20a27391f6dc 469 cclk /= div;
hexley 0:20a27391f6dc 470
hexley 0:20a27391f6dc 471 // Get Timer load value (velocity capture period)
hexley 0:20a27391f6dc 472 Load = (uint64_t)(LPC_QEI->QEILOAD + 1);
hexley 0:20a27391f6dc 473 // Get Edge
hexley 0:20a27391f6dc 474 edges = (uint64_t)((LPC_QEI->QEICONF & QEI_CONF_CAPMODE) ? 4 : 2);
hexley 0:20a27391f6dc 475 // Calculate RPM
hexley 0:20a27391f6dc 476 rpm = ((( uint64_t)cclk * ulVelCapValue * 60) / (Load * ulPPR * edges));
hexley 0:20a27391f6dc 477
hexley 0:20a27391f6dc 478 return (uint32_t)(rpm);
hexley 0:20a27391f6dc 479 }
hexley 0:20a27391f6dc 480
hexley 0:20a27391f6dc 481 /*********************************************************************//**
hexley 0:20a27391f6dc 482 * @brief Append interrupt handler for specific QEI interrupt source
hexley 0:20a27391f6dc 483 *
hexley 0:20a27391f6dc 484 * @param[in] ulISRType Interrupt Flag Status type, should be:
hexley 0:20a27391f6dc 485 * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
hexley 0:20a27391f6dc 486 * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
hexley 0:20a27391f6dc 487 * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
hexley 0:20a27391f6dc 488 * - QEI_INTFLAG_DIR_Int: Change of direction interrupt
hexley 0:20a27391f6dc 489 * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
hexley 0:20a27391f6dc 490 * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
hexley 0:20a27391f6dc 491 * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
hexley 0:20a27391f6dc 492 * current position interrupt
hexley 0:20a27391f6dc 493 * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
hexley 0:20a27391f6dc 494 * current position interrupt
hexley 0:20a27391f6dc 495 * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
hexley 0:20a27391f6dc 496 * current position interrupt
hexley 0:20a27391f6dc 497 * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
hexley 0:20a27391f6dc 498 * index count interrupt
hexley 0:20a27391f6dc 499 * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
hexley 0:20a27391f6dc 500 * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
hexley 0:20a27391f6dc 501 * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
hexley 0:20a27391f6dc 502 *
hexley 0:20a27391f6dc 503 * @return none
hexley 0:20a27391f6dc 504 **********************************************************************/
hexley 0:20a27391f6dc 505 void QEIHW::AppendISR(uint32_t ulISRType, void(*fptr)(void)) {
hexley 0:20a27391f6dc 506 int i;
hexley 0:20a27391f6dc 507
hexley 0:20a27391f6dc 508 for(i = 0; i < 13; i++) {
hexley 0:20a27391f6dc 509 if( ulISRType == (1UL << i) ) {
hexley 0:20a27391f6dc 510 _qei_isr[i] = fptr;
hexley 0:20a27391f6dc 511 break;
hexley 0:20a27391f6dc 512 }
hexley 0:20a27391f6dc 513 }
hexley 0:20a27391f6dc 514 return;
hexley 0:20a27391f6dc 515 }
hexley 0:20a27391f6dc 516
hexley 0:20a27391f6dc 517 /*********************************************************************//**
hexley 0:20a27391f6dc 518 * @brief Unappend interrupt handler for specific QEI interrupt source
hexley 0:20a27391f6dc 519 *
hexley 0:20a27391f6dc 520 * @param[in] ulISRType Interrupt Flag Status type, should be:
hexley 0:20a27391f6dc 521 * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt
hexley 0:20a27391f6dc 522 * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt
hexley 0:20a27391f6dc 523 * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt
hexley 0:20a27391f6dc 524 * - QEI_INTFLAG_DIR_Int: Change of direction interrupt
hexley 0:20a27391f6dc 525 * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt
hexley 0:20a27391f6dc 526 * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt
hexley 0:20a27391f6dc 527 * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the
hexley 0:20a27391f6dc 528 * current position interrupt
hexley 0:20a27391f6dc 529 * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the
hexley 0:20a27391f6dc 530 * current position interrupt
hexley 0:20a27391f6dc 531 * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the
hexley 0:20a27391f6dc 532 * current position interrupt
hexley 0:20a27391f6dc 533 * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current
hexley 0:20a27391f6dc 534 * index count interrupt
hexley 0:20a27391f6dc 535 * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt
hexley 0:20a27391f6dc 536 * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt
hexley 0:20a27391f6dc 537 * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt
hexley 0:20a27391f6dc 538 *
hexley 0:20a27391f6dc 539 * @return none
hexley 0:20a27391f6dc 540 **********************************************************************/
hexley 0:20a27391f6dc 541 void QEIHW::UnAppendISR(uint32_t ulISRType) {
hexley 0:20a27391f6dc 542 int i;
hexley 0:20a27391f6dc 543
hexley 0:20a27391f6dc 544 for(i = 0; i < 13; i++) {
hexley 0:20a27391f6dc 545 if( ulISRType == (1UL << i) ) {
hexley 0:20a27391f6dc 546 _qei_isr[i] = NULL;
hexley 0:20a27391f6dc 547 break;
hexley 0:20a27391f6dc 548 }
hexley 0:20a27391f6dc 549 }
hexley 0:20a27391f6dc 550 return;
hexley 0:20a27391f6dc 551 }
hexley 0:20a27391f6dc 552
hexley 0:20a27391f6dc 553
hexley 0:20a27391f6dc 554 void QEIHW::_Qeiisr(void)
hexley 0:20a27391f6dc 555 {
hexley 0:20a27391f6dc 556 instance->Qeiisr();
hexley 0:20a27391f6dc 557 }
hexley 0:20a27391f6dc 558
hexley 0:20a27391f6dc 559 /*********************************************************************//**
hexley 0:20a27391f6dc 560 * @brief QEI interrupt service dispatcher.
hexley 0:20a27391f6dc 561 *
hexley 0:20a27391f6dc 562 * @param[in] none
hexley 0:20a27391f6dc 563 *
hexley 0:20a27391f6dc 564 * @return none
hexley 0:20a27391f6dc 565 **********************************************************************/
hexley 0:20a27391f6dc 566 void QEIHW::Qeiisr(void)
hexley 0:20a27391f6dc 567 {
hexley 0:20a27391f6dc 568 int32_t i;
hexley 0:20a27391f6dc 569
hexley 0:20a27391f6dc 570 //User defined interrupt handlers. Check all possible sources, dispatch to corresponding non-null service routines.
hexley 0:20a27391f6dc 571 for(i = 0; i < 13; i++) {
hexley 0:20a27391f6dc 572 if(LPC_QEI->QEIINTSTAT & ((uint32_t)(1<<i)) ) {
hexley 0:20a27391f6dc 573 if (_qei_isr[i] != NULL) {
hexley 0:20a27391f6dc 574 _qei_isr[i]();
hexley 0:20a27391f6dc 575 }
hexley 0:20a27391f6dc 576 }
hexley 0:20a27391f6dc 577 }
hexley 0:20a27391f6dc 578 return;
hexley 0:20a27391f6dc 579 }
hexley 0:20a27391f6dc 580