Port to LPC1549. Partially tested, not all features ported

Fork of QEI_hw by Hexley Ball

Revision:
3:68844cd35e64
Parent:
2:53f8ae2cf502
diff -r 53f8ae2cf502 -r 68844cd35e64 qeihw.cpp
--- a/qeihw.cpp	Tue Dec 28 19:32:07 2010 +0000
+++ b/qeihw.cpp	Fri Aug 14 16:36:38 2015 +0000
@@ -27,12 +27,20 @@
  **********************************************************************/
 QEIHW::QEIHW(uint32_t _dirinv, uint32_t _sigmode, uint32_t _capmode, uint32_t _invinx)
 {
+#ifdef TARGET_LPC1768    
     /* Set up clock and power for QEI module */
     LPC_SC->PCONP |= PCONP_QEI_ENABLE;
 
     /* The clock for theQEI module is set to FCCLK  */
     LPC_SC->PCLKSEL1 = LPC_SC->PCLKSEL1 & ~(3UL<<0) | ((PCLKSEL_CCLK_DIV_1 & 3)<<0); 
+#elif defined(TARGET_LPC1549)
+    /* Enable clock for the QEI module */
+    LPC_SYSCON->SYSAHBCLKCTRL1 = LPC_SYSCON->SYSAHBCLKCTRL1 | (1<<21);
+    /* Clear peripheral reset for entire comparator block */
+    LPC_SYSCON->PRESETCTRL1 = 0;
+#endif
 
+#ifdef TARGET_LPC1768
     /* 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
@@ -49,6 +57,11 @@
     // MCI2 (Index)
     LPC_PINCON->PINSEL3 = (LPC_PINCON->PINSEL3 & PINSEL3_MCI2_MASK) | PINSEL3_MCI2 ;
     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_MCI2;
+#elif defined(TARGET_LPC1549) // Assign pins
+    LPC_SWM->PINASSIGN14 = (LPC_SWM->PINASSIGN14 & 0x000000FF) 
+        |(24<<QEIO_PHA_I) | (0<<QEIO_PHB_I) | (34<<QEIO_IDX_I);
+        // P0_24              P0_0              P1_3
+#endif
     
     // Initialize all remaining values in QEI peripheral
     LPC_QEI->QEICON = QEI_CON_RESP | QEI_CON_RESV | QEI_CON_RESI;
@@ -59,7 +72,13 @@
     LPC_QEI->INXCMP = 0x00;
     LPC_QEI->QEILOAD = 0x00;
     LPC_QEI->VELCOMP = 0x00;
+#ifdef TARGET_LPC1768
     LPC_QEI->FILTER = 200000;       // Default for mechanical switches.
+#elif defined(TARGET_LPC1549)
+    LPC_QEI->FILTERPHA = 200000;
+    LPC_QEI->FILTERPHB = 200000;
+    LPC_QEI->FILTERINX = 200000;
+#endif
 
     // Set QEI configuration value corresponding to the call parameters
     LPC_QEI->QEICONF = (
@@ -109,9 +128,11 @@
  **********************************************************************/
 void QEIHW::DeInit()
 {
+#ifdef TARGET_LPC1768
     /* Turn off clock and power for QEI module */
     LPC_SC->PCONP &= PCONP_QEI_DISABLE;
 
+
     /* Return pins to their default assignment (PINSEL = 0, PINMODE = PULLDOWN) */
     // MCI0 (PhA) -> LED-2 (p1.20)
     LPC_PINCON->PINSEL3 &= PINSEL3_MCI0_MASK;
@@ -124,6 +145,9 @@
     // MCI2 (Index) -> p1.24
     LPC_PINCON->PINSEL3 &= PINSEL3_MCI2_MASK;
     LPC_PINCON->PINMODE3 = (LPC_PINCON->PINMODE3 & PINMODE3_MCI2_MASK) | PINMODE3_GPIO1p24;
+#elif defined(TARGET_LPC1549)
+    LPC_SWM->PINASSIGN14 = LPC_SWM ->PINASSIGN14 & 0x000000FF;
+#endif
 }
 
 /*********************************************************************//**
@@ -214,6 +238,7 @@
  **********************************************************************/
 void QEIHW::SetVelocityTimerReload_us( uint32_t ulReloadValue)
 {
+#ifdef TARGET_LPC1768
     int div;
 
     //Work out CCLK
@@ -248,6 +273,33 @@
     cclk /=div;
     cclk =((uint64_t)cclk / (1000000/ulReloadValue)) - 1;
     LPC_QEI->QEILOAD = (uint32_t) cclk;
+#elif defined(TARGET_LPC1549)
+    uint32_t p;
+    uint32_t sysclk; 
+    uint32_t qeicount;
+
+    // Assuming using crystal as clock source
+    // Workout system clock (pg 63 LPC15xx user guide)
+    uint32_t psel = ((LPC_SYSCON->SYSPLLCTRL & 0x000000C0) >> 6); // p value
+    uint32_t msel = ((LPC_SYSCON->SYSPLLCTRL & 0x0000001F) + 1); // m description = msel value + 1
+    
+    switch(psel)                     // p description
+    {
+        case 0: p = 1; break;
+        case 1: p = 2; break;
+        case 2: p = 4; break;
+        case 3: p = 8; break;
+    }
+    
+    sysclk = msel * XTAL_FREQ /(p * 2);
+    
+    ulReloadValue = LPC_QEI->LOAD;
+    
+    qeicount = ((uint64_t)sysclk / (1000000/ulReloadValue)) - 1;
+    
+    //LPC_QEI->LOAD = (uint32_t)qeicount;
+    LPC_QEI->LOAD = (uint32_t)(ulReloadValue);
+#endif
 }
 
 /*********************************************************************//**
@@ -279,7 +331,8 @@
  **********************************************************************/
 uint32_t QEIHW::GetVelocityCap()
 {
-    return (LPC_QEI->QEICAP);
+    //return (LPC_QEI->QEICAP);
+    return (LPC_QEI->QEILOAD);
 }
 
 /*********************************************************************//**
@@ -302,7 +355,14 @@
  **********************************************************************/
 void QEIHW::SetDigiFilter( uint32_t ulSamplingPulse)
 {
+#ifdef TARGET_LPC1768
     LPC_QEI->FILTER = ulSamplingPulse;
+#elif defined(TARGET_LPC1549)
+    LPC_QEI->FILTERPHA = ulSamplingPulse;
+    LPC_QEI->FILTERPHB = ulSamplingPulse;
+    LPC_QEI->FILTERINX = ulSamplingPulse;
+#endif
+    
 }
 
 /*********************************************************************//**
@@ -440,6 +500,7 @@
     uint64_t rpm, Load, edges;
     int div;
     
+#ifdef TARGET_LPC1768
     // Get current Clock rate for timer input
     //Work out CCLK
     uint32_t m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
@@ -476,6 +537,39 @@
     edges = (uint64_t)((LPC_QEI->QEICONF & QEI_CONF_CAPMODE) ? 4 : 2);
     // Calculate RPM
     rpm = ((( uint64_t)cclk * ulVelCapValue * 60) / (Load * ulPPR * edges));
+#elif defined(TARGET_LPC1549)
+    // Assuming using crystal as clock source
+    // Workout system clock (pg 63 LPC15xx user guide)
+    uint32_t psel = ((LPC_SYSCON->SYSPLLCTRL & 0x000000C0) >> 6); // p value
+    uint32_t msel = ((LPC_SYSCON->SYSPLLCTRL & 0x0000001F) + 1); // m description = msel value + 1
+    
+    uint32_t p;
+    uint32_t sysclk; 
+    uint32_t qeicount;
+    uint32_t ulReloadValue;
+    
+    switch(psel)                     // p description
+    {
+        case 0: p = 1; break;
+        case 1: p = 2; break;
+        case 2: p = 4; break;
+        case 3: p = 8; break;
+    }
+    
+    sysclk = msel * XTAL_FREQ /(p * 2);
+    
+    ulReloadValue = LPC_QEI->LOAD;
+    
+    qeicount = ((uint64_t)sysclk / (1000000/ulReloadValue)) - 1;
+    
+    // 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);
+    
+    rpm = (sysclk * ulVelCapValue * 60) / (Load * ulPPR * edges);
+#endif
 
     return (uint32_t)(rpm);
 }