From ea036478c240fa93747cb3bb8a6c02b5bfa03e57 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Wed, 26 Jun 2019 17:04:40 -0600 Subject: [PATCH 01/10] Initial push. Mostly working. Needs writeMicro and overloaded attach. --- libraries/Servo/keywords.txt | 28 +++++++++++ libraries/Servo/library.properties | 9 ++++ libraries/Servo/src/Servo.cpp | 74 ++++++++++++++++++++++++++++++ libraries/Servo/src/Servo.h | 46 +++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 libraries/Servo/keywords.txt create mode 100644 libraries/Servo/library.properties create mode 100644 libraries/Servo/src/Servo.cpp create mode 100644 libraries/Servo/src/Servo.h diff --git a/libraries/Servo/keywords.txt b/libraries/Servo/keywords.txt new file mode 100644 index 00000000..39478d63 --- /dev/null +++ b/libraries/Servo/keywords.txt @@ -0,0 +1,28 @@ +####################################### +# Syntax Coloring Map +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +attach KEYWORD2 +write KEYWORD2 +detach KEYWORD2 +read KEYWORD2 + +writeMicroseconds KEYWORD2 +attached KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/libraries/Servo/library.properties b/libraries/Servo/library.properties new file mode 100644 index 00000000..fef49e29 --- /dev/null +++ b/libraries/Servo/library.properties @@ -0,0 +1,9 @@ +name=Servo +version=1.0.0 +author=SparkFun Electronics +maintainer=SparkFun Electronics +sentence=Allows control of standard PWM based servos +paragraph= +category=Device Control +url=http://www.arduino.cc/en/Reference/Servo +architectures=apollo3 diff --git a/libraries/Servo/src/Servo.cpp b/libraries/Servo/src/Servo.cpp new file mode 100644 index 00000000..56e0ae94 --- /dev/null +++ b/libraries/Servo/src/Servo.cpp @@ -0,0 +1,74 @@ +/* + +Copyright (c) 2015 Arduino LLC. All rights reserved. +Copyright (c) 2019 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include "Servo.h" +#include "Arduino.h" + +//Constructor +Servo::Servo() +{ +} + +//Assign global var +void Servo::attach(uint8_t pinNumber) +{ + _servoPinNumber = pinNumber; + _servoPadNumber = ap3_gpio_pin2pad(pinNumber); +} + +void Servo::write(uint8_t servoPosition) +{ + _servoPosition = servoPosition; + if (_servoPosition > 180) + _servoPosition = 180; //Bounds check + + uint16_t newServoPosition = map(servoPosition, 0, 180, 0, 1023); + + servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions +} + +void Servo::writeMicroseconds(uint8_t servoPosition) +{ + + servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions +} + +void Servo::detach(void) +{ + _servoPinNumber = NULL; + _servoPadNumber = NULL; + pinMode(_servoPinNumber, INPUT); //Will stop PWM output +} + +uint8_t Servo::read(void) +{ + return (_servoPosition); +} + +bool Servo::attached(uint8_t pinNumber) +{ + if (_servoPinNumber == pinNumber) + return (true); + return (false); +} \ No newline at end of file diff --git a/libraries/Servo/src/Servo.h b/libraries/Servo/src/Servo.h new file mode 100644 index 00000000..b3a0ce9b --- /dev/null +++ b/libraries/Servo/src/Servo.h @@ -0,0 +1,46 @@ +/* +Copyright (c) 2019 SparkFun Electronics + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +// ToDo: Make TwoWire a library (under "libraries") to get syntax highlighting + +#ifndef _AP3_SERVO_H_ +#define _AP3_SERVO_H_ + +#include "Arduino.h" + +class Servo +{ +public: + Servo(); + void attach(uint8_t pinNumber); + void write(uint8_t servoPosition); + void detach(void); + uint8_t read(void); + bool attached(uint8_t pinNumber); + +private: + uint8_t _servoPadNumber = NULL; + uint8_t _servoPinNumber = NULL; + uint8_t _servoPosition; +}; + +#endif // _AP3_SERVO_H_ From e379561baf0a1136c5508f1ff5fd3396638fca1b Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 1 Jul 2019 19:44:53 -0600 Subject: [PATCH 02/10] White space change --- cores/arduino/ard_sup/analog/ap3_analog.cpp | 258 ++++++++++---------- 1 file changed, 134 insertions(+), 124 deletions(-) diff --git a/cores/arduino/ard_sup/analog/ap3_analog.cpp b/cores/arduino/ard_sup/analog/ap3_analog.cpp index ed6ed621..71131d34 100644 --- a/cores/arduino/ard_sup/analog/ap3_analog.cpp +++ b/cores/arduino/ard_sup/analog/ap3_analog.cpp @@ -27,9 +27,9 @@ SOFTWARE. #include "ap3_analog.h" -// Define the clock source and frequency to use for -// PWM generation. -// Chose 12 MHz to allow maximal resolution with a +// Define the clock source and frequency to use for +// PWM generation. +// Chose 12 MHz to allow maximal resolution with a // target maximum width of 2ms (for RC servos) // 1/12MHz = 0.083 uS per LSB. // 2ms/0.083us = 24000 LSB for 2 ms wide pulse @@ -41,14 +41,14 @@ SOFTWARE. instead or maybe we can even go ahead and support the Servo library */ -#define AP3_ANALOG_CLK -#define AP3_ANALOG_FREQ 12000000 -#define AP3_ANALOG_FRAME_PERIOD 24000 +#define AP3_ANALOG_CLK +#define AP3_ANALOG_FREQ 12000000 +#define AP3_ANALOG_FRAME_PERIOD 24000 //***************************************************************************** // // Tables copied from am_hal_ctimer.c because they are declared as static within -// that file, but they would be useful here too. +// that file, but they would be useful here too. // // Lookup tables used by am_hal_ctimer_output_config(). // @@ -65,63 +65,63 @@ SOFTWARE. // OUTCFG 7 = A7OUT2. // //***************************************************************************** -#define CTXPADNUM(ctx) ((CTx_tbl[ctx] >> 0) & 0x3f) -#define CTXPADFNC(ctx) ((CTx_tbl[ctx] >> 8) & 0x7) -#define CTX(pad, fn) ((fn << 8) | (pad << 0)) +#define CTXPADNUM(ctx) ((CTx_tbl[ctx] >> 0) & 0x3f) +#define CTXPADFNC(ctx) ((CTx_tbl[ctx] >> 8) & 0x7) +#define CTX(pad, fn) ((fn << 8) | (pad << 0)) static const uint16_t CTx_tbl[32] = -{ - CTX(12,2), CTX(25,2), CTX(13,2), CTX(26,2), CTX(18,2), // 0 - 4 - CTX(27,2), CTX(19,2), CTX(28,2), CTX( 5,7), CTX(29,2), // 5 - 9 - CTX( 6,5), CTX(30,2), CTX(22,2), CTX(31,2), CTX(23,2), // 10 - 14 - CTX(32,2), CTX(42,2), CTX( 4,6), CTX(43,2), CTX( 7,7), // 15 - 19 - CTX(44,2), CTX(24,5), CTX(45,2), CTX(33,6), CTX(46,2), // 20 - 24 - CTX(39,2), CTX(47,2), CTX(35,5), CTX(48,2), CTX(37,7), // 25 - 29 - CTX(49,2), CTX(11,2) // 30 - 31 + { + CTX(12, 2), CTX(25, 2), CTX(13, 2), CTX(26, 2), CTX(18, 2), // 0 - 4 + CTX(27, 2), CTX(19, 2), CTX(28, 2), CTX(5, 7), CTX(29, 2), // 5 - 9 + CTX(6, 5), CTX(30, 2), CTX(22, 2), CTX(31, 2), CTX(23, 2), // 10 - 14 + CTX(32, 2), CTX(42, 2), CTX(4, 6), CTX(43, 2), CTX(7, 7), // 15 - 19 + CTX(44, 2), CTX(24, 5), CTX(45, 2), CTX(33, 6), CTX(46, 2), // 20 - 24 + CTX(39, 2), CTX(47, 2), CTX(35, 5), CTX(48, 2), CTX(37, 7), // 25 - 29 + CTX(49, 2), CTX(11, 2) // 30 - 31 }; -#define OUTC(timB,timN,N2) ((N2 << 4) | (timB << 3) | (timN << 0)) -#define OUTCTIMN(ctx,n) (outcfg_tbl[ctx][n] & (0x7 << 0)) -#define OUTCTIMB(ctx,n) (outcfg_tbl[ctx][n] & (0x1 << 3)) -#define OUTCO2(ctx,n) (outcfg_tbl[ctx][n] & (0x1 << 4)) +#define OUTC(timB, timN, N2) ((N2 << 4) | (timB << 3) | (timN << 0)) +#define OUTCTIMN(ctx, n) (outcfg_tbl[ctx][n] & (0x7 << 0)) +#define OUTCTIMB(ctx, n) (outcfg_tbl[ctx][n] & (0x1 << 3)) +#define OUTCO2(ctx, n) (outcfg_tbl[ctx][n] & (0x1 << 4)) static const uint8_t outcfg_tbl[32][4] = -{ - {OUTC(0,0,0), OUTC(1,2,1), OUTC(0,5,1), OUTC(0,6,0)}, // CTX0: A0OUT, B2OUT2, A5OUT2, A6OUT - {OUTC(0,0,1), OUTC(0,0,0), OUTC(0,5,0), OUTC(1,7,1)}, // CTX1: A0OUT2, A0OUT, A5OUT, B7OUT2 - {OUTC(1,0,0), OUTC(1,1,1), OUTC(1,6,1), OUTC(0,7,0)}, // CTX2: B0OUT, B1OUT2, B6OUT2, A7OUT - {OUTC(1,0,1), OUTC(1,0,0), OUTC(0,1,0), OUTC(0,6,0)}, // CTX3: B0OUT2, B0OUT, A1OUT, A6OUT - {OUTC(0,1,0), OUTC(0,2,1), OUTC(0,5,1), OUTC(1,5,0)}, // CTX4: A1OUT, A2OUT2, A5OUT2, B5OUT - {OUTC(0,1,1), OUTC(0,1,0), OUTC(1,6,0), OUTC(0,7,0)}, // CTX5: A1OUT2, A1OUT, B6OUT, A7OUT - {OUTC(1,1,0), OUTC(0,1,0), OUTC(1,5,1), OUTC(1,7,0)}, // CTX6: B1OUT, A1OUT, B5OUT2, B7OUT - {OUTC(1,1,1), OUTC(1,1,0), OUTC(1,5,0), OUTC(0,7,0)}, // CTX7: B1OUT2, B1OUT, B5OUT, A7OUT - {OUTC(0,2,0), OUTC(0,3,1), OUTC(0,4,1), OUTC(1,6,0)}, // CTX8: A2OUT, A3OUT2, A4OUT2, B6OUT - {OUTC(0,2,1), OUTC(0,2,0), OUTC(0,4,0), OUTC(1,0,0)}, // CTX9: A2OUT2, A2OUT, A4OUT, B0OUT - {OUTC(1,2,0), OUTC(1,3,1), OUTC(1,4,1), OUTC(0,6,0)}, // CTX10: B2OUT, B3OUT2, B4OUT2, A6OUT - {OUTC(1,2,1), OUTC(1,2,0), OUTC(1,4,0), OUTC(1,5,1)}, // CTX11: B2OUT2, B2OUT, B4OUT, B5OUT2 - {OUTC(0,3,0), OUTC(1,1,0), OUTC(1,0,1), OUTC(1,6,1)}, // CTX12: A3OUT, B1OUT, B0OUT2, B6OUT2 - {OUTC(0,3,1), OUTC(0,3,0), OUTC(0,6,0), OUTC(1,4,1)}, // CTX13: A3OUT2, A3OUT, A6OUT, B4OUT2 - {OUTC(1,3,0), OUTC(1,1,0), OUTC(1,7,1), OUTC(0,7,0)}, // CTX14: B3OUT, B1OUT, B7OUT2, A7OUT - {OUTC(1,3,1), OUTC(1,3,0), OUTC(0,7,0), OUTC(0,4,1)}, // CTX15: B3OUT2, B3OUT, A7OUT, A4OUT2 - {OUTC(0,4,0), OUTC(0,0,0), OUTC(0,0,1), OUTC(1,3,1)}, // CTX16: A4OUT, A0OUT, A0OUT2, B3OUT2 - {OUTC(0,4,1), OUTC(1,7,0), OUTC(0,4,0), OUTC(0,1,1)}, // CTX17: A4OUT2, B7OUT, A4OUT, A1OUT2 - {OUTC(1,4,0), OUTC(1,0,0), OUTC(0,0,0), OUTC(0,3,1)}, // CTX18: B4OUT, B0OUT, A0OUT, A3OUT2 - {OUTC(1,4,1), OUTC(0,2,0), OUTC(1,4,0), OUTC(1,1,1)}, // CTX19: B4OUT2, A2OUT, B4OUT, B1OUT2 - {OUTC(0,5,0), OUTC(0,1,0), OUTC(0,1,1), OUTC(1,2,1)}, // CTX20: A5OUT, A1OUT, A1OUT2, B2OUT2 - {OUTC(0,5,1), OUTC(0,1,0), OUTC(1,5,0), OUTC(0,0,1)}, // CTX21: A5OUT2, A1OUT, B5OUT, A0OUT2 - {OUTC(1,5,0), OUTC(0,6,0), OUTC(0,1,0), OUTC(0,2,1)}, // CTX22: B5OUT, A6OUT, A1OUT, A2OUT2 - {OUTC(1,5,1), OUTC(0,7,0), OUTC(0,5,0), OUTC(1,0,1)}, // CTX23: B5OUT2, A7OUT, A5OUT, B0OUT2 - {OUTC(0,6,0), OUTC(0,2,0), OUTC(0,1,0), OUTC(1,1,1)}, // CTX24: A6OUT, A2OUT, A1OUT, B1OUT2 - {OUTC(1,4,1), OUTC(1,2,0), OUTC(0,6,0), OUTC(0,2,1)}, // CTX25: B4OUT2, B2OUT, A6OUT, A2OUT2 - {OUTC(1,6,0), OUTC(1,2,0), OUTC(0,5,0), OUTC(0,1,1)}, // CTX26: B6OUT, B2OUT, A5OUT, A1OUT2 - {OUTC(1,6,1), OUTC(0,1,0), OUTC(1,6,0), OUTC(1,2,1)}, // CTX27: B6OUT2, A1OUT, B6OUT, B2OUT2 - {OUTC(0,7,0), OUTC(0,3,0), OUTC(0,5,1), OUTC(1,0,1)}, // CTX28: A7OUT, A3OUT, A5OUT2, B0OUT2 - {OUTC(1,5,1), OUTC(0,1,0), OUTC(0,7,0), OUTC(0,3,1)}, // CTX29: B5OUT2, A1OUT, A7OUT, A3OUT2 - {OUTC(1,7,0), OUTC(1,3,0), OUTC(0,4,1), OUTC(0,0,1)}, // CTX30: B7OUT, B3OUT, A4OUT2, A0OUT2 - {OUTC(1,7,1), OUTC(0,6,0), OUTC(1,7,0), OUTC(1,3,1)}, // CTX31: B7OUT2, A6OUT, B7OUT, B3OUT2 + { + {OUTC(0, 0, 0), OUTC(1, 2, 1), OUTC(0, 5, 1), OUTC(0, 6, 0)}, // CTX0: A0OUT, B2OUT2, A5OUT2, A6OUT + {OUTC(0, 0, 1), OUTC(0, 0, 0), OUTC(0, 5, 0), OUTC(1, 7, 1)}, // CTX1: A0OUT2, A0OUT, A5OUT, B7OUT2 + {OUTC(1, 0, 0), OUTC(1, 1, 1), OUTC(1, 6, 1), OUTC(0, 7, 0)}, // CTX2: B0OUT, B1OUT2, B6OUT2, A7OUT + {OUTC(1, 0, 1), OUTC(1, 0, 0), OUTC(0, 1, 0), OUTC(0, 6, 0)}, // CTX3: B0OUT2, B0OUT, A1OUT, A6OUT + {OUTC(0, 1, 0), OUTC(0, 2, 1), OUTC(0, 5, 1), OUTC(1, 5, 0)}, // CTX4: A1OUT, A2OUT2, A5OUT2, B5OUT + {OUTC(0, 1, 1), OUTC(0, 1, 0), OUTC(1, 6, 0), OUTC(0, 7, 0)}, // CTX5: A1OUT2, A1OUT, B6OUT, A7OUT + {OUTC(1, 1, 0), OUTC(0, 1, 0), OUTC(1, 5, 1), OUTC(1, 7, 0)}, // CTX6: B1OUT, A1OUT, B5OUT2, B7OUT + {OUTC(1, 1, 1), OUTC(1, 1, 0), OUTC(1, 5, 0), OUTC(0, 7, 0)}, // CTX7: B1OUT2, B1OUT, B5OUT, A7OUT + {OUTC(0, 2, 0), OUTC(0, 3, 1), OUTC(0, 4, 1), OUTC(1, 6, 0)}, // CTX8: A2OUT, A3OUT2, A4OUT2, B6OUT + {OUTC(0, 2, 1), OUTC(0, 2, 0), OUTC(0, 4, 0), OUTC(1, 0, 0)}, // CTX9: A2OUT2, A2OUT, A4OUT, B0OUT + {OUTC(1, 2, 0), OUTC(1, 3, 1), OUTC(1, 4, 1), OUTC(0, 6, 0)}, // CTX10: B2OUT, B3OUT2, B4OUT2, A6OUT + {OUTC(1, 2, 1), OUTC(1, 2, 0), OUTC(1, 4, 0), OUTC(1, 5, 1)}, // CTX11: B2OUT2, B2OUT, B4OUT, B5OUT2 + {OUTC(0, 3, 0), OUTC(1, 1, 0), OUTC(1, 0, 1), OUTC(1, 6, 1)}, // CTX12: A3OUT, B1OUT, B0OUT2, B6OUT2 + {OUTC(0, 3, 1), OUTC(0, 3, 0), OUTC(0, 6, 0), OUTC(1, 4, 1)}, // CTX13: A3OUT2, A3OUT, A6OUT, B4OUT2 + {OUTC(1, 3, 0), OUTC(1, 1, 0), OUTC(1, 7, 1), OUTC(0, 7, 0)}, // CTX14: B3OUT, B1OUT, B7OUT2, A7OUT + {OUTC(1, 3, 1), OUTC(1, 3, 0), OUTC(0, 7, 0), OUTC(0, 4, 1)}, // CTX15: B3OUT2, B3OUT, A7OUT, A4OUT2 + {OUTC(0, 4, 0), OUTC(0, 0, 0), OUTC(0, 0, 1), OUTC(1, 3, 1)}, // CTX16: A4OUT, A0OUT, A0OUT2, B3OUT2 + {OUTC(0, 4, 1), OUTC(1, 7, 0), OUTC(0, 4, 0), OUTC(0, 1, 1)}, // CTX17: A4OUT2, B7OUT, A4OUT, A1OUT2 + {OUTC(1, 4, 0), OUTC(1, 0, 0), OUTC(0, 0, 0), OUTC(0, 3, 1)}, // CTX18: B4OUT, B0OUT, A0OUT, A3OUT2 + {OUTC(1, 4, 1), OUTC(0, 2, 0), OUTC(1, 4, 0), OUTC(1, 1, 1)}, // CTX19: B4OUT2, A2OUT, B4OUT, B1OUT2 + {OUTC(0, 5, 0), OUTC(0, 1, 0), OUTC(0, 1, 1), OUTC(1, 2, 1)}, // CTX20: A5OUT, A1OUT, A1OUT2, B2OUT2 + {OUTC(0, 5, 1), OUTC(0, 1, 0), OUTC(1, 5, 0), OUTC(0, 0, 1)}, // CTX21: A5OUT2, A1OUT, B5OUT, A0OUT2 + {OUTC(1, 5, 0), OUTC(0, 6, 0), OUTC(0, 1, 0), OUTC(0, 2, 1)}, // CTX22: B5OUT, A6OUT, A1OUT, A2OUT2 + {OUTC(1, 5, 1), OUTC(0, 7, 0), OUTC(0, 5, 0), OUTC(1, 0, 1)}, // CTX23: B5OUT2, A7OUT, A5OUT, B0OUT2 + {OUTC(0, 6, 0), OUTC(0, 2, 0), OUTC(0, 1, 0), OUTC(1, 1, 1)}, // CTX24: A6OUT, A2OUT, A1OUT, B1OUT2 + {OUTC(1, 4, 1), OUTC(1, 2, 0), OUTC(0, 6, 0), OUTC(0, 2, 1)}, // CTX25: B4OUT2, B2OUT, A6OUT, A2OUT2 + {OUTC(1, 6, 0), OUTC(1, 2, 0), OUTC(0, 5, 0), OUTC(0, 1, 1)}, // CTX26: B6OUT, B2OUT, A5OUT, A1OUT2 + {OUTC(1, 6, 1), OUTC(0, 1, 0), OUTC(1, 6, 0), OUTC(1, 2, 1)}, // CTX27: B6OUT2, A1OUT, B6OUT, B2OUT2 + {OUTC(0, 7, 0), OUTC(0, 3, 0), OUTC(0, 5, 1), OUTC(1, 0, 1)}, // CTX28: A7OUT, A3OUT, A5OUT2, B0OUT2 + {OUTC(1, 5, 1), OUTC(0, 1, 0), OUTC(0, 7, 0), OUTC(0, 3, 1)}, // CTX29: B5OUT2, A1OUT, A7OUT, A3OUT2 + {OUTC(1, 7, 0), OUTC(1, 3, 0), OUTC(0, 4, 1), OUTC(0, 0, 1)}, // CTX30: B7OUT, B3OUT, A4OUT2, A0OUT2 + {OUTC(1, 7, 1), OUTC(0, 6, 0), OUTC(1, 7, 0), OUTC(1, 3, 1)}, // CTX31: B7OUT2, A6OUT, B7OUT, B3OUT2 }; -uint16_t _analogBits = 10; //10-bit by default -uint8_t _analogWriteBits = 8; // 8-bit by default for writes -uint8_t _servoWriteBits = 8; // 8-bit by default for writes +uint16_t _analogBits = 10; //10-bit by default +uint8_t _analogWriteBits = 8; // 8-bit by default for writes +uint8_t _servoWriteBits = 8; // 8-bit by default for writes uint16_t analogRead(uint8_t pinNumber) { @@ -325,92 +325,102 @@ ap3_err_t ap3_change_channel(uint8_t padNumber) } } - - - - - - - - - -ap3_err_t ap3_pwm_output( uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk ){ +ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk) +{ // handle configuration, if necessary ap3_err_t retval = AP3_OK; ap3_gpio_pad_t pad = ap3_gpio_pin2pad(pin); - if(( pad == AP3_GPIO_PAD_UNUSED) || ( pad >= AP3_GPIO_MAX_PADS )){ return AP3_INVALID_ARG; } + if ((pad == AP3_GPIO_PAD_UNUSED) || (pad >= AP3_GPIO_MAX_PADS)) + { + return AP3_INVALID_ARG; + } uint32_t timer = 0; uint32_t segment = AM_HAL_CTIMER_TIMERA; uint32_t output = AM_HAL_CTIMER_OUTPUT_NORMAL; uint8_t ctx = 0; - for(ctx = 0; ctx < 32; ctx++){ - if( CTXPADNUM(ctx) == pad ){ + for (ctx = 0; ctx < 32; ctx++) + { + if (CTXPADNUM(ctx) == pad) + { break; } } - if( ctx >= 32 ){ + if (ctx >= 32) + { return AP3_ERR; // could not find pad in CTx table } // Now use CTx index to get configuration information // Now, for the given pad, determine the above values - if( (pad == 39) || (pad == 37) ){ + if ((pad == 39) || (pad == 37)) + { // pads 39 and 37 must be handled differently to avoid conflicting with other pins - if(pad == 39){ + if (pad == 39) + { // 39 timer = 6; segment = AM_HAL_CTIMER_TIMERA; output = AM_HAL_CTIMER_OUTPUT_SECONDARY; - }else{ + } + else + { // 37 timer = 7; segment = AM_HAL_CTIMER_TIMERA; output = AM_HAL_CTIMER_OUTPUT_NORMAL; } - }else{ - const uint8_t n = 0; // use the zeroeth index into the options for any pd except 37 and 39 + } + else + { + const uint8_t n = 0; // use the zeroeth index into the options for any pd except 37 and 39 timer = OUTCTIMN(ctx, 0); - if( OUTCTIMB(ctx, 0) ){ + if (OUTCTIMB(ctx, 0)) + { segment = AM_HAL_CTIMER_TIMERB; } - if( OUTCO2(ctx, 0) ){ + if (OUTCO2(ctx, 0)) + { output = AM_HAL_CTIMER_OUTPUT_SECONDARY; } } // Configure the pin - am_hal_ctimer_output_config(timer, - segment, - pad, - output, - AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA); // + am_hal_ctimer_output_config(timer, + segment, + pad, + output, + AM_HAL_GPIO_PIN_DRIVESTRENGTH_12MA); // // Configure the repeated pulse mode with our clock source am_hal_ctimer_config_single(timer, - segment, + segment, // (AM_HAL_CTIMER_FN_PWM_REPEAT | AP3_ANALOG_CLK | AM_HAL_CTIMER_INT_ENABLE) ); - (AM_HAL_CTIMER_FN_PWM_REPEAT | clk) ); + (AM_HAL_CTIMER_FN_PWM_REPEAT | clk)); // If this pad uses secondary output: - if( output == AM_HAL_CTIMER_OUTPUT_SECONDARY ){ + if (output == AM_HAL_CTIMER_OUTPUT_SECONDARY) + { // Need to explicitly enable compare registers 2/3 - uint32_t* pui32ConfigReg = NULL; - pui32ConfigReg = (uint32_t*)CTIMERADDRn(CTIMER, timer, AUX0); + uint32_t *pui32ConfigReg = NULL; + pui32ConfigReg = (uint32_t *)CTIMERADDRn(CTIMER, timer, AUX0); uint32_t ui32WriteVal = AM_REGVAL(pui32ConfigReg); - uint32_t ui32ConfigVal = (1 << CTIMER_AUX0_TMRA0EN23_Pos ); // using CTIMER_AUX0_TMRA0EN23_Pos because for now this number is common to all CTimer instances - if ( segment == AM_HAL_CTIMER_TIMERB ){ + uint32_t ui32ConfigVal = (1 << CTIMER_AUX0_TMRA0EN23_Pos); // using CTIMER_AUX0_TMRA0EN23_Pos because for now this number is common to all CTimer instances + if (segment == AM_HAL_CTIMER_TIMERB) + { ui32ConfigVal = ((ui32ConfigVal & 0xFFFF) << 16); } ui32WriteVal = (ui32WriteVal & ~(segment)) | ui32ConfigVal; AM_REGVAL(pui32ConfigReg) = ui32WriteVal; // then set the duty cycle with the 'aux' function - am_hal_ctimer_aux_period_set( timer, segment, fw, th); - }else{ + am_hal_ctimer_aux_period_set(timer, segment, fw, th); + } + else + { // Otherwise simply set the primary duty cycle am_hal_ctimer_period_set(timer, segment, fw, th); } @@ -423,9 +433,10 @@ ap3_err_t ap3_pwm_output( uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk ){ return AP3_OK; } - -ap3_err_t analogWriteResolution( uint8_t res ){ - if( res > 15 ){ +ap3_err_t analogWriteResolution(uint8_t res) +{ + if (res > 15) + { _analogWriteBits = 15; // max out the resolution when this happens return AP3_ERR; } @@ -433,25 +444,30 @@ ap3_err_t analogWriteResolution( uint8_t res ){ return AP3_OK; } -ap3_err_t analogWrite( uint8_t pin, uint32_t val ){ +ap3_err_t analogWrite(uint8_t pin, uint32_t val) +{ // Determine the high time based on input value and the current resolution setting - uint32_t fsv = (0x01 << _analogWriteBits); // full scale value for the current resolution setting - val = val % fsv; // prevent excess - uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock + uint32_t fsv = (0x01 << _analogWriteBits); // full scale value for the current resolution setting + val = val % fsv; // prevent excess + uint32_t clk = AM_HAL_CTIMER_HFRC_12MHZ; // Use an Ambiq HAL provided value to select which clock //uint32_t fw = 32768; // Choose the frame width in clock periods (32768 -> ~ 350 Hz) // uint32_t th = (uint32_t)( (fw * val) / fsv ); - if(val == 0){ - val = 1; // todo: change this so that when val==0 we set the mode to "force output low" + if (val == 0) + { + val = 1; // todo: change this so that when val==0 we set the mode to "force output low" } - if( val == fsv ){ - val -= 1; // todo: change this so that when val==fsv we just set the mode to "force output high" + if (val == fsv) + { + val -= 1; // todo: change this so that when val==fsv we just set the mode to "force output high" } - return ap3_pwm_output( pin, val, fsv, clk ); + return ap3_pwm_output(pin, val, fsv, clk); } -ap3_err_t servoWriteResolution( uint8_t res ){ - if( res > 15 ){ +ap3_err_t servoWriteResolution(uint8_t res) +{ + if (res > 15) + { _servoWriteBits = 15; // max out the resolution when this happens return AP3_ERR; } @@ -459,22 +475,16 @@ ap3_err_t servoWriteResolution( uint8_t res ){ return AP3_OK; } -ap3_err_t servoWrite( uint8_t pin, uint32_t val ){ +ap3_err_t servoWrite(uint8_t pin, uint32_t val) +{ // Determine the high time based on input value and the current resolution setting - uint32_t fsv = (0x01 << _servoWriteBits); // full scale value for the current resolution setting - val = val % fsv; // prevent excess - uint32_t clk = AM_HAL_CTIMER_HFRC_3MHZ; // Using 3 MHz to get fine-grained control up to 20 ms wide - uint32_t fw = 60000; // 20 ms wide frame - uint32_t max = 6000; // max width of RC pwm pulse is 2 ms or 6000 counts - uint32_t min = 3000; // min width of RC pwm pulse is 1 ms or 3000 counts - uint32_t th = (uint32_t)( ((max - min) * val) / fsv ) + min; - - return ap3_pwm_output( pin, th, fw, clk ); + uint32_t fsv = (0x01 << _servoWriteBits); // full scale value for the current resolution setting + val = val % fsv; // prevent excess + uint32_t clk = AM_HAL_CTIMER_HFRC_3MHZ; // Using 3 MHz to get fine-grained control up to 20 ms wide + uint32_t fw = 60000; // 20 ms wide frame + uint32_t max = 6000; // max width of RC pwm pulse is 2 ms or 6000 counts + uint32_t min = 3000; // min width of RC pwm pulse is 1 ms or 3000 counts + uint32_t th = (uint32_t)(((max - min) * val) / fsv) + min; + + return ap3_pwm_output(pin, th, fw, clk); } - - - - - - - From 23f1a51118be093074c4ed0316c631dd2a9f53c5 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 1 Jul 2019 19:51:00 -0600 Subject: [PATCH 03/10] Small error checking improvement to analogReadResolution() --- cores/arduino/ard_sup/analog/ap3_analog.cpp | 10 ++++++++-- cores/arduino/ard_sup/ap3_analog.h | 11 +++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/cores/arduino/ard_sup/analog/ap3_analog.cpp b/cores/arduino/ard_sup/analog/ap3_analog.cpp index 71131d34..98d23564 100644 --- a/cores/arduino/ard_sup/analog/ap3_analog.cpp +++ b/cores/arduino/ard_sup/analog/ap3_analog.cpp @@ -204,9 +204,15 @@ uint16_t analogRead(uint8_t pinNumber) //Apollo3 is capapble of 14-bit ADC but Arduino defaults to 10-bit //This modifies the global var that controls what is returned from analogRead() -void analogReadResolution(uint8_t bits) +ap3_err_t analogReadResolution(uint8_t bits) { - _analogBits = bits; + if (bits > 16) + { + _analogBits = 16; // max out the resolution when this happens + return AP3_ERR; + } + _analogBits = res; + return AP3_OK; } ap3_err_t ap3_adc_setup() diff --git a/cores/arduino/ard_sup/ap3_analog.h b/cores/arduino/ard_sup/ap3_analog.h index ed57a6d2..e41af024 100644 --- a/cores/arduino/ard_sup/ap3_analog.h +++ b/cores/arduino/ard_sup/ap3_analog.h @@ -42,12 +42,11 @@ ap3_err_t ap3_analog_pad_funcsel(ap3_gpio_pad_t padNumber, uint8_t *funcsel); ap3_err_t ap3_change_channel(ap3_gpio_pad_t padNumber); uint16_t analogRead(uint8_t pinNumber); -void analogReadResolution(uint8_t bits); - -ap3_err_t analogWriteResolution( uint8_t res ); -ap3_err_t analogWrite( uint8_t pin, uint32_t val ); -ap3_err_t servoWriteResolution( uint8_t res ); -ap3_err_t servoWrite( uint8_t pin, uint32_t val ); +ap3_err_t analogReadResolution(uint8_t bits); +ap3_err_t analogWriteResolution(uint8_t res); +ap3_err_t analogWrite(uint8_t pin, uint32_t val); +ap3_err_t servoWriteResolution(uint8_t res); +ap3_err_t servoWrite(uint8_t pin, uint32_t val); #endif // _AP3_ANALOG_H_ \ No newline at end of file From a335fd60fe7e019e04b640c9f679af6abf592e51 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 1 Jul 2019 21:09:22 -0600 Subject: [PATCH 04/10] Fix some datasheet errors --- cores/arduino/ard_sup/analog/ap3_analog.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/cores/arduino/ard_sup/analog/ap3_analog.cpp b/cores/arduino/ard_sup/analog/ap3_analog.cpp index 98d23564..3a4bdbd1 100644 --- a/cores/arduino/ard_sup/analog/ap3_analog.cpp +++ b/cores/arduino/ard_sup/analog/ap3_analog.cpp @@ -107,13 +107,14 @@ static const uint8_t outcfg_tbl[32][4] = {OUTC(1, 4, 1), OUTC(0, 2, 0), OUTC(1, 4, 0), OUTC(1, 1, 1)}, // CTX19: B4OUT2, A2OUT, B4OUT, B1OUT2 {OUTC(0, 5, 0), OUTC(0, 1, 0), OUTC(0, 1, 1), OUTC(1, 2, 1)}, // CTX20: A5OUT, A1OUT, A1OUT2, B2OUT2 {OUTC(0, 5, 1), OUTC(0, 1, 0), OUTC(1, 5, 0), OUTC(0, 0, 1)}, // CTX21: A5OUT2, A1OUT, B5OUT, A0OUT2 - {OUTC(1, 5, 0), OUTC(0, 6, 0), OUTC(0, 1, 0), OUTC(0, 2, 1)}, // CTX22: B5OUT, A6OUT, A1OUT, A2OUT2 + //{OUTC(1, 5, 0), OUTC(0, 6, 0), OUTC(0, 1, 0), OUTC(0, 2, 1)}, // CTX22: B5OUT, (error B1OUT) A6OUT, (error remove)A1OUT, A2OUT2 + {OUTC(1, 5, 0), OUTC(1, 1, 0), OUTC(0, 6, 0), OUTC(0, 2, 1)}, // CTX22: B5OUT, B1OUT, A6OUT, A2OUT2 {OUTC(1, 5, 1), OUTC(0, 7, 0), OUTC(0, 5, 0), OUTC(1, 0, 1)}, // CTX23: B5OUT2, A7OUT, A5OUT, B0OUT2 {OUTC(0, 6, 0), OUTC(0, 2, 0), OUTC(0, 1, 0), OUTC(1, 1, 1)}, // CTX24: A6OUT, A2OUT, A1OUT, B1OUT2 {OUTC(1, 4, 1), OUTC(1, 2, 0), OUTC(0, 6, 0), OUTC(0, 2, 1)}, // CTX25: B4OUT2, B2OUT, A6OUT, A2OUT2 {OUTC(1, 6, 0), OUTC(1, 2, 0), OUTC(0, 5, 0), OUTC(0, 1, 1)}, // CTX26: B6OUT, B2OUT, A5OUT, A1OUT2 {OUTC(1, 6, 1), OUTC(0, 1, 0), OUTC(1, 6, 0), OUTC(1, 2, 1)}, // CTX27: B6OUT2, A1OUT, B6OUT, B2OUT2 - {OUTC(0, 7, 0), OUTC(0, 3, 0), OUTC(0, 5, 1), OUTC(1, 0, 1)}, // CTX28: A7OUT, A3OUT, A5OUT2, B0OUT2 + {OUTC(0, 7, 1), OUTC(0, 3, 0), OUTC(0, 5, 1), OUTC(1, 0, 1)}, // CTX28: A7OUT(error B?), A3OUT, A5OUT2, B0OUT2 {OUTC(1, 5, 1), OUTC(0, 1, 0), OUTC(0, 7, 0), OUTC(0, 3, 1)}, // CTX29: B5OUT2, A1OUT, A7OUT, A3OUT2 {OUTC(1, 7, 0), OUTC(1, 3, 0), OUTC(0, 4, 1), OUTC(0, 0, 1)}, // CTX30: B7OUT, B3OUT, A4OUT2, A0OUT2 {OUTC(1, 7, 1), OUTC(0, 6, 0), OUTC(1, 7, 0), OUTC(1, 3, 1)}, // CTX31: B7OUT2, A6OUT, B7OUT, B3OUT2 From 4519b26fd423ed332f388ba363ed74ef47be33df Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Wed, 3 Jul 2019 21:17:36 -0600 Subject: [PATCH 05/10] Getting to compile after rebase --- cores/arduino/ard_sup/analog/ap3_analog.cpp | 2 +- libraries/Servo/src/Servo.cpp | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/cores/arduino/ard_sup/analog/ap3_analog.cpp b/cores/arduino/ard_sup/analog/ap3_analog.cpp index f470a0af..cab891db 100644 --- a/cores/arduino/ard_sup/analog/ap3_analog.cpp +++ b/cores/arduino/ard_sup/analog/ap3_analog.cpp @@ -239,7 +239,7 @@ ap3_err_t analogReadResolution(uint8_t bits) _analogBits = 16; // max out the resolution when this happens return AP3_ERR; } - _analogBits = res; + _analogBits = bits; return AP3_OK; } diff --git a/libraries/Servo/src/Servo.cpp b/libraries/Servo/src/Servo.cpp index 56e0ae94..461fd109 100644 --- a/libraries/Servo/src/Servo.cpp +++ b/libraries/Servo/src/Servo.cpp @@ -48,11 +48,10 @@ void Servo::write(uint8_t servoPosition) servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions } -void Servo::writeMicroseconds(uint8_t servoPosition) -{ - - servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions -} +// void Servo::writeMicroseconds(uint8_t servoPosition) +// { +// servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions +// } void Servo::detach(void) { From 75d12a8952f605f6c340f26c32eda7e5ce8f85bf Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Sun, 18 Aug 2019 21:09:09 -0600 Subject: [PATCH 06/10] Add extended servoWrite that accepts min/max values in micros. Add getServoResolution(). Arduino allows for opening of the min/max RC PWM pulse. The previous 1ms/2ms min/max limited generic servos to only 90 degrees of movement. The Arduino defaults of 544/2400 open this to 180 degrees. --- cores/arduino/ard_sup/analog/ap3_analog.cpp | 17 +++++++++++++++-- cores/arduino/ard_sup/ap3_analog.h | 2 ++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/cores/arduino/ard_sup/analog/ap3_analog.cpp b/cores/arduino/ard_sup/analog/ap3_analog.cpp index a3ace4be..a940677c 100644 --- a/cores/arduino/ard_sup/analog/ap3_analog.cpp +++ b/cores/arduino/ard_sup/analog/ap3_analog.cpp @@ -658,15 +658,28 @@ ap3_err_t servoWriteResolution(uint8_t res) return AP3_OK; } +uint8_t getServoResolution() +{ + return(_servoWriteBits); +} + ap3_err_t servoWrite(uint8_t pin, uint32_t val) +{ + return(servoWrite(pin, val, 544, 2400)); //Call servoWrite with Arduino default min/max microseconds. See: https://www.arduino.cc/en/Reference/ServoAttach +} + +ap3_err_t servoWrite(uint8_t pin, uint32_t val, uint16_t minMicros, uint16_t maxMicros) { // Determine the high time based on input value and the current resolution setting uint32_t fsv = (0x01 << _servoWriteBits); // full scale value for the current resolution setting val = val % fsv; // prevent excess uint32_t clk = AM_HAL_CTIMER_HFRC_3MHZ; // Using 3 MHz to get fine-grained control up to 20 ms wide uint32_t fw = 60000; // 20 ms wide frame - uint32_t max = 6000; // max width of RC pwm pulse is 2 ms or 6000 counts - uint32_t min = 3000; // min width of RC pwm pulse is 1 ms or 3000 counts + + //Convert microSeconds to PWM counts. + uint32_t min = minMicros * 3; + uint32_t max = maxMicros * 3; + uint32_t th = (uint32_t)(((max - min) * val) / fsv) + min; return ap3_pwm_output(pin, th, fw, clk); diff --git a/cores/arduino/ard_sup/ap3_analog.h b/cores/arduino/ard_sup/ap3_analog.h index d0feb278..68d40b05 100644 --- a/cores/arduino/ard_sup/ap3_analog.h +++ b/cores/arduino/ard_sup/ap3_analog.h @@ -49,7 +49,9 @@ ap3_err_t ap3_pwm_output(uint8_t pin, uint32_t th, uint32_t fw, uint32_t clk); ap3_err_t analogWriteResolution(uint8_t res); ap3_err_t analogWrite(uint8_t pin, uint32_t val); ap3_err_t servoWriteResolution(uint8_t res); +uint8_t getServoResolution(); ap3_err_t servoWrite(uint8_t pin, uint32_t val); +ap3_err_t servoWrite(uint8_t pin, uint32_t val, uint16_t minMicros, uint16_t maxMicros); ap3_err_t tone(uint8_t pin, uint32_t freq); ap3_err_t tone(uint8_t pin, uint32_t freq, uint32_t duration); From e8e1d3736b563e106d8f48fb4f76b27354c17134 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Sun, 18 Aug 2019 21:09:36 -0600 Subject: [PATCH 07/10] Remove pad tracking. Increase map to include 180. --- libraries/Servo/src/Servo.cpp | 10 +++++----- libraries/Servo/src/Servo.h | 3 +-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/libraries/Servo/src/Servo.cpp b/libraries/Servo/src/Servo.cpp index 461fd109..84c13390 100644 --- a/libraries/Servo/src/Servo.cpp +++ b/libraries/Servo/src/Servo.cpp @@ -34,7 +34,7 @@ Servo::Servo() void Servo::attach(uint8_t pinNumber) { _servoPinNumber = pinNumber; - _servoPadNumber = ap3_gpio_pin2pad(pinNumber); + pinMode(_servoPinNumber, OUTPUT); } void Servo::write(uint8_t servoPosition) @@ -43,9 +43,9 @@ void Servo::write(uint8_t servoPosition) if (_servoPosition > 180) _servoPosition = 180; //Bounds check - uint16_t newServoPosition = map(servoPosition, 0, 180, 0, 1023); + uint16_t newServoPosition = map(servoPosition, 0, 181, 0, ((uint16_t)0x01 << getServoResolution())); - servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions + servoWrite(_servoPinNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions } // void Servo::writeMicroseconds(uint8_t servoPosition) @@ -55,9 +55,9 @@ void Servo::write(uint8_t servoPosition) void Servo::detach(void) { - _servoPinNumber = NULL; - _servoPadNumber = NULL; pinMode(_servoPinNumber, INPUT); //Will stop PWM output + + _servoPinNumber = 0; } uint8_t Servo::read(void) diff --git a/libraries/Servo/src/Servo.h b/libraries/Servo/src/Servo.h index b3a0ce9b..a65576cc 100644 --- a/libraries/Servo/src/Servo.h +++ b/libraries/Servo/src/Servo.h @@ -38,8 +38,7 @@ class Servo bool attached(uint8_t pinNumber); private: - uint8_t _servoPadNumber = NULL; - uint8_t _servoPinNumber = NULL; + uint8_t _servoPinNumber = 0; uint8_t _servoPosition; }; From 46c9198133add0772d77ce9422fd50517f408cf1 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Sun, 18 Aug 2019 21:54:50 -0600 Subject: [PATCH 08/10] Add min/max micros to attach. Add writeMicroseconds(). --- libraries/Servo/src/Servo.cpp | 23 ++++++++++++++++------- libraries/Servo/src/Servo.h | 4 ++++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/libraries/Servo/src/Servo.cpp b/libraries/Servo/src/Servo.cpp index 84c13390..5c9413ea 100644 --- a/libraries/Servo/src/Servo.cpp +++ b/libraries/Servo/src/Servo.cpp @@ -28,15 +28,22 @@ SOFTWARE. //Constructor Servo::Servo() { + } -//Assign global var -void Servo::attach(uint8_t pinNumber) +void Servo::attach(uint8_t pinNumber, uint16_t minMicros, uint16_t maxMicros) { _servoPinNumber = pinNumber; + _minMicros = minMicros; + _maxMicros = maxMicros; pinMode(_servoPinNumber, OUTPUT); } +void Servo::attach(uint8_t pinNumber) +{ + attach(pinNumber, 544, 2400); //Start with Arduino defaults +} + void Servo::write(uint8_t servoPosition) { _servoPosition = servoPosition; @@ -45,13 +52,15 @@ void Servo::write(uint8_t servoPosition) uint16_t newServoPosition = map(servoPosition, 0, 181, 0, ((uint16_t)0x01 << getServoResolution())); - servoWrite(_servoPinNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions + servoWrite(_servoPinNumber, newServoPosition, _minMicros, _maxMicros); } -// void Servo::writeMicroseconds(uint8_t servoPosition) -// { -// servoWrite(_servoPadNumber, newServoPosition); // This and the above write should both produce 1.5 ms wide pulses, though using different resolutions -// } +void Servo::writeMicroseconds(uint16_t microSecs) +{ + //Convert microseconds to PWM value + uint16_t newServoPosition = microSecs; + servoWrite(_servoPinNumber, newServoPosition, _minMicros, _maxMicros); +} void Servo::detach(void) { diff --git a/libraries/Servo/src/Servo.h b/libraries/Servo/src/Servo.h index a65576cc..c9a5f3ee 100644 --- a/libraries/Servo/src/Servo.h +++ b/libraries/Servo/src/Servo.h @@ -31,8 +31,10 @@ class Servo { public: Servo(); + void attach(uint8_t pinNumber, uint16_t minMicros, uint16_t maxMicros); void attach(uint8_t pinNumber); void write(uint8_t servoPosition); + void writeMicroseconds(uint16_t microSecs); void detach(void); uint8_t read(void); bool attached(uint8_t pinNumber); @@ -40,6 +42,8 @@ class Servo private: uint8_t _servoPinNumber = 0; uint8_t _servoPosition; + uint16_t _minMicros; + uint16_t _maxMicros; }; #endif // _AP3_SERVO_H_ From fa169b100bb1abbf5173c4543792711a72cdef46 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 19 Aug 2019 15:26:42 -0600 Subject: [PATCH 09/10] Add writeMicroseconds() and a few keywords. --- cores/arduino/ard_sup/ap3_gpio.h | 2 +- libraries/Servo/keywords.txt | 2 ++ libraries/Servo/src/Servo.cpp | 16 +++++++++++----- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/cores/arduino/ard_sup/ap3_gpio.h b/cores/arduino/ard_sup/ap3_gpio.h index 2b2df02f..03657b43 100644 --- a/cores/arduino/ard_sup/ap3_gpio.h +++ b/cores/arduino/ard_sup/ap3_gpio.h @@ -45,7 +45,7 @@ extern const am_hal_gpio_pincfg_t g_AM_HAL_GPIO_INPUT_PULLDOWN; #define AP3_GPIO_IS_VALID(pad) ((pad >= 0) && (pad < AP3_GPIO_MAX_PADS)) extern ap3_gpio_pad_t ap3_gpio_pin2pad(ap3_gpio_pin_t pin); -#define AP3_GPIO_PAD_UNUSED (-1) +#define AP3_GPIO_PAD_UNUSED (255) #define AP3_GPIO_DEFAULT_PINCFG AP3_GPIO_PINCFG_NULL diff --git a/libraries/Servo/keywords.txt b/libraries/Servo/keywords.txt index 39478d63..b8c1b5c9 100644 --- a/libraries/Servo/keywords.txt +++ b/libraries/Servo/keywords.txt @@ -17,6 +17,8 @@ read KEYWORD2 writeMicroseconds KEYWORD2 attached KEYWORD2 +servoWriteResolution KEYWORD2 +getServoResolution KEYWORD2 ####################################### # Instances (KEYWORD2) diff --git a/libraries/Servo/src/Servo.cpp b/libraries/Servo/src/Servo.cpp index 5c9413ea..73264225 100644 --- a/libraries/Servo/src/Servo.cpp +++ b/libraries/Servo/src/Servo.cpp @@ -28,7 +28,6 @@ SOFTWARE. //Constructor Servo::Servo() { - } void Servo::attach(uint8_t pinNumber, uint16_t minMicros, uint16_t maxMicros) @@ -51,15 +50,22 @@ void Servo::write(uint8_t servoPosition) _servoPosition = 180; //Bounds check uint16_t newServoPosition = map(servoPosition, 0, 181, 0, ((uint16_t)0x01 << getServoResolution())); - servoWrite(_servoPinNumber, newServoPosition, _minMicros, _maxMicros); } void Servo::writeMicroseconds(uint16_t microSecs) { - //Convert microseconds to PWM value - uint16_t newServoPosition = microSecs; - servoWrite(_servoPinNumber, newServoPosition, _minMicros, _maxMicros); + uint16_t extendedMin = _minMicros; + uint16_t extendedMax = _maxMicros; + + if (microSecs > _maxMicros) + extendedMax = microSecs; + if (microSecs < _minMicros) + extendedMin = microSecs; + + //Map microseconds to PWM value + uint16_t newServoPosition = map(microSecs, extendedMin, extendedMax + 1, 0, ((uint16_t)0x01 << getServoResolution())); + servoWrite(_servoPinNumber, newServoPosition, extendedMin, extendedMax); } void Servo::detach(void) From dd2eee4499987676f96f116db7b749b97ff4e044 Mon Sep 17 00:00:00 2001 From: Nathan Seidle Date: Mon, 19 Aug 2019 15:48:32 -0600 Subject: [PATCH 10/10] Addin examples --- .../Example1_BasicServo.ino | 48 +++++++ .../Example2_TwoServos/Example2_TwoServos.ino | 51 +++++++ .../Example3_SetEndpoints.ino | 41 ++++++ .../Example4_SetResolution.ino | 52 +++++++ .../Example5_writeMicroseconds.ino | 39 +++++ .../Example6_19servos/Example6_19servos.ino | 101 +++++++++++++ .../Example7_29servos/Example7_29servos.ino | 136 ++++++++++++++++++ 7 files changed, 468 insertions(+) create mode 100644 libraries/Servo/examples/Example1_BasicServo/Example1_BasicServo.ino create mode 100644 libraries/Servo/examples/Example2_TwoServos/Example2_TwoServos.ino create mode 100644 libraries/Servo/examples/Example3_SetEndpoints/Example3_SetEndpoints.ino create mode 100644 libraries/Servo/examples/Example4_SetResolution/Example4_SetResolution.ino create mode 100644 libraries/Servo/examples/Example5_writeMicroseconds/Example5_writeMicroseconds.ino create mode 100644 libraries/Servo/examples/Example6_19servos/Example6_19servos.ino create mode 100644 libraries/Servo/examples/Example7_29servos/Example7_29servos.ino diff --git a/libraries/Servo/examples/Example1_BasicServo/Example1_BasicServo.ino b/libraries/Servo/examples/Example1_BasicServo/Example1_BasicServo.ino new file mode 100644 index 00000000..7c0267a0 --- /dev/null +++ b/libraries/Servo/examples/Example1_BasicServo/Example1_BasicServo.ino @@ -0,0 +1,48 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + This example demonstrates the control of a servo on pin 8 on the RedBoard Artemis. Any PWM + pin can control a servo. + + Hardware Connections: + Load this code + Connect a Servo to pin 18: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> 8 + + The servo will rotate back and forth. +*/ + +#include + +Servo myServo; + +int pos = 0; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServo.attach(8); +} + +void loop() +{ + //Sweep + for (pos = 0; pos <= 180; pos++) { // goes from 0 degrees to 180 degrees + myServo.write(pos); // tell servo to go to position in variable 'pos' + delay(5); // waits 15ms for the servo to reach the position + } + for (pos = 180; pos >= 0; pos--) { // goes from 180 degrees to 0 degrees + myServo.write(pos); // tell servo to go to position in variable 'pos' + delay(5); // waits 15ms for the servo to reach the position + } +} diff --git a/libraries/Servo/examples/Example2_TwoServos/Example2_TwoServos.ino b/libraries/Servo/examples/Example2_TwoServos/Example2_TwoServos.ino new file mode 100644 index 00000000..5af61d51 --- /dev/null +++ b/libraries/Servo/examples/Example2_TwoServos/Example2_TwoServos.ino @@ -0,0 +1,51 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + This example demonstrates controlling two servos. + + Hardware Connections: + Load this code + Connect a Servo to pin 18: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> 8 + + The servo will rotate back and forth. +*/ + +#include + +Servo myServoA; +Servo myServoB; + +int pos = 0; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServoA.attach(8); + myServoB.attach(7); +} + +void loop() +{ + //Sweep + for (pos = 0; pos <= 180; pos++) { + myServoA.write(pos); + myServoB.write(180 - pos); + delay(5); + } + for (pos = 180; pos >= 0; pos--) { + myServoA.write(pos); + myServoB.write(180 - pos); + delay(5); + } +} diff --git a/libraries/Servo/examples/Example3_SetEndpoints/Example3_SetEndpoints.ino b/libraries/Servo/examples/Example3_SetEndpoints/Example3_SetEndpoints.ino new file mode 100644 index 00000000..5ceb49cc --- /dev/null +++ b/libraries/Servo/examples/Example3_SetEndpoints/Example3_SetEndpoints.ino @@ -0,0 +1,41 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + Different servos have different end points. Arduino defaults to 544us (min) and 2400us (max). + These however can be changed at startup. For more info see: https://www.arduino.cc/en/Reference/ServoAttach + + Hardware Connections: + Load this code + Connect a Servo to pin 18: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> 8 + + The servo will rotate back and forth. +*/ + +#include + +Servo myServoA; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServoA.attach(8, 500, 2600); //Increase min/max to drive servo fully +} + +void loop() +{ + myServoA.write(180); //Go to max position + delay(2000); + myServoA.write(0); //Go to min position + delay(2000); +} diff --git a/libraries/Servo/examples/Example4_SetResolution/Example4_SetResolution.ino b/libraries/Servo/examples/Example4_SetResolution/Example4_SetResolution.ino new file mode 100644 index 00000000..dd2c867a --- /dev/null +++ b/libraries/Servo/examples/Example4_SetResolution/Example4_SetResolution.ino @@ -0,0 +1,52 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + Arduino defaults to 8-pin PWM resolution. This works for the majority of servos but can + be increased for projects that need it. + + servoWriteResolution() + getServoResolution() + + Are provided for changing and reading the resolution setting. + + Hardware Connections: + Load this code + Connect a Servo to pin 18: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> 8 + + The servo will rotate back and forth. +*/ + +#include + +Servo myServoA; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServoA.attach(8); + + servoWriteResolution(10); //Increase to 10-bit resolution. 16-bit is max. + + int currentRes = getServoResolution(); + Serial.print("Current resolution: "); + Serial.println(currentRes); +} + +void loop() +{ + myServoA.write(180); //Go to max position + delay(2000); + myServoA.write(0); //Go to min position + delay(2000); +} diff --git a/libraries/Servo/examples/Example5_writeMicroseconds/Example5_writeMicroseconds.ino b/libraries/Servo/examples/Example5_writeMicroseconds/Example5_writeMicroseconds.ino new file mode 100644 index 00000000..52597ffc --- /dev/null +++ b/libraries/Servo/examples/Example5_writeMicroseconds/Example5_writeMicroseconds.ino @@ -0,0 +1,39 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + This example shows how to write to the servo in microseconds instead of position. This + is helpful for find the min/max us settings for a given servo manufacturer. + + Hardware Connections: + Load this code + Connect a Servo to RX1: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> RX1 + + The servo will rotate back and forth. +*/ + +#include + +Servo myServo; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServo.attach(8); + + myServo.writeMicroseconds(600); //Servo will go to very near the 0 degree position +} + +void loop() +{ +} diff --git a/libraries/Servo/examples/Example6_19servos/Example6_19servos.ino b/libraries/Servo/examples/Example6_19servos/Example6_19servos.ino new file mode 100644 index 00000000..057aabe9 --- /dev/null +++ b/libraries/Servo/examples/Example6_19servos/Example6_19servos.ino @@ -0,0 +1,101 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + This example demonstrates the control of 19 servos simulataneously on the BlackBoard Artemis. + Any PWM pin is capable of 16 bit servo control. Need more than 19 servos? What are you building?! + Check out the BlackBoard ATP for 29 servo capable PWM pins. + + Hardware Connections: + Load this code + Connect a Servo to RX1: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> RX1 + + The servo will rotate back and forth. Similary, you can move the signal wire to any PWM + pin and you will see the servo move to a new position and hold. This shows that the other + PWM pins are all simultaneously and actively outputting a servo signal. +*/ + +#include + +Servo myServoRX; +Servo myServoTX; +Servo myServo2; +Servo myServo3; +Servo myServo4; +Servo myServo5; +Servo myServo6; +Servo myServo7; +Servo myServo8; +Servo myServo9; +Servo myServo10; +Servo myServoMOSI; +Servo myServoMISO; +Servo myServoSCK; +Servo myServoA0; +Servo myServoA1; +Servo myServoA3; +Servo myServoA5; +Servo myServoSCL; + +int pos = 0; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServoRX.attach(0); //Labeled RX1 + myServoTX.attach(1); //Labeled TX1 + myServo2.attach(2); + myServo3.attach(3); + myServo4.attach(4); + myServo5.attach(5); + myServo6.attach(6); + myServo7.attach(7); + myServo8.attach(8); + myServo9.attach(9); + myServo10.attach(10); + myServoMOSI.attach(11); //Labeled MOSI + myServoMISO.attach(12); //Labeled MISO + myServoSCK.attach(13); //Labeled SCK + myServoA0.attach(A0); + myServoA1.attach(A1); + myServoA3.attach(A3); + myServoA5.attach(A5); + myServoSCL.attach(SCL); + + myServo2.write(0); + myServo3.write(10); + myServo4.write(30); + myServo5.write(60); + myServo6.write(90); + myServo7.write(120); + myServo8.write(140); + myServo9.write(160); + myServo10.write(180); + myServoMOSI.write(0); + myServoMISO.write(30); + myServoSCK.write(60); + myServoA0.write(90); + myServoA1.write(120); + myServoA3.write(150); + myServoA5.write(0); + myServoSCL.write(30); + myServoTX.write(60); +} + +void loop() +{ + myServoRX.write(0); + delay(1500); + myServoRX.write(180); + delay(1500); +} diff --git a/libraries/Servo/examples/Example7_29servos/Example7_29servos.ino b/libraries/Servo/examples/Example7_29servos/Example7_29servos.ino new file mode 100644 index 00000000..71976f6f --- /dev/null +++ b/libraries/Servo/examples/Example7_29servos/Example7_29servos.ino @@ -0,0 +1,136 @@ +/* + Author: Nathan Seidle + SparkFun Electronics + Created: August 18th, 2019 + License: MIT. See SparkFun Arduino Apollo3 Project for more information + + Purchasing from SparkFun helps write code like this and helps us + release products open source so that we can help each other learn: https://www.sparkfun.com/artemis + + This example demonstrates the control of 29 servos simulataneously on the BlackBoard Artemis ATP. + Any PWM pin is capable of 16 bit servo control. Need more than 29 servos? What are you building?! + + Hardware Connections: + Load this code + Connect a Servo to pin 18: + Red Wire -> 3.3V or 5V + Black Wire -> GND + Signal (Yellow or White) -> 18 + + The servo will rotate back and forth. Similary, you can move the signal wire to any PWM + pin and you will see the servo move to a new position and hold. This shows that the other + PWM pins are all simultaneously and actively outputting a servo signal. + + There are 30 PWM capable pads on the Artemis. Pin 47 is used for bootloading and is not + easily accessible. There are 29 easily accessible on the ATP. +*/ + +#include + +Servo myServoSCL; +Servo myServoSCK; +Servo myServoMISO; +Servo myServoMOSI; +Servo myServo13; +Servo myServo12; +Servo myServo32; +Servo myServo28; +Servo myServo27; +Servo myServo23; + +Servo myServo22; +Servo myServo4; +Servo myServo35; +Servo myServoTX1; +Servo myServoRX1; +Servo myServo26; +Servo myServo19; +Servo myServo18; +Servo myServo37; +Servo myServo44; + +Servo myServo42; +Servo myServo43; +Servo myServo45; +Servo myServo31; +Servo myServo33; +Servo myServo11; +Servo myServo29; +Servo myServo48; +Servo myServo49; + +void setup() +{ + Serial.begin(9600); + Serial.println("SparkFun Servo Example"); + + myServoSCL.attach(SCL); + myServoSCK.attach(5); //Labeled SCK + myServoMISO.attach(6); //Labeled MISO + myServoMOSI.attach(7); //Labeled MOSI + myServo13.attach(13); + myServo12.attach(12); + myServo32.attach(32); + myServo28.attach(28); + myServo27.attach(27); + myServo23.attach(23); + myServo22.attach(22); + myServo4.attach(4); + myServo35.attach(35); + myServoTX1.attach(24); //Labeled TX1 + myServoRX1.attach(25); //Labeled RX1 + myServo26.attach(26); + myServo19.attach(19); + myServo18.attach(18); + myServo37.attach(37); + myServo44.attach(44); + myServo42.attach(42); + myServo43.attach(43); + myServo45.attach(45); + myServo31.attach(31); + myServo33.attach(33); + myServo11.attach(11); + myServo29.attach(29); + myServo48.attach(48); //Labeled TX0 (used for bootloading) + myServo49.attach(49); //Labeled RX0 (used for bootloading) + + int startAmount = 600; + + myServoSCL.writeMicroseconds(startAmount + 0); //600 + myServoSCK.writeMicroseconds(startAmount + 50); //650 + myServoMISO.writeMicroseconds(startAmount + 100); //700 + myServoMOSI.writeMicroseconds(startAmount + 150); //750 + myServo13.writeMicroseconds(startAmount + 200); //800 + myServo12.writeMicroseconds(startAmount + 250); //850 + myServo32.writeMicroseconds(startAmount + 300); //900 + myServo28.writeMicroseconds(startAmount + 350); //950 + myServo27.writeMicroseconds(startAmount + 400); //1000 + myServo23.writeMicroseconds(startAmount + 450); //1050 + myServo22.writeMicroseconds(startAmount + 500); //1100 + myServo4.writeMicroseconds(startAmount + 550); //1150 + myServo35.writeMicroseconds(startAmount + 600); //1200 + myServoTX1.writeMicroseconds(startAmount + 650); //1250 + myServoRX1.writeMicroseconds(startAmount + 700); //1300 + myServo26.writeMicroseconds(startAmount + 750); //1350 + myServo19.writeMicroseconds(startAmount + 800); //1400 + myServo18.writeMicroseconds(startAmount + 850); //1450 + myServo37.writeMicroseconds(startAmount + 900); //1500 + myServo44.writeMicroseconds(startAmount + 950); //1550 + myServo42.writeMicroseconds(startAmount + 1000); //1600 + myServo43.writeMicroseconds(startAmount + 1050); //1650 + myServo45.writeMicroseconds(startAmount + 1100); //1700 + myServo31.writeMicroseconds(startAmount + 1150); //1750 + myServo33.writeMicroseconds(startAmount + 1200); //1800 + myServo11.writeMicroseconds(startAmount + 1250); //1850 + myServo29.writeMicroseconds(startAmount + 1300); //1900 + myServo48.writeMicroseconds(startAmount + 1350); //1950 + myServo49.writeMicroseconds(startAmount + 1400); //2000 +} + +void loop() +{ + myServo18.write(0); + delay(1500); + myServo18.write(180); + delay(1500); +}