Skip to content

Commit edbfd12

Browse files
authored
Merge pull request #114 from Infineon/infineon_xmc_attached
Infineon xmc attached
2 parents 962ead5 + 974118b commit edbfd12

File tree

3 files changed

+385
-2
lines changed

3 files changed

+385
-2
lines changed

src/Servo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,10 @@
7575
#include "mbed/ServoTimers.h"
7676
#elif defined(ARDUINO_ARCH_RENESAS)
7777
#include "renesas/ServoTimers.h"
78+
#elif defined(ARDUINO_ARCH_XMC)
79+
#include "xmc/ServoTimers.h"
7880
#else
79-
#error "This library only supports boards with an AVR, SAM, SAMD, NRF52 or STM32F4 processor."
81+
#error "This library only supports boards with an AVR, SAM, SAMD, NRF52, STM32F4, Renesas or XMC processor."
8082
#endif
8183

8284
#define Servo_VERSION 2 // software version of this library
@@ -91,7 +93,7 @@
9193

9294
#define INVALID_SERVO 255 // flag indicating an invalid servo index
9395

94-
#if !defined(ARDUINO_ARCH_STM32F4)
96+
#if !defined(ARDUINO_ARCH_STM32F4) && !defined(ARDUINO_ARCH_XMC)
9597

