lpc17xx_qei.c (21230B)
1 /********************************************************************** 2 * $Id$ lpc17xx_qei.c 2010-05-21 3 *//** 4 * @file lpc17xx_qei.c 5 * @brief Contains all functions support for QEI firmware library on LPC17xx 6 * @version 2.0 7 * @date 21. May. 2010 8 * @author NXP MCU SW Application Team 9 * 10 * Copyright(C) 2010, NXP Semiconductor 11 * All rights reserved. 12 * 13 *********************************************************************** 14 * Software that is described herein is for illustrative purposes only 15 * which provides customers with programming information regarding the 16 * products. This software is supplied "AS IS" without any warranties. 17 * NXP Semiconductors assumes no responsibility or liability for the 18 * use of the software, conveys no license or title under any patent, 19 * copyright, or mask work right to the product. NXP Semiconductors 20 * reserves the right to make changes in the software without 21 * notification. NXP Semiconductors also make no representation or 22 * warranty that such application will be suitable for the specified 23 * use without further testing or modification. 24 * Permission to use, copy, modify, and distribute this software and its 25 * documentation is hereby granted, under NXP Semiconductors' 26 * relevant copyright in the software, without fee, provided that it 27 * is used in conjunction with NXP Semiconductors microcontrollers. This 28 * copyright, permission, and disclaimer notice must appear in all copies of 29 * this code. 30 **********************************************************************/ 31 32 /* Peripheral group ----------------------------------------------------------- */ 33 /** @addtogroup QEI 34 * @{ 35 */ 36 37 /* Includes ------------------------------------------------------------------- */ 38 #include "lpc17xx_qei.h" 39 #include "lpc17xx_clkpwr.h" 40 41 42 /* If this source file built with example, the LPC17xx FW library configuration 43 * file in each example directory ("lpc17xx_libcfg.h") must be included, 44 * otherwise the default FW library configuration file must be included instead 45 */ 46 #ifdef __BUILD_WITH_EXAMPLE__ 47 #include "lpc17xx_libcfg.h" 48 #else 49 #include "lpc17xx_libcfg_default.h" 50 #endif /* __BUILD_WITH_EXAMPLE__ */ 51 52 53 #ifdef _QEI 54 55 /* Private Types -------------------------------------------------------------- */ 56 /** @defgroup QEI_Private_Types QEI Private Types 57 * @{ 58 */ 59 60 /** 61 * @brief QEI configuration union type definition 62 */ 63 typedef union { 64 QEI_CFG_Type bmQEIConfig; 65 uint32_t ulQEIConfig; 66 } QEI_CFGOPT_Type; 67 68 /** 69 * @} 70 */ 71 72 73 /* Public Functions ----------------------------------------------------------- */ 74 /** @addtogroup QEI_Public_Functions 75 * @{ 76 */ 77 78 /*********************************************************************//** 79 * @brief Resets value for each type of QEI value, such as velocity, 80 * counter, position, etc.. 81 * @param[in] QEIx QEI peripheral, should be LPC_QEI 82 * @param[in] ulResetType QEI Reset Type, should be one of the following: 83 * - QEI_RESET_POS: Reset Position Counter 84 * - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal 85 * - QEI_RESET_VEL: Reset Velocity 86 * - QEI_RESET_IDX: Reset Index Counter 87 * @return None 88 **********************************************************************/ 89 void QEI_Reset(LPC_QEI_TypeDef *QEIx, uint32_t ulResetType) 90 { 91 CHECK_PARAM(PARAM_QEIx(QEIx)); 92 CHECK_PARAM(PARAM_QEI_RESET(ulResetType)); 93 94 QEIx->QEICON = ulResetType; 95 } 96 97 /*********************************************************************//** 98 * @brief Initializes the QEI peripheral according to the specified 99 * parameters in the QEI_ConfigStruct. 100 * @param[in] QEIx QEI peripheral, should be LPC_QEI 101 * @param[in] QEI_ConfigStruct Pointer to a QEI_CFG_Type structure 102 * that contains the configuration information for the 103 * specified QEI peripheral 104 * @return None 105 **********************************************************************/ 106 void QEI_Init(LPC_QEI_TypeDef *QEIx, QEI_CFG_Type *QEI_ConfigStruct) 107 { 108 109 CHECK_PARAM(PARAM_QEIx(QEIx)); 110 CHECK_PARAM(PARAM_QEI_DIRINV(QEI_ConfigStruct->DirectionInvert)); 111 CHECK_PARAM(PARAM_QEI_SIGNALMODE(QEI_ConfigStruct->SignalMode)); 112 CHECK_PARAM(PARAM_QEI_CAPMODE(QEI_ConfigStruct->CaptureMode)); 113 CHECK_PARAM(PARAM_QEI_INVINX(QEI_ConfigStruct->InvertIndex)); 114 115 /* Set up clock and power for QEI module */ 116 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCQEI, ENABLE); 117 118 /* As default, peripheral clock for QEI module 119 * is set to FCCLK / 2 */ 120 CLKPWR_SetPCLKDiv(CLKPWR_PCLKSEL_QEI, CLKPWR_PCLKSEL_CCLK_DIV_1); 121 122 // Reset all remaining value in QEI peripheral 123 QEIx->QEICON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI; 124 QEIx->QEIMAXPOS = 0x00; 125 QEIx->CMPOS0 = 0x00; 126 QEIx->CMPOS1 = 0x00; 127 QEIx->CMPOS2 = 0x00; 128 QEIx->INXCMP = 0x00; 129 QEIx->QEILOAD = 0x00; 130 QEIx->VELCOMP = 0x00; 131 QEIx->FILTER = 0x00; 132 // Disable all Interrupt 133 QEIx->QEIIEC = QEI_IECLR_BITMASK; 134 // Clear all Interrupt pending 135 QEIx->QEICLR = QEI_INTCLR_BITMASK; 136 // Set QEI configuration value corresponding to its setting up value 137 QEIx->QEICONF = ((QEI_CFGOPT_Type *)QEI_ConfigStruct)->ulQEIConfig; 138 } 139 140 141 /*********************************************************************//** 142 * @brief De-initializes the QEI peripheral registers to their 143 * default reset values. 144 * @param[in] QEIx QEI peripheral, should be LPC_QEI 145 * @return None 146 **********************************************************************/ 147 void QEI_DeInit(LPC_QEI_TypeDef *QEIx) 148 { 149 CHECK_PARAM(PARAM_QEIx(QEIx)); 150 151 /* Turn off clock and power for QEI module */ 152 CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCQEI, DISABLE); 153 } 154 155 156 /*****************************************************************************//** 157 * @brief Fills each QIE_InitStruct member with its default value: 158 * - DirectionInvert = QEI_DIRINV_NONE 159 * - SignalMode = QEI_SIGNALMODE_QUAD 160 * - CaptureMode = QEI_CAPMODE_4X 161 * - InvertIndex = QEI_INVINX_NONE 162 * @param[in] QIE_InitStruct Pointer to a QEI_CFG_Type structure 163 * which will be initialized. 164 * @return None 165 *******************************************************************************/ 166 void QEI_ConfigStructInit(QEI_CFG_Type *QIE_InitStruct) 167 { 168 QIE_InitStruct->CaptureMode = QEI_CAPMODE_4X; 169 QIE_InitStruct->DirectionInvert = QEI_DIRINV_NONE; 170 QIE_InitStruct->InvertIndex = QEI_INVINX_NONE; 171 QIE_InitStruct->SignalMode = QEI_SIGNALMODE_QUAD; 172 } 173 174 175 /*********************************************************************//** 176 * @brief Check whether if specified flag status is set or not 177 * @param[in] QEIx QEI peripheral, should be LPC_QEI 178 * @param[in] ulFlagType Status Flag Type, should be one of the following: 179 * - QEI_STATUS_DIR: Direction Status 180 * @return New Status of this status flag (SET or RESET) 181 **********************************************************************/ 182 FlagStatus QEI_GetStatus(LPC_QEI_TypeDef *QEIx, uint32_t ulFlagType) 183 { 184 CHECK_PARAM(PARAM_QEIx(QEIx)); 185 CHECK_PARAM(PARAM_QEI_STATUS(ulFlagType)); 186 return ((QEIx->QEISTAT & ulFlagType) ? SET : RESET); 187 } 188 189 /*********************************************************************//** 190 * @brief Get current position value in QEI peripheral 191 * @param[in] QEIx QEI peripheral, should be LPC_QEI 192 * @return Current position value of QEI peripheral 193 **********************************************************************/ 194 uint32_t QEI_GetPosition(LPC_QEI_TypeDef *QEIx) 195 { 196 CHECK_PARAM(PARAM_QEIx(QEIx)); 197 return (QEIx->QEIPOS); 198 } 199 200 /*********************************************************************//** 201 * @brief Set max position value for QEI peripheral 202 * @param[in] QEIx QEI peripheral, should be LPC_QEI 203 * @param[in] ulMaxPos Max position value to set 204 * @return None 205 **********************************************************************/ 206 void QEI_SetMaxPosition(LPC_QEI_TypeDef *QEIx, uint32_t ulMaxPos) 207 { 208 CHECK_PARAM(PARAM_QEIx(QEIx)); 209 QEIx->QEIMAXPOS = ulMaxPos; 210 } 211 212 /*********************************************************************//** 213 * @brief Set position compare value for QEI peripheral 214 * @param[in] QEIx QEI peripheral, should be LPC_QEI 215 * @param[in] bPosCompCh Compare Position channel, should be: 216 * - QEI_COMPPOS_CH_0: QEI compare position channel 0 217 * - QEI_COMPPOS_CH_1: QEI compare position channel 1 218 * - QEI_COMPPOS_CH_2: QEI compare position channel 2 219 * @param[in] ulPosComp Compare Position value to set 220 * @return None 221 **********************************************************************/ 222 void QEI_SetPositionComp(LPC_QEI_TypeDef *QEIx, uint8_t bPosCompCh, uint32_t ulPosComp) 223 { 224 uint32_t *tmp; 225 226 CHECK_PARAM(PARAM_QEIx(QEIx)); 227 CHECK_PARAM(PARAM_QEI_COMPPOS_CH(bPosCompCh)); 228 tmp = (uint32_t *) (&(QEIx->CMPOS0) + bPosCompCh * 4); 229 *tmp = ulPosComp; 230 231 } 232 233 /*********************************************************************//** 234 * @brief Get current index counter of QEI peripheral 235 * @param[in] QEIx QEI peripheral, should be LPC_QEI 236 * @return Current value of QEI index counter 237 **********************************************************************/ 238 uint32_t QEI_GetIndex(LPC_QEI_TypeDef *QEIx) 239 { 240 CHECK_PARAM(PARAM_QEIx(QEIx)); 241 return (QEIx->INXCNT); 242 } 243 244 /*********************************************************************//** 245 * @brief Set value for index compare in QEI peripheral 246 * @param[in] QEIx QEI peripheral, should be LPC_QEI 247 * @param[in] ulIndexComp Compare Index Value to set 248 * @return None 249 **********************************************************************/ 250 void QEI_SetIndexComp(LPC_QEI_TypeDef *QEIx, uint32_t ulIndexComp) 251 { 252 CHECK_PARAM(PARAM_QEIx(QEIx)); 253 QEIx->INXCMP = ulIndexComp; 254 } 255 256 /*********************************************************************//** 257 * @brief Set timer reload value for QEI peripheral. When the velocity timer is 258 * over-flow, the value that set for Timer Reload register will be loaded 259 * into the velocity timer for next period. The calculated velocity in RPM 260 * therefore will be affect by this value. 261 * @param[in] QEIx QEI peripheral, should be LPC_QEI 262 * @param[in] QEIReloadStruct QEI reload structure 263 * @return None 264 **********************************************************************/ 265 void QEI_SetTimerReload(LPC_QEI_TypeDef *QEIx, QEI_RELOADCFG_Type *QEIReloadStruct) 266 { 267 uint64_t pclk; 268 269 CHECK_PARAM(PARAM_QEIx(QEIx)); 270 CHECK_PARAM(PARAM_QEI_TIMERRELOAD(QEIReloadStruct->ReloadOption)); 271 272 if (QEIReloadStruct->ReloadOption == QEI_TIMERRELOAD_TICKVAL) { 273 QEIx->QEILOAD = QEIReloadStruct->ReloadValue - 1; 274 } else { 275 pclk = (uint64_t)CLKPWR_GetPCLK(CLKPWR_PCLKSEL_QEI); 276 pclk = (pclk /(1000000/QEIReloadStruct->ReloadValue)) - 1; 277 QEIx->QEILOAD = (uint32_t)pclk; 278 } 279 } 280 281 /*********************************************************************//** 282 * @brief Get current timer counter in QEI peripheral 283 * @param[in] QEIx QEI peripheral, should be LPC_QEI 284 * @return Current timer counter in QEI peripheral 285 **********************************************************************/ 286 uint32_t QEI_GetTimer(LPC_QEI_TypeDef *QEIx) 287 { 288 CHECK_PARAM(PARAM_QEIx(QEIx)); 289 return (QEIx->QEITIME); 290 } 291 292 /*********************************************************************//** 293 * @brief Get current velocity pulse counter in current time period 294 * @param[in] QEIx QEI peripheral, should be LPC_QEI 295 * @return Current velocity pulse counter value 296 **********************************************************************/ 297 uint32_t QEI_GetVelocity(LPC_QEI_TypeDef *QEIx) 298 { 299 CHECK_PARAM(PARAM_QEIx(QEIx)); 300 return (QEIx->QEIVEL); 301 } 302 303 /*********************************************************************//** 304 * @brief Get the most recently measured velocity of the QEI. When 305 * the Velocity timer in QEI is over-flow, the current velocity 306 * value will be loaded into Velocity Capture register. 307 * @param[in] QEIx QEI peripheral, should be LPC_QEI 308 * @return The most recently measured velocity value 309 **********************************************************************/ 310 uint32_t QEI_GetVelocityCap(LPC_QEI_TypeDef *QEIx) 311 { 312 CHECK_PARAM(PARAM_QEIx(QEIx)); 313 return (QEIx->QEICAP); 314 } 315 316 /*********************************************************************//** 317 * @brief Set Velocity Compare value for QEI peripheral 318 * @param[in] QEIx QEI peripheral, should be LPC_QEI 319 * @param[in] ulVelComp Compare Velocity value to set 320 * @return None 321 **********************************************************************/ 322 void QEI_SetVelocityComp(LPC_QEI_TypeDef *QEIx, uint32_t ulVelComp) 323 { 324 CHECK_PARAM(PARAM_QEIx(QEIx)); 325 QEIx->VELCOMP = ulVelComp; 326 } 327 328 /*********************************************************************//** 329 * @brief Set value of sampling count for the digital filter in 330 * QEI peripheral 331 * @param[in] QEIx QEI peripheral, should be LPC_QEI 332 * @param[in] ulSamplingPulse Value of sampling count to set 333 * @return None 334 **********************************************************************/ 335 void QEI_SetDigiFilter(LPC_QEI_TypeDef *QEIx, uint32_t ulSamplingPulse) 336 { 337 CHECK_PARAM(PARAM_QEIx(QEIx)); 338 QEIx->FILTER = ulSamplingPulse; 339 } 340 341 /*********************************************************************//** 342 * @brief Check whether if specified interrupt flag status in QEI 343 * peripheral is set or not 344 * @param[in] QEIx QEI peripheral, should be LPC_QEI 345 * @param[in] ulIntType Interrupt Flag Status type, should be: 346 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt 347 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt 348 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt 349 - QEI_INTFLAG_DIR_Int: Change of direction interrupt 350 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt 351 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt 352 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the 353 current position interrupt 354 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the 355 current position interrupt 356 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the 357 current position interrupt 358 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current 359 index count interrupt 360 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt 361 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt 362 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt 363 * @return New State of specified interrupt flag status (SET or RESET) 364 **********************************************************************/ 365 FlagStatus QEI_GetIntStatus(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType) 366 { 367 CHECK_PARAM(PARAM_QEIx(QEIx)); 368 CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType)); 369 370 return((QEIx->QEIINTSTAT & ulIntType) ? SET : RESET); 371 } 372 373 /*********************************************************************//** 374 * @brief Enable/Disable specified interrupt in QEI peripheral 375 * @param[in] QEIx QEI peripheral, should be LPC_QEI 376 * @param[in] ulIntType Interrupt Flag Status type, should be: 377 * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt 378 * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt 379 * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt 380 * - QEI_INTFLAG_DIR_Int: Change of direction interrupt 381 * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt 382 * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt 383 * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the 384 * current position interrupt 385 * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the 386 * current position interrupt 387 * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the 388 * current position interrupt 389 * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current 390 * index count interrupt 391 * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt 392 * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt 393 * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt 394 * @param[in] NewState New function state, should be: 395 * - DISABLE 396 * - ENABLE 397 * @return None 398 **********************************************************************/ 399 void QEI_IntCmd(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType, FunctionalState NewState) 400 { 401 CHECK_PARAM(PARAM_QEIx(QEIx)); 402 CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType)); 403 CHECK_PARAM(PARAM_FUNCTIONALSTATE(NewState)); 404 405 if (NewState == ENABLE) { 406 QEIx->QEIIES = ulIntType; 407 } else { 408 QEIx->QEIIEC = ulIntType; 409 } 410 } 411 412 413 /*********************************************************************//** 414 * @brief Sets (forces) specified interrupt in QEI peripheral 415 * @param[in] QEIx QEI peripheral, should be LPC_QEI 416 * @param[in] ulIntType Interrupt Flag Status type, should be: 417 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt 418 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt 419 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt 420 - QEI_INTFLAG_DIR_Int: Change of direction interrupt 421 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt 422 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt 423 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the 424 current position interrupt 425 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the 426 current position interrupt 427 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the 428 current position interrupt 429 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current 430 index count interrupt 431 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt 432 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt 433 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt 434 * @return None 435 **********************************************************************/ 436 void QEI_IntSet(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType) 437 { 438 CHECK_PARAM(PARAM_QEIx(QEIx)); 439 CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType)); 440 441 QEIx->QEISET = ulIntType; 442 } 443 444 /*********************************************************************//** 445 * @brief Clear (force) specified interrupt (pending) in QEI peripheral 446 * @param[in] QEIx QEI peripheral, should be LPC_QEI 447 * @param[in] ulIntType Interrupt Flag Status type, should be: 448 - QEI_INTFLAG_INX_Int: index pulse was detected interrupt 449 - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt 450 - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt 451 - QEI_INTFLAG_DIR_Int: Change of direction interrupt 452 - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt 453 - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt 454 - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the 455 current position interrupt 456 - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the 457 current position interrupt 458 - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the 459 current position interrupt 460 - QEI_INTFLAG_REV_Int: Index compare value is equal to the current 461 index count interrupt 462 - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt 463 - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt 464 - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt 465 * @return None 466 **********************************************************************/ 467 void QEI_IntClear(LPC_QEI_TypeDef *QEIx, uint32_t ulIntType) 468 { 469 CHECK_PARAM(PARAM_QEIx(QEIx)); 470 CHECK_PARAM(PARAM_QEI_INTFLAG(ulIntType)); 471 472 QEIx->QEICLR = ulIntType; 473 } 474 475 476 /*********************************************************************//** 477 * @brief Calculates the actual velocity in RPM passed via velocity 478 * capture value and Pulse Per Round (of the encoder) value 479 * parameter input. 480 * @param[in] QEIx QEI peripheral, should be LPC_QEI 481 * @param[in] ulVelCapValue Velocity capture input value that can 482 * be got from QEI_GetVelocityCap() function 483 * @param[in] ulPPR Pulse per round of encoder 484 * @return The actual value of velocity in RPM (Round per minute) 485 **********************************************************************/ 486 uint32_t QEI_CalculateRPM(LPC_QEI_TypeDef *QEIx, uint32_t ulVelCapValue, uint32_t ulPPR) 487 { 488 uint64_t rpm, clock, Load, edges; 489 490 // Get current Clock rate for timer input 491 clock = (uint64_t)CLKPWR_GetPCLK(CLKPWR_PCLKSEL_QEI); 492 // Get Timer load value (velocity capture period) 493 Load = (uint64_t)(QEIx->QEILOAD + 1); 494 // Get Edge 495 edges = (uint64_t)((QEIx->QEICONF & QEI_CONF_CAPMODE) ? 4 : 2); 496 // Calculate RPM 497 rpm = ((clock * ulVelCapValue * 60) / (Load * ulPPR * edges)); 498 499 return (uint32_t)(rpm); 500 } 501 502 503 /** 504 * @} 505 */ 506 507 #endif /* _QEI */ 508 509 /** 510 * @} 511 */ 512 513 /* --------------------------------- End Of File ------------------------------ */ 514