control speed motor PID QEIHW MOTOR

Committer:
fblanc
Date:
Wed Jul 18 13:06:05 2012 +0000
Revision:
0:37964304d479
[mbed] converted /Aubaine/QEI_hw_m

Who changed what in which revision?

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