Force controlled vibration analysis

Dependencies:   mbed

Committer:
eembed
Date:
Tue Dec 03 10:40:16 2019 +0000
Revision:
5:9ab19c63203e
Parent:
0:5459cdde6298
first commit;

Who changed what in which revision?

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