This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

QEI0 LM4F230H5QR

Hello,

Can anyone please tell me why I can not get interrupt for QEI1, will I can get interrupt on QEI0.

Setup.c:

__root const uVectorEntry __vector_table[] @ ".intvec" =
{
    { .ulPtr = (unsigned long)pulStack + sizeof(pulStack) },
                                            // The initial stack pointer
    ResetISR,                               // The reset handler
    NmiSR,                                  // The NMI handler
    FaultISR,                               // The hard fault handler

..........

   QEI1IntHandler,       // GPIO Port C
   QEI0IntHandler,       // GPIO Port D   

..........

};

 

Encoder.h:

/*****************************************************/
/*  For LM4F230H5QR                                                */
/*****************************************************/
#define QEI_PITCH_INDEX_PORT   GPIO_PORTD_BASE
#define QEI_PITCH_INDEX_PIN        GPIO_PIN_3
#define QEI_PITCH_INDEX_INT        INT_GPIOD

#define QEI_PITCH_PHA_PORT        GPIO_PORTD_BASE
#define QEI_PITCH_PHA_PIN            GPIO_PIN_6
#define QEI_PITCH_PHA_INT            INT_GPIOD

#define QEI_PITCH_PHB_PORT        GPIO_PORTD_BASE
#define QEI_PITCH_PHB_PIN            GPIO_PIN_7

//*****************************************************

#define QEI_ROLL_INDEX_PORT      GPIO_PORTC_BASE
#define QEI_ROLL_INDEX_PIN          GPIO_PIN_4
#define QEI_ROLL_INDEX_INT          INT_GPIOC

#define QEI_ROLL_PHA_PORT          GPIO_PORTC_BASE
#define QEI_ROLL_PHA_PIN              GPIO_PIN_5
#define QEI_ROLL_PHA_INT               INT_GPIOC

#define QEI_ROLL_PHB_PORT          GPIO_PORTC_BASE
#define QEI_ROLL_PHB_PIN              GPIO_PIN_6

//*****************************************************

Encoder.c:


