added support for LPC4088

Fork of QEI_hw by Hexley Ball

Revision:
3:9279a8f154c8
Parent:
2:53f8ae2cf502
diff -r 53f8ae2cf502 -r 9279a8f154c8 qeihw.cpp
--- a/qeihw.cpp	Tue Dec 28 19:32:07 2010 +0000
+++ b/qeihw.cpp	Wed Mar 02 10:37:13 2016 +0000
@@ -13,6 +13,7 @@
  * @author      hb
  **************************************************************************/
 #include "mbed.h"
+#include "pinmap.h" 
 #include "qeihw.h"
 
 QEIHW *QEIHW::instance;
@@ -25,8 +26,9 @@
  * @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)
+QEIHW::QEIHW(uint32_t _dirinv, uint32_t _sigmode, uint32_t _capmode, uint32_t _invinx, uint32_t _crespi)
 {
+#ifdef TARGET_LPC1768
     /* Set up clock and power for QEI module */
     LPC_SC->PCONP |= PCONP_QEI_ENABLE;
 
@@ -73,6 +75,58 @@
 
     // Clear any pending ints    
     LPC_QEI->QEICLR = QEI_INTCLR_BITMASK;   // Set the "clear" bits for for all sources in the Interrupt clear register             
+#elif TARGET_LPC4088
+    /* Set up clock and power for QEI module */
+    LPC_SC->PCONP |= PCONP_QEI_ENABLE;
+
+    /* The clock for theQEI module is set to FCCLK, PCLKSEL{4:0] = 0x1 */
+    LPC_SC->PCLKSEL = LPC_SC->PCLKSEL & ~(0x1fUL<<0) | ((PCLKSEL_CCLK_DIV_1 & 0x1fUL)<<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)
+    pin_function(P1_20, 3); // P1.20 = QEI_PHA
+    pin_mode(P1_20, PullUp);
+
+    // MCI1 (PhB)
+    pin_function(P1_23, 3); // P1.23 = QEI_PHB
+    pin_mode(P1_23, PullUp);
+
+    // MCI2 (Index)
+    pin_function(P1_24, 3); // P1.23 = QEI_IDX
+    pin_mode(P1_24, PullUp);
+    
+    // Initialize all remaining values in QEI peripheral
+    LPC_QEI->CON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI;
+    LPC_QEI->MAXPOS = 0xFFFFFFFF;                          // Default value
+    LPC_QEI->CMPOS0 = 0x00;
+    LPC_QEI->CMPOS1 = 0x00;
+    LPC_QEI->CMPOS2 = 0x00;
+    LPC_QEI->INXCMP0 = 0x00;
+    LPC_QEI->INXCMP1 = 0x00;
+    LPC_QEI->LOAD = 0x00;
+    LPC_QEI->VELCOMP = 0x00;
+    LPC_QEI->FILTERPHA = 0;       // Bypass Filter for PHA
+    LPC_QEI->FILTERPHB = 0;       // Bypass Filter for PHB
+    LPC_QEI->FILTERINX = 0;       // Bypass Filter for INDEX
+
+    // Set QEI configuration value corresponding to the call parameters
+    LPC_QEI->CONF = (
+        ((_dirinv << 0) & 1) | \
+        ((_sigmode << 1) & 2) | \
+        ((_capmode << 2) & 4) | \
+        ((_invinx << 3) & 8)  | \
+        ((_crespi << 4) & 16) );
+       
+    // Mask all int sources   
+    LPC_QEI->IEC = QEI_IECLR_BITMASK;    // Set the "clear" bits for all sources in the IE clear register              
+
+    // Clear any pending ints    
+    LPC_QEI->CLR = QEI_INTCLR_BITMASK;   // Set the "clear" bits for for all sources in the Interrupt clear register             
+#endif
     
     /* preemption = 1, sub-priority = 1 */
     NVIC_SetPriority(QEI_IRQn, ((0x01<<3)|0x01));
@@ -98,7 +152,11 @@
  **********************************************************************/
 void QEIHW::Reset(uint32_t ulResetType)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->QEICON = ulResetType;
+#elif TARGET_LPC4088
+    LPC_QEI->CON = ulResetType;
+#endif
 }
 
 /*********************************************************************//**
@@ -112,6 +170,7 @@
     /* Turn off clock and power for QEI module */
     LPC_SC->PCONP &= PCONP_QEI_DISABLE;
 
+#ifdef TARGET_LPC1768
     /* Return pins to their default assignment (PINSEL = 0, PINMODE = PULLDOWN) */
     // MCI0 (PhA) -> LED-2 (p1.20)
     LPC_PINCON->PINSEL3 &= PINSEL3_MCI0_MASK;
@@ -124,6 +183,16 @@
     // MCI2 (Index) -> p1.24
     LPC_PINCON->PINSEL3 &= PINSEL3_MCI2_MASK;
     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_GPIO1p24;
