Skip to content

Commit 782acdb

Browse files
authored
Merge pull request #287 from adafruit/master
catch up to master with tone()
2 parents 2d9f35b + 1f433a9 commit 782acdb

File tree

4 files changed

+236
-1
lines changed

4 files changed

+236
-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: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
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+
nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_SEQSTART0);
123+
}
124+
125+
126+
void noTone(uint8_t pin)
127+
{
128+
#if 0
129+
uint8_t pwm_type=g_APinDescription[pin].ulPWMChannel;
130+
NRF_PWM_Type * PWMInstance = NRF_PWM0;
131+
switch(pwm_type &0xF0){
132+
case 16://0x10
133+
PWMInstance = NRF_PWM1;
134+
break;
135+
case 32://0x20
136+
PWMInstance = NRF_PWM2;
137+
break;
138+
}
139+
#else
140+
NRF_PWM_Type * PWMInstance = NRF_PWM2;
141+
#endif
142+
143+
nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_STOP);
144+
nrf_pwm_disable(PWMInstance);
145+
}
146+
147+
#ifdef __cplusplus
148+
extern "C"{
149+
#endif
150+
151+
#if 0
152+
void PWM0_IRQHandler(void){
153+
nrf_pwm_event_clear(NRF_PWM0, NRF_PWM_EVENT_PWMPERIODEND);
154+
if(!no_stop){
155+
count_duration--;
156+
if(count_duration == 0)
157+
noTone(pin_sound);
158+
else
159+
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
160+
}
161+
else
162+
nrf_pwm_task_trigger(NRF_PWM0, NRF_PWM_TASK_SEQSTART0);
163+
}
164+
165+
void PWM1_IRQHandler(void){
166+
nrf_pwm_event_clear(NRF_PWM1, NRF_PWM_EVENT_PWMPERIODEND);
167+
if(!no_stop){
168+
count_duration--;
169+
if(count_duration == 0)
170+
noTone(pin_sound);
171+
else
172+
nrf_pwm_task_trigger(NRF_PWM1, NRF_PWM_TASK_SEQSTART0);
173+
}
174+
else
175+
nrf_pwm_task_trigger(NRF_PWM1, NRF_PWM_TASK_SEQSTART0);
176+
}
177+
#endif
178+
179+
void PWM2_IRQHandler(void){
180+
nrf_pwm_event_clear(NRF_PWM2, NRF_PWM_EVENT_PWMPERIODEND);
181+
if(!no_stop){
182+
count_duration--;
183+
if(count_duration == 0)
184+
noTone(pin_sound);
185+
else
186+
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
187+
}
188+
else
189+
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
190+
}
191+
192+
#ifdef __cplusplus
193+
}
194+
#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)