My Marlin configs for Fabrikator Mini and CTC i3 Pro B
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Tone.cpp 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515
  1. /* Tone.cpp
  2. A Tone Generator Library
  3. Written by Brett Hagman
  4. This library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. This library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with this library; if not, write to the Free Software
  14. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  15. Version Modified By Date Comments
  16. ------- ----------- -------- --------
  17. 0001 B Hagman 09/08/02 Initial coding
  18. 0002 B Hagman 09/08/18 Multiple pins
  19. 0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
  20. 0004 B Hagman 09/09/26 Fixed problems with ATmega8
  21. 0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
  22. 09/11/25 Changed pin toggle method to XOR
  23. 09/11/25 Fixed timer0 from being excluded
  24. 0006 D Mellis 09/12/29 Replaced objects with functions
  25. *************************************************/
  26. #include <avr/interrupt.h>
  27. #include <avr/pgmspace.h>
  28. #include <wiring.h>
  29. #include <pins_arduino.h>
  30. #if defined(__AVR_ATmega8__)
  31. #define TCCR2A TCCR2
  32. #define TCCR2B TCCR2
  33. #define COM2A1 COM21
  34. #define COM2A0 COM20
  35. #define OCR2A OCR2
  36. #define TIMSK2 TIMSK
  37. #define OCIE2A OCIE2
  38. #define TIMER2_COMPA_vect TIMER2_COMP_vect
  39. #define TIMSK1 TIMSK
  40. #endif
  41. // timerx_toggle_count:
  42. // > 0 - duration specified
  43. // = 0 - stopped
  44. // < 0 - infinitely (until stop() method called, or new play() called)
  45. #if !defined(__AVR_ATmega8__)
  46. volatile long timer0_toggle_count;
  47. volatile uint8_t *timer0_pin_port;
  48. volatile uint8_t timer0_pin_mask;
  49. #endif
  50. volatile long timer1_toggle_count;
  51. volatile uint8_t *timer1_pin_port;
  52. volatile uint8_t timer1_pin_mask;
  53. volatile long timer2_toggle_count;
  54. volatile uint8_t *timer2_pin_port;
  55. volatile uint8_t timer2_pin_mask;
  56. #if defined(__AVR_ATmega1280__)
  57. volatile long timer3_toggle_count;
  58. volatile uint8_t *timer3_pin_port;
  59. volatile uint8_t timer3_pin_mask;
  60. volatile long timer4_toggle_count;
  61. volatile uint8_t *timer4_pin_port;
  62. volatile uint8_t timer4_pin_mask;
  63. volatile long timer5_toggle_count;
  64. volatile uint8_t *timer5_pin_port;
  65. volatile uint8_t timer5_pin_mask;
  66. #endif
  67. #if defined(__AVR_ATmega1280__)
  68. #define AVAILABLE_TONE_PINS 1
  69. const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 3, 4, 5, 1, 0 */ };
  70. static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255, 255, 255, 255 */ };
  71. #elif defined(__AVR_ATmega8__)
  72. #define AVAILABLE_TONE_PINS 1
  73. const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1 */ };
  74. static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255 */ };
  75. #else
  76. #define AVAILABLE_TONE_PINS 1
  77. // Leave timer 0 to last.
  78. const uint8_t PROGMEM tone_pin_to_timer_PGM[] = { 2 /*, 1, 0 */ };
  79. static uint8_t tone_pins[AVAILABLE_TONE_PINS] = { 255 /*, 255, 255 */ };
  80. #endif
  81. static int8_t toneBegin(uint8_t _pin)
  82. {
  83. int8_t _timer = -1;
  84. // if we're already using the pin, the timer should be configured.
  85. for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
  86. if (tone_pins[i] == _pin) {
  87. return pgm_read_byte(tone_pin_to_timer_PGM + i);
  88. }
  89. }
  90. // search for an unused timer.
  91. for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
  92. if (tone_pins[i] == 255) {
  93. tone_pins[i] = _pin;
  94. _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
  95. break;
  96. }
  97. }
  98. if (_timer != -1)
  99. {
  100. // Set timer specific stuff
  101. // All timers in CTC mode
  102. // 8 bit timers will require changing prescalar values,
  103. // whereas 16 bit timers are set to either ck/1 or ck/64 prescalar
  104. switch (_timer)
  105. {
  106. #if !defined(__AVR_ATmega8__)
  107. case 0:
  108. // 8 bit timer
  109. TCCR0A = 0;
  110. TCCR0B = 0;
  111. bitWrite(TCCR0A, WGM01, 1);
  112. bitWrite(TCCR0B, CS00, 1);
  113. timer0_pin_port = portOutputRegister(digitalPinToPort(_pin));
  114. timer0_pin_mask = digitalPinToBitMask(_pin);
  115. break;
  116. #endif
  117. case 1:
  118. // 16 bit timer
  119. TCCR1A = 0;
  120. TCCR1B = 0;
  121. bitWrite(TCCR1B, WGM12, 1);
  122. bitWrite(TCCR1B, CS10, 1);
  123. timer1_pin_port = portOutputRegister(digitalPinToPort(_pin));
  124. timer1_pin_mask = digitalPinToBitMask(_pin);
  125. break;
  126. case 2:
  127. // 8 bit timer
  128. TCCR2A = 0;
  129. TCCR2B = 0;
  130. bitWrite(TCCR2A, WGM21, 1);
  131. bitWrite(TCCR2B, CS20, 1);
  132. timer2_pin_port = portOutputRegister(digitalPinToPort(_pin));
  133. timer2_pin_mask = digitalPinToBitMask(_pin);
  134. break;
  135. #if defined(__AVR_ATmega1280__)
  136. case 3:
  137. // 16 bit timer
  138. TCCR3A = 0;
  139. TCCR3B = 0;
  140. bitWrite(TCCR3B, WGM32, 1);
  141. bitWrite(TCCR3B, CS30, 1);
  142. timer3_pin_port = portOutputRegister(digitalPinToPort(_pin));
  143. timer3_pin_mask = digitalPinToBitMask(_pin);
  144. break;
  145. case 4:
  146. // 16 bit timer
  147. TCCR4A = 0;
  148. TCCR4B = 0;
  149. bitWrite(TCCR4B, WGM42, 1);
  150. bitWrite(TCCR4B, CS40, 1);
  151. timer4_pin_port = portOutputRegister(digitalPinToPort(_pin));
  152. timer4_pin_mask = digitalPinToBitMask(_pin);
  153. break;
  154. case 5:
  155. // 16 bit timer
  156. TCCR5A = 0;
  157. TCCR5B = 0;
  158. bitWrite(TCCR5B, WGM52, 1);
  159. bitWrite(TCCR5B, CS50, 1);
  160. timer5_pin_port = portOutputRegister(digitalPinToPort(_pin));
  161. timer5_pin_mask = digitalPinToBitMask(_pin);
  162. break;
  163. #endif
  164. }
  165. }
  166. return _timer;
  167. }
  168. // frequency (in hertz) and duration (in milliseconds).
  169. void tone(uint8_t _pin, unsigned int frequency, unsigned long duration)
  170. {
  171. uint8_t prescalarbits = 0b001;
  172. long toggle_count = 0;
  173. uint32_t ocr = 0;
  174. int8_t _timer;
  175. _timer = toneBegin(_pin);
  176. if (_timer >= 0)
  177. {
  178. // Set the pinMode as OUTPUT
  179. pinMode(_pin, OUTPUT);
  180. // if we are using an 8 bit timer, scan through prescalars to find the best fit
  181. if (_timer == 0 || _timer == 2)
  182. {
  183. ocr = F_CPU / frequency / 2 - 1;
  184. prescalarbits = 0b001; // ck/1: same for both timers
  185. if (ocr > 255)
  186. {
  187. ocr = F_CPU / frequency / 2 / 8 - 1;
  188. prescalarbits = 0b010; // ck/8: same for both timers
  189. if (_timer == 2 && ocr > 255)
  190. {
  191. ocr = F_CPU / frequency / 2 / 32 - 1;
  192. prescalarbits = 0b011;
  193. }
  194. if (ocr > 255)
  195. {
  196. ocr = F_CPU / frequency / 2 / 64 - 1;
  197. prescalarbits = _timer == 0 ? 0b011 : 0b100;
  198. if (_timer == 2 && ocr > 255)
  199. {
  200. ocr = F_CPU / frequency / 2 / 128 - 1;
  201. prescalarbits = 0b101;
  202. }
  203. if (ocr > 255)
  204. {
  205. ocr = F_CPU / frequency / 2 / 256 - 1;
  206. prescalarbits = _timer == 0 ? 0b100 : 0b110;
  207. if (ocr > 255)
  208. {
  209. // can't do any better than /1024
  210. ocr = F_CPU / frequency / 2 / 1024 - 1;
  211. prescalarbits = _timer == 0 ? 0b101 : 0b111;
  212. }
  213. }
  214. }
  215. }
  216. #if !defined(__AVR_ATmega8__)
  217. if (_timer == 0)
  218. TCCR0B = prescalarbits;
  219. else
  220. #endif
  221. TCCR2B = prescalarbits;
  222. }
  223. else
  224. {
  225. // two choices for the 16 bit timers: ck/1 or ck/64
  226. ocr = F_CPU / frequency / 2 - 1;
  227. prescalarbits = 0b001;
  228. if (ocr > 0xffff)
  229. {
  230. ocr = F_CPU / frequency / 2 / 64 - 1;
  231. prescalarbits = 0b011;
  232. }
  233. if (_timer == 1)
  234. TCCR1B = (TCCR1B & 0b11111000) | prescalarbits;
  235. #if defined(__AVR_ATmega1280__)
  236. else if (_timer == 3)
  237. TCCR3B = (TCCR3B & 0b11111000) | prescalarbits;
  238. else if (_timer == 4)
  239. TCCR4B = (TCCR4B & 0b11111000) | prescalarbits;
  240. else if (_timer == 5)
  241. TCCR5B = (TCCR5B & 0b11111000) | prescalarbits;
  242. #endif
  243. }
  244. // Calculate the toggle count
  245. if (duration > 0)
  246. {
  247. toggle_count = 2 * frequency * duration / 1000;
  248. }
  249. else
  250. {
  251. toggle_count = -1;
  252. }
  253. // Set the OCR for the given timer,
  254. // set the toggle count,
  255. // then turn on the interrupts
  256. switch (_timer)
  257. {
  258. #if !defined(__AVR_ATmega8__)
  259. case 0:
  260. OCR0A = ocr;
  261. timer0_toggle_count = toggle_count;
  262. bitWrite(TIMSK0, OCIE0A, 1);
  263. break;
  264. #endif
  265. case 1:
  266. OCR1A = ocr;
  267. timer1_toggle_count = toggle_count;
  268. bitWrite(TIMSK1, OCIE1A, 1);
  269. break;
  270. case 2:
  271. OCR2A = ocr;
  272. timer2_toggle_count = toggle_count;
  273. bitWrite(TIMSK2, OCIE2A, 1);
  274. break;
  275. #if defined(__AVR_ATmega1280__)
  276. case 3:
  277. OCR3A = ocr;
  278. timer3_toggle_count = toggle_count;
  279. bitWrite(TIMSK3, OCIE3A, 1);
  280. break;
  281. case 4:
  282. OCR4A = ocr;
  283. timer4_toggle_count = toggle_count;
  284. bitWrite(TIMSK4, OCIE4A, 1);
  285. break;
  286. case 5:
  287. OCR5A = ocr;
  288. timer5_toggle_count = toggle_count;
  289. bitWrite(TIMSK5, OCIE5A, 1);
  290. break;
  291. #endif
  292. }
  293. }
  294. }
  295. void noTone(uint8_t _pin)
  296. {
  297. int8_t _timer = -1;
  298. for (int i = 0; i < AVAILABLE_TONE_PINS; i++) {
  299. if (tone_pins[i] == _pin) {
  300. _timer = pgm_read_byte(tone_pin_to_timer_PGM + i);
  301. tone_pins[i] = 255;
  302. }
  303. }
  304. switch (_timer)
  305. {
  306. #if defined(__AVR_ATmega8__)
  307. case 1:
  308. bitWrite(TIMSK1, OCIE1A, 0);
  309. break;
  310. case 2:
  311. bitWrite(TIMSK2, OCIE2A, 0);
  312. break;
  313. #else
  314. case 0:
  315. TIMSK0 = 0;
  316. break;
  317. case 1:
  318. TIMSK1 = 0;
  319. break;
  320. case 2:
  321. TIMSK2 = 0;
  322. break;
  323. #endif
  324. #if defined(__AVR_ATmega1280__)
  325. case 3:
  326. TIMSK3 = 0;
  327. break;
  328. case 4:
  329. TIMSK4 = 0;
  330. break;
  331. case 5:
  332. TIMSK5 = 0;
  333. break;
  334. #endif
  335. }
  336. digitalWrite(_pin, 0);
  337. }
  338. #if 0
  339. #if !defined(__AVR_ATmega8__)
  340. ISR(TIMER0_COMPA_vect)
  341. {
  342. if (timer0_toggle_count != 0)
  343. {
  344. // toggle the pin
  345. *timer0_pin_port ^= timer0_pin_mask;
  346. if (timer0_toggle_count > 0)
  347. timer0_toggle_count--;
  348. }
  349. else
  350. {
  351. TIMSK0 = 0; // disable the interrupt
  352. *timer0_pin_port &= ~(timer0_pin_mask); // keep pin low after stop
  353. }
  354. }
  355. #endif
  356. ISR(TIMER1_COMPA_vect)
  357. {
  358. if (timer1_toggle_count != 0)
  359. {
  360. // toggle the pin
  361. *timer1_pin_port ^= timer1_pin_mask;
  362. if (timer1_toggle_count > 0)
  363. timer1_toggle_count--;
  364. }
  365. else
  366. {
  367. TIMSK1 = 0; // disable the interrupt
  368. *timer1_pin_port &= ~(timer1_pin_mask); // keep pin low after stop
  369. }
  370. }
  371. #endif
  372. ISR(TIMER2_COMPA_vect)
  373. {
  374. if (timer2_toggle_count != 0)
  375. {
  376. // toggle the pin
  377. *timer2_pin_port ^= timer2_pin_mask;
  378. if (timer2_toggle_count > 0)
  379. timer2_toggle_count--;
  380. }
  381. else
  382. {
  383. TIMSK2 = 0; // disable the interrupt
  384. *timer2_pin_port &= ~(timer2_pin_mask); // keep pin low after stop
  385. }
  386. }
  387. //#if defined(__AVR_ATmega1280__)
  388. #if 0
  389. ISR(TIMER3_COMPA_vect)
  390. {
  391. if (timer3_toggle_count != 0)
  392. {
  393. // toggle the pin
  394. *timer3_pin_port ^= timer3_pin_mask;
  395. if (timer3_toggle_count > 0)
  396. timer3_toggle_count--;
  397. }
  398. else
  399. {
  400. TIMSK3 = 0; // disable the interrupt
  401. *timer3_pin_port &= ~(timer3_pin_mask); // keep pin low after stop
  402. }
  403. }
  404. ISR(TIMER4_COMPA_vect)
  405. {
  406. if (timer4_toggle_count != 0)
  407. {
  408. // toggle the pin
  409. *timer4_pin_port ^= timer4_pin_mask;
  410. if (timer4_toggle_count > 0)
  411. timer4_toggle_count--;
  412. }
  413. else
  414. {
  415. TIMSK4 = 0; // disable the interrupt
  416. *timer4_pin_port &= ~(timer4_pin_mask); // keep pin low after stop
  417. }
  418. }
  419. ISR(TIMER5_COMPA_vect)
  420. {
  421. if (timer5_toggle_count != 0)
  422. {
  423. // toggle the pin
  424. *timer5_pin_port ^= timer5_pin_mask;
  425. if (timer5_toggle_count > 0)
  426. timer5_toggle_count--;
  427. }
  428. else
  429. {
  430. TIMSK5 = 0; // disable the interrupt
  431. *timer5_pin_port &= ~(timer5_pin_mask); // keep pin low after stop
  432. }
  433. }
  434. #endif