frederic blanc
/
qei_hw_motor
Keil MBC1700 demoboard and L293, QEI ,TFT, MOTOR, UART
Revision 0:9555690e7705, committed 2012-03-02
- Comitter:
- fblanc
- Date:
- Fri Mar 02 14:18:23 2012 +0000
- Commit message:
- v1.0
Changed in this revision
diff -r 000000000000 -r 9555690e7705 GLCD_MCB1700.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GLCD_MCB1700.lib Fri Mar 02 14:18:23 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/fblanc/code/GLCD_MCB1700/#b96b9110daf9
diff -r 000000000000 -r 9555690e7705 Motor.lib --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Motor.lib Fri Mar 02 14:18:23 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/simon/code/Motor/#f265e441bcd9
diff -r 000000000000 -r 9555690e7705 QEI_hw_m/qeihw.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QEI_hw_m/qeihw.cpp Fri Mar 02 14:18:23 2012 +0000 @@ -0,0 +1,584 @@ + /* mbed Library - QEI driver for LP1768 hardware + * Copyright (c) 2010, hball + * released under MIT license http://mbed.org/licence/mit + * modification QEIHW::SetPositionComp line 174 + * tmp = (uint32_t*)(((uint8_t*)&(LPC_QEI->CMPOS0)) + (bPosCompCh << 2)); + */ + +/***********************************************************************//** + * @file qeihw.cpp + * @brief Driver file for the QEI hardware. Requires connection to + * internal mbed circuit nodes. Adapted from the CMSIS + * driver, lpc17xx_qei.c, v 2.0 + * @version 0.1 + * @date 28 Dec 2010 + * @author hb + **************************************************************************/ +#include "mbed.h" +#include "qeihw.h" + +QEIHW *QEIHW::instance; + +/*********************************************************************//** + * @brief Create a QEI object and configure it. + * @param _dirinv Direction invert. When = 1, complements the QEICONF register DIR bit + * @param _sigmode Signal mode. When = 0, PhA and PhB are quadrature inputs. When = 1, PhA is direction and PhB is clock + * @param _capmode Capture mode. When = 0, count PhA edges only (2X mode). Whe = 1, count PhB edges also (4X mode). + * @param _invinx Invert index. When = 1, inverts the sense of the index signal + * @return None + **********************************************************************/ +QEIHW::QEIHW(uint32_t _dirinv, uint32_t _sigmode, uint32_t _capmode, uint32_t _invinx) +{ + /* Set up clock and power for QEI module */ + LPC_SC->PCONP |= PCONP_QEI_ENABLE; + + /* The clock for theQEI module is set to FCCLK */ + LPC_SC->PCLKSEL1 = LPC_SC->PCLKSEL1 & ~(3UL<<0) | ((PCLKSEL_CCLK_DIV_1 & 3)<<0); + + /* Assign the pins. They are hard-coded, not user-selected. The index + * pin is assigned, even though it is not easily accessed on the mbed. + * As it may be unconnected, it is given a pull-up resistor to minimize + * power drain. + */ + // MCI0 (PhA) + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI0_MASK) | PINSEL3_MCI0 ; + LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI0_MASK) | PINMODE3_MCI0; + + // MCI1 (PhB) + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI1_MASK) | PINSEL3_MCI1 ; + LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI1_MASK) | PINMODE3_MCI1; + + // MCI2 (Index) + LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI2_MASK) | PINSEL3_MCI2 ; + LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_MCI2; + + // Initialize all remaining values in QEI peripheral + LPC_QEI->QEICON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI; + LPC_QEI->QEIMAXPOS = 0xFFFFFFFF; // Default value + LPC_QEI->CMPOS0 = 0x00; + LPC_QEI->CMPOS1 = 0x00; + LPC_QEI->CMPOS2 = 0x00; + LPC_QEI->INXCMP = 0x00; + LPC_QEI->QEILOAD = 0x00; + LPC_QEI->VELCOMP = 0x00; + LPC_QEI->FILTER = 200000; // Default for mechanical switches. + + // Set QEI configuration value corresponding to the call parameters + LPC_QEI->QEICONF = ( + ((_dirinv << 0) & 1) | \ + ((_sigmode << 1) & 2) | \ + ((_capmode << 2) & 4) | \ + ((_invinx <<3) & 8) ); + + // Mask all int sources + LPC_QEI->QEIIEC = QEI_IECLR_BITMASK; // Set the "clear" bits for all sources in the IE clear register + + // Clear any pending ints + LPC_QEI->QEICLR = QEI_INTCLR_BITMASK; // Set the "clear" bits for for all sources in the Interrupt clear register + + /* preemption = 1, sub-priority = 1 */ + NVIC_SetPriority(QEI_IRQn, ((0x01<<3)|0x01)); + + //* Attach IRQ + instance = this; + NVIC_SetVector(QEI_IRQn, (uint32_t)&_Qeiisr); + + /* Enable interrupt for QEI */ + NVIC_EnableIRQ(QEI_IRQn); + +} + +/*********************************************************************//** + * @brief Resets value for each type of QEI value, such as velocity, + * counter, position, etc.. + * @param[in] ulResetType QEI Reset Type, should be one of the following: + * - QEI_RESET_POS: Reset Position Counter + * - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal + * - QEI_RESET_VEL: Reset Velocity + * - QEI_RESET_IDX: Reset Index Counter + * @return None + **********************************************************************/ +void QEIHW::Reset(uint32_t ulResetType) +{ + LPC_QEI->QEICON = ulResetType; +} + +/*********************************************************************//** + * @brief De-initializes the QEI peripheral registers to their + * default reset values. + * + * @return None + **********************************************************************/ +void QEIHW::DeInit() +{ + /* Turn off clock and power for QEI module */ + LPC_SC->PCONP &= PCONP_QEI_DISABLE; + + /* Return pins to their default assignment (PINSEL = 0, PINMODE = PULLDOWN) */ + // MCI0 (PhA) -> LED-2 (p1.20) + LPC_PINCON->PINSEL3 &= PINSEL3_MCI0_MASK; + LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI0_MASK) | PINMODE3_GPIO1p20; + + // MCI1 (PhB) -> LED-4 (p1.23) + LPC_PINCON->PINSEL3 &= PINSEL3_MCI1_MASK; + LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI1_MASK) | PINMODE3_GPIO1p23; + + // MCI2 (Index) -> p1.24 + LPC_PINCON->PINSEL3 &= PINSEL3_MCI2_MASK; + LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_GPIO1p24; +} + +/*********************************************************************//** + * @brief Report direction (QEISTAT bit DIR) + * + * @return State of the DIR bit (SET or RESET) + **********************************************************************/ +FlagStatus QEIHW::Direction() +{ + return ((LPC_QEI->QEISTAT & QEI_STATUS_DIR) ? SET : RESET); +} + +/*********************************************************************//** + * @brief Get current position value in QEI peripheral + * + * @return Current position value of QEI peripheral + **********************************************************************/ +uint32_t QEIHW::GetPosition() +{ + return (LPC_QEI->QEIPOS); +} + +/*********************************************************************//** + * @brief Set max position value for QEI peripheral + * + * @param[in] ulMaxPos Max position value to set + * @return None + **********************************************************************/ +void QEIHW::SetMaxPosition(uint32_t ulMaxPos) +{ + LPC_QEI->QEIMAXPOS = ulMaxPos; +} + +/*********************************************************************//** + * @brief Set position compare value for QEI peripheral + * @param[in] QEIx QEI peripheral, should be LPC_QEI + * @param[in] bPosCompCh Compare Position channel, should be: + * - QEI_COMPPOS_CH_0: QEI compare position channel 0 + * - QEI_COMPPOS_CH_1: QEI compare position channel 1 + * - QEI_COMPPOS_CH_2: QEI compare position channel 2 + * @param[in] ulPosComp Compare Position value to set + * @return None + **********************************************************************/ +void QEIHW::SetPositionComp( uint8_t bPosCompCh, uint32_t ulPosComp) +{ + uint32_t *tmp; + + tmp = (uint32_t*)(((uint8_t*)&(LPC_QEI->CMPOS0)) + (bPosCompCh << 2)); + *tmp = ulPosComp; +} + +/*********************************************************************//** + * @brief Get current index counter of QEI peripheral + * + * @return Current value of QEI index counter + **********************************************************************/ +uint32_t QEIHW::GetIndex() +{ + return (LPC_QEI->INXCNT); +} + +/*********************************************************************//** + * @brief Set value for index compare in QEI peripheral + * @param[in] ulIndexComp Compare Index Value to set + * @return None + **********************************************************************/ +void QEIHW::SetIndexComp( uint32_t ulIndexComp) +{ + LPC_QEI->INXCMP = ulIndexComp; +} + +/*********************************************************************//** + * @brief Set Velocity timer reload value + * + * @param[in] ulReloadValue Velocity timer reload count + * @return None + **********************************************************************/ +void QEIHW::SetVelocityTimerReload( uint32_t ulReloadValue) +{ + LPC_QEI->QEILOAD = ulReloadValue; +} + +/*********************************************************************//** + * @brief Set Velocity timer reload value in microseconds + * + * @param[in] ulReloadValue Velocity timer reload count + * @return None + **********************************************************************/ +void QEIHW::SetVelocityTimerReload_us( uint32_t ulReloadValue) +{ + int div; + + //Work out CCLK + uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1; + uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1; + uint32_t cclkdiv = LPC_SC->CCLKCFG + 1; + uint32_t Fcco = (2 * m * XTAL_FREQ) / n; + uint32_t cclk = Fcco / cclkdiv; + + + +// div = CLKPWR_GetPCLKSEL(ClkType); + div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK; + switch (div) + { + case 0: + div = 4; + break; + + case 1: + div = 1; + break; + + case 2: + div = 2; + break; + + case 3: + div = 8; + break; + } + cclk /=div; + cclk =((uint64_t)cclk / (1000000/ulReloadValue)) - 1; + LPC_QEI->QEILOAD = (uint32_t) cclk; +} + +/*********************************************************************//** + * @brief Get current timer counter in QEI peripheral + * + * @return Current timer counter in QEI peripheral + **********************************************************************/ +uint32_t QEIHW::GetTimer() +{ + return (LPC_QEI->QEITIME); +} + +/*********************************************************************//** + * @brief Get current velocity pulse counter in current time period + * + * @return Current velocity pulse counter value + **********************************************************************/ +uint32_t QEIHW::GetVelocity() +{ + return (LPC_QEI->QEIVEL); +} + +/*********************************************************************//** + * @brief Get the most recently captured velocity of the QEI. When + * the Velocity timer in QEI is over-flow, the current velocity + * value will be loaded into Velocity Capture register. + * + * @return The most recently measured velocity value + **********************************************************************/ +uint32_t QEIHW::GetVelocityCap() +{ + return (LPC_QEI->QEICAP); +} + +/*********************************************************************//** + * @brief Set Velocity Compare value for QEI peripheral + * + * @param[in] ulVelComp Compare Velocity value to set + * @return None + **********************************************************************/ +void QEIHW::SetVelocityComp( uint32_t ulVelComp) +{ + LPC_QEI->VELCOMP = ulVelComp; +} + +/*********************************************************************//** + * @brief Set value of sampling count for the digital filter in + * QEI peripheral + * + * @param[in] ulSamplingPulse Value of sampling count to set + * @return None + **********************************************************************/ +void QEIHW::SetDigiFilter( uint32_t ulSamplingPulse) +{ + LPC_QEI->FILTER = ulSamplingPulse; +} + +/*********************************************************************//** + * @brief Check whether if specified interrupt flag status in QEI + * peripheral is set or not + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return New State of specified interrupt flag status (SET or RESET) + **********************************************************************/ +FlagStatus QEIHW::GetIntStatus( uint32_t ulIntType) +{ + return((LPC_QEI->QEIINTSTAT & ulIntType) ? SET : RESET); +} + +/*********************************************************************//** + * @brief Enable/Disable specified interrupt in QEI peripheral + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + * - QEI_INTFLAG_DIR_Int: Change of direction interrupt + * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + * index count interrupt + * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @param[in] NewState New function state, should be: + * - DISABLE + * - ENABLE + * @return None + **********************************************************************/ +void QEIHW::IntCmd( uint32_t ulIntType, FunctionalState NewState) +{ + if (NewState == ENABLE) { + LPC_QEI->QEIIES = ulIntType; + } else { + LPC_QEI->QEIIEC = ulIntType; + } +} + +/*********************************************************************//** + * @brief Assert specified interrupt in QEI peripheral + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return None + **********************************************************************/ +void QEIHW::IntSet( uint32_t ulIntType) +{ + LPC_QEI->QEISET = ulIntType; +} + +/*********************************************************************//** + * @brief De-assert specified interrupt (pending) in QEI peripheral + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return None + **********************************************************************/ +void QEIHW::IntClear( uint32_t ulIntType) +{ + LPC_QEI->QEICLR = ulIntType; +} + +/*********************************************************************//** + * @brief Calculates the actual velocity in RPM passed via velocity + * capture value and Pulse Per Revolution (of the encoder) value + * parameter input. + * + * @param[in] ulVelCapValue Velocity capture input value that can + * be got from QEI_GetVelocityCap() function + * @param[in] ulPPR Pulse per round of encoder + * @return The actual value of velocity in RPM (Revolutions per minute) + **********************************************************************/ +uint32_t QEIHW::CalculateRPM( uint32_t ulVelCapValue, uint32_t ulPPR) +{ + uint64_t rpm, Load, edges; + int div; + + // Get current Clock rate for timer input + //Work out CCLK + uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1; + uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1; + uint32_t cclkdiv = LPC_SC->CCLKCFG + 1; + uint32_t Fcco = (2 * m * XTAL_FREQ) / n; + uint32_t cclk = Fcco / cclkdiv; + +// div = CLKPWR_GetPCLKSEL(ClkType); + div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK; + switch (div) + { + case 0: + div = 4; + break; + + case 1: + div = 1; + break; + + case 2: + div = 2; + break; + + case 3: + div = 8; + break; + } + cclk /= div; + + // Get Timer load value (velocity capture period) + Load = (uint64_t)(LPC_QEI->QEILOAD + 1); + // Get Edge + edges = (uint64_t)((LPC_QEI->QEICONF & QEI_CONF_CAPMODE) ? 4 : 2); + // Calculate RPM + rpm = ((( uint64_t)cclk * ulVelCapValue * 60) / (Load * ulPPR * edges)); + + return (uint32_t)(rpm); +} + +/*********************************************************************//** + * @brief Append interrupt handler for specific QEI interrupt source + * + * @param[in] ulISRType Interrupt Flag Status type, should be: + * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + * - QEI_INTFLAG_DIR_Int: Change of direction interrupt + * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + * index count interrupt + * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * + * @return none + **********************************************************************/ +void QEIHW::AppendISR(uint32_t ulISRType, void(*fptr)(void)) { + int i; + + for(i = 0; i < 13; i++) { + if( ulISRType == (1UL << i) ) { + _qei_isr[i] = fptr; + break; + } + } + return; +} + +/*********************************************************************//** + * @brief Unappend interrupt handler for specific QEI interrupt source + * + * @param[in] ulISRType Interrupt Flag Status type, should be: + * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + * - QEI_INTFLAG_DIR_Int: Change of direction interrupt + * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + * index count interrupt + * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * + * @return none + **********************************************************************/ +void QEIHW::UnAppendISR(uint32_t ulISRType) { + int i; + + for(i = 0; i < 13; i++) { + if( ulISRType == (1UL << i) ) { + _qei_isr[i] = NULL; + break; + } + } + return; +} + + +void QEIHW::_Qeiisr(void) +{ + instance->Qeiisr(); +} + +/*********************************************************************//** + * @brief QEI interrupt service dispatcher. + * + * @param[in] none + * + * @return none + **********************************************************************/ +void QEIHW::Qeiisr(void) +{ + int32_t i; + + //User defined interrupt handlers. Check all possible sources, dispatch to corresponding non-null service routines. + for(i = 0; i < 13; i++) { + if(LPC_QEI->QEIINTSTAT & ((uint32_t)(1<<i)) ) { + if (_qei_isr[i] != NULL) { + _qei_isr[i](); + } + } + } + return; +} +
diff -r 000000000000 -r 9555690e7705 QEI_hw_m/qeihw.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/QEI_hw_m/qeihw.h Fri Mar 02 14:18:23 2012 +0000 @@ -0,0 +1,633 @@ + /* mbed Library - QEIhw + * Copyright (c) 2010, hball + * released under MIT license http://mbed.org/licence/mit + */ + +/***********************************************************************//** + * @file qeihw.h + * @brief Header file for the qeihw driver. Adapted from the CMSIS + * header, lpc17xx_qei.h, v 2.0 + * @version 0.0 + * @date 10 Dec 2010 + * @author hb + **************************************************************************/ + + +#ifndef MBED_QEIHW_H +#define MBED_QEIHW_H + +/* Includes ------------------------------------------------------------------- */ +#include "mbed.h" + + +/* Public Types --------------------------------------------------------------- */ + +/* Flag Status type definition */ +typedef enum {RESET = 0, SET = !RESET} FlagStatus, IntStatus, SetState; + +/* Functional State Definition */ +typedef enum {DISABLE = 0, ENABLE = !DISABLE} FunctionalState; + + +/* Other definitions */ +#define XTAL_FREQ 12000000 + +/* Public Functions ----------------------------------------------------------- */ +/** @defgroup QEI_Public_Functions QEI Public Functions +*/ + +/** QEI hardware interface class +* Requires mbed hardware modification: connect +* encoder PhA to p1.20, and PhB to p1.23. +* +* Example: +* @code +* // Display changes in encoder position and direction +#include "mbed.h" +* #include "qeihw.h" +* +* DigitalOut led1(LED1); +* DigitalOut led3(LED3); +* QEIHW qei(QEI_DIRINV_NONE, QEI_SIGNALMODE_QUAD, QEI_CAPMODE_2X, QEI_INVINX_NONE ); +* +* int main() { +* int32_t temp, position = 0; +* qei.SetDigiFilter(480UL); +* qei.SetMaxPosition(0xFFFFFFFF); +* +* while(1) { +* while(position == (temp = qei.GetPosition()) ); +* position = temp; +* printf("New position = %d.\r\n", temp); +* led1 = qei.Direction() == SET ? 1 : 0; +* led3 = !led1; +* wait(0.1); +* } +* } +* @endcode +*/ + +class QEIHW { +public: + + /** Create a QEI object and configure it + * + * @param _dirinv Direction invert. When = 1, complements the QEICONF register DIR bit + * @param _sigmode Signal mode. When = 0, PhA and PhB are quadrature inputs. When = 1, PhA is direction and PhB is clock + * @param _capmode Capture mode. When = 0, count PhA edges only (2X mode). Whe = 1, count PhB edges also (4X mode). + * @param _invinx Invert index. When = 1, inverts the sense of the index signal + */ + QEIHW( uint32_t _dirinv, uint32_t _sigmode, uint32_t _capmode, uint32_t _invinx); + +/** Resets value for each type of QEI value, such as velocity, position, etc. + * + * @param[in] ulResetType QEI Reset Type, should be one of the following: + * - QEI_RESET_POS: Reset Position Counter + * - QEI_RESET_POSOnIDX: Reset Position Counter on Index signal + * - QEI_RESET_VEL: Reset Velocity + * - QEI_RESET_IDX: Reset Index Counter + */ +void Reset(uint32_t ulResetType); + +/** Powers down the QEI block, returns pins to GPIO mode + * + */ +void DeInit(); + +/** Report direction (QEISTAT bit DIR) + * + * @return State of the DIR bit (SET or RESET) + */ +FlagStatus Direction(); + +/** + * @brief Get current position value in QEI peripheral + * + * @return Current position value of QEI peripheral + */ +uint32_t GetPosition(); + +/** Set max position value for QEI peripheral + * + * @param[in] ulMaxPos Max position value to set + * @return None + */ +void SetMaxPosition(uint32_t ulMaxPos); + +/** Set position compare value for QEI peripheral + * @param[in] bPosCompCh Compare Position channel, should be: + * - QEI_COMPPOS_CH_0: QEI compare position channel 0 + * - QEI_COMPPOS_CH_1: QEI compare position channel 1 + * - QEI_COMPPOS_CH_2: QEI compare position channel 2 + * @param[in] ulPosComp Compare Position value to set + * @return None + */ +void SetPositionComp( uint8_t bPosCompCh, uint32_t ulPosComp); + +/** Get current index counter of QEI peripheral + * + * @return Current value of QEI index counter + */ +uint32_t GetIndex(); + +/** Set value for index compare in QEI peripheral + * @param[in] ulIndexComp Compare Index Value to set + * @return None + */ +void SetIndexComp( uint32_t ulIndexComp); + +/** Set Velocity timer reload value + * + * @param[in] ulReloadValue Velocity timer reload count + * @return None + */ +void SetVelocityTimerReload( uint32_t ulReloadValue); + +/** Set Velocity timer reload value in microseconds + * + * @param[in] ulReloadValue Velocity timer reload count + * @return None + */ +void SetVelocityTimerReload_us( uint32_t ulReloadValue); + +/** Get current timer counter in QEI peripheral + * + * @return Current timer counter in QEI peripheral + */ +uint32_t GetTimer(); + +/** Get current velocity pulse counter in current time period + * + * @return Current velocity pulse counter value + */ +uint32_t GetVelocity(); + +/** Get the most recently measured velocity of the QEI. When + * the Velocity timer in QEI is over-flow, the current velocity + * value will be loaded into Velocity Capture register. + * + * @return The most recently measured velocity value + */ +uint32_t GetVelocityCap(); + +/** Set Velocity Compare value for QEI peripheral + * + * @param[in] ulVelComp Compare Velocity value to set + * @return None + */ +void SetVelocityComp( uint32_t ulVelComp); + +/** Set value of sampling count for the digital filter in + * QEI peripheral + * + * @param[in] ulSamplingPulse Value of sampling count to set + * @return None + */ +void SetDigiFilter( uint32_t ulSamplingPulse); + +/** Check whether if specified interrupt flag status in QEI + * peripheral is set or not + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return New State of specified interrupt flag status (SET or RESET) + */ +FlagStatus GetIntStatus( uint32_t ulIntType); + +/** Enable/Disable specified interrupt in QEI peripheral + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + * - QEI_INTFLAG_DIR_Int: Change of direction interrupt + * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + * index count interrupt + * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @param[in] NewState New function state, should be: + * - DISABLE + * - ENABLE + * @return None + */ +void IntCmd( uint32_t ulIntType, FunctionalState NewState); + +/** Asserts specified interrupt in QEI peripheral + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return None + */ +void IntSet( uint32_t ulIntType); + +/** De-asserts specified interrupt (pending) in QEI peripheral + * + * @param[in] ulIntType Interrupt Flag Status type, should be: + - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + - QEI_INTFLAG_DIR_Int: Change of direction interrupt + - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + current position interrupt + - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + current position interrupt + - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + index count interrupt + - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * @return None + */ +void IntClear( uint32_t ulIntType); + +/** Append interrupt handler for specific QEI interrupt source + * + * @param[in] ulISRType Interrupt Flag Status type, should be: + * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + * - QEI_INTFLAG_DIR_Int: Change of direction interrupt + * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + * index count interrupt + * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * + * @return none + */ +void AppendISR(uint32_t ulISRType, void(*fptr)(void)); + +/** Unappend interrupt handler for specific QEI interrupt source + * + * @param[in] ulISRType Interrupt Flag Status type, should be: + * - QEI_INTFLAG_INX_Int: index pulse was detected interrupt + * - QEI_INTFLAG_TIM_Int: Velocity timer over flow interrupt + * - QEI_INTFLAG_VELC_Int: Capture velocity is less than compare interrupt + * - QEI_INTFLAG_DIR_Int: Change of direction interrupt + * - QEI_INTFLAG_ERR_Int: An encoder phase error interrupt + * - QEI_INTFLAG_ENCLK_Int: An encoder clock pulse was detected interrupt + * - QEI_INTFLAG_POS0_Int: position 0 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS1_Int: position 1 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_POS2_Int: position 2 compare value is equal to the + * current position interrupt + * - QEI_INTFLAG_REV_Int: Index compare value is equal to the current + * index count interrupt + * - QEI_INTFLAG_POS0REV_Int: Combined position 0 and revolution count interrupt + * - QEI_INTFLAG_POS1REV_Int: Combined position 1 and revolution count interrupt + * - QEI_INTFLAG_POS2REV_Int: Combined position 2 and revolution count interrupt + * + * @return none + */ +void UnAppendISR(uint32_t ulISRType); + + +/** + * @brief Calculates the actual velocity in RPM passed via velocity + * capture value and Pulse Per Revolution (of the encoder) value + * parameter input. + * + * @param[in] ulVelCapValue Velocity capture input value that can + * be got from QEI_GetVelocityCap() function + * @param[in] ulPPR Pulse per round of encoder + * @return The actual value of velocity in RPM (Revolutions per minute) + */ +uint32_t CalculateRPM( uint32_t ulVelCapValue, uint32_t ulPPR); + + +/* Public Macros -------------------------------------------------------------- */ +/* QEI Reset types */ +#define QEI_RESET_POS QEI_CON_RESP /**< Reset position counter */ +#define QEI_RESET_POSOnIDX QEI_CON_RESPI /**< Reset Posistion Counter on Index */ +#define QEI_RESET_VEL QEI_CON_RESV /**< Reset Velocity */ +#define QEI_RESET_IDX QEI_CON_RESI /**< Reset Index Counter */ + +/* QEI Direction Invert Type Option */ +#define QEI_DIRINV_NONE ((uint32_t)(0)) /**< Direction is not inverted */ +#define QEI_DIRINV_CMPL ((uint32_t)(1)) /**< Direction is complemented */ + +/* QEI Signal Mode Option */ +#define QEI_SIGNALMODE_QUAD ((uint32_t)(0)) /**< Signal operation: Quadrature phase mode */ +#define QEI_SIGNALMODE_CLKDIR ((uint32_t)(1)) /**< Signal operation: Clock/Direction mode */ + +/* QEI Capture Mode Option */ +#define QEI_CAPMODE_2X ((uint32_t)(0)) /**< Capture mode: Only Phase-A edges are counted (2X) */ +#define QEI_CAPMODE_4X ((uint32_t)(1)) /**< Capture mode: BOTH PhA and PhB edges are counted (4X)*/ + +/* QEI Invert Index Signal Option */ +#define QEI_INVINX_NONE ((uint32_t)(0)) /**< Invert Index signal option: None */ +#define QEI_INVINX_EN ((uint32_t)(1)) /**< Invert Index signal option: Enable */ + +/* QEI timer reload option */ +#define QEI_TIMERRELOAD_TICKVAL ((uint8_t)(0)) /**< Reload value in absolute value */ +#define QEI_TIMERRELOAD_USVAL ((uint8_t)(1)) /**< Reload value in microsecond value */ + +/* QEI Flag Status type */ +#define QEI_STATUS_DIR ((uint32_t)(1<<0)) /**< Direction status */ + +/* QEI Compare Position channel option */ +#define QEI_COMPPOS_CH_0 ((uint8_t)(0)) /**< QEI compare position channel 0 */ +#define QEI_COMPPOS_CH_1 ((uint8_t)(1)) /**< QEI compare position channel 1 */ +#define QEI_COMPPOS_CH_2 ((uint8_t)(2)) /**< QEI compare position channel 2 */ + +/* QEI interrupt flag type */ +#define QEI_INTFLAG_INX_Int ((uint32_t)(1<<0)) /**< index pulse was detected interrupt */ +#define QEI_INTFLAG_TIM_Int ((uint32_t)(1<<1)) /**< Velocity timer over flow interrupt */ +#define QEI_INTFLAG_VELC_Int ((uint32_t)(1<<2)) /**< Capture velocity is less than compare interrupt */ +#define QEI_INTFLAG_DIR_Int ((uint32_t)(1<<3)) /**< Change of direction interrupt */ +#define QEI_INTFLAG_ERR_Int ((uint32_t)(1<<4)) /**< An encoder phase error interrupt */ +#define QEI_INTFLAG_ENCLK_Int ((uint32_t)(1<<5)) /**< An encoder clock pulse was detected interrupt */ +#define QEI_INTFLAG_POS0_Int ((uint32_t)(1<<6)) /**< position 0 compare value is equal to the + current position interrupt */ +#define QEI_INTFLAG_POS1_Int ((uint32_t)(1<<7)) /**< position 1 compare value is equal to the + current position interrupt */ +#define QEI_INTFLAG_POS2_Int ((uint32_t)(1<<8)) /**< position 2 compare value is equal to the + current position interrupt */ +#define QEI_INTFLAG_REV_Int ((uint32_t)(1<<9)) /**< Index compare value is equal to the current + index count interrupt */ +#define QEI_INTFLAG_POS0REV_Int ((uint32_t)(1<<10)) /**< Combined position 0 and revolution count interrupt */ +#define QEI_INTFLAG_POS1REV_Int ((uint32_t)(1<<11)) /**< Combined position 1 and revolution count interrupt */ +#define QEI_INTFLAG_POS2REV_Int ((uint32_t)(1<<12)) /**< Combined position 2 and revolution count interrupt */ + +/* QEI Process position reporting options */ +#define QEI_PROCESS_OPERATE 0; +#define QEI_PROCESS_RESET 1; +#define QEI_PROCESS_INCREMENTAL 0; +#define QEI_PROCESS_ACCUMULATE 1; +#define QEI_PROCESS_LINEAR 0; +#define QEI_PROCESS_WEIGHTED 1; + +private: +static void _Qeiisr(void); +void Qeiisr(void); +static QEIHW *instance; + +void(*_qei_isr[13])(); + + +/* Private Macros ------------------------------------------------------------- */ +/* --------------------- BIT DEFINITIONS -------------------------------------- */ +/* Quadrature Encoder Interface Control Register Definition --------------------- */ +/*********************************************************************//** + * Macro defines for QEI Control register + **********************************************************************/ +#define QEI_CON_RESP ((uint32_t)(1<<0)) /**< Reset position counter */ +#define QEI_CON_RESPI ((uint32_t)(1<<1)) /**< Reset Posistion Counter on Index */ +#define QEI_CON_RESV ((uint32_t)(1<<2)) /**< Reset Velocity */ +#define QEI_CON_RESI ((uint32_t)(1<<3)) /**< Reset Index Counter */ +#define QEI_CON_BITMASK ((uint32_t)(0x0F)) /**< QEI Control register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Configuration register + **********************************************************************/ +#define QEI_CONF_DIRINV ((uint32_t)(1<<0)) /**< Direction Invert */ +#define QEI_CONF_SIGMODE ((uint32_t)(1<<1)) /**< Signal mode */ +#define QEI_CONF_CAPMODE ((uint32_t)(1<<2)) /**< Capture mode */ +#define QEI_CONF_INVINX ((uint32_t)(1<<3)) /**< Invert index */ +#define QEI_CONF_BITMASK ((uint32_t)(0x0F)) /**< QEI Configuration register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Status register + **********************************************************************/ +#define QEI_STAT_DIR ((uint32_t)(1<<0)) /**< Direction bit */ +#define QEI_STAT_BITMASK ((uint32_t)(1<<0)) /**< QEI status register bit-mask */ + +/* Quadrature Encoder Interface Interrupt registers definitions --------------------- */ +/*********************************************************************//** + * Macro defines for QEI Interrupt Status register + **********************************************************************/ +#define QEI_INTSTAT_INX_Int ((uint32_t)(1<<0)) /**< Indicates that an index pulse was detected */ +#define QEI_INTSTAT_TIM_Int ((uint32_t)(1<<1)) /**< Indicates that a velocity timer overflow occurred */ +#define QEI_INTSTAT_VELC_Int ((uint32_t)(1<<2)) /**< Indicates that capture velocity is less than compare velocity */ +#define QEI_INTSTAT_DIR_Int ((uint32_t)(1<<3)) /**< Indicates that a change of direction was detected */ +#define QEI_INTSTAT_ERR_Int ((uint32_t)(1<<4)) /**< Indicates that an encoder phase error was detected */ +#define QEI_INTSTAT_ENCLK_Int ((uint32_t)(1<<5)) /**< Indicates that and encoder clock pulse was detected */ +#define QEI_INTSTAT_POS0_Int ((uint32_t)(1<<6)) /**< Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTSTAT_POS1_Int ((uint32_t)(1<<7)) /**< Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTSTAT_POS2_Int ((uint32_t)(1<<8)) /**< Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTSTAT_REV_Int ((uint32_t)(1<<9)) /**< Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTSTAT_POS0REV_Int ((uint32_t)(1<<10)) /**< Combined position 0 and revolution count interrupt. Set when + both the POS0_Int bit is set and the REV_Int is set */ +#define QEI_INTSTAT_POS1REV_Int ((uint32_t)(1<<11)) /**< Combined position 1 and revolution count interrupt. Set when + both the POS1_Int bit is set and the REV_Int is set */ +#define QEI_INTSTAT_POS2REV_Int ((uint32_t)(1<<12)) /**< Combined position 2 and revolution count interrupt. Set when + both the POS2_Int bit is set and the REV_Int is set */ +#define QEI_INTSTAT_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Status register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Set register + **********************************************************************/ +#define QEI_INTSET_INX_Int ((uint32_t)(1<<0)) /**< Set Bit Indicates that an index pulse was detected */ +#define QEI_INTSET_TIM_Int ((uint32_t)(1<<1)) /**< Set Bit Indicates that a velocity timer overflow occurred */ +#define QEI_INTSET_VELC_Int ((uint32_t)(1<<2)) /**< Set Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_INTSET_DIR_Int ((uint32_t)(1<<3)) /**< Set Bit Indicates that a change of direction was detected */ +#define QEI_INTSET_ERR_Int ((uint32_t)(1<<4)) /**< Set Bit Indicates that an encoder phase error was detected */ +#define QEI_INTSET_ENCLK_Int ((uint32_t)(1<<5)) /**< Set Bit Indicates that and encoder clock pulse was detected */ +#define QEI_INTSET_POS0_Int ((uint32_t)(1<<6)) /**< Set Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTSET_POS1_Int ((uint32_t)(1<<7)) /**< Set Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTSET_POS2_Int ((uint32_t)(1<<8)) /**< Set Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTSET_REV_Int ((uint32_t)(1<<9)) /**< Set Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTSET_POS0REV_Int ((uint32_t)(1<<10)) /**< Set Bit that combined position 0 and revolution count interrupt */ +#define QEI_INTSET_POS1REV_Int ((uint32_t)(1<<11)) /**< Set Bit that Combined position 1 and revolution count interrupt */ +#define QEI_INTSET_POS2REV_Int ((uint32_t)(1<<12)) /**< Set Bit that Combined position 2 and revolution count interrupt */ +#define QEI_INTSET_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Set register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Clear register + **********************************************************************/ +#define QEI_INTCLR_INX_Int ((uint32_t)(1<<0)) /**< Clear Bit Indicates that an index pulse was detected */ +#define QEI_INTCLR_TIM_Int ((uint32_t)(1<<1)) /**< Clear Bit Indicates that a velocity timer overflow occurred */ +#define QEI_INTCLR_VELC_Int ((uint32_t)(1<<2)) /**< Clear Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_INTCLR_DIR_Int ((uint32_t)(1<<3)) /**< Clear Bit Indicates that a change of direction was detected */ +#define QEI_INTCLR_ERR_Int ((uint32_t)(1<<4)) /**< Clear Bit Indicates that an encoder phase error was detected */ +#define QEI_INTCLR_ENCLK_Int ((uint32_t)(1<<5)) /**< Clear Bit Indicates that and encoder clock pulse was detected */ +#define QEI_INTCLR_POS0_Int ((uint32_t)(1<<6)) /**< Clear Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTCLR_POS1_Int ((uint32_t)(1<<7)) /**< Clear Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTCLR_POS2_Int ((uint32_t)(1<<8)) /**< Clear Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTCLR_REV_Int ((uint32_t)(1<<9)) /**< Clear Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTCLR_POS0REV_Int ((uint32_t)(1<<10)) /**< Clear Bit that combined position 0 and revolution count interrupt */ +#define QEI_INTCLR_POS1REV_Int ((uint32_t)(1<<11)) /**< Clear Bit that Combined position 1 and revolution count interrupt */ +#define QEI_INTCLR_POS2REV_Int ((uint32_t)(1<<12)) /**< Clear Bit that Combined position 2 and revolution count interrupt */ +#define QEI_INTCLR_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Clear register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Enable register + **********************************************************************/ +#define QEI_INTEN_INX_Int ((uint32_t)(1<<0)) /**< Enabled Interrupt Bit Indicates that an index pulse was detected */ +#define QEI_INTEN_TIM_Int ((uint32_t)(1<<1)) /**< Enabled Interrupt Bit Indicates that a velocity timer overflow occurred */ +#define QEI_INTEN_VELC_Int ((uint32_t)(1<<2)) /**< Enabled Interrupt Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_INTEN_DIR_Int ((uint32_t)(1<<3)) /**< Enabled Interrupt Bit Indicates that a change of direction was detected */ +#define QEI_INTEN_ERR_Int ((uint32_t)(1<<4)) /**< Enabled Interrupt Bit Indicates that an encoder phase error was detected */ +#define QEI_INTEN_ENCLK_Int ((uint32_t)(1<<5)) /**< Enabled Interrupt Bit Indicates that and encoder clock pulse was detected */ +#define QEI_INTEN_POS0_Int ((uint32_t)(1<<6)) /**< Enabled Interrupt Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_INTEN_POS1_Int ((uint32_t)(1<<7)) /**< Enabled Interrupt Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_INTEN_POS2_Int ((uint32_t)(1<<8)) /**< Enabled Interrupt Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_INTEN_REV_Int ((uint32_t)(1<<9)) /**< Enabled Interrupt Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_INTEN_POS0REV_Int ((uint32_t)(1<<10)) /**< Enabled Interrupt Bit that combined position 0 and revolution count interrupt */ +#define QEI_INTEN_POS1REV_Int ((uint32_t)(1<<11)) /**< Enabled Interrupt Bit that Combined position 1 and revolution count interrupt */ +#define QEI_INTEN_POS2REV_Int ((uint32_t)(1<<12)) /**< Enabled Interrupt Bit that Combined position 2 and revolution count interrupt */ +#define QEI_INTEN_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Enable register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Enable Set register + **********************************************************************/ +#define QEI_IESET_INX_Int ((uint32_t)(1<<0)) /**< Set Enable Interrupt Bit Indicates that an index pulse was detected */ +#define QEI_IESET_TIM_Int ((uint32_t)(1<<1)) /**< Set Enable Interrupt Bit Indicates that a velocity timer overflow occurred */ +#define QEI_IESET_VELC_Int ((uint32_t)(1<<2)) /**< Set Enable Interrupt Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_IESET_DIR_Int ((uint32_t)(1<<3)) /**< Set Enable Interrupt Bit Indicates that a change of direction was detected */ +#define QEI_IESET_ERR_Int ((uint32_t)(1<<4)) /**< Set Enable Interrupt Bit Indicates that an encoder phase error was detected */ +#define QEI_IESET_ENCLK_Int ((uint32_t)(1<<5)) /**< Set Enable Interrupt Bit Indicates that and encoder clock pulse was detected */ +#define QEI_IESET_POS0_Int ((uint32_t)(1<<6)) /**< Set Enable Interrupt Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_IESET_POS1_Int ((uint32_t)(1<<7)) /**< Set Enable Interrupt Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_IESET_POS2_Int ((uint32_t)(1<<8)) /**< Set Enable Interrupt Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_IESET_REV_Int ((uint32_t)(1<<9)) /**< Set Enable Interrupt Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_IESET_POS0REV_Int ((uint32_t)(1<<10)) /**< Set Enable Interrupt Bit that combined position 0 and revolution count interrupt */ +#define QEI_IESET_POS1REV_Int ((uint32_t)(1<<11)) /**< Set Enable Interrupt Bit that Combined position 1 and revolution count interrupt */ +#define QEI_IESET_POS2REV_Int ((uint32_t)(1<<12)) /**< Set Enable Interrupt Bit that Combined position 2 and revolution count interrupt */ +#define QEI_IESET_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Enable Set register bit-mask */ + +/*********************************************************************//** + * Macro defines for QEI Interrupt Enable Clear register + **********************************************************************/ +#define QEI_IECLR_INX_Int ((uint32_t)(1<<0)) /**< Clear Enabled Interrupt Bit Indicates that an index pulse was detected */ +#define QEI_IECLR_TIM_Int ((uint32_t)(1<<1)) /**< Clear Enabled Interrupt Bit Indicates that a velocity timer overflow occurred */ +#define QEI_IECLR_VELC_Int ((uint32_t)(1<<2)) /**< Clear Enabled Interrupt Bit Indicates that capture velocity is less than compare velocity */ +#define QEI_IECLR_DIR_Int ((uint32_t)(1<<3)) /**< Clear Enabled Interrupt Bit Indicates that a change of direction was detected */ +#define QEI_IECLR_ERR_Int ((uint32_t)(1<<4)) /**< Clear Enabled Interrupt Bit Indicates that an encoder phase error was detected */ +#define QEI_IECLR_ENCLK_Int ((uint32_t)(1<<5)) /**< Clear Enabled Interrupt Bit Indicates that and encoder clock pulse was detected */ +#define QEI_IECLR_POS0_Int ((uint32_t)(1<<6)) /**< Clear Enabled Interrupt Bit Indicates that the position 0 compare value is equal to the + current position */ +#define QEI_IECLR_POS1_Int ((uint32_t)(1<<7)) /**< Clear Enabled Interrupt Bit Indicates that the position 1compare value is equal to the + current position */ +#define QEI_IECLR_POS2_Int ((uint32_t)(1<<8)) /**< Clear Enabled Interrupt Bit Indicates that the position 2 compare value is equal to the + current position */ +#define QEI_IECLR_REV_Int ((uint32_t)(1<<9)) /**< Clear Enabled Interrupt Bit Indicates that the index compare value is equal to the current + index count */ +#define QEI_IECLR_POS0REV_Int ((uint32_t)(1<<10)) /**< Clear Enabled Interrupt Bit that combined position 0 and revolution count interrupt */ +#define QEI_IECLR_POS1REV_Int ((uint32_t)(1<<11)) /**< Clear Enabled Interrupt Bit that Combined position 1 and revolution count interrupt */ +#define QEI_IECLR_POS2REV_Int ((uint32_t)(1<<12)) /**< Clear Enabled Interrupt Bit that Combined position 2 and revolution count interrupt */ +#define QEI_IECLR_BITMASK ((uint32_t)(0x1FFF)) /**< QEI Interrupt Enable Clear register bit-mask */ + +/*********************************************************************//** + * Macro defines for PCONP register QEI-related bits + **********************************************************************/ +#define PCONP_QEI_ENABLE ((uint32_t)(1<<18)) /**< QEI peripheral power enable bit */ +#define PCONP_QEI_DISABLE ~((uint32_t)(1<<18)) /**< QEI peripheral power disable bit-mask */ + +/*********************************************************************//** + * Macro defines for PCLKSELx register QEI-related bits + **********************************************************************/ +#define PCLKSEL_CCLK_DIV_1 1UL /**< Set PCLK to CCLK/1 */ +#define PCLKSEL_CCLK_DIV_2 2UL /**< Set PCLK to CCLK/2 */ +#define PCLKSEL_CCLK_DIV_4 0UL /**< Set PCLK to CCLK/4 */ +#define PCLKSEL_CCLK_DIV_8 3UL /**< Set PCLK to CCLK/8 */ +#define PCLKSEL1_PCLK_QEI_MASK ((uint32_t)(3<<0)) /**< PCLK_QEI PCLK_QEI bit field mask */ +/*********************************************************************//** + * Macro defines for PINSEL3 register QEI-related bits + **********************************************************************/ +#define PINSEL3_MCI0 ((uint32_t)(1<<8)) /**< MCIO (PhA) pin select */ +#define PINSEL3_MCI0_MASK ~((uint32_t)(3<<8)) /**< MCIO (PhA) pin mask */ +#define PINSEL3_MCI1 ((uint32_t)(1<<14)) /**< MCI1 (PhB) pin select */ +#define PINSEL3_MCI1_MASK ~((uint32_t)(3<<14)) /**< MCI2 (PhB) pin mask */ +#define PINSEL3_MCI2 ((uint32_t)(1<<16)) /**< MCI2 (Index) pin select */ +#define PINSEL3_MCI2_MASK ~((uint32_t)(3<<16)) /**< MCI2 (Index) pin mask */ + +/*********************************************************************//** + * Macro defines for PINMODE3 register QEI-related bits + **********************************************************************/ +#define PIN_PULL_UP 0UL +#define PIN_REPEATER 1UL +#define PIN_NORESISTOR 2UL +#define PIN_PULL_DOWN 3UL + +#define PINMODE3_MCI0 ((uint32_t)(PIN_NORESISTOR<<8)) /**< MCIO (PhA) resistor selection */ +#define PINMODE3_GPIO1p20 ((uint32_t)(PIN_PULL_DOWN<<8)) /**< GPIO 1.20) resistor selection */ +#define PINMODE3_MCI0_MASK ~((uint32_t)(3<<8)) /**< MCIO (PhA) resistor mask */ + +#define PINMODE3_MCI1 ((uint32_t)(PIN_NORESISTOR<<14)) /**< MCI1 (PhB) resistor selection */ +#define PINMODE3_GPIO1p23 ((uint32_t)(PIN_PULL_DOWN<<14)) /**< GPIO 1.23) resistor selection */ +#define PINMODE3_MCI1_MASK ~((uint32_t)(3<<14)) /**< MCI1 (PhB) resistor mask */ + +#define PINMODE3_MCI2 ((uint32_t)(PIN_PULL_UP<<16)) /**< MCI2 (Index) resistor selection */ +#define PINMODE3_GPIO1p24 ((uint32_t)(PIN_PULL_DOWN<<16)) /**< GPIO 1.24) resistor selection */ +#define PINMODE3_MCI2_MASK ~((uint32_t)(3<<16)) /**< MCI2 (Index) resistor mask */ + +}; + + +#endif /* MBED_QEI_H */ +/* --------------------------------- End Of File ------------------------------ */
diff -r 000000000000 -r 9555690e7705 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Fri Mar 02 14:18:23 2012 +0000 @@ -0,0 +1,176 @@ +/** +* @file qei_hw_motor +* @brief Keil MBC1700 demoboard and L293, QEI ,TFT, MOTOR, UART +* C27 and C81 removed +* @author Frederic BLANC (Published 01/03/2012 www.mbed.org) +*/ +#include "mbed.h" +#include "qeihw.h" +#include "GLCD_MCB1700.h" +#include "Motor.h" +#define PPR 624 //Pulse per round of encoder +#define PWM 0.7 // 0 to 1.0 +//#define TFT 1 //if comment TFT is OFF else if define TFT is ON (µvision limit 32Ko) +//LED +DigitalOut led_DIR(P1_28); +DigitalOut led_POS0(P1_29); +DigitalOut led_POS1(P1_31); +DigitalOut led_POS2(P2_2); +//reseved MOTOR P2_3, P2_4, P2_5 +DigitalOut led_RX(P2_6); + + +//QEI +QEIHW qei(QEI_DIRINV_NONE, QEI_SIGNALMODE_QUAD, QEI_CAPMODE_4X, QEI_INVINX_NONE ); +//TFT +char text[32]; +// MOTOR +Motor m(P2_3, P2_4, P2_5); // pwm, fwd, rev L293 +int consigne=0; +float pwm=0; +int sens=0; +//serial COM0 +Serial pc(P0_2, P0_3);//Tx Rx +void pc_rx(void) { + char c; + led_RX=1; + c=pc.getc(); + switch (c) { + // consigne + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + pc.printf("\r\nconsigne="); + char buf[256]; + buf[0]=c; + pc.putc(c); + for (int i=1; c!='\r'; ++i) { + c=pc.getc(); + buf[i]=c; + pc.putc(c); + + } + pc.putc('\n'); + consigne=atoi(buf); + + case '+': + if (c=='+') { + ++consigne; + pc.putc(c); + } + case '-': + if (c=='-') { + --consigne; + pc.putc(c); + } + + if (consigne<100) + consigne=100; + if (consigne>600) + consigne=600; + qei.SetPositionComp(QEI_COMPPOS_CH_0,consigne); + qei.IntCmd(QEI_INTFLAG_POS0_Int, ENABLE); + if (consigne!=0) { + qei.SetPositionComp(QEI_COMPPOS_CH_1,consigne-1); + qei.IntCmd(QEI_INTFLAG_POS1_Int, ENABLE); + } + qei.SetPositionComp(QEI_COMPPOS_CH_2,consigne+1); + qei.IntCmd(QEI_INTFLAG_POS2_Int, ENABLE); + int tmp; + tmp = consigne-qei.GetPosition(); + if (tmp > 0) + sens=1; + else if (tmp < 0) + sens=-1; + else if (tmp ==0) + sens=0; + + break; + //PWM + case 'P': + case 'p': + pc.printf("\r\nPWM="); + pc.scanf("%f",&pwm); + pc.printf("%f\r\n",pwm); + + break; + //STOP + case ' ': + pc.printf("\r\nSTOP\r\n"); + sens=0; + break; + + } + led_RX=0; +} +//ISR +void isr_POS0(void) { + led_POS0 = 1; + sens=0; + qei.IntClear(QEI_INTFLAG_POS0_Int); + +} + +void isr_POS1(void) { + led_POS1 = 1; + sens=1; + qei.IntClear(QEI_INTFLAG_POS1_Int); +} + +void isr_POS2(void) { + led_POS2 = 1; + sens=-1; + qei.IntClear(QEI_INTFLAG_POS2_Int); +} + +int main() { + //init GLCD +#ifdef TFT + GLCD_Init(); + GLCD_Clear (White); + sprintf(text,"QEI HARDWARE MOTOR"); + GLCD_DisplayString (0, 0, 1, (unsigned char *)text); +#endif + //init QEI + qei.SetDigiFilter(1UL); //4294967295 + qei.SetMaxPosition(0xFFFFFFFF); + qei.SetVelocityTimerReload_us(100000); + //isr POS0 + qei.AppendISR(QEI_INTFLAG_POS0_Int, &isr_POS0); + qei.AppendISR(QEI_INTFLAG_POS1_Int, &isr_POS1); + qei.AppendISR(QEI_INTFLAG_POS2_Int, &isr_POS2); + + pwm=PWM; + while (1) { + led_POS0 = 0; + led_POS1 = 0; + led_POS2 = 0; + led_RX=0; + //TFT +#ifdef TFT + sprintf(text,"pos : %d vs %d", qei.GetPosition(),consigne); + GLCD_DisplayString (1, 0, 1, (unsigned char *)text); + sprintf(text,"idx : %d ", qei.GetIndex()); + GLCD_DisplayString (2, 0, 1, (unsigned char *)text); + sprintf(text,"dir : %d ", qei.Direction() == SET ? -1 : 1); + GLCD_DisplayString (3, 0, 1, (unsigned char *)text); + sprintf(text,"vel : %d ", qei.GetVelocity ()); + GLCD_DisplayString (4, 0, 1, (unsigned char *)text); + sprintf(text,"rpm : %d ", qei.CalculateRPM (qei.GetVelocityCap (), PPR)); + GLCD_DisplayString (5, 0, 1, (unsigned char *)text); + sprintf(text,"PWM : %f ", pwm); + GLCD_DisplayString (5, 0, 1, (unsigned char *)text); +#endif + led_DIR = qei.Direction() == SET ? 1 : 0; + m.speed(sens * pwm); + if (pc.readable()) + pc_rx(); + } +}
diff -r 000000000000 -r 9555690e7705 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Fri Mar 02 14:18:23 2012 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/4c0c40fd0593