Skip to content

Commit 9c2d833

Browse files
Add Servo class; change Tone to use TIM7; add TIM map to wiring_private.h
1 parent effb535 commit 9c2d833

File tree

15 files changed

+443
-20
lines changed

15 files changed

+443
-20
lines changed

cores/stm32l4/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,10 @@ LDFLAGS = -L../../variants/dragonfly -Os -Wl,--gc-sections -save-temps $(EXTRAS
1212
WARNINGS = -w
1313
EXTRAS = -DSTM32L476xx -D__FPU_PRESENT=1 -march=armv7e-m -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mabi=aapcs -mslow-flash-data
1414
DEFINES = -DF_CPU=80000000L -DARDUINO=10606 -D_ARDUINO_STM32L4_DRAGONFLY -DARDUINO_ARCH_STM32L4
15-
INCLUDES = -I../../system/libstm32l4_dragonfly/CMSIS/Include -I../../system/libstm32l4_dragonfly/CMSIS/Device/ST/STM32L4xx/Include -I../../system/libstm32l4_dragonfly/USB/HAL/Inc -I../../system/libstm32l4_dragonfly/USB/Core/Inc -I../../system/libstm32l4_dragonfly/USB/Class/CDC/Inc -I../../system/libstm32l4_dragonfly/USB/Class/MSC/Inc -I../../system/libstm32l4_dragonfly/USB -I../../system/libstm32l4_dragonfly/ -I../../variants/dragonfly -I../../libraries/SPI/ -I../../libraries/Wire/ -I../../libraries/SerialFlash/ -I../../libraries/SerialFlash/util -I.
15+
INCLUDES = -I../../system/libstm32l4_dragonfly/CMSIS/Include -I../../system/libstm32l4_dragonfly/CMSIS/Device/ST/STM32L4xx/Include -I../../system/libstm32l4_dragonfly/USB/HAL/Inc -I../../system/libstm32l4_dragonfly/USB/Core/Inc -I../../system/libstm32l4_dragonfly/USB/Class/CDC/Inc -I../../system/libstm32l4_dragonfly/USB/Class/MSC/Inc -I../../system/libstm32l4_dragonfly/USB -I../../system/libstm32l4_dragonfly/ -I../../variants/dragonfly -I../../libraries/SPI/ -I../../libraries/Wire/ -I../../libraries/Servo/src/ -I.
1616

1717
SRCS = \
18+
../../libraries/Servo/src/Servo.cpp \
1819
../../libraries/SPI/SPI.cpp \
1920
../../libraries/Wire/Wire.cpp \
2021
../../variants/dragonfly/variant.cpp \
@@ -42,6 +43,7 @@ SRCS = \
4243
wiring_shift.c
4344

4445
OBJS = \
46+
../../libraries/Servo/src/Servo.o \
4547
../../libraries/SPI/SPI.o \
4648
../../libraries/Wire/Wire.o \
4749
../../variants/dragonfly/variant.o \

cores/stm32l4/Tone.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ void tone (uint32_t pin, uint32_t frequency, uint32_t duration)
5959
}
6060

6161
if (stm32l4_tone.state == TIMER_STATE_NONE) {
62-
stm32l4_timer_create(&stm32l4_tone, TIMER_INSTANCE_TIM6, STM32L4_TONE_IRQ_PRIORITY, 0);
62+
stm32l4_timer_create(&stm32l4_tone, TIMER_INSTANCE_TIM7, STM32L4_TONE_IRQ_PRIORITY, 0);
6363
}
6464

6565
GPIO_TypeDef *GPIO = g_APinDescription[pin].GPIO;

