Keil MBC1700 demoboard and L293, QEI ,TFT, MOTOR, UART

Dependencies:   mbed Motor

Committer:
fblanc
Date:
Fri Mar 02 14:18:23 2012 +0000
Revision:
0:9555690e7705
v1.0

Who changed what in which revision?

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