KL25Z Comparator library

Dependents:   ComparatorIn_demo TEMT6200_demo 05_comparator_demo 05_comparator_demo ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ComparatorIn.cpp Source File

ComparatorIn.cpp

00001 /**************************************************************************************************
00002  *****                                                                                        *****
00003  *****  Name: ComparatorIn.cpp                                                                *****
00004  *****  Date: 05/06/2013                                                                      *****
00005  *****  Auth: Frank Vannieuwkerke                                                             *****
00006  *****  Func: library for KL25Z Comparator                                                    *****
00007  *****                                                                                        *****
00008  **************************************************************************************************/
00009 
00010 #include "ComparatorIn.h"
00011  
00012 void (*comparatorin_rise_fptr)(void);     // Pointer to user function - called after rising IRQ assertion.
00013 void (*comparatorin_fall_fptr)(void);     // Pointer to user function - called after falling IRQ assertion.
00014 AnalogOut *_dac12;                        // Pointer to AnalogOut
00015 
00016 const PinMap ComparatorIn::PinMap_CMP[] = {
00017     {PTC6,  CMP0_IN0, 0},
00018     {PTC7,  CMP0_IN1, 0},
00019     {PTC8,  CMP0_IN2, 0},
00020     {PTC9,  CMP0_IN3, 0},
00021     {PTE30, CMP0_IN4, 0},       // 12-bit DAC0
00022     {PTE29, CMP0_IN5, 0},       // ADC0_SE4b
00023     {NC,    NC,       0}        // Internal 6-bit DAC0
00024 };
00025 
00026 
00027 ComparatorIn::ComparatorIn(PinName pinP, PinName pinM)
00028 {
00029     comparatorin_rise_fptr = NULL;
00030     comparatorin_fall_fptr = NULL;
00031     CMPnumberP = (CMPName)pinmap_peripheral(pinP, PinMap_CMP);
00032     if (CMPnumberP == (uint32_t)NC)         // When NC, use DAC0
00033         CMPnumberP = 0x07;
00034     CMPnumberM = (CMPName)pinmap_peripheral(pinM, PinMap_CMP);
00035     if (CMPnumberM == (uint32_t)NC)         // When NC, use DAC0
00036         CMPnumberM = 0x07;
00037 
00038     SIM->SCGC4 |=SIM_SCGC4_CMP_MASK; // Enable HSCMP module clock
00039 
00040     hscmp_clear();
00041     CMP0->CR0   = 0x00;  // Filter and digital hysteresis disabled
00042     CMP0->CR1   = 0x17;  // Continuous mode, high-speed compare, unfiltered output, output pin disabled
00043     CMP0->FPR   = 0x00;  // Filter disabled
00044     CMP0->SCR   = 0x06;  // Disable all interrupts and clear flags (flags are cleared by this write)
00045     CMP0->DACCR = 0xE0;  // DAC enabled, Vdd is 6bit reference, threshold set to 1/2 of full-scale (1.65V)
00046     CMP0->MUXCR = (CMPnumberP << 3) | (CMPnumberM & 0x07);  // P-input/M-input are ext.channels defined by CMPnumberP/CMPnumberN
00047 
00048     if(CMPnumberP < 6) pinmap_pinout(pinP, PinMap_CMP); // Map pins
00049     if(CMPnumberM < 6) pinmap_pinout(pinM, PinMap_CMP); // Map pins
00050 
00051     if((CMPnumberP == 4) || (CMPnumberM == 4)) _dac12 = new AnalogOut (PTE30);  // When PTE30 is selected, use it as 12-bit DAC
00052     
00053     NVIC_SetVector(CMP0_IRQn, (uint32_t)&_cmpISR);      // Set comparator ISR to _cmpISR routine
00054     falling(NULL);                                      // set falling IRQ pointer to NULL
00055     rising(NULL);                                       // set rising IRQ pointer to NULL
00056     NVIC_DisableIRQ(CMP0_IRQn);                         // disable CMP0 IRQ
00057 };
00058  
00059 void ComparatorIn::FilterCount(unsigned char fico)
00060 {
00061     if((fico > 0) && (fico < 8))
00062     {
00063         unsigned char tmp;
00064         tmp = (CMP0->CR0 & 0x8F) | CMP_CR0_FILTER_CNT(fico);        // Replace old value
00065         CMP0->CR0 = tmp;                                            // Set filter count
00066     }
00067 }
00068 
00069 void ComparatorIn::hysteresis(unsigned char hyst)
00070 {
00071     if(hyst < 4)
00072     {
00073         unsigned char tmp;
00074         tmp = (CMP0->CR0 & 0xFC) | CMP_CR0_HYSTCTR(hyst);           // Replace old value
00075         CMP0->CR0 = tmp;                                            // Set hysteresis
00076     }
00077 }
00078 
00079 void ComparatorIn::SampleMode(unsigned char samp_en)
00080 {
00081     if((CMP0->CR1 & CMP_CR1_WE_MASK) == 0)                  // Only allow change when window mode is inactive
00082     {
00083         if(samp_en == 1) CMP0->CR1 |= CMP_CR1_SE_MASK;      // Enable
00084         else CMP0->CR1 &= ~CMP_CR1_SE_MASK;                 // Disable
00085     }
00086 }
00087 
00088 void ComparatorIn::WindowMode(unsigned char win_en)
00089 {
00090     if((CMP0->CR1 & CMP_CR1_SE_MASK) == 0)                  // Only allow change when sample mode is inactive
00091     {
00092         if(win_en == 1) CMP0->CR1 |= CMP_CR1_WE_MASK;       // Enable
00093         else CMP0->CR1 &= ~CMP_CR1_WE_MASK;                 // Disable
00094     }
00095 }
00096 
00097 void ComparatorIn::TrigMode(unsigned char trig_en)
00098 {
00099     if(trig_en == 1) CMP0->CR1 |= CMP_CR1_TRIGM_MASK;       // Enable
00100     else CMP0->CR1 &= ~CMP_CR1_TRIGM_MASK;                  // Disable
00101 }
00102 
00103 void ComparatorIn::PowerMode(unsigned char pmode)
00104 {
00105     if(pmode == 1) CMP0->CR1 |= CMP_CR1_PMODE_MASK;      // Set high speed
00106     else CMP0->CR1 &= ~CMP_CR1_PMODE_MASK;               // Set low speed
00107 }
00108 
00109 void ComparatorIn::invert(unsigned char inv)
00110 {
00111     if(inv == 1) CMP0->CR1 |= CMP_CR1_INV_MASK;          // Enable
00112     else CMP0->CR1 &= ~CMP_CR1_INV_MASK;                 // Disable
00113 }
00114 
00115 void ComparatorIn::OutputSelect(unsigned char cos)
00116 {
00117     if(cos == 1) CMP0->CR1 |= CMP_CR1_COS_MASK;          // Enable
00118     else CMP0->CR1 &= ~CMP_CR1_COS_MASK;                 // Disable
00119 }
00120 
00121 void ComparatorIn::OutputPin(PinName ope)
00122 {
00123     PinName pin_stat;
00124     pin_stat = op_status();                                  // Get pin status
00125     // Only change settings if new pin differs from old pin AND the correct pin is selected.
00126     if((ope != pin_stat) && ((ope == PTC0) || (ope == PTC5) || (ope == PTE0) || (ope == NC)))
00127     {
00128         if(ope == NC)
00129         {
00130             if (pin_stat != NC) op_disable(pin_stat);        // disconnect current pin
00131             CMP0->CR1 &= ~CMP_CR1_OPE_MASK;                  // Disable comparator output pin connect
00132         }
00133         else
00134         {
00135             op_enable(ope, pin_stat);                        // Connect new pin
00136             CMP0->CR1 &= ~CMP_CR1_OPE_MASK;                  // Enable comparator output pin connect
00137         }
00138     }
00139 }
00140 
00141 void ComparatorIn::enable(unsigned char en)
00142 {
00143     if(en == 1) CMP0->CR1 |= CMP_CR1_EN_MASK;            // Enable
00144     else CMP0->CR1 &= ~CMP_CR1_EN_MASK;                  // Disable
00145 }
00146 
00147 void ComparatorIn::FilterPeriod(unsigned char fipe)
00148 {
00149     CMP0->FPR = CMP_FPR_FILT_PER(fipe);
00150 }
00151 
00152 void ComparatorIn::dma(unsigned char dmaen)
00153 {
00154     if(dmaen == 1) CMP0->SCR |= CMP_SCR_DMAEN_MASK;      // Enable
00155     else CMP0->SCR &= ~CMP_SCR_DMAEN_MASK;               // Disable
00156 }
00157 
00158 unsigned char ComparatorIn::status(void)
00159 {
00160     return (CMP0->SCR & 0x01);
00161 }
00162 
00163 void ComparatorIn::dac(unsigned char den)
00164 {
00165     if(den == 1) CMP0->DACCR |= CMP_DACCR_DACEN_MASK;    // Enable
00166     else CMP0->DACCR &= ~CMP_DACCR_DACEN_MASK;           // Disable
00167 }
00168 
00169 void ComparatorIn::RefSource(unsigned char res)
00170 {
00171     if(res == 1) CMP0->DACCR |= CMP_DACCR_VRSEL_MASK;    // Enable
00172     else CMP0->DACCR &= ~CMP_DACCR_VRSEL_MASK;           // Disable
00173 }
00174 
00175 void ComparatorIn::treshold(float vo_pct)
00176 {
00177     
00178     if(vo_pct < 0.0) vo_pct = 0.0;
00179     if(vo_pct > 1.0) vo_pct = 1.0;;
00180 
00181     if((CMPnumberP == 7) || (CMPnumberM == 7))
00182     {
00183         dac6_write(vo_pct * (float)0x3F);
00184     }
00185     if((CMPnumberP == 4) || (CMPnumberM == 4))
00186     {
00187         _dac12->write(vo_pct);
00188     }
00189 }
00190 
00191 void ComparatorIn::PassThrough(unsigned char ptm)
00192 {
00193     if(ptm == 1) CMP0->MUXCR |= CMP_MUXCR_MSEL_MASK;     // Enable
00194     else CMP0->MUXCR &= ~CMP_MUXCR_MSEL_MASK;            // Disable
00195 }
00196 
00197 void ComparatorIn::SwitchPlus(unsigned char pinP)
00198 {
00199 }
00200  
00201 void ComparatorIn::SwitchMin(unsigned char pinM)
00202 {
00203 }
00204  
00205 void ComparatorIn::hscmp_clear(void)
00206 {
00207   CMP0->CR0   = 0;
00208   CMP0->CR1   = 0;
00209   CMP0->FPR   = 0;
00210   CMP0->SCR   = 0x06;  // Clear flags if set.
00211   CMP0->DACCR = 0;
00212   CMP0->MUXCR = 0;
00213 }
00214 
00215 void ComparatorIn::rising(void(*fptr)(void))
00216 {
00217     if(fptr == NULL)
00218     {
00219         CMP0->SCR &= ~CMP_SCR_IER_MASK;  // Disable rising int.
00220         CMP0->SCR |=  CMP_SCR_CFR_MASK;  // clear flag
00221         if(comparatorin_fall_fptr == NULL)
00222             NVIC_DisableIRQ(CMP0_IRQn);
00223     }
00224     else
00225     {
00226         comparatorin_rise_fptr = fptr;
00227         CMP0->SCR |= (CMP_SCR_IER_MASK | CMP_SCR_CFR_MASK);  // Enable rising int. and clear flag
00228         NVIC_EnableIRQ(CMP0_IRQn);  // enable CMP0 interrupt
00229     }
00230 }
00231  
00232 void ComparatorIn::falling(void(*fptr)(void))
00233 {
00234     if(fptr == NULL)
00235     {
00236         CMP0->SCR &= ~CMP_SCR_IEF_MASK;  // Disable falling int.
00237         CMP0->SCR |=  CMP_SCR_CFF_MASK;  // clear flag
00238         if(comparatorin_rise_fptr == NULL)
00239             NVIC_DisableIRQ(CMP0_IRQn);
00240     }
00241     else
00242     {
00243         comparatorin_fall_fptr = fptr;
00244         CMP0->SCR |= (CMP_SCR_IEF_MASK | CMP_SCR_CFF_MASK);  // Enable falling int. and clear flag
00245         NVIC_EnableIRQ(CMP0_IRQn);  // enable CMP0 interrupt
00246     }
00247 }
00248 
00249 void ComparatorIn::_cmpISR(void)  
00250 {
00251     // Interrupt flags are cleared by writing 1 to the CFx flag
00252     // Rising edge
00253     if (((CMP0->SCR & CMP_SCR_IER_MASK)==CMP_SCR_IER_MASK) && ((CMP0->SCR & CMP_SCR_CFR_MASK)==CMP_SCR_CFR_MASK))
00254     {
00255         CMP0->SCR |= CMP_SCR_CFR_MASK;                                // Clear the flag
00256         if (comparatorin_rise_fptr != NULL) comparatorin_rise_fptr(); // call user function
00257     }
00258 
00259     // Falling edge
00260     if (((CMP0->SCR & CMP_SCR_IEF_MASK)==CMP_SCR_IEF_MASK) && ((CMP0->SCR & CMP_SCR_CFF_MASK)==CMP_SCR_CFF_MASK))
00261     {
00262         CMP0->SCR |= CMP_SCR_CFF_MASK;                                // Clear the flag
00263         if (comparatorin_fall_fptr != NULL) comparatorin_fall_fptr(); // call user function
00264     } 
00265 }
00266 
00267 /*
00268 IMPORTANT : Do not alter the if... sequence in op_status.
00269             We need to check if the port is active (using SIM->SCGC5) BEFORE reading PORTn->PCR[x].
00270             Reading PORTn->PCR[x] while a port is inactive will block the system.
00271             At startup, SIM->SCGC5 = 00000380h. This means only PORTA is enabled.
00272 */
00273 PinName ComparatorIn::op_status(void)
00274 {
00275     if((SIM->SCGC5 & SIM_SCGC5_PORTE_MASK) == 1)
00276     {
00277         if((PORTE->PCR[0] & PORT_PCR_MUX_MASK) == 0x500u) return(PTE0);  // check if current pin = PTE0
00278     }
00279     if((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) == 1)
00280     {
00281         if((PORTC->PCR[0] & PORT_PCR_MUX_MASK) == 0x500u) return(PTC0);  // check if current pin = PTC0
00282         if((PORTC->PCR[5] & PORT_PCR_MUX_MASK) == 0x600u) return(PTC5);  // check if current pin = PTC5
00283     }
00284     return(NC);
00285 }
00286 
00287 void ComparatorIn::op_enable(PinName pen, PinName pstat)
00288 {
00289     if(pstat != NC) op_disable(pstat);               // If a pin is connected - disconnect before connecting new pin
00290     switch (pen)
00291     {
00292         case PTC0:
00293             if((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) == 0) SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;    // If PORTC is inactive: Enable
00294             PORTC->PCR[0] = PORT_PCR_MUX(5);                                                    // Set PTC0 mux to CMP0
00295             break;
00296         case PTC5:
00297             if((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) == 0) SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK;    // If PORTC is inactive: Enable
00298             PORTC->PCR[5] = PORT_PCR_MUX(6);                                                    // Set PTC5 mux to CMP0
00299             break;
00300         case PTE0:
00301             if((SIM->SCGC5 & SIM_SCGC5_PORTE_MASK) == 0) SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK;    // If PORTE is inactive: Enable
00302             PORTE->PCR[0] = PORT_PCR_MUX(5);                                                    // Set PTE0 mux to CMP0
00303             break;
00304         default:
00305         break;
00306     }
00307 }
00308 
00309 void ComparatorIn::op_disable(PinName pdi)
00310 {
00311     switch (pdi)
00312     {
00313         case PTC0:
00314             PORTC->PCR[0] &= PORT_PCR_MUX(1);             // Set PTC0 mux to ALT1
00315             break;
00316         case PTC5:
00317             PORTC->PCR[5] &= PORT_PCR_MUX(1);             // Set PTC5 mux to ALT1
00318             break;
00319         case PTE0:
00320             PORTE->PCR[0] &= PORT_PCR_MUX(1);             // Set PTE0 mux to ALT1
00321             break;
00322         default:
00323         break;
00324     }
00325 }
00326 
00327 void ComparatorIn::dac6_write(unsigned int value)
00328 {
00329     unsigned int tmp;
00330     value &= 0x3F;                                   // 6-bit
00331     tmp = (CMP0->DACCR & 0xC0) | value;              // Replace old value
00332     CMP0->DACCR = tmp;                               // Set Vout DAC
00333 }
00334 
00335 
00336