2
* fsm-main.c: main() function for SpaghettiMonster.
4
* Copyright (C) 2017 Selene Scriven
6
* This program is free software: you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation, either version 3 of the License, or
9
* (at your option) any later version.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program. If not, see <http://www.gnu.org/licenses/>.
1
// fsm-main.c: main() function for SpaghettiMonster.
2
// Copyright (C) 2017-2023 Selene ToyKeeper
3
// SPDX-License-Identifier: GPL-3.0-or-later
23
7
#include "fsm-main.h"
25
9
#if PWM_CHANNELS == 4
10
#ifdef AVRXMEGA3 // ATTINY816, 817, etc
11
#error 4-channel PWM not currently set up for the AVR 1-Series
26
13
// 4th PWM channel requires manually turning the pin on/off via interrupt :(
27
14
ISR(TIMER1_OVF_vect) {
28
15
//bitClear(PORTB, 3);
26
// FIXME: hw_setup() shouldn't be here ... move it entirely to hwdef files
39
27
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
40
28
static inline void hw_setup() {
41
// configure PWM channels
43
DDRB |= (1 << PWM1_PIN);
44
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
48
DDRB |= (1 << PWM2_PIN);
51
// Second PWM counter is ... weird
52
DDRB |= (1 << PWM3_PIN);
54
GTCCR = _BV (COM1B1) | _BV (PWM1B);
55
OCR1C = 255; // Set ceiling value to maximum
58
// 4th PWM channel is ... not actually supported in hardware :(
59
DDRB |= (1 << PWM4_PIN);
60
//OCR1C = 255; // Set ceiling value to maximum
61
TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 2<<CS10;
62
GTCCR = (2<<COM1B0) | (1<<PWM1B);
63
// set up an interrupt to control PWM4 pin
64
TIMSK |= (1<<OCIE1A) | (1<<TOIE1);
29
#if !defined(USE_GENERIC_HWDEF_SETUP)
32
// configure PWM channels
34
DDRB |= (1 << PWM1_PIN);
35
TCCR0B = 0x01; // pre-scaler for timer (1 => 1, 2 => 8, 3 => 64...)
37
#if (PWM1_PIN == PB4) // Second PWM counter is ... weird
39
GTCCR = _BV (COM1B1) | _BV (PWM1B);
40
OCR1C = 255; // Set ceiling value to maximum
43
// tint ramping needs second channel enabled,
44
// despite PWM_CHANNELS being only 1
45
#if (PWM_CHANNELS >= 2) || defined(USE_TINT_RAMPING)
46
DDRB |= (1 << PWM2_PIN);
47
#if (PWM2_PIN == PB4) // Second PWM counter is ... weird
49
GTCCR = _BV (COM1B1) | _BV (PWM1B);
50
OCR1C = 255; // Set ceiling value to maximum
54
DDRB |= (1 << PWM3_PIN);
55
#if (PWM3_PIN == PB4) // Second PWM counter is ... weird
57
GTCCR = _BV (COM1B1) | _BV (PWM1B);
58
OCR1C = 255; // Set ceiling value to maximum
62
// 4th PWM channel is ... not actually supported in hardware :(
63
DDRB |= (1 << PWM4_PIN);
64
//OCR1C = 255; // Set ceiling value to maximum
65
TCCR1 = 1<<CTC1 | 1<<PWM1A | 3<<COM1A0 | 2<<CS10;
66
GTCCR = (2<<COM1B0) | (1<<PWM1B);
67
// set up an interrupt to control PWM4 pin
68
TIMSK |= (1<<OCIE1A) | (1<<TOIE1);
68
PORTB = (1 << SWITCH_PIN); // e-switch is the only input
69
PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
72
PORTB = (1 << SWITCH_PIN); // e-switch is the only input
73
PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
74
#endif // ifdef USE_GENERIC_HWDEF_SETUP
71
#elif (ATTINY == 1634)
76
#elif (ATTINY == 1634) || defined(AVRXMEGA3) // ATTINY816, 817, etc
72
77
static inline void hw_setup() {
73
78
// this gets tricky with so many pins...
74
79
// ... so punt it to the hwdef file
139
149
// if event queue not empty, empty it
140
150
process_emissions();
152
// if loop() tried to change state, process that now
153
StatePtr df = deferred_state;
155
set_state(df, deferred_state_arg);
156
deferred_state = NULL;
157
//deferred_state_arg = 0; // unnecessary
142
160
// enter standby mode if requested
143
161
// (works better if deferred like this)
144
162
if (go_to_standby) {
164
182
// catch up on interrupts
165
183
handle_deferred_interrupts();
185
// turn delays back on, if they were off
186
nice_delay_interrupt = 0;
167
188
// give the recipe some time slices
170
// in case we fell through, turn delays back on
171
nice_delay_interrupt = 0;