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;
}