//*****************************************************************************
//
// This function prepares the quadrature encoder module for capturing the
// position and speed of the motor.
//
//*****************************************************************************
void
Encoder_Init(unsigned long ulBase)
{

 if(ulBase == QEI0_BASE)  
 {
  //
  // Enable the peripherals QEI example.
  // 
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
 
     // unlock GPIO PD7
     GPIO_PORTD_LOCK_R = GPIO_LOCK_KEY;
  GPIO_PORTD_CR_R = GPIO_PIN_7;

  //Enable GPIO for QEI0
  //PD3-> IDX0     
  //PD6-> PHA0
  //PD7-> PHB0
  GPIOPinConfigure(GPIO_PD3_IDX0);  
  GPIOPinConfigure(GPIO_PD6_PHA0); 
  GPIOPinConfigure(GPIO_PD7_PHB0);

  GPIOPinTypeQEI(QEI_PITCH_PHA_PORT,QEI_PITCH_PHA_PIN);
  GPIOPinTypeQEI(QEI_PITCH_PHB_PORT,QEI_PITCH_PHB_PIN);
  GPIOPinTypeQEI(QEI_PITCH_INDEX_PORT,QEI_PITCH_INDEX_PIN);
  
  
  // Set D 0 and 1 to alternative use
  GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);//GPIO_DIR_MODE_HW 
  GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
  GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
  

  //
  // Configure the QEI module.
  //
  QEIConfigure(QEI0_BASE,
       (QEI_CONFIG_NO_RESET | QEI_CONFIG_CAPTURE_A_B |
        QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), QEI1_POSCNT_MAX-1);
  
  
  //Set to 0
  QEIPositionSet(QEI0_BASE, 100);

  QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_1, 500000); //Configure the Velocity capture Module //500000 is 10ms at 50MHz

  QEIVelocityEnable(QEI0_BASE); //Enable the Velocity capture Module 
  
  QEIIntEnable(QEI0_BASE, QEI_INTDIR | QEI_INTINDEX);   //Enable Interrupt when the Timer is reach 0 on Valocity capture mode
  
  QEIEnable(QEI0_BASE);
    
  //
  // Configure the encoder input to generate an interrupt on every rising
  // edge.
  //
  GPIOIntTypeSet(QEI_PITCH_PHA_PORT, QEI_PITCH_PHA_PIN, GPIO_RISING_EDGE);
  GPIOPinIntEnable(QEI_PITCH_PHA_PORT, QEI_PITCH_PHA_PIN);
  IntEnable(QEI_PITCH_PHA_INT);   

  //Interrupt Enable
  //IntEnable(INT_QEI1);

   
 }
 else
 if(ulBase == QEI1_BASE)  // J8 ROLL Encoder
 {

  //
  // Enable the peripherals QEI example.
  // 
  SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
  SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI1);

  //Enable GPIO for QEI1
  //PC4-> IDX0     
  //PC5-> PHA0
  //PC6-> PHB0
  GPIOPinConfigure(GPIO_PC4_IDX1);  
  GPIOPinConfigure(GPIO_PC5_PHA1); 
  GPIOPinConfigure(GPIO_PC6_PHB1);  
   
  GPIOPinTypeQEI(QEI_ROLL_PHA_PORT,QEI_ROLL_PHA_PIN);
  GPIOPinTypeQEI(QEI_ROLL_PHB_PORT,QEI_ROLL_PHB_PIN);
  GPIOPinTypeQEI(QEI_ROLL_INDEX_PORT,QEI_ROLL_INDEX_PIN);
  
  
  // Set F 0 and 1 to alternative use
  GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);//GPIO_DIR_MODE_HW 
  GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
  GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
  

  //
  // Configure the QEI module.
  //
  QEIConfigure(QEI1_BASE,
       (QEI_CONFIG_NO_RESET | QEI_CONFIG_CAPTURE_A_B |
        QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), QEI1_POSCNT_MAX-1);
  
  
  //Set to 0
  QEIPositionSet(QEI1_BASE, 0);

  QEIVelocityConfigure(QEI1_BASE, QEI_VELDIV_1, 500000); //Configure the Velocity capture Module //500000 is 10ms at 50MHz

  QEIVelocityEnable(QEI1_BASE); //Enable the Velocity capture Module 
  
  QEIIntEnable(QEI1_BASE, QEI_INTDIR | QEI_INTINDEX);   //Enable Interrupt when the Timer is reach 0 on Valocity capture mode
  
  QEIEnable(QEI1_BASE);
    
  //
  // Configure the encoder input to generate an interrupt on every rising
  // edge.
  //
  GPIOIntTypeSet(QEI_ROLL_PHA_PORT, QEI_ROLL_PHA_PIN, GPIO_RISING_EDGE);
  GPIOPinIntEnable(QEI_ROLL_PHA_PORT, QEI_ROLL_PHA_PIN);
  IntEnable(QEI_ROLL_PHA_INT);   

  //Interrupt Enable
  //IntEnable(INT_QEI1); 
  }
}

  • Eran4576 said:

    Can anyone please tell me why I can not get interrupt for QEI1, will I can get interrupt on QEI0.

    Surely!  However motivation sags when you remain silent to detailed assistance recently provided...

    http://e2e.ti.com/support/microcontrollers/stellaris_arm_cortex-m3_microcontroller/f/473/t/211589.aspx 

    And further - while I "sulk" @ your seeming, "disregard/expectation of free, instant, detailed tech support" forum vendor dislikes such "repeat posts!"  (You have near identical one which "someway/somehow" failed to generate interest...

  • Hi cb1

    First of all sorry sorry sorry! your absolutely right.

    I have not  login to my.Ti , so I have not seen the option "YES" or other to answer your question.

    You've been help me so far, I"m just in the development so sometimes I forget myself.

    Thanks

    Eran Segal

     

  • Can anyone please tell me why I can not get interrupt for QEI1, will I can get interrupt on QEI0.

    Setup.c:

    __root const uVectorEntry __vector_table[] @ ".intvec" =
    {
        { .ulPtr = (unsigned long)pulStack + sizeof(pulStack) },
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler

    ..........

       QEI1IntHandler,       // GPIO Port C
       QEI0IntHandler,       // GPIO Port D   

    ..........

    };

     

    Encoder.h:

    /*****************************************************/
    /*  For LM4F230H5QR                                                */
    /*****************************************************/
    #define QEI_PITCH_INDEX_PORT   GPIO_PORTD_BASE
    #define QEI_PITCH_INDEX_PIN        GPIO_PIN_3
    #define QEI_PITCH_INDEX_INT        INT_GPIOD

    #define QEI_PITCH_PHA_PORT        GPIO_PORTD_BASE
    #define QEI_PITCH_PHA_PIN            GPIO_PIN_6
    #define QEI_PITCH_PHA_INT            INT_GPIOD

    #define QEI_PITCH_PHB_PORT        GPIO_PORTD_BASE
    #define QEI_PITCH_PHB_PIN            GPIO_PIN_7

    //*****************************************************

    #define QEI_ROLL_INDEX_PORT      GPIO_PORTC_BASE
    #define QEI_ROLL_INDEX_PIN          GPIO_PIN_4
    #define QEI_ROLL_INDEX_INT          INT_GPIOC

    #define QEI_ROLL_PHA_PORT          GPIO_PORTC_BASE
    #define QEI_ROLL_PHA_PIN              GPIO_PIN_5
    #define QEI_ROLL_PHA_INT               INT_GPIOC

    #define QEI_ROLL_PHB_PORT          GPIO_PORTC_BASE
    #define QEI_ROLL_PHB_PIN              GPIO_PIN_6

    //*****************************************************

    Encoder.c:


    //*****************************************************************************
    //
    // This function prepares the quadrature encoder module for capturing the
    // position and speed of the motor.
    //
    //*****************************************************************************
    void
    Encoder_Init(unsigned long ulBase)
    {

     if(ulBase == QEI0_BASE)  
     {
      //
      // Enable the peripherals QEI example.
      // 
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);
     
         // unlock GPIO PD7
         GPIO_PORTD_LOCK_R = GPIO_LOCK_KEY;
      GPIO_PORTD_CR_R = GPIO_PIN_7;

      //Enable GPIO for QEI0
      //PD3-> IDX0     
      //PD6-> PHA0
      //PD7-> PHB0
      GPIOPinConfigure(GPIO_PD3_IDX0);  
      GPIOPinConfigure(GPIO_PD6_PHA0); 
      GPIOPinConfigure(GPIO_PD7_PHB0);

      GPIOPinTypeQEI(QEI_PITCH_PHA_PORT,QEI_PITCH_PHA_PIN);
      GPIOPinTypeQEI(QEI_PITCH_PHB_PORT,QEI_PITCH_PHB_PIN);
      GPIOPinTypeQEI(QEI_PITCH_INDEX_PORT,QEI_PITCH_INDEX_PIN);
      
      
      // Set D 0 and 1 to alternative use
      GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_3, GPIO_DIR_MODE_HW);//GPIO_DIR_MODE_HW 
      GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
      GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_7, GPIO_DIR_MODE_HW);
      

      //
      // Configure the QEI module.
      //
      QEIConfigure(QEI0_BASE,
           (QEI_CONFIG_NO_RESET | QEI_CONFIG_CAPTURE_A_B |
            QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), QEI1_POSCNT_MAX-1);
      
      
      //Set to 0
      QEIPositionSet(QEI0_BASE, 100);

      QEIVelocityConfigure(QEI0_BASE, QEI_VELDIV_1, 500000); //Configure the Velocity capture Module //500000 is 10ms at 50MHz

      QEIVelocityEnable(QEI0_BASE); //Enable the Velocity capture Module 
      
      QEIIntEnable(QEI0_BASE, QEI_INTDIR | QEI_INTINDEX);   //Enable Interrupt when the Timer is reach 0 on Valocity capture mode
      
      QEIEnable(QEI0_BASE);
        
      //
      // Configure the encoder input to generate an interrupt on every rising
      // edge.
      //
      GPIOIntTypeSet(QEI_PITCH_PHA_PORT, QEI_PITCH_PHA_PIN, GPIO_RISING_EDGE);
      GPIOPinIntEnable(QEI_PITCH_PHA_PORT, QEI_PITCH_PHA_PIN);
      IntEnable(QEI_PITCH_PHA_INT);   

      //Interrupt Enable
      //IntEnable(INT_QEI1);

       
     }
     else
     if(ulBase == QEI1_BASE)  // J8 ROLL Encoder
     {

      //
      // Enable the peripherals QEI example.
      // 
      SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
      SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI1);

      //Enable GPIO for QEI1
      //PC4-> IDX0     
      //PC5-> PHA0
      //PC6-> PHB0
      GPIOPinConfigure(GPIO_PC4_IDX1);  
      GPIOPinConfigure(GPIO_PC5_PHA1); 
      GPIOPinConfigure(GPIO_PC6_PHB1);  
       
      GPIOPinTypeQEI(QEI_ROLL_PHA_PORT,QEI_ROLL_PHA_PIN);
      GPIOPinTypeQEI(QEI_ROLL_PHB_PORT,QEI_ROLL_PHB_PIN);
      GPIOPinTypeQEI(QEI_ROLL_INDEX_PORT,QEI_ROLL_INDEX_PIN);
      
      
      // Set F 0 and 1 to alternative use
      GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_4, GPIO_DIR_MODE_HW);//GPIO_DIR_MODE_HW 
      GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_5, GPIO_DIR_MODE_HW);
      GPIODirModeSet(GPIO_PORTC_BASE, GPIO_PIN_6, GPIO_DIR_MODE_HW);
      

      //
      // Configure the QEI module.
      //
      QEIConfigure(QEI1_BASE,
           (QEI_CONFIG_NO_RESET | QEI_CONFIG_CAPTURE_A_B |
            QEI_CONFIG_QUADRATURE | QEI_CONFIG_NO_SWAP), QEI1_POSCNT_MAX-1);
      
      
      //Set to 0
      QEIPositionSet(QEI1_BASE, 0);

      QEIVelocityConfigure(QEI1_BASE, QEI_VELDIV_1, 500000); //Configure the Velocity capture Module //500000 is 10ms at 50MHz

      QEIVelocityEnable(QEI1_BASE); //Enable the Velocity capture Module 
      
      QEIIntEnable(QEI1_BASE, QEI_INTDIR | QEI_INTINDEX);   //Enable Interrupt when the Timer is reach 0 on Valocity capture mode
      
      QEIEnable(QEI1_BASE);
        
      //
      // Configure the encoder input to generate an interrupt on every rising
      // edge.
      //
      GPIOIntTypeSet(QEI_ROLL_PHA_PORT, QEI_ROLL_PHA_PIN, GPIO_RISING_EDGE);
      GPIOPinIntEnable(QEI_ROLL_PHA_PORT, QEI_ROLL_PHA_PIN);
      IntEnable(QEI_ROLL_PHA_INT);   

      //Interrupt Enable
      //IntEnable(INT_QEI1); 
      }
    }

  • @Eran - No one wants your sorrow.   Common courtesy will benefit you long into the future - both in school and @ work.  And I do thank you for the Verify Answer tick on your earlier referenced PWM post. 

    That said - is there a means to, "untick" the Verify Answer for this post.  Don't believe myself/others have "answered" (yet alone provided anything - "verifiable!") 

    Be sure to download latest errata - make sure that your MCU does support this QEI operation.  I will try to assist - I have my own encoder code (in ARM Assembler) and will have to set-up my new M4F custom board & read + experiment w/StellarisWare.   (we find it beneficial to work w/ many ARMS - from different makers - Assembler helps here)   I will strive to get you usable StellarisWare answer - but may take me till the weekend.

    Can you better/further detail what works and what fails in your current implementation.  Will give your code quick read @ lunch - but if nothing "jumps out" the more detail you provide the faster/easier solution for interested, "helpers."

  • "Ducking" your post bothered me - so...   Earlier - w/in your PWM post (which you "Verified Answered") I identified your trend for employing multiple modules (in that case PWM Modules) when a single one would suffice.  And here - again - such "penchant" (trend) continues!   As General, Sun Tzu taught - know thy enemy (or forum requester)...

    Why do you employ both QEI0 and QEI1?   Have you two, separate encoders - attached to two separate motors?  

    If not - far simpler/faster to employ just one QEI Module.   Would you be so good as to rewrite your code to reflect this guidance - and again test/verify & report?

  • And now - better insight.  Look here:

    #define QEI_PITCH_PHB_PORT        GPIO_PORTD_BASE
    #define QEI_PITCH_PHB_PIN            GPIO_PIN_7

    The above code reveals your, "normal/customary" treatment of Port D - Pin 7.   However - your MCU's Errata (Rev A1/A2) advises:

    Thus PD7 has a higher purpose - does not, "take kindly" to your attempt to, "re-purpose."   What then to do?

    Workaround:
    To reconfigure the pins to their intended reset state (GPIO Input, GPIODEN =0), software must clear
    the corresponding bits in the GPIOAFSEL and GPIODEN registers for the associated pins. For pins
    PD7 and PF0, software must clear the corresponding AFSEL bits using the register commit control
    procedures described in the Commit Control section in the General-Purpose Input/Outputs chapter
    in the data sheet. 

    Believe this will resolve this aspect of your issue...     ducked post  end>

     

  • Hi,

    I add 2 lines and it works!

    //You should add two lines before configure PD6 and PD7
          HWREG(GPIO_PORTD_BASE + 0x520) = 0x4C4F434B; //Unlock GPIOCR, see datasheet page 711
          HWREG(GPIO_PORTD_BASE + 0x524) = 0x000000ff; //Change GPIOCR from 0x7f-> 0xff,see datasheet page 712

    Goodluck!

    Le Manh Hai

  • Wot a struggle!

    This also works and might be edifying...      

        // *************************************************************************************************** Lx4F232H5QD
        //    Initialize right side QEI (Quadrature Encoder Interface) for use by the right side drive
        //    Uses GPIO Port D bits PD6 & PD7 (no Index output on the encoder)
        //    Note: Port D pin 7 defaults to a NMI input at reset. That functionality is protected by a mechanism
        //    which must be "unlocked" before it can be made available to another module (like QEI0).
        // ***************************************************************************************************

        // Enable Port D module so we can work with it
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);

        // Make pin direction of bits 6 and 7 INPUTS (this may be unnecessary?)
        ROM_GPIODirModeSet(GPIO_PORTD_BASE, GPIO_PIN_7 | GPIO_PIN_6, GPIO_DIR_MODE_IN);

        // Write this 'key' 0x4C4F434B into Port D's Lock register to enable access to Port D's Commit register
        GPIO_PORTD_LOCK_R = 0x4C4F434B;

        // Flip only bit 7 ON to ALLOW Port D bit 7 to be switched from NMI use to QEI use
        GPIO_PORTD_CR_R |= 0x80;

        // Switch pin usage
        GPIO_PORTD_AFSEL_R |= 0x80;            // Selects alternative usage for the pin
        GPIO_PORTD_PCTL_R  |= 0x60000000;    // Selects QEI0 PHB0 in particular (pages 722 & 1405 in LM4F232H5QD manual)

        // Flip only bit 7 OFF to Re-lock
        GPIO_PORTD_CR_R &= !0x08;

        // Enable programming access to QEI Module 0
        ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_QEI0);

        // Tell the mux which particular QEI function to connect to specified pin
        ROM_GPIOPinConfigure(GPIO_PD6_PHA0);
        ROM_GPIOPinConfigure(GPIO_PD7_PHB0);    // now redundant

        // Tell the GPIO module which pins will be QEI type pins
        ROM_GPIOPinTypeQEI(GPIO_PORTD_BASE, GPIO_PIN_7 | GPIO_PIN_6);

        // Zero the position counter
        ROM_QEIPositionSet(QEI0_BASE, 5900);

    etc.