+#elif TARGET_LPC4088
+    pin_function(P1_20, 0); 
+    pin_mode(P1_20, PullDown);
+
+    pin_function(P1_23, 0); 
+    pin_mode(P1_23, PullDown);
+
+    pin_function(P1_24, 0); 
+    pin_mode(P1_24, PullDown);
+#endif
 }
 
 /*********************************************************************//**
@@ -133,7 +202,11 @@
  **********************************************************************/
 FlagStatus QEIHW::Direction()
 {
+#ifdef TARGET_LPC1768
     return ((LPC_QEI->QEISTAT & QEI_STATUS_DIR) ? SET : RESET);
+#elif TARGET_LPC4088
+    return ((LPC_QEI->STAT & QEI_STATUS_DIR) ? SET : RESET);
+#endif
 }
 
 /*********************************************************************//**
@@ -143,7 +216,11 @@
  **********************************************************************/
 uint32_t QEIHW::GetPosition()
 {
+#ifdef TARGET_LPC1768
     return (LPC_QEI->QEIPOS);
+#elif TARGET_LPC4088
+    return (LPC_QEI->POS);
+#endif
 }
 
 /*********************************************************************//**
@@ -154,7 +231,11 @@
  **********************************************************************/
 void QEIHW::SetMaxPosition(uint32_t ulMaxPos)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->QEIMAXPOS = ulMaxPos;
+#elif TARGET_LPC4088
+    LPC_QEI->MAXPOS = ulMaxPos;
+#endif
 }
 
 /*********************************************************************//**
@@ -192,7 +273,11 @@
  **********************************************************************/
 void QEIHW::SetIndexComp( uint32_t ulIndexComp)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->INXCMP = ulIndexComp;
+#elif TARGET_LPC4088
+    LPC_QEI->INXCMP0 = ulIndexComp;
+#endif
 }
 
 /*********************************************************************//**
@@ -203,7 +288,11 @@
  **********************************************************************/
 void QEIHW::SetVelocityTimerReload( uint32_t ulReloadValue)
 {   
-         LPC_QEI->QEILOAD = ulReloadValue;
+#ifdef TARGET_LPC1768
+    LPC_QEI->QEILOAD = ulReloadValue;
+#elif TARGET_LPC4088
+    LPC_QEI->LOAD = ulReloadValue;
+#endif
 }
 
 /*********************************************************************//**
@@ -219,12 +308,17 @@
     //Work out CCLK
     uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
     uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1;
+#ifdef TARGET_LPC1768
     uint32_t cclkdiv = LPC_SC->CCLKCFG + 1;
+#elif TARGET_LPC4088
+    uint32_t cclkdiv = (LPC_SC->CCLKSEL & 0x1f) + 1;
+#endif
     uint32_t Fcco = (2 * m * XTAL_FREQ) / n;
     uint32_t cclk = Fcco / cclkdiv;
     
 
     
+#ifdef TARGET_LPC1768
 //    div = CLKPWR_GetPCLKSEL(ClkType);
     div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK;
     switch (div)
@@ -247,7 +341,17 @@
     }
     cclk /=div;
     cclk =((uint64_t)cclk / (1000000/ulReloadValue)) - 1;
+
     LPC_QEI->QEILOAD = (uint32_t) cclk;
+
+#elif TARGET_LPC4088
+    div = LPC_SC->PCLKSEL & PCLKSEL1_PCLK_QEI_MASK;
+    if (div != 0)
+        cclk /=div;
+    cclk =((uint64_t)cclk / (1000000/ulReloadValue)) - 1;
+
+    LPC_QEI->LOAD = (uint32_t) cclk;
+#endif
 }
 
 /*********************************************************************//**
@@ -257,7 +361,11 @@
  **********************************************************************/
 uint32_t QEIHW::GetTimer()
 {
+#ifdef TARGET_LPC1768
     return (LPC_QEI->QEITIME);
+#elif TARGET_LPC4088
+    return (LPC_QEI->TIME);
+#endif
 }
 
 /*********************************************************************//**
@@ -267,7 +375,11 @@
  **********************************************************************/
 uint32_t QEIHW::GetVelocity()
 {
+#ifdef TARGET_LPC1768
     return (LPC_QEI->QEIVEL);
+#elif TARGET_LPC4088
+    return (LPC_QEI->VEL);
+#endif
 }
 
 /*********************************************************************//**
@@ -279,7 +391,11 @@
  **********************************************************************/
 uint32_t QEIHW::GetVelocityCap()
 {
+#ifdef TARGET_LPC1768
     return (LPC_QEI->QEICAP);
+#elif TARGET_LPC4088
+    return (LPC_QEI->CAP);
+#endif
 }
 
 /*********************************************************************//**
@@ -302,7 +418,13 @@
  **********************************************************************/
 void QEIHW::SetDigiFilter( uint32_t ulSamplingPulse)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->FILTER = ulSamplingPulse;
