KL25Z Comparator library

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

KL25Z Comparator library

Comparator features

  • Operational over the entire supply range
  • Inputs may range from rail to rail
  • Programmable hysteresis control
  • Selectable interrupt on rising-edge, falling-edge, or both rising or falling edges of the comparator output
  • Selectable inversion on comparator output
  • Capability to produce a wide range of outputs such as:
    • Sampled
    • Windowed, which is ideal for certain PWM zero-crossing-detection applications
    • Digitally filtered:
      • Filter can be bypassed
      • Can be clocked via external SAMPLE signal or scaled bus clock
  • External hysteresis can be used at the same time that the output filter is used for internal functions
  • Two software selectable performance levels:
    • Shorter propagation delay at the expense of higher power
    • Low power, with longer propagation delay
  • DMA transfer support not yet implemented in this library
    • A comparison event can be selected to trigger a DMA transfer
  • Functional in all modes of operation
  • The window and filter functions are not available in the following modes:
    • Stop
    • VLPS
    • LLS
    • VLLSx

Block diagram

/media/uploads/frankvnk/kl25z_comparator_block_diagram.jpg

Introduction

This library allows us to create comparator objects between different inputs.
The comparator + and - inputs can be routed to one out of eight reference inputs (see table).
Input selection

Pin name#MUX inputCMP0Comment
PTC6000IN0CMP0_IN0
PTC7001IN1CMP0_IN1
PTC8010IN2CMP0_IN2
PTC9011IN3CMP0_IN3
PTE30100IN4CMP0_IN412-bit DAC0
PTE29101IN5CMP0_IN5
110IN61V internal Bandgap*
NC111IN7internal 6-bit DAC0
(table 1)

* Not yet implemented

Using the library

Selecting pins on initialisation
Upon initialisation, the comparator registers are set to following values:

    CMP0->CR0   = 0x00;  // Filter and digital hysteresis disabled
    CMP0->CR1   = 0x17;  // Continuous mode, high-speed compare, unfiltered output, output pin disabled
    CMP0->FPR   = 0x00;  // Filter disabled
    CMP0->SCR   = 0x06;  // Disable all interrupts and clear flags (flags are cleared by this write)
    CMP0->DACCR = 0xE0;  // DAC enabled, Vdd is 6bit reference, threshold set to 1/2 of full-scale (1.65V)

The library accepts two input parameters:
example:

ComparatorIn compi(PTC8, NC);
  • First parameter : + input pin.
  • Second parameter : - input pin.
    Every pin from the 'Pin name' column in (table 1) can be selected.

notes

  • IN6 (internal 1V bandgap reference) has no pin name and is not selectable on init.
    However, we can use the SwitchPlus and SwitchMin functions to change the corresponding input to IN6.
  • There are two special cases for the input parameters:
    • NC : Connect the internal 6-bit DAC0 to IN7.
    • PTE30 : configures PTE30 as 12-bit DAC0 output and connect to IN4.
      IMPORTANT: Make sure no external output is connected to PTE30 when you declare this pin, otherwise you WILL destroy the external device and/or the CPU.

Example
Following code demonstrates interrupt callback and polling mode.
Note: Polling the comparator this way won't always trigger the printf because of the wait() instructions (if we go above and below the threshold during the wait() time, then the polling cannot not see this change).

/***********************************************************
CODE EXAMPLE FOR AMBIENT LIGHT SENSOR ON KL25Z + Wi-Go BOARD
 ***********************************************************/
#include "ComparatorIn.h"
#include "mbed.h"

DigitalOut blinker(LED_BLUE);
DigitalOut cmpled(LED_GREEN);
DigitalOut cmp_en (PTD5);
AnalogIn cmp_lvl (PTB0);
ComparatorIn compi(PTC8, NC); // in+ = PTC8, in- = internal 6-bit DAC 

// Comparator callback functions
void cmp_rise_ISR(void)
{
    cmpled = 0;
}

void cmp_fall_ISR(void)
{
    cmpled = 1;
}

