Skip to content

Commit d7cd2d6

Browse files
authored
Merge branch 'master' into development
2 parents d117a7a + 32777b9 commit d7cd2d6

File tree

4 files changed

+176
-2
lines changed

4 files changed

+176
-2
lines changed

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ sentence=Allows Arduino/Genuino boards to control a variety of servo motors.
66
paragraph=This library can control a great number of servos.<br />It makes careful use of timers: the library can control 12 servos using only 1 timer.<br />On the Arduino Due you can control up to 60 servos.<br />
77
category=Device Control
88
url=http://www.arduino.cc/en/Reference/Servo
9-
architectures=avr,sam,samd,stm32f4
9+
architectures=avr,sam,samd,nrf52,stm32f4

src/Servo.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@
6767
#include "samd/ServoTimers.h"
6868
#elif defined(ARDUINO_ARCH_STM32F4)
6969
#include "stm32f4/ServoTimers.h"
70+
#elif defined(ARDUINO_ARCH_NRF52)
71+
#include "nrf52/ServoTimers.h"
7072
#else
71-
#error "This library only supports boards with an AVR, SAM, SAMD or STM32F4 processor."
73+
#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor."
7274
#endif
7375

7476
#define Servo_VERSION 2 // software version of this library

src/nrf52/Servo.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
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. See the GNU
12+
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+
#if defined(ARDUINO_ARCH_NRF52)
20+
21+
#include <Arduino.h>
22+
#include <Servo.h>
23+
24+
25+
static servo_t servos[MAX_SERVOS]; // static array of servo structures
26+
27+
uint8_t ServoCount = 0; // the total number of attached servos
28+
29+
30+
31+
uint32_t group_pins[3][NRF_PWM_CHANNEL_COUNT]={{NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}, {NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED, NRF_PWM_PIN_NOT_CONNECTED}};
32+
static uint16_t seq_values[3][NRF_PWM_CHANNEL_COUNT]={{0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}};
33+
34+
Servo::Servo()
35+
{
36+
if (ServoCount < MAX_SERVOS) {
37+
this->servoIndex = ServoCount++; // assign a servo index to this instance
38+
} else {
39+
this->servoIndex = INVALID_SERVO; // too many servos
40+
}
41+
42+
}
43+
44+
uint8_t Servo::attach(int pin)
45+
{
46+
47+
return this->attach(pin, 0, 2500);
48+
}
49+
50+
51+
uint8_t Servo::attach(int pin, int min, int max)
52+
{
53+
int servo_min, servo_max;
54+
if (this->servoIndex < MAX_SERVOS) {
55+
pinMode(pin, OUTPUT); // set servo pin to output
56+
servos[this->servoIndex].Pin.nbr = pin;
57+
58+
if(min < servo_min) min = servo_min;
59+
if (max > servo_max) max = servo_max;
60+
this->min = min;
61+
this->max = max;
62+
63+
servos[this->servoIndex].Pin.isActive = true;
64+
65+
}
66+
return this->servoIndex;
67+
}
68+
69+
void Servo::detach()
70+
{
71+
servos[this->servoIndex].Pin.isActive = false;
72+
}
73+
74+
75+
void Servo::write(int value)
76+
{
77+
if (value < 0)
78+
value = 0;
79+
else if (value > 180)
80+
value = 180;
81+
value = map(value, 0, 180, MIN_PULSE, MAX_PULSE);
82+
83+
writeMicroseconds(value);
84+
}
85+
86+
87+
void Servo::writeMicroseconds(int value)
88+
{
89+
uint8_t channel, instance;
90+
uint8_t pin = servos[this->servoIndex].Pin.nbr;
91+
//instance of pwm module is MSB - look at VWariant.h
92+
instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16;
93+
//index of pwm channel is LSB - look at VWariant.h
94+
channel=g_APinDescription[pin].ulPWMChannel & 0x0F;
95+
group_pins[instance][channel]=g_APinDescription[pin].ulPin;
96+
NRF_PWM_Type * PWMInstance = instance == 0 ? NRF_PWM0 : (instance == 1 ? NRF_PWM1 : NRF_PWM2);
97+
//configure pwm instance and enable it
98+
seq_values[instance][channel]= value | 0x8000;
99+
nrf_pwm_sequence_t const seq={
100+
seq_values[instance],
101+
NRF_PWM_VALUES_LENGTH(seq_values),
102+
0,
103+
0
104+
};
105+
nrf_pwm_pins_set(PWMInstance, group_pins[instance]);
106+
nrf_pwm_enable(PWMInstance);
107+
nrf_pwm_configure(PWMInstance, NRF_PWM_CLK_125kHz, NRF_PWM_MODE_UP, 2500); // 20ms - 50Hz
108+
nrf_pwm_decoder_set(PWMInstance, NRF_PWM_LOAD_INDIVIDUAL, NRF_PWM_STEP_AUTO);
109+
nrf_pwm_sequence_set(PWMInstance, 0, &seq);
110+
nrf_pwm_loop_set(PWMInstance, 0UL);
111+
nrf_pwm_task_trigger(PWMInstance, NRF_PWM_TASK_SEQSTART0);
112+
}
113+
114+
int Servo::read() // return the value as degrees
115+
{
116+
return map(readMicroseconds(), MIN_PULSE, MAX_PULSE, 0, 180);
117+
}
118+
119+
int Servo::readMicroseconds()
120+
{
121+
uint8_t channel, instance;
122+
uint8_t pin=servos[this->servoIndex].Pin.nbr;
123+
instance=(g_APinDescription[pin].ulPWMChannel & 0xF0)/16;
124+
channel=g_APinDescription[pin].ulPWMChannel & 0x0F;
125+
// remove the 16th bit we added before
126+
return seq_values[instance][channel] & 0x7FFF;
127+
}
128+
129+
bool Servo::attached()
130+
{
131+
return servos[this->servoIndex].Pin.isActive;
132+
}
133+
134+
#endif // ARDUINO_ARCH_NRF52

src/nrf52/ServoTimers.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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. See the GNU
12+
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+
/*
20+
* NRF52 doesn't use timer, but pwm. This file include definitions to keep
21+
* compatibility with the Servo library standards.
22+
*/
23+
24+
#ifndef __SERVO_TIMERS_H__
25+
#define __SERVO_TIMERS_H__
26+
27+
/**
28+
* NRF52 Only definitions
29+
* ---------------------
30+
*/
31+
32+
#define MIN_PULSE 55
33+
#define MAX_PULSE 284
34+
35+
// define one timer in order to have MAX_SERVOS = 12
36+
typedef enum { _timer1, _Nbr_16timers } timer16_Sequence_t;
37+
38+
#endif // __SERVO_TIMERS_H__

0 commit comments

Comments
 (0)