Statistics
| Branch: | Revision:

ddr4s / fw / wiringPi / wiringPi / softTone.c @ 32:cadb9025f1e0

History | View | Annotate | Download (3.29 KB)

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
static pthread_t threads [MAX_PINS] ;
41

    
42
static int newPin = -1 ;
43

    
44

    
45
/*
46
 * softToneThread:
47
 *        Thread to do the actual PWM output
48
 *********************************************************************************
49
 */
50

    
51
static PI_THREAD (softToneThread)
52
{
53
  int pin, freq, halfPeriod ;
54
  struct sched_param param ;
55

    
56
  param.sched_priority = sched_get_priority_max (SCHED_RR) ;
57
  pthread_setschedparam (pthread_self (), SCHED_RR, &param) ;
58

    
59
  pin    = newPin ;
60
  newPin = -1 ;
61

    
62
  piHiPri (50) ;
63

    
64
  for (;;)
65
  {
66
    freq = freqs [pin] ;
67
    if (freq == 0)
68
      delay (1) ;
69
    else
70
    {
71
      halfPeriod = 500000 / freq ;
72

    
73
      digitalWrite (pin, HIGH) ;
74
      delayMicroseconds (halfPeriod) ;
75

    
76
      digitalWrite (pin, LOW) ;
77
      delayMicroseconds (halfPeriod) ;
78
    }
79
  }
80

    
81
  return NULL ;
82
}
83

    
84

    
85
/*
86
 * softToneWrite:
87
 *        Write a frequency value to the given pin
88
 *********************************************************************************
89
 */
90

    
91
void softToneWrite (int pin, int freq)
92
{
93
  pin &= 63 ;
94

    
95
  /**/ if (freq < 0)
96
    freq = 0 ;
97
  else if (freq > 5000)        // Max 5KHz
98
    freq = 5000 ;
99

    
100
  freqs [pin] = freq ;
101
}
102

    
103

    
104
/*
105
 * softToneCreate:
106
 *        Create a new tone thread.
107
 *********************************************************************************
108
 */
109

    
110
int softToneCreate (int pin)
111
{
112
  int res ;
113
  pthread_t myThread ;
114

    
115
  pinMode      (pin, OUTPUT) ;
116
  digitalWrite (pin, LOW) ;
117

    
118
  if (threads [pin] != 0)
119
    return -1 ;
120

    
121
  freqs [pin] = 0 ;
122

    
123
  newPin = pin ;
124
  res    = pthread_create (&myThread, NULL, softToneThread, NULL) ;
125

    
126
  while (newPin != -1)
127
    delay (1) ;
128

    
129
  threads [pin] = myThread ;
130

    
131
  return res ;
132
}
133

    
134

    
135
/*
136
 * softToneStop:
137
 *        Stop an existing softTone thread
138
 *********************************************************************************
139
 */
140

    
141
void softToneStop (int pin)
142
{
143
  if (threads [pin] != 0)
144
  {
145
    pthread_cancel (threads [pin]) ;
146
    pthread_join   (threads [pin], NULL) ;
147
    threads [pin] = 0 ;
148
    digitalWrite (pin, LOW) ;
149
  }
150
}