Skip to content

Commit d3f313b

Browse files
committed
Use HwPWM ownership abstraction
1 parent 38abc94 commit d3f313b

File tree

1 file changed

+43
-16
lines changed

1 file changed

+43
-16
lines changed

cores/nRF5/Tone.cpp

Lines changed: 43 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,35 +34,54 @@ Version Modified By Date Comments
3434
0010 Arduino.org 16/07/27 Added Arduino Primo support
3535
*************************************************/
3636

37-
37+
#include "Arduino.h"
3838
#include "Tone.h"
3939
#include "WVariant.h"
4040

4141
unsigned long int count_duration=0;
4242
volatile bool no_stop = false;
4343
uint8_t pin_sound=0;
44+
static uintptr_t _toneToken = (uintptr_t)(&_toneToken);
4445

4546

4647
void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
4748
{
49+
static_assert(sizeof(unsigned long) == sizeof(uint32_t));
50+
4851
unsigned int time_per=0;
49-
50-
if((frequency < 20) | (frequency > 25000)) return;
51-
52+
53+
// limit frequency to reasonable audible range
54+
if((frequency < 20) | (frequency > 25000)) {
55+
LOG_LV1("TON", "frequency outside range [20..25000] -- ignoring");
56+
return;
57+
}
58+
59+
// Use fixed PWM2 (due to need to connect interrupt)
60+
if (!HwPWMx[2]->isOwner(_toneToken) &&
61+
!HwPWMx[2]->takeOwnership(_toneToken)) {
62+
LOG_LV1("TON", "unable to allocate PWM2 to Tone");
63+
return;
64+
}
5265

5366
float per=float(1)/frequency;
5467
time_per=per/0.000008;
5568
unsigned int duty=time_per/2;
56-
if(duration > 0){
69+
if(duration > 0) {
5770
no_stop = false;
5871
float mil=float(duration)/1000;
59-
if(per>mil)
72+
if(per>mil) {
6073
count_duration=1;
61-
else
74+
} else {
6275
count_duration= mil/per;
63-
}
64-
else
76+
}
77+
} else {
6578
no_stop = true;
79+
}
80+
81+
// PWM configuration depends on the following:
82+
// [ ] time_per
83+
// [ ] duty ( via seq )
84+
// [ ] pin ( via pins[0] )
6685

6786
// Configure PWM
6887
static uint16_t seq_values[]={0};
@@ -97,6 +116,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
97116
break;
98117
}
99118
#else
119+
100120
// Use fixed PWM2, TODO could conflict with other usage
101121
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};
102122
pins[0] = g_ADigitalPinMap[pin];
@@ -110,7 +130,7 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
110130
nrf_pwm_configure(PWMInstance, NRF_PWM_CLK_125kHz, NRF_PWM_MODE_UP, time_per);
111131
nrf_pwm_decoder_set(PWMInstance, NRF_PWM_LOAD_COMMON, NRF_PWM_STEP_AUTO);
112132
nrf_pwm_sequence_set(PWMInstance, 0, &seq);
113-
nrf_pwm_shorts_enable(PWMInstance, NRF_PWM_SHORT_SEQEND0_STOP_MASK);
133+
nrf_pwm_shorts_enable(PWMInstance, NRF_PWM_SHORT_SEQEND0_STOP_MASK); // shortcut for when SEQ0 ends, PWM output will automatically stop
114134

115135
// enable interrupt
116136
nrf_pwm_event_clear(PWMInstance, NRF_PWM_EVENT_PWMPERIODEND);
@@ -125,6 +145,11 @@ void tone(uint8_t pin, unsigned int frequency, unsigned long duration)
125145

126146
void noTone(uint8_t pin)
127147
{
148+
if (!HwPWMx[2]->isOwner(_toneToken)) {
149+
LOG_LV1("TON", "Attempt to set noTone when not the owner of the PWM peripheral. Ignoring call....");
150+
return;
151+
}
152+
128153
#if 0
129154
uint8_t pwm_type=g_APinDescription[pin].ulPWMChannel;
130155
NRF_PWM_Type * PWMInstance = NRF_PWM0;
@@ -180,13 +205,15 @@ void PWM2_IRQHandler(void){
180205
nrf_pwm_event_clear(NRF_PWM2, NRF_PWM_EVENT_PWMPERIODEND);
181206
if(!no_stop){
182207
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
208+
if(count_duration == 0) {
209+
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_STOP);
210+
nrf_pwm_disable(NRF_PWM2);
211+
} else {
212+
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
213+
}
214+
} else {
189215
nrf_pwm_task_trigger(NRF_PWM2, NRF_PWM_TASK_SEQSTART0);
216+
}
190217
}
191218

192219
#ifdef __cplusplus

0 commit comments

Comments
 (0)