Quantcast
Channel: Processors forum - Recent Threads
Viewing all articles
Browse latest Browse all 17527

Linux/BEAGLEBK: EQEP Position Counter Reset on Index Event (QEPCTL[PCRM] = 00) doesn't always work

$
0
0

Part Number:BEAGLEBK

Tool/software: Linux

QPOSCNT is not always resetting on index events.

Beaglebone Black

Linux version 4.4.36-ti-r72

16MHz VCTCXO into QEP2A

GPS PPS into QEP2IDX

I'm expecting QPOSCNT to reset on every IDX event.  It should read something close to 16000000 each time.  This doesn’t happen.  QPOSCNT keeps increasing.

The strange thing is that sometimes it works just fine after a reboot, and continues working.  Sometimes it fails after a reboot and requires another reboot before it will start working again.  Register dumps indicate some differences in QEPSTS and QFLG but it's not clear to me what's going on.

FAILURE CASE:

QPOSCNT:    072b47e5

QPOSINIT:   00000000

QPOSMAX:    ffffffff

QPOSCMP:    00000000

QPOSILAT:   0716ed86

QPOSSLAT:   00000000

QPOSLAT:    00000000

QUTMR:      00000000

QUPRD:      00000000

QWDTMR:     0000

QWDPRD:     0000

QDECCTL:    8800

QEPCTL:     0018

QCAPCTL:    0000

QPOSCTL:    0000

QEINT:      0400

QFLG:       0040

QCLR:       0000

QFRC:       0000

QEPSTS:     00a0

QCTMR:      0000

QCPRD:      0000

QCTMRLAT:   0000

QCPRDLAT:   0000

REVID:      44d31103

WORKING CASE:

QPOSCNT:    0000a60e

QPOSINIT:   00000000

QPOSMAX:    ffffffff

QPOSCMP:    00000000

QPOSILAT:   00f42400

QPOSSLAT:   00000000

QPOSLAT:    00000000

QUTMR:      00000000

QUPRD:      00000000

QWDTMR:     0000

QWDPRD:     0000

QDECCTL:    8800

QEPCTL:     0018

QCAPCTL:    0000

QPOSCTL:    0000

QEINT:      0400

QFLG:       0042

QCLR:       0000

QFRC:       0000

QEPSTS:     00f3

QCTMR:      0000

QCPRD:      0000

QCTMRLAT:   0000

QCPRDLAT:   0000

REVID:      44d31103

static int __init init_hw(struct steering *steering)

{

        printk(KERN_INFO "initializing hardware\n");

        /* Enable clocks in the clock module */

        writel(0x2, steering->cm_per_base + CM_PER_EPWMSS0_CLKCTRL);

        writel(0x2, steering->cm_per_base + CM_PER_EPWMSS1_CLKCTRL);

        writel(0x2, steering->cm_per_base + CM_PER_EPWMSS2_CLKCTRL);

        /* Enable clocks in the PWMSS module */

        // FIXME - should read/modify write in case someone else using ECAP?

        writel( PWMSS_CLKCONFIG_PWM_EN, steering->pwmss_epwm_addr + PWMSS_CLKCONFIG);

        writel( PWMSS_CLKCONFIG_EQEP_EN, steering->pwmss_eqep_addr + PWMSS_CLKCONFIG);

        /* Wakeup PWMSS - no-idle */

        writel(PWMSS_SYSCONFIG_NOIDLE, steering->pwmss_eqep_addr + PWMSS_SYSCONFIG);

        writel(PWMSS_SYSCONFIG_NOIDLE, steering->pwmss_epwm_addr + PWMSS_SYSCONFIG);

        /* Enable the PWM timebase clocks in the control module.  This is a priviledged write */

        writel(0x7, steering->control_module_base + PWMSS_CTRL);

        /* Config EQEP.

         * Counter clocked by VCXO. Reset counter on GPS pulse 

         *

         * 0x28 QDECCTL[QSRC] = 2.      Up-count mode.

         *      QDECCTL[XCR] = 1.       rising edge clock only

         * 0x2A QEPCTL[PRCM] = 0.       reset on index event

         *      QEPCTL[IEL] = 1.        rising edge of GPS PPS as index event

         *      QEPCTL[PHEN] = 1.       enable?

         * 0x30 QEINT[IEL] = 1          interrupt on index event

         * 0x32 QEFLG[IEL] = 1          the interrupt status bit

         * 0x34 QECLR[IEL] = 1          the interrupt clear bit

         *

         * On every GPS rising edge, counter value is latched to QPOSILAT on index and QPOSSLAT on strobe.

         * 0x0  QPOSCNT

         * 0x10 QPOSILAT

         */

        writew(EQEP_QDECCTL_QSRC(2) | EQEP_QDECCTL_XCR, steering->eqep_addr + EQEP_QDECCTL);                    /* up-count mode */

        writew(EQEP_QEPCTL_PCRM(0) | EQEP_QEPCTL_IEL(1) | EQEP_QEPCTL_PHEN, steering->eqep_addr + EQEP_QEPCTL); /* rising edge of IDX and reset */

        writew(~0, steering->eqep_addr + EQEP_QCLR);                                                            /* clear interrupts */

        writew(EQEP_INT_IEL, steering->eqep_addr + EQEP_QEINT);                                                 /* enable interrupts */                                                    

        writew(~0, steering->eqep_addr + EQEP_QCLR);                                                            /* clear interrupts */

        writel(~0, steering->eqep_addr + EQEP_QPOSMAX);                                                         /* full span for count */

        writel(0, steering->eqep_addr + EQEP_QPOSINIT);                                                         /* reset to zero on idx */

        writew(0, steering->eqep_addr + EQEP_QCAPCTL);                                                          /* no capture */

        return 0;

}


Viewing all articles
Browse latest Browse all 17527

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>