Gordons Projects

--> Projects Top-Level GIT

wiringPi Version 2 - First commit (of v2)
[wiringPi] / wiringPi / softTone.c
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
29 #include <stdio.h>
30 #include <pthread.h>
31
32 #include "wiringPi.h"
33 #include "softTone.h"
34
35 #define MAX_PINS        64
36
37 #define PULSE_TIME      100
38
39 static int freqs [MAX_PINS] ;
40
41 static int newPin = -1 ;
42
43
44 /*
45  * softToneThread:
46  *      Thread to do the actual PWM output
47  *********************************************************************************
48  */
49
50 static PI_THREAD (softToneThread)
51 {
52   int pin, freq, halfPeriod ;
53
54   pin    = newPin ;
55   newPin = -1 ;
56
57   piHiPri (50) ;
58
59   for (;;)
60   {
61     freq = freqs [pin] ;
62     if (freq == 0)
63       delay (1) ;
64     else
65     {
66       halfPeriod = 500000 / freq ;
67
68       digitalWrite (pin, HIGH) ;
69       delayMicroseconds (halfPeriod) ;
70
71       digitalWrite (pin, LOW) ;
72       delayMicroseconds (halfPeriod) ;
73     }
74   }
75
76   return NULL ;
77 }
78
79
80 /*
81  * softToneWrite:
82  *      Write a frequency value to the given pin
83  *********************************************************************************
84  */
85
86 void softToneWrite (int pin, int freq)
87 {
88   pin &= 63 ;
89
90   /**/ if (freq < 0)
91     freq = 0 ;
92   else if (freq > 5000) // Max 5KHz
93     freq = 5000 ;
94
95   freqs [pin] = freq ;
96 }
97
98
99 /*
100  * softToneCreate:
101  *      Create a new tone thread.
102  *********************************************************************************
103  */
104
105 int softToneCreate (int pin)
106 {
107   int res ;
108
109   pinMode      (pin, OUTPUT) ;
110   digitalWrite (pin, LOW) ;
111
112   freqs [pin] = 0 ;
113
114   newPin = pin ;
115   res = piThreadCreate (softToneThread) ;
116
117   while (newPin != -1)
118     delay (1) ;
119
120   return res ;
121 }