|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
-
-
- #include <Arduino.h>
-
-
-
-
-
-
- static uint32_t tone_toggle_count;
- static volatile uint32_t *tone_reg;
- static uint32_t tone_mask;
- static float tone_usec=0.0;
- static uint32_t tone_new_count=0;
- static IntervalTimer tone_timer;
- static uint8_t tone_pin=255;
-
- void tone_interrupt(void);
-
- #define TONE_CLEAR_PIN (tone_reg[34] = tone_mask)
- #define TONE_TOGGLE_PIN (tone_reg[35] = tone_mask)
- #define TONE_OUTPUT_PIN (tone_reg[1] |= tone_mask)
-
- void tone(uint8_t pin, uint16_t frequency, uint32_t duration)
- {
- uint32_t count;
- volatile uint32_t *muxreg;
- float usec;
-
- if (pin >= CORE_NUM_DIGITAL) return;
- if (duration) {
- count = (frequency * duration / 1000) * 2;
- if (!(count & 1)) count++;
- } else {
- count = 0xFFFFFFFD;
- }
- if (frequency < 1) frequency = 1;
- usec = (float)500000.0 / (float)frequency;
- muxreg = portConfigRegister(pin);
-
-
-
- __disable_irq();
- if (pin == tone_pin) {
-
- if (usec == tone_usec) {
-
- tone_toggle_count = (tone_toggle_count & 1) + count - 1;
- } else {
-
-
-
-
- tone_usec = usec;
- tone_new_count = count;
- tone_toggle_count = (tone_toggle_count & 1);
- }
- } else {
-
- if (tone_pin < CORE_NUM_DIGITAL) {
- TONE_CLEAR_PIN;
- }
-
- tone_pin = pin;
- tone_reg = portOutputRegister(pin);
- tone_mask = digitalPinToBitMask(pin);
- TONE_CLEAR_PIN;
- TONE_OUTPUT_PIN;
- *muxreg = 5;
-
- tone_toggle_count = count;
- tone_usec = usec;
- tone_timer.begin(tone_interrupt, usec);
- }
- __enable_irq();
- }
-
-
- void tone_interrupt(void)
- {
- if (tone_toggle_count) {
-
- TONE_TOGGLE_PIN;
- tone_toggle_count--;
- if (tone_toggle_count == 0xFFFFFFFB) tone_toggle_count = 0xFFFFFFFD;
- } else {
-
- TONE_CLEAR_PIN;
- if (tone_new_count > 0) {
-
- tone_timer.begin(tone_interrupt, tone_usec);
- tone_toggle_count = tone_new_count;
- tone_new_count = 0;
- } else {
-
- tone_timer.end();
- tone_pin = 255;
- }
- }
- }
-
- void noTone(uint8_t pin)
- {
- if (pin >= CORE_NUM_DIGITAL) return;
- __disable_irq();
- if (pin == tone_pin) {
- tone_timer.end();
- TONE_CLEAR_PIN;
- tone_pin = 255;
- }
- __enable_irq();
- }
-
-
-
|