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.

How to implement eQEP function on AM335x

Other Parts Discussed in Thread: SYSBIOSSDK-IND-SITARA, CONTROLSUITE

Hi

Please help.

How to implement eQEP function on AM335x?

We require a sample code.

SDK: http://www.ti.com/tool/sysbiossdk-ind-sitara

Thanks.

From Wull Hsu

  • Hi,

    I'm afraid eQEP driver is not available on AM335x. But there are drivers in controlSUITE for the same IP(http://www.ti.com/tool/controlsuite). The examples can be found here

    ti\controlSUITE\device_support\f28m36x\v202\F28M36x_examples_Control\eqep_pos_speed\c28
    ti\controlSUITE\device_support\f28m36x\v202\F28M36x_examples_Control\eqep_freq_cal\c28

    Regards,
    Vinesh

  • Hi Vinesh,

    I want to implement "Quadrature Count Mode" on BeagleBone.

    I created "eqep2_setting.c", but still have some problem.

    7853.eqep2_setting.c
    #include "soc_AM335x.h"
    #include "interrupt.h"
    #include "ehrpwm.h"
    #include "evmAM335x.h"
    #include "uartStdio.h"
    #include "hw_types.h"
    
    #include "hw_control_AM335x.h"
    #include "hw_cm_wkup.h"
    #include "hw_cm_per.h"
    #include "gpio.h"
    #include "hw_pwmss.h"
    
    /****************************************************************************/
    /*              		LOCAL DEFINE                                   		*/
    /****************************************************************************/
    // EQEP Register define
    #define EQEP_QPOSCNT		0x00
    #define EQEP_QPOSINIT		0x04
    #define EQEP_QPOSMAX		0x08
    #define EQEP_QPOSCMP		0x0C
    #define EQEP_QPOSILAT		0x10
    #define EQEP_QPOSSLAT		0x14
    #define EQEP_QPOSLAT		0x18
    #define EQEP_QUTMR			0x1C
    #define EQEP_QUPRD			0x20
    #define EQEP_QWDTMR			0x24
    #define EQEP_QWDPRD			0x26
    #define EQEP_QDECCTL		0x28
    #define EQEP_QEPCTL			0x2A
    #define EQEP_QCAPCTL		0x2C
    #define EQEP_QPOSCTL		0x2E
    #define EQEP_QEINT			0x30
    #define EQEP_QFLG			0x32
    #define EQEP_QCLR			0x34
    #define EQEP_QFRC			0x36
    #define EQEP_QEPSTS			0x38
    #define EQEP_QCTMR			0x3A
    #define EQEP_QCPRD			0x3C
    #define EQEP_QCTMRLAT		0x3E
    #define EQEP_QCPRDLAT		0x40
    #define EQEP_REVID			0x5C
    
    #define PWMSS_EQEPCLK_EN					(0x10)
    #define PWMSS_CLOCK_CONFIG               	(0x08)
    
    #define Quadrature_Count_Mode				(0x0000)
    #define EQEP_QEPCTL_FREESOFT_QUTMR			(0x8000)
    #define EQEP_QEPCTL_PCRM_IndexEvent			(0x0000)
    #define EQEP_QEPCTL_UTE						(0x0002)
    #define EQEP_QEPCTL_QCLM_EN					(0x0004)
    #define EQEP_QEPCTL_PHEN_EN					(0x0008)
    #define EQEP_QCAPCTL_UPPS_QCLKDIV32			(0x0005)
    #define EQEP_QCAPCTL_CCPS_SYSCLKOUTDIV64	(0x0060)
    #define EQEP_QCAPCTL_CEN					(0x8000)
    
    #define EQEP_QEINT_UTO						(0x0800)
    #define EQEP_QEINT_IEL						(0x0400)
    #define EQEP_QEINT_PCO						(0x0040)
    #define EQEP_QEINT_PCU						(0x0020)
    
    #define EQEP_QFLG_PCO						(0x0040)
    #define EQEP_QFLG_PCU						(0x0020)
    #define EQEP_QCLR_PCO						(0x0040)
    #define EQEP_QCLR_PCU						(0x0020)
    
    /****************************************************************************/
    /*              LOCAL FUNCTION PROTOTYPES                                   */
    /****************************************************************************/
    void eQEP2INTConfigure(void);
    void eQEP2Isr(void);
    unsigned int GeteQEP2Pos(void);
    unsigned int eQEPGetQPOSCNTData(unsigned int baseAdd);
    
    /****************************************************************************/
    /*              GLOBAL VARIABLE DEFINITIONS									*/
    /****************************************************************************/
    unsigned int overflow = 0;
    unsigned int downflow = 0;
    unsigned int isrCount = 0;
    
    unsigned int eQEP2Pos = 0;
    unsigned int eQEP2_QPOSCNT = 0;
    
    /****************************************************************************/
    /*             LOCAL FUNCTION DEFINITIONS                                   */
    /****************************************************************************/
    
    int main(void)
    {
        // -----------------------------------------------------------------------
    	//		eQEP2
    	// -----------------------------------------------------------------------
        printf("\nStart eQEP clock config.\n");
    
        // Enable CM_PER_EPWMSS2_CLKCTRL
        PWMSSModuleClkConfig(2);
    
        // Pin mux initial
    	// Pin name = CONTROL_CONF_GPMC_AD12 mapping to EQEP2A_IN - GPIO1_12(GPMC_AD12)
    	HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(12)) = CONTROL_CONF_MUXMODE(4);
    	// Pin name = CONTROL_CONF_GPMC_AD13 mapping to EQEP2B_IN - GPIO1_13(GPMC_AD13)
    	HWREG(SOC_CONTROL_REGS + CONTROL_CONF_GPMC_AD(13)) = CONTROL_CONF_MUXMODE(4);
    
    	// Enable eqep clock
    	HWREG(SOC_PWMSS2_REGS + PWMSS_CLOCK_CONFIG) |= PWMSS_EQEPCLK_EN;
    	// -----------------------------------------------------------------------
    
    	printf("Start eQEP setting\n");
    
    	// Unit Timer 80 MHz SYSCLKOUT
        HWREG(SOC_EQEP_2_REGS + EQEP_QUPRD) = 80000000;
    
        // QEP quadrature count mode
        HWREGH(SOC_EQEP_2_REGS + EQEP_QDECCTL) |= Quadrature_Count_Mode;
    
        // Emulation Control Bits, FREE_SOFT=2;
        HWREGH(SOC_EQEP_2_REGS + EQEP_QEPCTL) |= EQEP_QEPCTL_FREESOFT_QUTMR;
    
        // PCRM=00 mode - QPOSCNT reset on index event
        HWREGH(SOC_EQEP_2_REGS + EQEP_QEPCTL) |= EQEP_QEPCTL_PCRM_IndexEvent;
    
        // Unit Timeout Enable
        HWREGH(SOC_EQEP_2_REGS + EQEP_QEPCTL) |= EQEP_QEPCTL_UTE;
    
        // eQEP capture latch mode, Latch on unit time out
        HWREGH(SOC_EQEP_2_REGS + EQEP_QEPCTL) |= EQEP_QEPCTL_QCLM_EN;
    
        // QPOSMAX=0xffffffff
        HWREG(SOC_EQEP_2_REGS + EQEP_QPOSMAX) = 0xFFFFFFFF;
    
        // Quadrature position counter enable
        HWREGH(SOC_EQEP_2_REGS + EQEP_QEPCTL) |= EQEP_QEPCTL_PHEN_EN;
    
        // 1/32 for unit position
    	HWREG(SOC_EQEP_2_REGS + EQEP_QCAPCTL) |= EQEP_QCAPCTL_UPPS_QCLKDIV32;
    
    	// 1/64 for CAP clock
    	HWREG(SOC_EQEP_2_REGS + EQEP_QCAPCTL) |= EQEP_QCAPCTL_CCPS_SYSCLKOUTDIV64;
    
    	// QEP Capture Enable
    	HWREGH(SOC_EQEP_2_REGS + EQEP_QCAPCTL) |= EQEP_QCAPCTL_CEN;
    
    	// ----------------------------------------------------------------------------
    	// Enable IRQ in CPSR
    	IntMasterIRQEnable();
    	// Configure eqep2 interrupt
    	eQEP2INTConfigure();
    
    	// QEINT enable the interrupt
    	HWREGH(SOC_EQEP_2_REGS + EQEP_QEINT) = (EQEP_QEINT_UTO|EQEP_QEINT_IEL|EQEP_QEINT_PCO|EQEP_QEINT_PCU);
    
    #endif
    
    	printf("Start eQEP function\n");
    
    	while(1)
    	{
    		eQEP2Pos = GeteQEP2Pos();
    	}
    
    }
    
    void eQEP2Isr(void)
    {
    	isrCount++;
    	isrCount %= 65535;
    //	printf("eQEP2 count: %d\n", isrCount);
    
    	eQEP2_QPOSCNT = HWREG(SOC_EQEP_2_REGS + EQEP_QPOSCNT);
    	printf("eQEP2 QPOSCNT: %d\n", eQEP2_QPOSCNT);
    
    	if((HWREGH(SOC_EQEP_2_REGS + EQEP_QFLG)) & EQEP_QFLG_PCO)
    	{
    		overflow++;
    		overflow %= 65535;
    
    		printf("Get overflow flag\n");
    		
    		// Clear PCO flag
    		HWREGH(SOC_EQEP_2_REGS + EQEP_QCLR) |= EQEP_QCLR_PCO;
    	}
    	else if((HWREGH(SOC_EQEP_2_REGS + EQEP_QFLG)) & EQEP_QFLG_PCU)
    	{
    		downflow++;
    		downflow %= 65535;
    
    		printf("Get downflow flag\n");
    		
    		// Clear PCU flag
    		HWREGH(SOC_EQEP_2_REGS + EQEP_QCLR) |= EQEP_QCLR_PCU;
    	}
    
    }
    
    unsigned int GeteQEP2Pos(void)
    {
    	unsigned int temp=0, CNT=0;
    
    	CNT = eQEPGetQPOSCNTData(SOC_EQEP_2_REGS);
    	if((overflow == 0)&&(downflow == 0)){
    		temp = CNT;
    	}else{
    		temp = CNT + (overflow - downflow)*MAXPOS;
    	}
    
    	return temp;
    }
    
    /*
     * Configure the eQEP2 interrupt
     */
    void eQEP2INTConfigure(void)
    {
    	/* Intialize the ARM Interrupt Controller(AINTC) */
    	IntAINTCInit();
    
    	/* Registering the Interrupt Service Routine(ISR). */
    	IntRegister(SYS_INT_eQEP2INT, eQEP2Isr);
    
    	/* Setting the priority for the system interrupt in AINTC. */
    	IntPrioritySet(SYS_INT_eQEP2INT, 0, AINTC_HOSTINT_ROUTE_IRQ);
    
    	/* Enabling the system interrupt in AINTC. */
    	IntSystemEnable(SYS_INT_eQEP2INT);
    }
    
    /*
     * Get the count from QPOSCNT
     */
    unsigned int eQEPGetQPOSCNTData(unsigned int baseAdd)
    {
    	unsigned int POSCount = 0;
    	POSCount = HWREG(baseAdd + EQEP_QPOSCNT);
    	return POSCount;
    }

    Did I do something wrong ?

    Please HELP ME.

    SDK: StarterWare 02.00.01.01