KL25Z Comparator library
Dependents: ComparatorIn_demo TEMT6200_demo 05_comparator_demo 05_comparator_demo ... more
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
Generated on Tue Jul 12 2022 21:37:49 by 1.7.2