int main()
{
    cmp_en = 1;
    cmpled = 1;

    compi.rising(&cmp_rise_ISR);                // Set pointer to rising interrupt function
    compi.falling(&cmp_fall_ISR);               // Set pointer to falling interrupt function
    compi.treshold(0.5);                        // Set comparator threshold to 1.65V = 32 * 3.3V / 64

    while(1)
    {
        printf("Light sensor : %7.5f Volt\n",cmp_lvl*3.3);
        blinker = 1;
        wait(1);
        blinker = 0;
        wait(0.2);
        if (compi.status() == 0x01)
        {
            printf("*** Treshold reached : %7.5f\n",cmp_lvl*3.3);
        }
    }
}


Notes

  • When we enable the comparator interrupt, we need to declare user callback function(s) (rising and/or falling interrupt) AND initialise the function pointer(s).
    example:

compi.rising(&cmp_rise_ISR);
compi.falling(&cmp_fall_ISR);
  • Currently, following functions are not yet implemented:
    • On the fly MUX switching for + input (SwitchPlus function).
    • On the fly MUX switching for - input (SwitchMin function).
    • DMA transfer.
Committer:
frankvnk
Date:
Sun Jun 16 10:03:19 2013 +0000
Revision:
14:875486333dc2
Parent:
13:2d499824ba05
Child:
15:f340e0545b53
ISR changed - separated rising/falling setup & callback

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 1:ccac56d8f1cb 1 /**************************************************************************************************
frankvnk 1:ccac56d8f1cb 2 ***** *****
frankvnk 1:ccac56d8f1cb 3 ***** Name: ComparatorIn.cpp *****
frankvnk 1:ccac56d8f1cb 4 ***** Date: 05/06/2013 *****
frankvnk 1:ccac56d8f1cb 5 ***** Auth: Frank Vannieuwkerke *****
frankvnk 1:ccac56d8f1cb 6 ***** Func: library for KL25Z Comparator *****
frankvnk 1:ccac56d8f1cb 7 ***** *****
frankvnk 1:ccac56d8f1cb 8 **************************************************************************************************/
frankvnk 1:ccac56d8f1cb 9
frankvnk 0:e742ad3d7dac 10 #include "ComparatorIn.h"
frankvnk 0:e742ad3d7dac 11
frankvnk 14:875486333dc2 12 void (*rise_fptr)(void); // Pointer to user function - called after rising IRQ assertion.
frankvnk 14:875486333dc2 13 void (*fall_fptr)(void); // Pointer to user function - called after falling IRQ assertion.
frankvnk 0:e742ad3d7dac 14
frankvnk 0:e742ad3d7dac 15 const PinMap ComparatorIn::PinMap_CMP[] = {
frankvnk 0:e742ad3d7dac 16 {PTC6, CMP0_IN0, 0},
frankvnk 0:e742ad3d7dac 17 {PTC7, CMP0_IN1, 0},
frankvnk 0:e742ad3d7dac 18 {PTC8, CMP0_IN2, 0},
frankvnk 0:e742ad3d7dac 19 {PTC9, CMP0_IN3, 0},
frankvnk 0:e742ad3d7dac 20 {PTE30, CMP0_IN4, 0}, // ADC0_SE23
frankvnk 0:e742ad3d7dac 21 {PTE29, CMP0_IN5, 0}, // ADC0_SE4b
frankvnk 0:e742ad3d7dac 22 {NC, NC, 0}
frankvnk 0:e742ad3d7dac 23 };
frankvnk 0:e742ad3d7dac 24
frankvnk 0:e742ad3d7dac 25 ComparatorIn::ComparatorIn(PinName pinP, PinName pinM)
frankvnk 0:e742ad3d7dac 26 {
frankvnk 14:875486333dc2 27 rise_fptr = NULL;
frankvnk 14:875486333dc2 28 fall_fptr = NULL;
frankvnk 0:e742ad3d7dac 29 CMPnumberP = (CMPName)pinmap_peripheral(pinP, PinMap_CMP);
frankvnk 0:e742ad3d7dac 30 if (CMPnumberP == (uint32_t)NC) // When NC, use DAC0
frankvnk 0:e742ad3d7dac 31 CMPnumberP = 0x07;
frankvnk 0:e742ad3d7dac 32 CMPnumberM = (CMPName)pinmap_peripheral(pinM, PinMap_CMP);
frankvnk 0:e742ad3d7dac 33 if (CMPnumberM == (uint32_t)NC) // When NC, use DAC0
frankvnk 0:e742ad3d7dac 34 CMPnumberM = 0x07;
frankvnk 0:e742ad3d7dac 35
frankvnk 0:e742ad3d7dac 36 SIM->SCGC4 |=SIM_SCGC4_CMP_MASK; // Enable HSCMP module clock
frankvnk 0:e742ad3d7dac 37
frankvnk 0:e742ad3d7dac 38 hscmp_clear();
frankvnk 0:e742ad3d7dac 39 CMP0->CR0 = 0x00; // Filter and digital hysteresis disabled
frankvnk 0:e742ad3d7dac 40 CMP0->CR1 = 0x17; // Continuous mode, high-speed compare, unfiltered output, output pin disabled
frankvnk 0:e742ad3d7dac 41 CMP0->FPR = 0x00; // Filter disabled
frankvnk 13:2d499824ba05 42 CMP0->SCR = 0x06; // Disable all interrupts and clear flags (flags are cleared by this write)
frankvnk 6:9b1268dd1d16 43 CMP0->DACCR = 0xE0; // DAC enabled, Vdd is 6bit reference, threshold set to 1/2 of full-scale (1.65V)
frankvnk 0:e742ad3d7dac 44 CMP0->MUXCR = (CMPnumberP << 3) | (CMPnumberM & 0x07); // P-input/M-input are ext.channels defined by CMPnumberP/CMPnumberN
frankvnk 0:e742ad3d7dac 45
frankvnk 14:875486333dc2 46 if(CMPnumberP < 6) pinmap_pinout(pinP, PinMap_CMP); // Map pins
frankvnk 14:875486333dc2 47 if(CMPnumberM < 6) pinmap_pinout(pinM, PinMap_CMP); // Map pins
frankvnk 14:875486333dc2 48
frankvnk 14:875486333dc2 49 NVIC_SetVector(CMP0_IRQn, (uint32_t)&_cmpISR); // Set comparator ISR to _cmpISR routine
frankvnk 0:e742ad3d7dac 50 };
frankvnk 0:e742ad3d7dac 51
frankvnk 0:e742ad3d7dac 52 void ComparatorIn::filter_count(unsigned char fico)
frankvnk 0:e742ad3d7dac 53 {
frankvnk 0:e742ad3d7dac 54 if((fico > 0) && (fico < 8))
frankvnk 0:e742ad3d7dac 55 {
frankvnk 0:e742ad3d7dac 56 unsigned char tmp;
frankvnk 11:c0ef9948278b 57 tmp = (CMP0->CR0 & 0x8F) | CMP_CR0_FILTER_CNT(fico); // Replace old value
frankvnk 11:c0ef9948278b 58 CMP0->CR0 = tmp; // Set filter count
frankvnk 0:e742ad3d7dac 59 }
frankvnk 0:e742ad3d7dac 60 }
frankvnk 0:e742ad3d7dac 61
frankvnk 0:e742ad3d7dac 62 void ComparatorIn::hysteresis(unsigned char hyst)
frankvnk 0:e742ad3d7dac 63 {
frankvnk 0:e742ad3d7dac 64 if(hyst < 4)
frankvnk 0:e742ad3d7dac 65 {
frankvnk 0:e742ad3d7dac 66 unsigned char tmp;
frankvnk 11:c0ef9948278b 67 tmp = (CMP0->CR0 & 0xFC) | CMP_CR0_HYSTCTR(hyst); // Replace old value
frankvnk 11:c0ef9948278b 68 CMP0->CR0 = tmp; // Set hysteresis
frankvnk 0:e742ad3d7dac 69 }
frankvnk 0:e742ad3d7dac 70 }
frankvnk 0:e742ad3d7dac 71
frankvnk 0:e742ad3d7dac 72 void ComparatorIn::sample_mode(unsigned char samp_en)
frankvnk 0:e742ad3d7dac 73 {
frankvnk 0:e742ad3d7dac 74 if((CMP0->CR1 & CMP_CR1_WE_MASK) == 0) // Only allow change when window mode is inactive
frankvnk 0:e742ad3d7dac 75 {
frankvnk 0:e742ad3d7dac 76 if(samp_en == 1) CMP0->CR1 |= CMP_CR1_SE_MASK; // Enable
frankvnk 0:e742ad3d7dac 77 else CMP0->CR1 &= ~CMP_CR1_SE_MASK; // Disable
frankvnk 0:e742ad3d7dac 78 }
frankvnk 0:e742ad3d7dac 79 }
frankvnk 0:e742ad3d7dac 80
frankvnk 0:e742ad3d7dac 81 void ComparatorIn::window_mode(unsigned char win_en)
frankvnk 0:e742ad3d7dac 82 {
frankvnk 0:e742ad3d7dac 83 if((CMP0->CR1 & CMP_CR1_SE_MASK) == 0) // Only allow change when sample mode is inactive
frankvnk 0:e742ad3d7dac 84 {
frankvnk 0:e742ad3d7dac 85 if(win_en == 1) CMP0->CR1 |= CMP_CR1_WE_MASK; // Enable
frankvnk 0:e742ad3d7dac 86 else CMP0->CR1 &= ~CMP_CR1_WE_MASK; // Disable
frankvnk 0:e742ad3d7dac 87 }
frankvnk 0:e742ad3d7dac 88 }
frankvnk 0:e742ad3d7dac 89
frankvnk 0:e742ad3d7dac 90 void ComparatorIn::trig_mode(unsigned char trig_en)
frankvnk 0:e742ad3d7dac 91 {
frankvnk 0:e742ad3d7dac 92 if(trig_en == 1) CMP0->CR1 |= CMP_CR1_TRIGM_MASK; // Enable
frankvnk 0:e742ad3d7dac 93 else CMP0->CR1 &= ~CMP_CR1_TRIGM_MASK; // Disable
frankvnk 0:e742ad3d7dac 94 }
frankvnk 0:e742ad3d7dac 95
frankvnk 0:e742ad3d7dac 96 void ComparatorIn::power_mode(unsigned char pmode)
frankvnk 0:e742ad3d7dac 97 {
frankvnk 0:e742ad3d7dac 98 if(pmode == 1) CMP0->CR1 |= CMP_CR1_PMODE_MASK; // Set high speed
frankvnk 0:e742ad3d7dac 99 else CMP0->CR1 &= ~CMP_CR1_PMODE_MASK; // Set low speed
frankvnk 0:e742ad3d7dac 100 }
frankvnk 0:e742ad3d7dac 101
frankvnk 0:e742ad3d7dac 102 void ComparatorIn::invert(unsigned char inv)
frankvnk 0:e742ad3d7dac 103 {
frankvnk 0:e742ad3d7dac 104 if(inv == 1) CMP0->CR1 |= CMP_CR1_INV_MASK; // Enable
frankvnk 0:e742ad3d7dac 105 else CMP0->CR1 &= ~CMP_CR1_INV_MASK; // Disable
frankvnk 0:e742ad3d7dac 106 }
frankvnk 0:e742ad3d7dac 107
frankvnk 0:e742ad3d7dac 108 void ComparatorIn::output_select(unsigned char cos)
frankvnk 0:e742ad3d7dac 109 {
frankvnk 0:e742ad3d7dac 110 if(cos == 1) CMP0->CR1 |= CMP_CR1_COS_MASK; // Enable
frankvnk 0:e742ad3d7dac 111 else CMP0->CR1 &= ~CMP_CR1_COS_MASK; // Disable
frankvnk 0:e742ad3d7dac 112 }
frankvnk 0:e742ad3d7dac 113
frankvnk 12:0a0648bddb98 114 void ComparatorIn::output_pin_en(PinName ope)
frankvnk 0:e742ad3d7dac 115 {
frankvnk 12:0a0648bddb98 116 PinName pin_stat;
frankvnk 12:0a0648bddb98 117 pin_stat = op_status(); // Get pin status
frankvnk 12:0a0648bddb98 118 // Only change settings if new pin differs from old pin AND the correct pin is selected.
frankvnk 12:0a0648bddb98 119 if((ope != pin_stat) && ((ope == PTC0) || (ope == PTC5) || (ope == PTE0) || (ope == NC)))
frankvnk 12:0a0648bddb98 120 {
frankvnk 12:0a0648bddb98 121 if(ope == NC)
frankvnk 12:0a0648bddb98 122 {
frankvnk 12:0a0648bddb98 123 if (pin_stat != NC) op_disable(pin_stat); // disconnect current pin
frankvnk 12:0a0648bddb98 124 CMP0->CR1 &= ~CMP_CR1_OPE_MASK; // Disable comparator output pin connect
frankvnk 12:0a0648bddb98 125 }
frankvnk 12:0a0648bddb98 126 else
frankvnk 12:0a0648bddb98 127 {
frankvnk 12:0a0648bddb98 128 op_enable(ope, pin_stat); // Connect new pin
frankvnk 12:0a0648bddb98 129 CMP0->CR1 &= ~CMP_CR1_OPE_MASK; // Enable comparator output pin connect
frankvnk 12:0a0648bddb98 130 }
frankvnk 12:0a0648bddb98 131 }
frankvnk 0:e742ad3d7dac 132 }
frankvnk 0:e742ad3d7dac 133
frankvnk 0:e742ad3d7dac 134 void ComparatorIn::enable(unsigned char en)
frankvnk 0:e742ad3d7dac 135 {
frankvnk 0:e742ad3d7dac 136 if(en == 1) CMP0->CR1 |= CMP_CR1_EN_MASK; // Enable
frankvnk 0:e742ad3d7dac 137 else CMP0->CR1 &= ~CMP_CR1_EN_MASK; // Disable
frankvnk 0:e742ad3d7dac 138 }
frankvnk 0:e742ad3d7dac 139
frankvnk 0:e742ad3d7dac 140 void ComparatorIn::filter_period(unsigned char fipe)
frankvnk 0:e742ad3d7dac 141 {
frankvnk 0:e742ad3d7dac 142 CMP0->FPR = CMP_FPR_FILT_PER(fipe);
frankvnk 0:e742ad3d7dac 143 }
frankvnk 0:e742ad3d7dac 144
frankvnk 0:e742ad3d7dac 145 void ComparatorIn::dma_en(unsigned char dmaen)
frankvnk 0:e742ad3d7dac 146 {
frankvnk 0:e742ad3d7dac 147 if(dmaen == 1) CMP0->SCR |= CMP_SCR_DMAEN_MASK; // Enable
frankvnk 0:e742ad3d7dac 148 else CMP0->SCR &= ~CMP_SCR_DMAEN_MASK; // Disable
frankvnk 0:e742ad3d7dac 149 }
frankvnk 0:e742ad3d7dac 150
frankvnk 0:e742ad3d7dac 151 unsigned char ComparatorIn::status(void)
frankvnk 0:e742ad3d7dac 152 {
frankvnk 0:e742ad3d7dac 153 return (CMP0->SCR & 0x01);
frankvnk 0:e742ad3d7dac 154 }
frankvnk 0:e742ad3d7dac 155
frankvnk 0:e742ad3d7dac 156 void ComparatorIn::dac_en(unsigned char den)
frankvnk 0:e742ad3d7dac 157 {
frankvnk 0:e742ad3d7dac 158 if(den == 1) CMP0->DACCR |= CMP_DACCR_DACEN_MASK; // Enable
frankvnk 0:e742ad3d7dac 159 else CMP0->DACCR &= ~CMP_DACCR_DACEN_MASK; // Disable
frankvnk 0:e742ad3d7dac 160 }
frankvnk 0:e742ad3d7dac 161
frankvnk 0:e742ad3d7dac 162 void ComparatorIn::ref_source(unsigned char res)
frankvnk 0:e742ad3d7dac 163 {
frankvnk 0:e742ad3d7dac 164 if(res == 1) CMP0->DACCR |= CMP_DACCR_VRSEL_MASK; // Enable
frankvnk 0:e742ad3d7dac 165 else CMP0->DACCR &= ~CMP_DACCR_VRSEL_MASK; // Disable
frankvnk 0:e742ad3d7dac 166 }
frankvnk 0:e742ad3d7dac 167
frankvnk 13:2d499824ba05 168 void ComparatorIn::treshold(float vo_pct)
frankvnk 0:e742ad3d7dac 169 {
frankvnk 13:2d499824ba05 170 if(vo_pct < 0.0)
frankvnk 0:e742ad3d7dac 171 {
frankvnk 13:2d499824ba05 172 dac6_write(0);
frankvnk 13:2d499824ba05 173 }
frankvnk 13:2d499824ba05 174 else if(vo_pct > 1.0)
frankvnk 13:2d499824ba05 175 {
frankvnk 13:2d499824ba05 176 dac6_write(0x3F);
frankvnk 13:2d499824ba05 177 }
frankvnk 13:2d499824ba05 178 else
frankvnk 13:2d499824ba05 179 {
frankvnk 13:2d499824ba05 180 dac6_write(vo_pct * (float)0x3F);
frankvnk 0:e742ad3d7dac 181 }
frankvnk 0:e742ad3d7dac 182 }
frankvnk 0:e742ad3d7dac 183
frankvnk 0:e742ad3d7dac 184 void ComparatorIn::pass_through(unsigned char ptm)
frankvnk 0:e742ad3d7dac 185 {
frankvnk 0:e742ad3d7dac 186 if(ptm == 1) CMP0->MUXCR |= CMP_MUXCR_MSEL_MASK; // Enable
frankvnk 0:e742ad3d7dac 187 else CMP0->MUXCR &= ~CMP_MUXCR_MSEL_MASK; // Disable
frankvnk 0:e742ad3d7dac 188 }
frankvnk 0:e742ad3d7dac 189
frankvnk 0:e742ad3d7dac 190 void ComparatorIn::switch_plus(unsigned char pinP)
frankvnk 0:e742ad3d7dac 191 {
frankvnk 0:e742ad3d7dac 192 }
frankvnk 0:e742ad3d7dac 193
frankvnk 0:e742ad3d7dac 194 void ComparatorIn::switch_min(unsigned char pinM)
frankvnk 0:e742ad3d7dac 195 {
frankvnk 0:e742ad3d7dac 196 }
frankvnk 0:e742ad3d7dac 197
frankvnk 0:e742ad3d7dac 198 void ComparatorIn::hscmp_clear(void)
frankvnk 0:e742ad3d7dac 199 {
frankvnk 0:e742ad3d7dac 200 CMP0->CR0 = 0;
frankvnk 0:e742ad3d7dac 201 CMP0->CR1 = 0;
frankvnk 0:e742ad3d7dac 202 CMP0->FPR = 0;
frankvnk 0:e742ad3d7dac 203 CMP0->SCR = 0x06; // Clear flags if set.
frankvnk 0:e742ad3d7dac 204 CMP0->DACCR = 0;
frankvnk 0:e742ad3d7dac 205 CMP0->MUXCR = 0;
frankvnk 0:e742ad3d7dac 206 }
frankvnk 0:e742ad3d7dac 207
frankvnk 14:875486333dc2 208 void ComparatorIn::int_en(bool ien)
frankvnk 14:875486333dc2 209 {
frankvnk 14:875486333dc2 210 if(ien) NVIC_EnableIRQ(CMP0_IRQn); // Enable comparator ISR
frankvnk 14:875486333dc2 211 else NVIC_DisableIRQ(CMP0_IRQn); // Disable comparator ISR
frankvnk 14:875486333dc2 212 }
frankvnk 14:875486333dc2 213
frankvnk 14:875486333dc2 214 void ComparatorIn::rising(void(*fptr)(void))
frankvnk 0:e742ad3d7dac 215 {
frankvnk 14:875486333dc2 216 rise_fptr = fptr;
frankvnk 14:875486333dc2 217 CMP0->SCR |= (CMP_SCR_IER_MASK | CMP_SCR_CFR_MASK); // Enable rising int. and clear flag
frankvnk 14:875486333dc2 218 }
frankvnk 14:875486333dc2 219
frankvnk 14:875486333dc2 220 void ComparatorIn::falling(void(*fptr)(void))
frankvnk 14:875486333dc2 221 {
frankvnk 14:875486333dc2 222 fall_fptr = fptr;
frankvnk 14:875486333dc2 223 CMP0->SCR |= (CMP_SCR_IEF_MASK | CMP_SCR_CFF_MASK); // Enable falling int. and clear flag
frankvnk 0:e742ad3d7dac 224 }
frankvnk 0:e742ad3d7dac 225
frankvnk 0:e742ad3d7dac 226 void ComparatorIn::_cmpISR(void)
frankvnk 0:e742ad3d7dac 227 {
frankvnk 14:875486333dc2 228 // Interrupt flags are cleared by writing 1 to the CFx flag
frankvnk 14:875486333dc2 229 // Rising edge
frankvnk 0:e742ad3d7dac 230 if (((CMP0->SCR & CMP_SCR_IER_MASK)==CMP_SCR_IER_MASK) && ((CMP0->SCR & CMP_SCR_CFR_MASK)==CMP_SCR_CFR_MASK))
frankvnk 0:e742ad3d7dac 231 {
frankvnk 12:0a0648bddb98 232 CMP0->SCR |= CMP_SCR_CFR_MASK; // Clear the flag
frankvnk 14:875486333dc2 233 if (rise_fptr != NULL) rise_fptr(); // call user function
frankvnk 0:e742ad3d7dac 234 }
frankvnk 0:e742ad3d7dac 235
frankvnk 14:875486333dc2 236 // Falling edge
frankvnk 0:e742ad3d7dac 237 if (((CMP0->SCR & CMP_SCR_IEF_MASK)==CMP_SCR_IEF_MASK) && ((CMP0->SCR & CMP_SCR_CFF_MASK)==CMP_SCR_CFF_MASK))
frankvnk 0:e742ad3d7dac 238 {
frankvnk 12:0a0648bddb98 239 CMP0->SCR |= CMP_SCR_CFF_MASK; // Clear the flag
frankvnk 14:875486333dc2 240 if (fall_fptr != NULL) fall_fptr(); // call user function
frankvnk 12:0a0648bddb98 241 }
frankvnk 12:0a0648bddb98 242 }
frankvnk 12:0a0648bddb98 243
frankvnk 12:0a0648bddb98 244 /*
frankvnk 12:0a0648bddb98 245 IMPORTANT : Do not alter the if... sequence in op_status.
frankvnk 12:0a0648bddb98 246 We need to check if the port is active (using SIM->SCGC5) BEFORE reading PORTn->PCR[x].
frankvnk 12:0a0648bddb98 247 Reading PORTn->PCR[x] while a port is inactive will block the system.
frankvnk 12:0a0648bddb98 248 At startup, SIM->SCGC5 = 00000380h. This means only PORTA is enabled.
frankvnk 12:0a0648bddb98 249 */
frankvnk 12:0a0648bddb98 250 PinName ComparatorIn::op_status(void)
frankvnk 12:0a0648bddb98 251 {
frankvnk 12:0a0648bddb98 252 if((SIM->SCGC5 & SIM_SCGC5_PORTE_MASK) == 1)
frankvnk 12:0a0648bddb98 253 {
frankvnk 12:0a0648bddb98 254 if((PORTE->PCR[0] & PORT_PCR_MUX_MASK) == 0x500u) return(PTE0); // check if current pin = PTE0
frankvnk 0:e742ad3d7dac 255 }
frankvnk 12:0a0648bddb98 256 if((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) == 1)
frankvnk 12:0a0648bddb98 257 {
frankvnk 12:0a0648bddb98 258 if((PORTC->PCR[0] & PORT_PCR_MUX_MASK) == 0x500u) return(PTC0); // check if current pin = PTC0
frankvnk 12:0a0648bddb98 259 if((PORTC->PCR[5] & PORT_PCR_MUX_MASK) == 0x600u) return(PTC5); // check if current pin = PTC5
frankvnk 12:0a0648bddb98 260 }
frankvnk 12:0a0648bddb98 261 return(NC);
frankvnk 0:e742ad3d7dac 262 }
frankvnk 0:e742ad3d7dac 263
frankvnk 12:0a0648bddb98 264 void ComparatorIn::op_enable(PinName pen, PinName pstat)
frankvnk 12:0a0648bddb98 265 {
frankvnk 12:0a0648bddb98 266 if(pstat != NC) op_disable(pstat); // If a pin is connected - disconnect before connecting new pin
frankvnk 12:0a0648bddb98 267 switch (pen)
frankvnk 12:0a0648bddb98 268 {
frankvnk 12:0a0648bddb98 269 case PTC0:
frankvnk 12:0a0648bddb98 270 if((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) == 0) SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; // If PORTC is inactive: Enable
frankvnk 12:0a0648bddb98 271 PORTC->PCR[0] = PORT_PCR_MUX(5); // Set PTC0 mux to CMP0
frankvnk 12:0a0648bddb98 272 break;
frankvnk 12:0a0648bddb98 273 case PTC5:
frankvnk 12:0a0648bddb98 274 if((SIM->SCGC5 & SIM_SCGC5_PORTC_MASK) == 0) SIM->SCGC5 |= SIM_SCGC5_PORTC_MASK; // If PORTC is inactive: Enable
frankvnk 12:0a0648bddb98 275 PORTC->PCR[5] = PORT_PCR_MUX(6); // Set PTC5 mux to CMP0
frankvnk 12:0a0648bddb98 276 break;
frankvnk 12:0a0648bddb98 277 case PTE0:
frankvnk 12:0a0648bddb98 278 if((SIM->SCGC5 & SIM_SCGC5_PORTE_MASK) == 0) SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; // If PORTE is inactive: Enable
frankvnk 12:0a0648bddb98 279 PORTE->PCR[0] = PORT_PCR_MUX(5); // Set PTE0 mux to CMP0
frankvnk 12:0a0648bddb98 280 break;
frankvnk 12:0a0648bddb98 281 default:
frankvnk 12:0a0648bddb98 282 break;
frankvnk 12:0a0648bddb98 283 }
frankvnk 12:0a0648bddb98 284 }
frankvnk 1:ccac56d8f1cb 285
frankvnk 12:0a0648bddb98 286 void ComparatorIn::op_disable(PinName pdi)
frankvnk 12:0a0648bddb98 287 {
frankvnk 12:0a0648bddb98 288 switch (pdi)
frankvnk 12:0a0648bddb98 289 {
frankvnk 12:0a0648bddb98 290 case PTC0:
frankvnk 12:0a0648bddb98 291 PORTC->PCR[0] &= PORT_PCR_MUX(1); // Set PTC0 mux to ALT1
frankvnk 12:0a0648bddb98 292 break;
frankvnk 12:0a0648bddb98 293 case PTC5:
frankvnk 12:0a0648bddb98 294 PORTC->PCR[5] &= PORT_PCR_MUX(1); // Set PTC5 mux to ALT1
frankvnk 12:0a0648bddb98 295 break;
frankvnk 12:0a0648bddb98 296 case PTE0:
frankvnk 12:0a0648bddb98 297 PORTE->PCR[0] &= PORT_PCR_MUX(1); // Set PTE0 mux to ALT1
frankvnk 12:0a0648bddb98 298 break;
frankvnk 12:0a0648bddb98 299 default:
frankvnk 12:0a0648bddb98 300 break;
frankvnk 12:0a0648bddb98 301 }
frankvnk 12:0a0648bddb98 302 }
frankvnk 13:2d499824ba05 303
frankvnk 13:2d499824ba05 304 void ComparatorIn::dac6_write(unsigned int value)
frankvnk 13:2d499824ba05 305 {
frankvnk 13:2d499824ba05 306 unsigned int tmp;
frankvnk 13:2d499824ba05 307 value &= 0x3F; // 6-bit
frankvnk 13:2d499824ba05 308 tmp = (CMP0->DACCR & 0xC0) | value; // Replace old value
frankvnk 13:2d499824ba05 309 CMP0->DACCR = tmp; // Set Vout DAC
frankvnk 13:2d499824ba05 310 }
frankvnk 14:875486333dc2 311