Subversion Repositories MK-Marlin

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 ron 1
/**
2
 * Marlin 3D Printer Firmware
3
 * Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4
 *
5
 * Based on Sprinter and grbl.
6
 * Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
7
 *
8
 * This program is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU General Public License as published by
10
 * the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 * GNU General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU General Public License
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
 *
21
 */
22
 
23
#ifndef __BUZZER_H__
24
#define __BUZZER_H__
25
 
26
#include "types.h"
27
#include "fastio.h"
28
#include "circularqueue.h"
29
#include "temperature.h"
30
 
31
#include "MarlinConfig.h"
32
 
33
#define TONE_QUEUE_LENGTH 4
34
 
35
/**
36
 * @brief Tone structure
37
 * @details Simple abstraction of a tone based on a duration and a frequency.
38
 */
39
struct tone_t {
40
  uint16_t duration;
41
  uint16_t frequency;
42
};
43
 
44
/**
45
 * @brief Buzzer class
46
 */
47
class Buzzer {
48
  private:
49
    struct state_t {
50
      tone_t   tone;
51
      uint32_t endtime;
52
    } state;
53
 
54
  protected:
55
    CircularQueue<tone_t, TONE_QUEUE_LENGTH> buffer;
56
 
57
    /**
58
     * @brief Inverts the sate of a digital PIN
59
     * @details This will invert the current state of an digital IO pin.
60
     */
61
    void invert() {
62
      TOGGLE(BEEPER_PIN);
63
    }
64
 
65
    /**
66
     * @brief Turn off a digital PIN
67
     * @details Alias of digitalWrite(PIN, LOW) using FastIO
68
     */
69
    void off() {
70
      WRITE(BEEPER_PIN, LOW);
71
    }
72
 
73
    /**
74
     * @brief Turn on a digital PIN
75
     * @details Alias of digitalWrite(PIN, HIGH) using FastIO
76
     */
77
    void on() {
78
      WRITE(BEEPER_PIN, HIGH);
79
    }
80
 
81
    /**
82
     * @brief Resets the state of the class
83
     * @details Brings the class state to a known one.
84
     */
85
    void reset() {
86
      this->off();
87
      this->state.endtime = 0;
88
    }
89
 
90
  public:
91
    /**
92
     * @brief Class constructor
93
     */
94
    Buzzer() {
95
      SET_OUTPUT(BEEPER_PIN);
96
      this->reset();
97
    }
98
 
99
    /**
100
     * @brief Add a tone to the queue
101
     * @details Adds a tone_t structure to the ring buffer, will block IO if the
102
     *          queue is full waiting for one slot to get available.
103
     *
104
     * @param duration Duration of the tone in milliseconds
105
     * @param frequency Frequency of the tone in hertz
106
     */
107
    void tone(const uint16_t &duration, const uint16_t &frequency=0) {
108
      while (buffer.isFull()) {
109
        this->tick();
110
        thermalManager.manage_heater();
111
      }
112
      tone_t tone = { duration, frequency };
113
      this->buffer.enqueue(tone);
114
    }
115
 
116
    /**
117
     * @brief Loop function
118
     * @details This function should be called at loop, it will take care of
119
     *          playing the tones in the queue.
120
     */
121
    virtual void tick() {
122
      const millis_t now = millis();
123
 
124
      if (!this->state.endtime) {
125
        if (this->buffer.isEmpty()) return;
126
 
127
        this->state.tone = this->buffer.dequeue();
128
        this->state.endtime = now + this->state.tone.duration;
129
 
130
        if (this->state.tone.frequency > 0) {
131
          #if ENABLED(SPEAKER)
132
            CRITICAL_SECTION_START;
133
            ::tone(BEEPER_PIN, this->state.tone.frequency, this->state.tone.duration);
134
            CRITICAL_SECTION_END;
135
          #else
136
            this->on();
137
          #endif
138
        }
139
      }
140
      else if (ELAPSED(now, this->state.endtime)) this->reset();
141
    }
142
};
143
 
144
extern Buzzer buzzer;
145
 
146
#endif