cores/stm32l4/wiring_private.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ extern "C" {
3535
#include "stm32l4_gpio.h"
3636
#include "stm32l4_uart.h"
3737
#include "stm32l4_i2c.h"
38+
#include "stm32l4_servo.h"
3839
#include "stm32l4_spi.h"
3940
#include "stm32l4_usbd_cdc.h"
4041
#include "stm32l4_system.h"
@@ -78,6 +79,23 @@ extern "C" {
7879
*
7980
************************************************************************/
8081

82+
/************************************************************************
83+
* TIM map:
84+
*
85+
* TIM1 PWM
86+
* TIM2 CAPTURE
87+
* TIM3 PWM
88+
* TIM4 PWM
89+
* TIM5 PWM
90+
* TIM6 (ADC)
91+
* TIM7 TONE
92+
* TIM8
93+
* TIM15 SERVO
94+
* TIM16 IR
95+
* TIM17 IR
96+
*
97+
************************************************************************/
98+
8199
extern stm32l4_exti_t stm32l4_exti;
82100

83101
#ifdef __cplusplus

libraries/SPI/library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name=SPI
22
version=1.0
33
author=Thomas Roell
4-
maintainer=GrumpyOldPizza <[email protected]>
4+
55
sentence=Enables the communication with devices that use the Serial Peripheral Interface (SPI) Bus. Specific implementation for STM32L4.
66
paragraph=
77
category=Communication

libraries/Servo/README.adoc

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
= Servo Library for Arduino =
2+
3+
This library allows an Arduino board to control RC (hobby) servo motors.
4+
5+
For more information about this library please visit us at
6+
http://www.arduino.cc/en/Reference/Servo
7+
8+
== License ==
9+
10+
Copyright (c) 2013 Arduino LLC. All right reserved.
11+
Copyright (c) 2009 Michael Margolis. All right reserved.
12+
13+
This library is free software; you can redistribute it and/or
14+
modify it under the terms of the GNU Lesser General Public
15+
License as published by the Free Software Foundation; either
16+
version 2.1 of the License, or (at your option) any later version.
17+
18+
This library 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 GNU
21+
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 this library; if not, write to the Free Software
25+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/*
2+
Controlling a servo position using a potentiometer (variable resistor)
3+
by Michal Rinott <http://people.interaction-ivrea.it/m.rinott>
4+
5+
modified on 8 Nov 2013
6+
by Scott Fitzgerald
7+
http://www.arduino.cc/en/Tutorial/Knob
8+
*/
9+
10+
#include <Servo.h>
11+
12+
Servo myservo; // create servo object to control a servo
13+
14+
int potpin = 0; // analog pin used to connect the potentiometer
15+
int val; // variable to read the value from the analog pin
16+
17+
void setup() {
18+
myservo.attach(9); // attaches the servo on pin 9 to the servo object
19+
}
20+
21+
void loop() {
22+
val = analogRead(potpin); // reads the value of the potentiometer (value between 0 and 1023)
23+
val = map(val, 0, 1023, 0, 180); // scale it to use it with the servo (value between 0 and 180)
24+
myservo.write(val); // sets the servo position according to the scaled value
25+
delay(15); // waits for the servo to get there
26+
}
27+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Sweep
2+
by BARRAGAN <http://barraganstudio.com>
3+
This example code is in the public domain.
4+
5+
modified 8 Nov 2013
6+
by Scott Fitzgerald
7+
http://www.arduino.cc/en/Tutorial/Sweep
8+
*/
9+
10+
#include <Servo.h>
11+
12+
Servo myservo; // create servo object to control a servo
13+
// twelve servo objects can be created on most boards
14+
15+
int pos = 0; // variable to store the servo position
16+
17+
void setup() {
18+
myservo.attach(9); // attaches the servo on pin 9 to the servo object
19+
}
20+
21+
void loop() {
22+
for (pos = 0; pos <= 180; pos += 1) { // goes from 0 degrees to 180 degrees
23+
// in steps of 1 degree
24+
myservo.write(pos); // tell servo to go to position in variable 'pos'
25+
delay(15); // waits 15ms for the servo to reach the position
26+
}
27+
for (pos = 180; pos >= 0; pos -= 1) { // goes from 180 degrees to 0 degrees
28+
myservo.write(pos); // tell servo to go to position in variable 'pos'
29+
delay(15); // waits 15ms for the servo to reach the position
30+
}
31+
}
32+

libraries/Servo/keywords.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#######################################
2+
# Syntax Coloring Map Servo
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
Servo KEYWORD1 Servo
10+
11+
#######################################
12+
# Methods and Functions (KEYWORD2)
13+
#######################################
14+
attach KEYWORD2
15+
detach KEYWORD2
16+
write KEYWORD2
17+
read KEYWORD2
18+
attached KEYWORD2
19+
writeMicroseconds KEYWORD2
20+
readMicroseconds KEYWORD2
21+
22+
#######################################
23+
# Constants (LITERAL1)
24+
#######################################

libraries/Servo/library.properties

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=Servo
2+
version=1.1.2
3+
author=Thomas Roell
4+
5+
sentence=Allows STM32L4 boards to control a variety of servo motors.
6+
paragraph=This library can control a great number of servos.<br />It makes careful use of timers: the library can control 9 servos using only 1 timer.<br />
7+
category=Device Control
8+
url=http://www.arduino.cc/en/Reference/Servo
9+
architectures=stm32l4

libraries/Servo/src/Servo.cpp

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
/*
2+
Copyright (c) 2015 Arduino LLC. All right reserved.
3+
Copyright (c) 2016 Thomas Roell. All right reserved.
4+
5+
This library is free software; you can redistribute it and/or
6+
modify it under the terms of the GNU Lesser General Public
7+
License as published by the Free Software Foundation; either
8+
version 2.1 of the License, or (at your option) any later version.
9+
10+
This library is distributed in the hope that it will be useful,
11+
but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
Lesser General Public License for more details.
14+
15+
You should have received a copy of the GNU Lesser General Public
16+
License along with this library; if not, write to the Free Software
17+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*/
19+
20+
#include <Arduino.h>
21+
#include <Servo.h>
22+
23+
#include "wiring_private.h"
24+
25+
#define INVALID_SERVO 255
26+
27+
static stm32l4_servo_t stm32l4_servo;
28+
29+
static uint8_t ServoAttached = 0;
30+
static volatile bool ServoSync = false;
31+
static stm32l4_servo_table_t ServoTable;
32+
33+
static void servo_event_callback(void *context, uint32_t events)
34+
{
35+
if (ServoSync)
36+
{
37+
ServoSync = 0;
38+
39+
stm32l4_servo_configure(&stm32l4_servo, &ServoTable);
40+
}
41+
}
42+
43+
Servo::Servo()
44+
{
45+
uint8_t servoIndex;
46+
47+
if (stm32l4_servo.state == SERVO_STATE_NONE) {
48+
stm32l4_servo_create(&stm32l4_servo, TIMER_INSTANCE_TIM15, STM32L4_SERVO_IRQ_PRIORITY);
49+
}
50+
51+
if (ServoTable.entries < MAX_SERVOS) {
52+
this->servoIndex = ServoTable.entries;
53+
54+
ServoTable.slot[this->servoIndex].pin = GPIO_PIN_NONE;
55+
ServoTable.slot[this->servoIndex].width = DEFAULT_PULSE_WIDTH;
56+
57+
ServoTable.entries++;
58+
} else {
59+
this->servoIndex = INVALID_SERVO;
60+
}
61+
}
62+
63+
uint8_t Servo::attach(int pin)
64+
{
65+
return this->attach(pin, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
66+
}
67+
68+
uint8_t Servo::attach(int pin, int min, int max)
69+
{
70+
if (g_APinDescription[pin].GPIO == NULL) {
71+
return INVALID_SERVO;
72+
}
73+
74+
if (this->servoIndex >= MAX_SERVOS) {
75+
return INVALID_SERVO;
76+
}
77+
78+
if (ServoTable.slot[this->servoIndex].pin == GPIO_PIN_NONE) {
79+
ServoAttached++;
80+
}
81+
82+
pinMode(pin, OUTPUT);
83+
84+
ServoTable.slot[this->servoIndex].pin = g_APinDescription[pin].pin;
85+
86+
this->min = min;
87+
this->max = max;
88+
89+
if (stm32l4_servo.state < SERVO_STATE_READY) {
90+
stm32l4_servo_enable(&stm32l4_servo, &ServoTable, servo_event_callback, NULL, SERVO_EVENT_SYNC);
91+
} else {
92+
if (ServoAttached == 1) {
93+
stm32l4_servo_configure(&stm32l4_servo, &ServoTable);
94+
} else {
95+
ServoSync = true;
96+
}
97+
}
98+
99+
return this->servoIndex;
100+
}
101+
102+
void Servo::detach()
103+
{
104+
if (this->servoIndex >= MAX_SERVOS) {
105+
return;
106+
}
107+
108+
if (ServoTable.slot[this->servoIndex].pin != GPIO_PIN_NONE) {
109+
ServoAttached--;
110+
}
111+
112+
ServoTable.slot[this->servoIndex].pin = GPIO_PIN_NONE; // store default values
113+
114+
ServoSync = true;
115+
}
116+
117+
void Servo::write(int angle)
118+
{
119+
int width;
120+
121+
if (angle < 200) {
122+
if (angle < 0) {
123+
angle = 0;
124+
}
125+
126+
if (angle > 180) {
127+
angle = 180;
128+
}
129+
130+
width = map(angle, 0, 180, this->min, this->max);
131+
} else {
132+
width = angle;
133+
}
134+
135+
writeMicroseconds(width);
136+
}
137+
138+
void Servo::writeMicroseconds(int width)
139+
{
140+
if (this->servoIndex >= MAX_SERVOS) {
141+
return;
142+
}
143+
144+
if (width < SERVO_PULSE_MIN) {
145+
width = SERVO_PULSE_MIN;
146+
}
147+
148+
if (width > SERVO_PULSE_MAX) {
149+
width = SERVO_PULSE_MAX;
150+
}
151+
152+
ServoTable.slot[this->servoIndex].width = width;
153+
154+
ServoSync = true;
155+
}
156+
157+
int Servo::read() // return the value as degrees
158+
{
159+
return map(readMicroseconds()+1, this->min, this->max, 0, 180);
160+
}
161+
162+
int Servo::readMicroseconds()
163+
{
164+
if (this->servoIndex >= MAX_SERVOS) {
165+
return 0;
166+
}
167+
168+
return ServoTable.slot[this->servoIndex].width;
169+
}
170+
171+
bool Servo::attached()
172+
{
173+
return (ServoTable.slot[this->servoIndex].pin != GPIO_PIN_NONE);
174+
}

0 commit comments

Comments
 (0)