Skip to content

Commit

Permalink
Move comparator attach/detachInterrupt and ISR to separate cpp file
Browse files Browse the repository at this point in the history
This makes it possible for the dot_a_linkage to optimize away the file when the ISR is not in use, saving about 200 bytes for every sketch that includes Logic.h
  • Loading branch information
MCUdude committed Jun 18, 2022
1 parent 41b09f2 commit 38d58d2
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 80 deletions.
3 changes: 2 additions & 1 deletion megaavr/libraries/Comparator/library.properties
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name=Comparator
version=1.1.0
version=1.1.1
author=MCUdude
maintainer=MCUdude
sentence=A library for interfacing with the built-in analog comparator
paragraph=
category=Signal Input/Output
url=https://github.com/MCUdude/MegaCoreX
dot_a_linkage=true
architectures=megaavr
79 changes: 0 additions & 79 deletions megaavr/libraries/Comparator/src/Comparator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,6 @@

AnalogComparator Comparator(0, AC0);

// Array for storing ISR function pointers
#if defined(AC2_AC_vect)
static volatile voidFuncPtr intFuncAC[3];
#elif defined(AC1_AC_vect)
static volatile voidFuncPtr intFuncAC[2];
#elif defined(AC0_AC_vect)
static volatile voidFuncPtr intFuncAC[1];
#else
#error target does not have an analog comparator!
#endif


AnalogComparator::AnalogComparator(const uint8_t comp_number, AC_t& ac) : comparator_number(comp_number), AC(ac)
{
}
Expand Down Expand Up @@ -78,70 +66,3 @@ bool AnalogComparator::read()
{
return !!(AC0.STATUS & AC_STATE_bm);
}

void AnalogComparator::attachInterrupt(void (*userFunc)(void), uint8_t mode)
{
AC_INTMODE_t intmode;
switch (mode)
{
// Set RISING, FALLING or CHANGE interrupt trigger for the comparator output
case RISING:
intmode = AC_INTMODE_POSEDGE_gc;
break;
case FALLING:
intmode = AC_INTMODE_NEGEDGE_gc;
break;
case CHANGE:
intmode = AC_INTMODE_BOTHEDGE_gc;
break;
default:
// Only RISING, FALLING and CHANGE is supported
return;
}
AC.CTRLA = (AC.CTRLA & ~AC_INTMODE_POSEDGE_gc) | intmode;

// Store function pointer
intFuncAC[comparator_number] = userFunc;

// Enable interrupt
AC.INTCTRL |= AC_CMP_bm;
}

void AnalogComparator::detachInterrupt()
{
// Disable interrupt
AC.INTCTRL &= ~AC_CMP_bm;
}

#ifdef AC0_AC_vect
ISR(AC0_AC_vect)
{
// Run user function
intFuncAC[0]();

// Clear flag
AC0.STATUS = AC_CMP_bm;
}
#endif

#ifdef AC1_AC_vect
ISR(AC1_AC_vect)
{
// Run user function
intFuncAC[1]();

// Clear flag
AC1.STATUS = AC_CMP_bm;
}
#endif

#ifdef AC2_AC_vect
ISR(AC2_AC_vect)
{
// Run user function
intFuncAC[2]();

// Clear flag
AC2.STATUS = AC_CMP_bm;
}
#endif
11 changes: 11 additions & 0 deletions megaavr/libraries/Comparator/src/Comparator.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,17 @@ class AnalogComparator
bool enable = false;
};

// Array for storing ISR function pointers
#if defined(AC2_AC_vect)
static volatile voidFuncPtr intFuncAC[3];
#elif defined(AC1_AC_vect)
static volatile voidFuncPtr intFuncAC[2];
#elif defined(AC0_AC_vect)
static volatile voidFuncPtr intFuncAC[1];
#else
#error target does not have an analog comparator!
#endif

#if defined(AC0_AC_vect)
extern AnalogComparator Comparator0;
#define Comparator Comparator0
Expand Down
71 changes: 71 additions & 0 deletions megaavr/libraries/Comparator/src/Comparator_ISR.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// This file will be optimized away if attachInterrupt or detachInterrupt isn't used in
// user program, thanks to dot_a_linkage set in library.properties

#include "Comparator.h"

void AnalogComparator::attachInterrupt(void (*userFunc)(void), uint8_t mode)
{
AC_INTMODE_t intmode;
switch (mode)
{
// Set RISING, FALLING or CHANGE interrupt trigger for the comparator output
case RISING:
intmode = AC_INTMODE_POSEDGE_gc;
break;
case FALLING:
intmode = AC_INTMODE_NEGEDGE_gc;
break;
case CHANGE:
intmode = AC_INTMODE_BOTHEDGE_gc;
break;
default:
// Only RISING, FALLING and CHANGE is supported
return;
}
AC.CTRLA = (AC.CTRLA & ~AC_INTMODE_POSEDGE_gc) | intmode;

// Store function pointer
intFuncAC[comparator_number] = userFunc;

// Enable interrupt
AC.INTCTRL |= AC_CMP_bm;
}

void AnalogComparator::detachInterrupt()
{
// Disable interrupt
AC.INTCTRL &= ~AC_CMP_bm;
}

#ifdef AC0_AC_vect
ISR(AC0_AC_vect)
{
// Run user function
intFuncAC[0]();

// Clear flag
AC0.STATUS = AC_CMP_bm;
}
#endif

#ifdef AC1_AC_vect
ISR(AC1_AC_vect)
{
// Run user function
intFuncAC[1]();

// Clear flag
AC1.STATUS = AC_CMP_bm;
}
#endif

#ifdef AC2_AC_vect
ISR(AC2_AC_vect)
{
// Run user function
intFuncAC[2]();

// Clear flag
AC2.STATUS = AC_CMP_bm;
}
#endif

0 comments on commit 38d58d2

Please sign in to comment.