1
/***************************************************************************
2
* Copyright (C) 2020 by santiago González *
3
* santigoro@gmail.com *
5
* This program is free software; you can redistribute it and/or modify *
6
* it under the terms of the GNU General Public License as published by *
7
* the Free Software Foundation; either version 3 of the License, or *
8
* (at your option) any later version. *
10
* This program is distributed in the hope that it will be useful, *
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13
* GNU General Public License for more details. *
15
* You should have received a copy of the GNU General Public License *
16
* along with this program; if not, see <http://www.gnu.org/licenses/>. *
18
***************************************************************************/
20
#include "mcuinterrupts.h"
24
uint8_t Interrupt::m_enGlobal = 0;
25
Interrupt* Interrupt::m_active = 0l;
26
std::multimap<uint8_t, Interrupt*> Interrupt::m_running;
27
std::multimap<uint8_t, Interrupt*> Interrupt::m_pending;
28
QHash<QString, Interrupt*> Interrupt::m_interrupts;
30
Interrupt::Interrupt( QString name, uint16_t vector, eMcu* mcu )
37
m_ram = mcu->getRam();
39
Interrupt::~Interrupt(){}
41
void Interrupt::reset()
49
void Interrupt::clearFlag()
51
m_ram[m_flagReg] &= ~m_flagMask; // Clear Interrupt flag
54
void Interrupt::enableFlag( uint8_t en )
59
void Interrupt::setPriority( uint8_t p )
64
void Interrupt::raise( uint8_t v )
66
if( !m_enable ) return;
67
m_ram[m_flagReg] |= m_flagMask; // Set Interrupt flag
70
// Interrupt are stored in static std::multimap
71
// by priority order, highest at end
72
m_pending.emplace( m_priority, this ); // Add to pending interrupts
75
void Interrupt::execute()
77
m_mcu->cpu->CALL_ADDR( m_vector );
81
void Interrupt::exitInt() // Exit from this interrupt
83
if( m_running.size() ) // There are interrupts interrupted
85
auto it = prev( m_running.end() );
86
m_active = it->second; // Set interrupted Interrupt as active
87
m_running.erase( it ); // Remove Interrupt from running list
92
//------------------------STATIC MEMBERS ------------------------
93
//---------------------------------------------------------------
95
void Interrupt::retI() // Static
100
void Interrupt::enableGlobal( uint8_t en ) // Static
105
void Interrupt::runInterrupts() // Static
107
if( !m_enGlobal ) return; // Global Interrupts disabled
108
if( m_pending.empty() ) return; // No Interrupts to run
110
auto it = prev( m_pending.end() );
111
uint8_t priority = it->first;
112
Interrupt* interrupt = it->second;
114
if( m_active ) // Only interrupt other Interrupts with lower priority
116
if( priority <= m_active->priority() ) return;
118
// An interrupt being interrupted, add to running list.
119
m_running.emplace( m_active->priority(), m_active );
121
m_pending.erase( it ); // Remove Interrupt from pending list
122
interrupt->execute();
125
void Interrupt::resetInts() // Static
131
for( QString inte : m_interrupts.keys() )
132
m_interrupts.value( inte )->reset();
135
void Interrupt::remove() // Static
137
for( QString inte : m_interrupts.keys() )
138
delete m_interrupts.value( inte );
140
m_interrupts.clear();