9698
typedef struct {
9799
uint8_t nbr :6 ; // a pin number from 0 to 63

src/xmc/Servo.cpp

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/******************************************************************************
2+
* The MIT License
3+
*
4+
* Copyright (c) 2010, LeafLabs, LLC.
5+
*
6+
* Permission is hereby granted, free of charge, to any person
7+
* obtaining a copy of this software and associated documentation
8+
* files (the "Software"), to deal in the Software without
9+
* restriction, including without limitation the rights to use, copy,
10+
* modify, merge, publish, distribute, sublicense, and/or sell copies
11+
* of the Software, and to permit persons to whom the Software is
12+
* furnished to do so, subject to the following conditions:
13+
*
14+
* The above copyright notice and this permission notice shall be
15+
* included in all copies or substantial portions of the Software.
16+
*
17+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24+
* SOFTWARE.
25+
*****************************************************************************/
26+
27+
#if defined(ARDUINO_ARCH_XMC)
28+
29+
#include "ServoTimers.h"
30+
31+
uint8_t _ServoCount = 1; // internal counter to check if max numbers of servos is reached
32+
static uint8_t _allowed[MAX_PWM_SERVOS] = ALLOWED_PINS; // internal array to check allowed pwm pins
33+
static uint8_t _servos[MAX_PWM_SERVOS]; // static array of used servo pins for checking
34+
35+
36+
/**
37+
* @brief None blocking wait loop.
38+
*
39+
* @param uS microseconds to wait
40+
*/
41+
static void _delayUs(unsigned long uS)
42+
{
43+
unsigned long time_now = micros();
44+
while (micros() < time_now + uS)
45+
;
46+
}
47+
48+
49+
Servo::Servo()
50+
{
51+
if (_ServoCount <= MAX_PWM_SERVOS )
52+
{
53+
this->servoIndex = _ServoCount++;
54+
55+
this->_minAngle = MIN_ANGLE;
56+
this->_maxAngle = MAX_ANGLE;
57+
this->_minPW = MIN_PULSE_WIDTH;
58+
this->_maxPW = MAX_PULSE_WIDTH;
59+
this->_pin = 0;
60+
this->_isActive = false;
61+
this->_pwm = 0;
62+
this->_deg = 0.0;
63+
}else{
64+
this->servoIndex = INVALID_SERVO;
65+
}
66+
}
67+
68+
uint8_t Servo::attach(uint8_t pin, uint16_t min, uint16_t max)
69+
{
70+
if (this->servoIndex <= MAX_PWM_SERVOS )
71+
{
72+
// validate selected pin
73+
bool pin_allowed = false;
74+
for( int i = 0; i < MAX_PWM_SERVOS; i++)
75+
{
76+
// check if pin already in use
77+
if ( _servos[i] == pin)
78+
return INVALID_SERVO;
79+
80+
// check if selected pin has a pwm unit on the used XMC board
81+
if ( _allowed[i] == pin)
82+
pin_allowed = true;
83+
}
84+
// return if pin is not found in allowed pin list
85+
if ( !pin_allowed )
86+
return INVALID_SERVO;
87+
88+
// Set min/max values according the input and check for absolute limits
89+
if (min < MIN_PULSE_CHECK)
90+
{
91+
this->_minAngle = constrain(min,MIN_ANGLE,MAX_ANGLE);
92+
this->_minPW = MIN_PULSE_WIDTH;
93+
} else {
94+
this->_minAngle = MIN_ANGLE; //TODO has to calculated
95+
this->_minPW = constrain(min,MIN_PULSE_WIDTH,MAX_PULSE_WIDTH);
96+
}
97+
98+
if (max < MIN_PULSE_CHECK)
99+
{
100+
this->_maxAngle = constrain(max,MIN_ANGLE,MAX_ANGLE);
101+
this->_maxPW = 2 * MAX_PULSE_WIDTH;
102+
} else {
103+
this->_maxAngle = MAX_ANGLE; //TODO has to calculated
104+
this->_maxPW = constrain(max,MIN_PULSE_WIDTH,MAX_PULSE_WIDTH);
105+
}
106+
107+
this->_pin = pin;
108+
this->_isActive = true;
109+
110+
setAnalogWriteFrequency(this->_pin, REFRESH_FREQUENCY);
111+
analogWriteResolution(ADC_RESOLUTION);
112+
113+
}
114+
115+
return this->servoIndex;
116+
}
117+
118+
119+
void Servo::detach()
120+
{
121+
this->servoIndex = _ServoCount--;
122+
123+
this->_minAngle = MIN_ANGLE;
124+
this->_maxAngle = MAX_ANGLE;
125+
this->_minPW = MIN_PULSE_WIDTH;
126+
this->_maxPW = MAX_PULSE_WIDTH;
127+
128+
this->_pin = 0;
129+
this->_isActive = false;
130+
this->_pwm = 0;
131+
this->_deg = 0.0;
132+
}
133+
134+
void Servo::write(int value)
135+
{
136+
if (value < MIN_PULSE_CHECK)
137+
{
138+
// angle must be inside the boundaries
139+
double angle = constrain(value, this->_minAngle, this->_maxAngle);
140+
double dutyCycle = ( 0.5 + ( angle / MAX_ANGLE ) * 2.0 ) * DUTYCYCLE_STEPS;
141+
142+
this->_deg = angle;
143+
this->_pwm = uint16_t(dutyCycle);
144+
145+
analogWrite(this->_pin, uint16_t(dutyCycle));
146+
_delayUs(50);
147+
} else {
148+
writeMicroseconds(value);
149+
}
150+
}
151+
152+
void Servo::writeMicroseconds(int value)
153+
{
154+
// value must be inside the boundaries
155+
double pw = constrain(value,this->_minPW, this->_maxPW);
156+
double dutyCycle = map(pw, MIN_PULSE_WIDTH,MAX_PULSE_WIDTH, 0.5 * DUTYCYCLE_STEPS, 2.5 * DUTYCYCLE_STEPS);
157+
158+
this->_deg = ( dutyCycle - DUTYCYCLE_STEPS * 0.5 ) * MAX_ANGLE / ( 2 * DUTYCYCLE_STEPS );
159+
this->_pwm = uint16_t(dutyCycle);
160+
161+
analogWrite(this->_pin, uint16_t(dutyCycle));
162+
_delayUs(50);
163+
}
164+
165+
#endif

0 commit comments

Comments
 (0)