Skip to content

Commit 724d73b

Browse files
authored
Merge pull request #286 from adafruit/develop
added Tone()
2 parents e690442 + e2c329a commit 724d73b

File tree

4 files changed

+234
-1
lines changed

4 files changed

+234
-1
lines changed

changelog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Adafruit nRF52 Arduino Core Changelog
22

3+
# 0.11.1
4+
5+
- Refactor Ada Callback, use ISCR to detect isr context. Use function instead of macro
6+
- Implement #240 run travis test with all example sketches
7+
- Fix auto-start of advertising when central is connected, thanks to @ogatatsu PR #268
8+
- Added Tone()/noTone() functions
9+
310
# 0.11.0
411

512
- Rework USB driver to support Adafruit_TinyUSB library (support HID and MSC)

cores/nRF5/Arduino.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ void suspendLoop(void);
5050
#ifdef __cplusplus
5151
#include "WCharacter.h"
5252
#include "WString.h"
53-
// #include "Tone.h"
53+
#include "Tone.h"
5454
#include "WMath.h"
5555
#include "HardwareSerial.h"
5656
#include "pulse.h"

cores/nRF5/Tone.cpp

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
/* Tone.cpp
2+
3+
A Tone Generator Library
4+
5+
Written by Brett Hagman
6+
7+
This library is free software; you can redistribute it and/or
8+
modify it under the terms of the GNU Lesser General Public
9+
License as published by the Free Software Foundation; either
10+
version 2.1 of the License, or (at your option) any later version.
11+
12+
This library is distributed in the hope that it will be useful,
13+
but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15+
Lesser General Public License for more details.
16+
17+
You should have received a copy of the GNU Lesser General Public
18+
License along with this library; if not, write to the Free Software
19+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20+
21+
Version Modified By Date Comments
22+
------- ----------- -------- --------
23+
0001 B Hagman 09/08/02 Initial coding
24+
0002 B Hagman 09/08/18 Multiple pins
25+
0003 B Hagman 09/08/18 Moved initialization from constructor to begin()
26+
0004 B Hagman 09/09/26 Fixed problems with ATmega8
27+
0005 B Hagman 09/11/23 Scanned prescalars for best fit on 8 bit timers
28+
09/11/25 Changed pin toggle method to XOR
29+
09/11/25 Fixed timer0 from being excluded
30+
0006 D Mellis 09/12/29 Replaced objects with functions
31+
0007 M Sproul 10/08/29 Changed #ifdefs from cpu to register
32+
0008 S Kanemoto 12/06/22 Fixed for Leonardo by @maris_HY
33+
0009 Arduino.org 15/06/30 Add M0/M0 Pro support
34+
0010 Arduino.org 16/07/27 Added Arduino Primo support
35+
*************************************************/
36+
37+
38+
#include "Tone.h"
39+
#include "WVariant.h"
40+
41+
unsigned long int count_duration=0;
42+
volatile bool no_stop = false;
43+
uint8_t pin_sound=0;
44+
45+
46+
void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
47+
{
48+
unsigned int time_per=0;
49+
50+
if((frequency < 20) | (frequency > 25000)) return;
51+
52+
53+
float per=float(1)/frequency;
54+
time_per=per/0.000008;
55+
unsigned int duty=time_per/2;
56+
if(duration > 0){
57+
no_stop = false;
58+
float mil=float(duration)/1000;
59+
if(per>mil)
60+
count_duration=1;
61+
else
62+
count_duration= mil/per;
63+
}
64+
else
65+
no_stop = true;
66+
67+
// Configure PWM
68+
static uint16_t seq_values[]={0};
69+
//In each value, the most significant bit (15) determines the polarity of the output
70+
//0x8000 is MSB = 1
71+
seq_values[0]= duty | 0x8000;
72+
nrf_pwm_sequence_t const seq={
73+
seq_values,
74+
NRF_PWM_VALUES_LENGTH(seq_values),
75+
0,
76+
0
77+
};
78+
79+
#if 0
80+
//assign pin to pwm channel - look at WVariant.h for details about ulPWMChannel attribute
81+
uint8_t pwm_type=g_APinDescription[pin].ulPWMChannel;
82+
if(pwm_type == NOT_ON_PWM)
83+
return;
84+
85+
uint32_t pins[NRF_PWM_CHANNEL_COUNT]={NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED};
86+
pins[pwm_type & 0x0F]=g_APinDescription[pin].ulPin;
87+
IRQn_Type IntNo = PWM0_IRQn;
88+
NRF_PWM_Type * PWMInstance = NRF_PWM0;
89+
switch(pwm_type &0xF0){
90+
case 16://0x10
91+
PWMInstance = NRF_PWM1;
92+
IntNo = PWM1_IRQn;
93+
break;
94+
case 32://0x20
95+
PWMInstance = NRF_PWM2;
96+
IntNo = PWM2_IRQn;
97+
break;
98+
}
99+
#else
100+
// Use fixed PWM2, TODO could conflict with other usage
101+
uint32_t pins[NRF_PWM_CHANNEL_COUNT]={NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED};
102+
pins[0] = g_ADigitalPinMap[pin];
103+
104+
IRQn_Type IntNo = PWM2_IRQn;
105+
NRF_PWM_Type * PWMInstance = NRF_PWM2;
106+
#endif
107+
108+
nrf_pwm_pins_set(PWMInstance, pins);
109+
nrf_pwm_enable(PWMInstance);
110+
nrf_pwm_configure(PWMInstance, NRF_PWM_CLK_125kHz, NRF_PWM_MODE_UP, time_per);
111+
nrf_pwm_decoder_set(PWMInstance, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO);
112+
nrf_pwm_sequence_set(PWMInstance, 0, &seq);
113+
nrf_pwm_shorts_enable(PWMInstance, NRF_PWM_SHORT_SEQEND0_STOP_MASK);
114+
115+
// enable interrupt
116+
nrf_pwm_event_clear(PWMInstance, NRF_PWM_EVENT_PWMPERIODEND);
117+
nrf_pwm_int_enable(PWMInstance, NRF_PWM_INT_PWMPERIODEND_MASK);
118+
NVIC_SetPriority(IntNo, 6); //low priority
119+
NVIC_ClearPendingIRQ(IntNo);
120+
NVIC_EnableIRQ(IntNo);
121+
}
122+
123+
124+
void noTone(uint8_t pin)
125+
{
126+
#if 0
127+
uint8_t pwm_type=g_APinDescription[pin].ulPWMChannel;
128+
NRF_PWM_Type * PWMInstance = NRF_PWM0;
129+
switch(pwm_type &0xF0){
130+
case 16://0x10
131+
PWMInstance = NRF_PWM1;
132+
break;
133+
case 32://0x20
134+
PWMInstance = NRF_PWM2;
135+
break;
136+
}
137+
#else
138+
NRF_PWM_Type * PWMInstance = NRF_PWM2;
139+
#endif
140+
141+
nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_STOP);
142+
nrf_pwm_disable(PWMInstance);
143+
}
144+
145+
#ifdef __cplusplus
146+
extern "C"{
147+
#endif
148+
149+
#if 0
150+
void PWM0_IRQHandler(void){
151+
nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_PWMPERIODEND);
152+
if(!no_stop){
153+
count_duration--;
154+
if(count_duration == 0)
155+
noTone(pin_sound);
156+
else
157+
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
158+
}
159+
else
160+
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
161+
}
162+
163+
void PWM1_IRQHandler(void){
164+
nrf_pwm_event_clear(NRF_PWM1, NRF_PWM_EVENT_PWMPERIODEND);
165+
if(!no_stop){
166+
count_duration--;
167+
if(count_duration == 0)
168+
noTone(pin_sound);
169+
else
170+
nrf_pwm_task_trigger(NRF_PWM1, NRF_PWM_TASK_SEQSTART0);
171+
}
172+
else
173+
nrf_pwm_task_trigger(NRF_PWM1, NRF_PWM_TASK_SEQSTART0);
174+
}
175+
#endif
176+
177+
void PWM2_IRQHandler(void){
178+
nrf_pwm_event_clear(NRF_PWM2, NRF_PWM_EVENT_PWMPERIODEND);
179+
if(!no_stop){
180+
count_duration--;
181+
if(count_duration == 0)
182+
noTone(pin_sound);
183+
else
184+
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
185+
}
186+
else
187+
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
188+
}
189+
190+
#ifdef __cplusplus
191+
}
192+
#endif

cores/nRF5/Tone.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
Copyright (c) 2016 Arduino. All right reserved.
3+
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+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#ifndef _WIRING_TONE_
20+
#define _WIRING_TONE_
21+
22+
#include <stdint.h>
23+
#include <stdlib.h>
24+
#include <math.h>
25+
#include "wiring_digital.h"
26+
#include "nrf_pwm.h"
27+
28+
29+
void tone(uint8_t pin, unsigned int frequency, unsigned long duration = 0);
30+
void noTone(uint8_t pin);
31+
32+
33+
34+
#endif /* _WIRING_TONE_ */

0 commit comments

Comments
 (0)