Stefan Poels / Mbed 2 deprecated MLX8030x_B6PV_Demo

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "LPC17xx.h"
00003 
00004 #define GUI 1
00005 #define TeraTerm 0
00006 
00007 LocalFileSystem local("local");
00008 
00009 Serial pc(USBTX, USBRX);
00010 
00011 DigitalOut  LedSpi(LED1);                       // LED active during SPI communication 
00012 PwmOut      LedDiagn(LED2);                     // LED active with duty cycle of B6PV "DIAG"-pin
00013 DigitalOut  LedUSB(LED3);                       // LED active if USB connection is established with GUI
00014 DigitalOut  LedApplication(LED4);               // LED active when application is running
00015 
00016 PwmOut      pwmon(p26);                         // B6PV "PWMON"-pin
00017 DigitalIn   spibusy(p9);                        // B6PV "SPI_BUSY"-pin
00018 SPI         spi(p5, p6, p7);                    // B6PV "MOSI", "MISO", "CLK"-pins
00019 DigitalOut  cs(p8);                             // B6PV "CS"-pin
00020 
00021 DigitalOut  OCsimulation(p24);  
00022 
00023 int                 iPWMPeriod      = 1000;     // Set initial PWM period to 1000us or 1kHz
00024 float               fPWMDutyCycle   = 0.0;      // Set initial duty cycle to 0.0 or 0% -> OFF
00025 
00026 volatile uint32_t   u32DiagnDC      = 0;        // Duty cycle from the diagnostics input
00027 const uint16_t      DUTY_CYCLE_ACCURACY = 1000; // Used to enhance the duty cycle calculation (HighTime * 1000)/Period         
00028 volatile uint32_t   u32DiagnPeriod  = 0;        // Period from the diagnostics input
00029 const uint32_t      u32DiagnMaxPeriod = 9600000;// Minimum 10Hz diagnostics frequeny (96MHz/10Hz=9.6e6)
00030 volatile uint32_t   u32DiagnCapA    = 0;        // Timer capture for a falling edge of diagnostics input
00031 volatile uint32_t   u32DiagnCapB    = 0;        // Timer capture for a rising edge of diagnostics input
00032 volatile bool       bTimer2MR0      = false;    // Timer2 reached match register MR0 (used to detect 0% and 100% duty cycle)
00033 
00034 volatile uint32_t   u32SpeedCapA    = 0;        // Timer capture for a 1st edge of speed feedback
00035 volatile uint32_t   u32SpeedCapB    = 0;        // Timer capture for a 2nd edge of speed feedback
00036 volatile uint32_t   u32Speed        = 0;        // Minimum speed
00037 const uint32_t      u32SpeedMaxPeriod= 16000000;// Minum 1eHz = 6Hz commutation speed (96MHz/6Hz=16e6)
00038 volatile bool       bTimer2MR1      = false;    // Timer2 reached match register MR1 (used to detect 0eHz speed = motor still)
00039 
00040 bool                bUsbConnected   = false;    // Boolean to indicate USB connection with GUI
00041 
00042 void SpiInit(void);                             // SPI initialization
00043 void Timer2Init(void);                          // Timer 2 initialization 
00044 void SerialUSBInit(void);                       // Serial USB intialization
00045 void TIMER2_IRQHandler(void);                   // Timer 2 interrupt handler for determining diagnostics duty cycle
00046 uint32_t TransceiveSpiFrame(uint32_t);          // Transceive one SPI frame: Transmit MOSI - Receive MISO
00047 
00048 int main() {
00049     
00050     SpiInit();    
00051     Timer2Init();
00052     SerialUSBInit();
00053     
00054     int iCnt = 0;
00055     uint32_t u32SPIframe = 0;
00056     uint32_t u32result = 0;
00057     
00058     pwmon.period_us(iPWMPeriod);
00059     pwmon.write(fPWMDutyCycle);
00060       
00061     while(1) 
00062     {  
00063         LedApplication = 1;
00064         LedDiagn = float(u32DiagnDC)/DUTY_CYCLE_ACCURACY;       
00065         
00066     #if GUI
00067         char strCommand[8];
00068         if (pc.readable()) 
00069         {              
00070             int err = pc.scanf("%s",&strCommand);
00071             if ((strCommand[0] == 'I') && (strCommand[1] == 'D'))
00072             {
00073                 if (pc.writeable())
00074                     pc.printf("MBED\n");   
00075                     
00076                 int err = pc.scanf("%s",&strCommand);
00077                 if ((strCommand[0] == 'O') && (strCommand[1] == 'K'))
00078                 {
00079                     bUsbConnected = true;
00080                     LedUSB = 1;        
00081                 }   
00082             }
00083             else if (strCommand[0] == 'X')
00084             {
00085                 bUsbConnected = false;
00086                 LedUSB = 0;     
00087             }
00088         }  
00089     #endif  //GUI    
00090         
00091     #ifdef TeraTerm
00092         char c = pc.getc();
00093         switch (c)    
00094         {    
00095         case '\r': // If 'enter' is pressed, send the SPI MOSI-frame
00096             if (!spibusy) 
00097             {
00098                 // Show SPI communication active via LED
00099                 LedSpi = 1;
00100                 wait(0.1);
00101                 u32result = TransceiveSpiFrame(u32SPIframe);
00102                 LedSpi = 0;
00103                 
00104                 pc.printf("\nThe SPI MOSI-frame send = 0x%.8X \n", u32SPIframe);
00105                 pc.printf("The SPI MISO-frame received = 0x%.8X\n", u32result);
00106                 
00107                 iCnt = 0;
00108                 //u32SPIframe = 0;
00109             }
00110             else 
00111             {
00112                 pc.printf("\nSPI busy \nPress enter to try again \n");
00113             }
00114             
00115             pc.printf("The diagnostics frequency is %uHz \n", SystemCoreClock/u32DiagnPeriod);
00116             pc.printf("The diagnostics duty cycle is %.1f%%\n\n", float(u32DiagnDC)/DUTY_CYCLE_ACCURACY*100);
00117             //pc.printf("The speed is %u eHz \n", u32Speed);   
00118             
00119             break;         
00120         
00121         case '1':  // Set '1' in SPI MOSI-frame to be send      
00122             if (iCnt == 0)
00123                 u32SPIframe = (1<<31);
00124             else
00125                 u32SPIframe |= (1<<(31-iCnt));  // shift bits: first entered is MSB 
00126             iCnt++;
00127             pc.printf("%c",c);              // print entered character
00128             if (iCnt > 31)                  // 32-bits can be entered (circular)
00129                 iCnt = 0;
00130             else if (((iCnt) % 4) == 0)     // print space every 4-bits 
00131                 pc.printf(" ");
00132             break;
00133                    
00134         case '0': // Set '0' in SPI MOSI-frame to be send
00135             if (iCnt == 0)
00136                 u32SPIframe = 0;
00137             else 
00138                 u32SPIframe &=~ (1<<(31-iCnt)); // shift bits: first entered is MSB
00139             iCnt++;
00140             pc.printf("%c",c);              // print entered character
00141             if (iCnt > 31)                  // 32-bits can be entered (circular)
00142                 iCnt = 0;
00143             else if (((iCnt) % 4) == 0)     // print space every 4-bits
00144                 pc.printf(" ");
00145             break;
00146             
00147         case 'h': // PWM higher frequency                            
00148             if ((iPWMPeriod - 10) > 100)        // max 10kHz or 100us
00149             {    iPWMPeriod -= 10;}  
00150             else 
00151             {   iPWMPeriod = 100;}
00152             pwmon.period_us(iPWMPeriod);
00153             pwmon.write(fPWMDutyCycle);         // bug in mbed that duty cycle is not maintained on update of period
00154             break; 
00155          
00156         case 'l': // PWM lower frequency
00157             if ((iPWMPeriod + 10) < 10000)      // min 100Hz or 10000us
00158             {    iPWMPeriod += 10;}  
00159             else 
00160             {   iPWMPeriod = 10000;}
00161             pwmon.period_us(iPWMPeriod);
00162             pwmon.write(fPWMDutyCycle);         // bug in mbed that duty cycle is not maintained on update of period 
00163             break;
00164                     
00165         case 'b': // PWM bigger duty cycle
00166             if ((fPWMDutyCycle + 0.001) < 1)    // max 100% duty cycle
00167             {    fPWMDutyCycle += 0.001;} 
00168             else 
00169             {   fPWMDutyCycle = 1;}
00170             pwmon.write(fPWMDutyCycle); 
00171             break;
00172                            
00173         case 's': // PWM smaller duty cycle
00174             if ((fPWMDutyCycle - 0.001) > 0)    // min 0% duty cycle
00175             {    fPWMDutyCycle -= 0.001;}  
00176             else 
00177             {   fPWMDutyCycle = 0;}
00178             pwmon.write(fPWMDutyCycle); 
00179             break;     
00180             
00181         case 'r': // read  
00182             //pc.printf("Read FPGA register 1");
00183             //u32SPIframe = 0xCF020000;        
00184             //u32SPIframe |= (1<<16);
00185             //u32SPIframe |= 0x00000000;
00186             u32result = TransceiveSpiFrame(0xCF090000);//(0xCC290000);        
00187             pc.printf("Read  FPGA register 4 returns 0x%.8X \n",u32result);
00188             
00189             break; 
00190             
00191         case 'w': //write 
00192             //pc.printf("Write 0xA16C to FPGA register 1");
00193             //u32SPIframe = 0xCF020000;        
00194             //u32SPIframe |= (0<<16);
00195             //u32SPIframe |= 0x0000A16C;
00196             u32result = TransceiveSpiFrame(0xCF083182);//(0xCC28FFFF);        
00197             pc.printf("Write FPGA register 4 returns 0x%.8X \n",u32result);
00198             break;
00199             
00200          case 'i': // read ID from B6PV     
00201             u32result = TransceiveSpiFrame(0xCC810000);
00202             if (u32result == 0x00000000)
00203                 pc.printf("B6PV - DOE1 \n");
00204             else if (u32result == 0x00000001)
00205                 pc.printf("B6PV - DOE2 \n");
00206             else if (u32result == 0x00000002)
00207                 pc.printf("B6PV - DOE3 \n");
00208             else if (u32result == 0x00000003)
00209                 pc.printf("B6PV - DOE4 \n");
00210             else
00211                 pc.printf("B6PV - Read ID error \n B6PV returns 0x%.8X \n",u32result);
00212             break; 
00213               
00214         case 't': // trim B6PV and configure FPGA     
00215             u32result = TransceiveSpiFrame(0xCC0A0001); // DOE1_IC5_TRIM_VDDA
00216             u32result = TransceiveSpiFrame(0xCC0C0001); // DOE1_IC5_TRIM_VDDD
00217             u32result = TransceiveSpiFrame(0xCC0E0001); // DOE1_IC5_TRIM_VBG
00218             u32result = TransceiveSpiFrame(0xCC100004); // DOE1_IC5_TRIM_IBIAS
00219             u32result = TransceiveSpiFrame(0xCC3A0016); // DOE1_IC5_TRIM_RCO
00220             
00221             u32result = TransceiveSpiFrame(0xCF000200); // Set PWM mode
00222             u32result = TransceiveSpiFrame(0xCF02FFFF); // Set current limit to max
00223             u32result = TransceiveSpiFrame(0xCF04FFFF); // Set current limit to max
00224             u32result = TransceiveSpiFrame(0xCF06FFFF); // Set 
00225             u32result = TransceiveSpiFrame(0xCF083182); // Set ALIGN1-2_TIME, STEP1_TIME
00226             u32result = TransceiveSpiFrame(0xCF0A0CE9); // Set STEP2-4_TIME
00227             u32result = TransceiveSpiFrame(0xCF0C0010); // Set wait time to ???
00228             u32result = TransceiveSpiFrame(0xCF0E0000); // Set timer6-7
00229             u32result = TransceiveSpiFrame(0xCF100000); // Set CW
00230             u32result = TransceiveSpiFrame(0xCF120003); // Set rotor trials to 3
00231             
00232             u32result = TransceiveSpiFrame(0xCF3A0001); // Set EE_READY
00233             
00234             pc.printf("\nTrimming of B6PV and start-up configuration in FPGA done \n");
00235             break;
00236         
00237         case 'g': // trim B6PV and configure FPGA     
00238             if (fPWMDutyCycle == 0)
00239             {
00240                 fPWMDutyCycle = 0.5;
00241                 pwmon.write(fPWMDutyCycle);
00242             }
00243             else 
00244             {
00245                 fPWMDutyCycle = 0.0;
00246                 pwmon.write(fPWMDutyCycle);    
00247             }
00248             pc.printf("\nSet PWM/ON to %1.1f%% duty cycle on PWM-ON pin\n",fPWMDutyCycle*100);
00249                 
00250             break;
00251             
00252         case 'n': //write to FPGA to turn LED on
00253             u32SPIframe = 0xCF3E8000;
00254             u32result = TransceiveSpiFrame(u32SPIframe);                    
00255             pc.printf("\nLED on \n");
00256             break;
00257             
00258         case 'f': //write to FPGA to turn LED off
00259             u32SPIframe = 0xCF3E0000;//0xCF3E0000;
00260             u32result = TransceiveSpiFrame(u32SPIframe);                    
00261             pc.printf("\nLED off \n");
00262             break;
00263         
00264         case '2': //write to FPGA to turn LED off
00265             u32SPIframe = 0xCF360081;
00266             u32result = TransceiveSpiFrame(u32SPIframe);                    
00267             pc.printf("\nInduce soft error 0 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00268             break;
00269         case '3': //write to FPGA to turn LED off
00270             u32SPIframe = 0xCF360082;
00271             u32result = TransceiveSpiFrame(u32SPIframe);                    
00272             pc.printf("\nInduce soft error 1 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00273             break;
00274         case '4': //write to FPGA to turn LED off
00275             u32SPIframe = 0xCF360084;
00276             u32result = TransceiveSpiFrame(u32SPIframe);                    
00277             pc.printf("\nInduce soft error 2 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00278             break;
00279         case '5': //write to FPGA to turn LED off
00280             u32SPIframe = 0xCF360088;
00281             u32result = TransceiveSpiFrame(u32SPIframe);                    
00282             pc.printf("\nInduce soft error 3 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00283             break;
00284         case '6': //write to FPGA to turn LED off
00285             u32SPIframe = 0xCF360090;
00286             u32result = TransceiveSpiFrame(u32SPIframe);                    
00287             pc.printf("\nInduce soft error 4 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00288             break;
00289         case '7': //write to FPGA to turn LED off
00290             u32SPIframe = 0xCF3600A0;
00291             u32result = TransceiveSpiFrame(u32SPIframe);                    
00292             pc.printf("\nInduce soft error 5 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00293             break;
00294         case '8': //write to FPGA to turn LED off
00295             u32SPIframe = 0xCF3600C0;
00296             u32result = TransceiveSpiFrame(u32SPIframe);                    
00297             pc.printf("\nInduce soft error 6 by sending MOSI frame = 0x%.8X \n", u32SPIframe);
00298             break;
00299         case '9': //write to FPGA to turn LED off
00300             u32SPIframe = 0xCF3600FF;
00301             u32result = TransceiveSpiFrame(u32SPIframe); 
00302             wait(0.0011);  
00303             u32SPIframe = 0xCF360080;
00304             u32result = TransceiveSpiFrame(u32SPIframe);                     
00305             pc.printf("\nInduce all soft errors by sending MOSI frame = 0x%.8X followed by removing all soft errors \n", u32SPIframe);
00306             break;
00307         
00308         case 'o': // give a pulse on FPGA OC-pin to simulate over current error
00309             OCsimulation = 1;
00310             wait(0.0001);
00311             OCsimulation = 0;
00312             break;
00313         
00314         case 'a': //try to write 0xFFFF to all FPGA register addresses [31:0]
00315             int iSpiErrCnt = 0; 
00316             for (uint32_t i3=0; i3<0x0000FFFF; i3+=0x00000155)
00317             {
00318                 uint32_t u32MosiWriteFrame = 0xCF000000;
00319                 uint32_t u32MosiReadFrame  = 0xCF010000;
00320                 pc.printf("Using data  0x%.8X to test read instruction \n", i3); 
00321                 for (int i2=0; i2<32; i2++)     
00322                 {
00323                     //pc.printf("Testing address %i\n", i2);
00324                     for (int i1=0; i1<0x0000FFFF; i1++)
00325                     {
00326                         uint32_t u32MisoWriteFrame = TransceiveSpiFrame(u32MosiWriteFrame+i1);
00327                         //pc.printf("The SPI MOSI-frame to write = 0x%.8X \nThe SPI MISO-frame received = 0x%.8X \n", u32SPIframe,u32result);  
00328                         wait(0.00001);
00329                         uint32_t u32MisoReadFrame = TransceiveSpiFrame(u32MosiReadFrame+i3); 
00330                         //pc.printf("The SPI MOSI-frame to read = 0x%.8X \nThe SPI MISO-frame received = 0x%.8X \n", u32SPIframe,u32result);                 
00331                         if ((u32MisoReadFrame & 0x0000FFFF) != i1)
00332                         {
00333                             iSpiErrCnt++;    
00334                             pc.printf("The SPI MOSI-frame to write = 0x%.8X \nThe SPI MISO-frame received to write = 0x%.8X \n", u32MosiWriteFrame+i1,u32MisoWriteFrame);   
00335                             pc.printf("The SPI MOSI-frame to read = 0x%.8X \nThe SPI MISO-frame received to read = 0x%.8X \n", u32MosiReadFrame+i3,u32MisoReadFrame);   
00336                         }
00337                     }
00338                     u32MosiWriteFrame += 0x00020000;
00339                     u32MosiReadFrame  += 0x00020000;
00340                 }   
00341                 pc.printf("The number of SPI errors = %i \n", iSpiErrCnt);
00342             }            
00343             break; 
00344              
00345         case 'p': //PWM decoder test [31:0]
00346             u32result = TransceiveSpiFrame(0xCF000200);
00347             FILE *Datalogging = fopen("/local/PWMDecoder.csv", "w"); 
00348             for (int i1=10000; i1>80; i1=i1*0.90)
00349             { 
00350                 pwmon.period_us(i1); 
00351                 for (float f1=0.2; f1>0; f1-=0.001)     
00352                 {
00353                     pwmon.write(f1);
00354                     //float fWaitTime = (float)(i1*5)/(1000000);
00355                     wait(0.1);
00356                     fprintf(Datalogging, "%i-%.4f+%u*%.2f\n", i1,f1,u32DiagnPeriod,float(u32DiagnDC)/DUTY_CYCLE_ACCURACY*100);   
00357                 }
00358                 for (float f1=0.0; f1<=1.001; f1+=0.001)     
00359                 {
00360                     pwmon.write(f1);
00361                     //float fWaitTime = (float)(i1*5)/(1000000);
00362                     wait(0.1);
00363                     fprintf(Datalogging, "%i-%.4f+%u*%.2f\n", i1,f1,u32DiagnPeriod,float(u32DiagnDC)/DUTY_CYCLE_ACCURACY*100);  
00364                 }
00365             }
00366             fclose(Datalogging);
00367            break;              
00368                            
00369         
00370         }
00371     #endif //TeraTerm     
00372     }
00373 }
00374 
00375 
00376 /* **************************************************************************************
00377  * Setup the spi for 16 bit data, high steady state clock,                              
00378  * base value of the clock is zero CPOL = 0                                             
00379  * data  captured on the rising edge and data propagated on a falling edge = CPHA = 0   
00380  * SPImode = [CPOL CPHA] = [01] = 1                                                     
00381  * with a 1MHz clock rate                                                               
00382  ****************************************************************************************/
00383 
00384 void SpiInit() {
00385     cs = 1;
00386     spi.format(16,0);        
00387     spi.frequency(1000000);    
00388 }  
00389 
00390 
00391 uint32_t TransceiveSpiFrame(uint32_t u32MosiMessage){
00392     
00393 //    LPC_PINCON->PINSEL0  &=~ 0x0000C000;    // Set p7(=P0.7) to GPIO mode
00394 //    LPC_GPIO0->FIODIR   |=  (1<<7);         // Set p7 as output
00395 //    LPC_GPIO0->FIOSET = (1<<7);             // Set p7 high
00396 //    LPC_GPIO0->FIOCLR = (1<<7);             // Set p7 low
00397 //    LPC_PINCON->PINSEL0  |=  0x00008000;    // Set p7(=P0.7) to SPI-SCK mode
00398     
00399     // Select the device by seting chip select low
00400     cs = 0;
00401 
00402     // Send first 16 bit of 32-bit frame
00403     uint32_t u32MisoMessage = (spi.write((uint16_t)(u32MosiMessage>>16))<<16);
00404 
00405     // Send second 16 bit of 32-bit frame
00406     u32MisoMessage |=  spi.write((uint16_t)(u32MosiMessage));
00407 
00408     // Deselect the device
00409     wait(0.0000000000000001);
00410     cs = 1;
00411     
00412     return u32MisoMessage;
00413 }
00414 
00415 /* **************************************************************************************
00416  * Setup the spi for 16 bit data, high steady state clock,                              
00417  * base value of the clock is zero CPOL = 0                                             
00418  * data  captured on the falling edge and data propagated on a rising edge = CPHA = 1   
00419  * SPImode = [CPOL CPHA] = [01] = 1                                                     
00420  * with a 1MHz clock rate                                                               
00421  ****************************************************************************************/
00422 
00423 void SerialUSBInit() {
00424     pc.format(8, Serial::None, 1);
00425     pc.baud(9600);    
00426 }  
00427 
00428 
00429 /* **************************************************************************************   
00430  * Setup TIMER2 to capture edges on two seperate channels                               
00431  * - Channel 0 :    B6PV "DIAG"-pin                                                                
00432  *                  Capture alternating rising/falling edge to determine duty cycle     
00433  * - Channel 1 :    B6PV "SPEED"-pin                                                    
00434  *                  Capture rising/falling edges to determine average high-low time     
00435  ****************************************************************************************/
00436 void Timer2Init(){
00437     
00438     LPC_PINCON->PINSEL0  |= 0x00000300; // Set p30(=P0.4) to CAP2.0 = B6PV "DIAG"-pin
00439     LPC_PINCON->PINMODE0 |= 0x00000200; // set p30(=P0.4) to have neither pull-up nor pull-down resistors 
00440       
00441     LPC_PINCON->PINSEL0  |= 0x00000C00; // set p29(=P0.5) to CAP2.1 = B6PV "SPEED"-pin
00442     LPC_PINCON->PINMODE0 |= 0x00000800; // set p29(=P0.5) to have neither pull-up nor pull-down resistors 
00443 
00444     NVIC_SetVector(TIMER2_IRQn, uint32_t(TIMER2_IRQHandler));
00445     NVIC_EnableIRQ(TIMER2_IRQn);
00446     //NVIC_DisableIRQ(TIMER2_IRQn);
00447     
00448     LPC_SC->PCONP |= (1 << 22);         // Timer2 power on
00449     LPC_SC->PCLKSEL1 |= (1 << 12);      // Divide CCLK by 1 for Timer2
00450    
00451     LPC_TIM2->TC = 0;                   // Clear timer counter
00452     LPC_TIM2->PC = 0;                   // Clear prescale counter
00453     LPC_TIM2->PR = 0;                   // Clear prescale register
00454     LPC_TIM2->CTCR = 0x00;              // Set timer mode
00455     LPC_TIM2->TCR |= (1 << 1);          // Reset timer
00456     LPC_TIM2->TCR &=~(1 << 1);          // Release reset
00457     LPC_TIM2->IR = 0xFFFFFFFF;          // Clear interrupt register
00458     
00459     LPC_TIM2->CCR |=(1<<0);             // Enable cap2.0 on rising edge
00460     LPC_TIM2->CCR |=(1<<2);             // Enable interrupt on cap2.0 event
00461     LPC_TIM2->MR0  = u32DiagnMaxPeriod; // Match register 0 for 0%-100% detection 
00462     LPC_TIM2->MCR |=(1<<0);             // Enable interrupt when TIM2 reaches MR0
00463     
00464     LPC_TIM2->CCR |=((1<<3)|(1<<4));    // Enable cap2.1 on rising and falling edge
00465     LPC_TIM2->CCR |=(1<<5);             // Enable interrupt on cap2.1 event
00466     LPC_TIM2->MR0  = u32SpeedMaxPeriod; // Match register 1 for motor speed 0 detection
00467     LPC_TIM2->MCR |=(1<<3);             // Enable interrupt when TIM2 reaches MR1
00468     
00469     LPC_TIM2->TCR |= (1 << 0);          // start Timer2
00470 }
00471 
00472 
00473 /* **********************************************************************************
00474  * 
00475  ************************************************************************************/
00476 void TIMER2_IRQHandler(void)
00477 {
00478     uint32_t pending = LPC_TIM2->IR;
00479     
00480     /********************************************************** 
00481      * If timer2 capture channel 0 interrupt  
00482      * Used for edge detection on DIAG-pin (duty cycle)
00483      **********************************************************/
00484     if(pending & (1<<4))                    // if timer2 interrupt on capture channel 0 = DIAGNOSTICS
00485     {                  
00486         if(LPC_TIM2->CCR & (1<<0))          // if cap2.0 rising edge
00487         {
00488             LPC_TIM2->CCR &=~(1<<0);        // disable cap2.0 rising  edge                  
00489             
00490             u32DiagnCapA = LPC_TIM2->CR0;   
00491                         
00492             LPC_TIM2->CCR |= (1<<1);        // enable  cap2.0 falling edge  
00493         }
00494         else if (LPC_TIM2->CCR & (1<<1))    // if cap2.0 falling edge
00495         {    
00496             LPC_TIM2->CCR &=~(1<<1);        // disable cap2.0 falling edge 
00497 
00498             uint32_t u32DiagnCapBtemp = LPC_TIM2->CR0;          
00499             uint32_t diagnHighT = u32DiagnCapBtemp - u32DiagnCapA;  
00500             
00501             if ((u32DiagnCapBtemp-u32DiagnCapB)>(u32DiagnPeriod+(u32DiagnPeriod>>1))) 
00502                 u32DiagnPeriod      = ((u32DiagnCapBtemp-u32DiagnCapB)>>1); 
00503             else
00504                u32DiagnPeriod      = u32DiagnCapBtemp-u32DiagnCapB; 
00505             
00506             if (diagnHighT<u32DiagnPeriod)
00507                 u32DiagnDC      = (diagnHighT*DUTY_CYCLE_ACCURACY)/u32DiagnPeriod;             
00508             
00509             u32DiagnCapB = u32DiagnCapBtemp;
00510             
00511             LPC_TIM2->CCR |= (1<<0);        // enable  cap2.0 rising  edge 
00512         }
00513     
00514         LPC_TIM2->IR |= (1<<4);             // clear Timer2 interrupt flag for capture channel 0 event
00515         LPC_TIM2->MR0  = LPC_TIM2->TC + (u32DiagnMaxPeriod<<1);
00516      }      
00517      else if(pending & (1<<0))
00518      {
00519         if(LPC_TIM2->CCR & (1<<1))
00520             u32DiagnDC = 1*DUTY_CYCLE_ACCURACY;
00521         else
00522             u32DiagnDC = 0;
00523             
00524         u32DiagnPeriod = 0xFFFFFFFF;                
00525         LPC_TIM2->IR |= (1<<0);             // clear Timer2 interrupt flag for match register 0 event
00526         LPC_TIM2->MR0  = LPC_TIM2->TC + (u32DiagnMaxPeriod<<1);
00527      }
00528      
00529      /********************************************************** 
00530      * If timer2 capture channel 1 interrupt  
00531      * Used for edge detection on SPEED-pin (high / low time) 
00532      **********************************************************/ 
00533      if(pending & (1<<5))                       
00534      {      
00535         u32SpeedCapA = u32SpeedCapB; 
00536         u32SpeedCapB = LPC_TIM2->CR1; 
00537         
00538         // Calculate time between 2 edges = commutation time [us]
00539         uint32_t tempCommTime = ((u32SpeedCapB-u32SpeedCapA)/96);
00540         
00541         // Calculate averaged speed via 1/(6 x commutation time) [eHz]
00542         u32Speed = ((u32Speed + (1000000000/(tempCommTime*6)))>>1); 
00543         
00544         // Clear timer2 chanel 1 interrupt flag   
00545         LPC_TIM2->IR |= (1<<5);     
00546         
00547         //        
00548         LPC_TIM2->MR1  = LPC_TIM2->TC + (u32SpeedMaxPeriod<<1); 
00549      }
00550      else if(pending & (1<<1))
00551      {
00552         u32Speed = 0;              
00553         LPC_TIM2->IR |= (1<<1);             // clear Timer2 interrupt flag for match register 0 event
00554         LPC_TIM2->MR1  = LPC_TIM2->TC + (u32SpeedMaxPeriod<<1);
00555      }
00556 }
00557