+#elif TARGET_LPC4088
+    LPC_QEI->FILTERPHA = ulSamplingPulse;
+    LPC_QEI->FILTERPHB = ulSamplingPulse;
+    LPC_QEI->FILTERINX = ulSamplingPulse;
+#endif
 }
 
 /*********************************************************************//**
@@ -331,7 +453,11 @@
  **********************************************************************/
 FlagStatus QEIHW::GetIntStatus( uint32_t ulIntType)
 {
+#ifdef TARGET_LPC1768
     return((LPC_QEI->QEIINTSTAT & ulIntType) ? SET : RESET);
+#elif TARGET_LPC4088
+    return((LPC_QEI->INTSTAT & ulIntType) ? SET : RESET);
+#endif
 }
 
 /*********************************************************************//**
@@ -362,11 +488,19 @@
  **********************************************************************/
 void QEIHW::IntCmd( uint32_t ulIntType, FunctionalState NewState)
 {
+#ifdef TARGET_LPC1768
     if (NewState == ENABLE) {
         LPC_QEI->QEIIES = ulIntType;
     } else {
         LPC_QEI->QEIIEC = ulIntType;
     }
+#elif TARGET_LPC4088
+    if (NewState == ENABLE) {
+        LPC_QEI->IES = ulIntType;
+    } else {
+        LPC_QEI->IEC = ulIntType;
+    }
+#endif
 }
 
 /*********************************************************************//**
@@ -394,7 +528,11 @@
  **********************************************************************/
 void QEIHW::IntSet( uint32_t ulIntType)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->QEISET = ulIntType;
+#elif TARGET_LPC4088
+    LPC_QEI->SET = ulIntType;
+#endif
 }
 
 /*********************************************************************//**
@@ -422,7 +560,11 @@
  **********************************************************************/
 void QEIHW::IntClear( uint32_t ulIntType)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->QEICLR = ulIntType;
+#elif TARGET_LPC4088
+    LPC_QEI->CLR = ulIntType;
+#endif
 }
 
 /*********************************************************************//**
@@ -444,10 +586,16 @@
     //Work out CCLK
     uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
     uint32_t n = (LPC_SC->PLL0CFG >> 16) + 1;
+#ifdef TARGET_LPC1768
     uint32_t cclkdiv = LPC_SC->CCLKCFG + 1;
+#elif TARGET_LPC4088
+    uint32_t cclkdiv = (LPC_SC->CCLKSEL & 0x1f) + 1;
+#endif
     uint32_t Fcco = (2 * m * XTAL_FREQ) / n;
     uint32_t cclk = Fcco / cclkdiv;
     
+
+#ifdef TARGET_LPC1768
 //    div = CLKPWR_GetPCLKSEL(ClkType);
     div = LPC_SC->PCLKSEL1 & PCLKSEL1_PCLK_QEI_MASK;
     switch (div)
@@ -468,8 +616,8 @@
         div = 8;
         break;
     }
-    cclk /= div;
-    
+    cclk /=div;
+
     // Get Timer load value (velocity capture period)
     Load  = (uint64_t)(LPC_QEI->QEILOAD + 1);
     // Get Edge
@@ -477,6 +625,21 @@
     // Calculate RPM
     rpm = ((( uint64_t)cclk * ulVelCapValue * 60) / (Load * ulPPR * edges));
 
+#elif TARGET_LPC4088
+    div = LPC_SC->PCLKSEL & PCLKSEL1_PCLK_QEI_MASK;
+    if (div != 0)
+        cclk /=div;
+
+    // Get Timer load value (velocity capture period)
+    Load  = (uint64_t)(LPC_QEI->LOAD + 1);
+    // Get Edge
+    edges = (uint64_t)((LPC_QEI->CONF & QEI_CONF_CAPMODE) ? 4 : 2);
+    // Calculate RPM
+    rpm = ((( uint64_t)cclk * ulVelCapValue * 60) / (Load * ulPPR * edges));
+#endif
+
+    
+
     return (uint32_t)(rpm);
 }
 
@@ -569,6 +732,7 @@
 {
     int32_t i;
 
+#ifdef TARGET_LPC1768
     //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)) ) {
@@ -577,6 +741,16 @@
             }
         }
     }
+#elif TARGET_LPC4088
+    //User defined interrupt handlers. Check all possible sources, dispatch to corresponding non-null service routines.
+    for(i = 0; i < 16; i++) {
+        if(LPC_QEI->INTSTAT & ((uint32_t)(1<<i)) ) {
+            if (_qei_isr[i] != NULL) {
+                _qei_isr[i]();
+            }
+        }
+    }
+#endif
     return;
 }