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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. /*
  2. * softTone.c:
  3. * For that authentic retro sound...
  4. * Er... A little experiment to produce tones out of a Pi using
  5. * one (or 2) GPIO pins and a piezeo "speaker" element.
  6. * (Or a high impedance speaker, but don'y blame me if you blow-up
  7. * the GPIO pins!)
  8. * Copyright (c) 2012 Gordon Henderson
  9. ***********************************************************************
  10. * This file is part of wiringPi:
  11. * https://projects.drogon.net/raspberry-pi/wiringpi/
  12. *
  13. * wiringPi is free software: you can redistribute it and/or modify
  14. * it under the terms of the GNU Lesser General Public License as
  15. * published by the Free Software Foundation, either version 3 of the
  16. * License, or (at your option) any later version.
  17. *
  18. * wiringPi is distributed in the hope that it will be useful,
  19. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  21. * GNU Lesser General Public License for more details.
  22. *
  23. * You should have received a copy of the GNU Lesser General Public
  24. * License along with wiringPi.
  25. * If not, see <http://www.gnu.org/licenses/>.
  26. ***********************************************************************
  27. */
  28. #include <stdio.h>
  29. #include <pthread.h>
  30. #include "wiringPi.h"
  31. #include "softTone.h"
  32. #define MAX_PINS 64
  33. #define PULSE_TIME 100
  34. static int freqs [MAX_PINS] ;
  35. static pthread_t threads [MAX_PINS] ;
  36. static int newPin = -1 ;
  37. /*
  38. * softToneThread:
  39. * Thread to do the actual PWM output
  40. *********************************************************************************
  41. */
  42. static PI_THREAD (softToneThread)
  43. {
  44. int pin, freq, halfPeriod ;
  45. struct sched_param param ;
  46. param.sched_priority = sched_get_priority_max (SCHED_RR) ;
  47. pthread_setschedparam (pthread_self (), SCHED_RR, &param) ;
  48. pin = newPin ;
  49. newPin = -1 ;
  50. piHiPri (50) ;
  51. for (;;)
  52. {
  53. freq = freqs [pin] ;
  54. if (freq == 0)
  55. delay (1) ;
  56. else
  57. {
  58. halfPeriod = 500000 / freq ;
  59. digitalWrite (pin, HIGH) ;
  60. delayMicroseconds (halfPeriod) ;
  61. digitalWrite (pin, LOW) ;
  62. delayMicroseconds (halfPeriod) ;
  63. }
  64. }
  65. return NULL ;
  66. }
  67. /*
  68. * softToneWrite:
  69. * Write a frequency value to the given pin
  70. *********************************************************************************
  71. */
  72. void softToneWrite (int pin, int freq)
  73. {
  74. pin &= 63 ;
  75. /**/ if (freq < 0)
  76. freq = 0 ;
  77. else if (freq > 5000) // Max 5KHz
  78. freq = 5000 ;
  79. freqs [pin] = freq ;
  80. }
  81. /*
  82. * softToneCreate:
  83. * Create a new tone thread.
  84. *********************************************************************************
  85. */
  86. int softToneCreate (int pin)
  87. {
  88. int res ;
  89. pthread_t myThread ;
  90. pinMode (pin, OUTPUT) ;
  91. digitalWrite (pin, LOW) ;
  92. if (threads [pin] != 0)
  93. return -1 ;
  94. freqs [pin] = 0 ;
  95. newPin = pin ;
  96. res = pthread_create (&myThread, NULL, softToneThread, NULL) ;
  97. while (newPin != -1)
  98. delay (1) ;
  99. threads [pin] = myThread ;
  100. return res ;
  101. }
  102. /*
  103. * softToneStop:
  104. * Stop an existing softTone thread
  105. *********************************************************************************
  106. */
  107. void softToneStop (int pin)
  108. {
  109. if (threads [pin] != 0)
  110. {
  111. pthread_cancel (threads [pin]) ;
  112. pthread_join (threads [pin], NULL) ;
  113. threads [pin] = 0 ;
  114. digitalWrite (pin, LOW) ;
  115. }
  116. }