diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c8472c3..b58c2af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,7 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p Please ensure to specify the following: * Arduino IDE version (e.g. 1.8.19) or Platform.io version -* `NRF52` Core Version (e.g. Adafruit NRF52 core v1.3.0) +* `NRF52` Core Version (e.g. Adafruit NRF52 core v1.3.0, Seeed nRF52 core v1.0.0) * Contextual information (e.g. what you were trying to achieve) * Simplest possible steps to reproduce * Anything that might be relevant in your opinion, such as: @@ -27,12 +27,13 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.19 -Arduino NRF52 Core Version 1.3.0 +Adafruit NRF52 Core Version 1.3.0 +NRF52840_ITSYBITSY OS: Ubuntu 20.04 LTS -Linux xy-Inspiron-3593 5.13.0-40-generic #45~20.04.1-Ubuntu SMP Mon Apr 4 09:38:31 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux +Linux xy-Inspiron-3593 5.15.0-52-generic #58~20.04.1-Ubuntu SMP Thu Oct 13 13:09:46 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux Context: -I encountered a crash while trying to use the Timer Interrupt. +I encountered a crash while using this library Steps to reproduce: 1. ... @@ -41,13 +42,32 @@ Steps to reproduce: 4. ... ``` +--- + ### Sending Feature Requests Feel free to post feature requests. It's helpful if you can explain exactly why the feature would be useful. There are usually some outstanding feature requests in the [existing issues list](https://github.com/khoih-prog/NRF52_ISR_Servo/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. +--- + ### Sending Pull Requests Pull Requests with changes and fixes are also welcome! +Please use the `astyle` to reformat the updated library code as follows (demo for Ubuntu Linux) + +1. Change directory to the library GitHub + +``` +xy@xy-Inspiron-3593:~$ cd Arduino/xy/NRF52_ISR_Servo_GitHub/ +xy@xy-Inspiron-3593:~/Arduino/xy/NRF52_ISR_Servo_GitHub$ +``` + +2. Issue astyle command + +``` +xy@xy-Inspiron-3593:~/Arduino/xy/NRF52_ISR_Servo_GitHub$ bash utils/restyle.sh +``` + diff --git a/changelog.md b/changelog.md index 768ab58..bd95274 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,7 @@ ## Table of Contents * [Changelog](#changelog) + * [Releases v1.2.1](#releases-v121) * [Releases v1.2.0](#releases-v120) * [Releases v1.1.0](#releases-v110) * [Releases v1.0.0](#releases-v100) @@ -22,6 +23,12 @@ ## Changelog +### Releases v1.2.1 + +1. Add support to Seeeduino nRF52840-based boards such as **Seeed_XIAO_NRF52840 and Seeed_XIAO_NRF52840_SENSE**, etc. using Seeeduino `nRF52` core +2. Add astyle using `allman` style. Restyle the library +3. Update `Packages' Patches` to add Seeeduino `nRF52` core + ### Releases v1.2.0 1. Permit using servos with different pulse ranges simultaneously. Check [Fix Bug #5 : Permit using servos with different pulse ranges simultaneously #4](https://github.com/khoih-prog/RP2040_ISR_Servo/pull/4) diff --git a/examples/multiFileProject/multiFileProject.cpp b/examples/multiFileProject/multiFileProject.cpp index 6f51e94..a2076f0 100644 --- a/examples/multiFileProject/multiFileProject.cpp +++ b/examples/multiFileProject/multiFileProject.cpp @@ -1,9 +1,9 @@ /**************************************************************************************************************************** multiFileProject.cpp For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo diff --git a/examples/multiFileProject/multiFileProject.h b/examples/multiFileProject/multiFileProject.h index 0e7be01..3980abf 100644 --- a/examples/multiFileProject/multiFileProject.h +++ b/examples/multiFileProject/multiFileProject.h @@ -1,9 +1,9 @@ /**************************************************************************************************************************** multiFileProject.h For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo diff --git a/examples/multiFileProject/multiFileProject.ino b/examples/multiFileProject/multiFileProject.ino index 4bfd826..028557a 100644 --- a/examples/multiFileProject/multiFileProject.ino +++ b/examples/multiFileProject/multiFileProject.ino @@ -1,9 +1,9 @@ /**************************************************************************************************************************** multiFileProject.ino For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo @@ -12,39 +12,35 @@ // To demo how to include files in multi-file Projects -#if !(defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \ - defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || \ - defined(NRF52840_CLUE) || defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || \ - defined(MDBT50Q_RX) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) ) - #error This code is designed to run on nRF52 platform! Please check your Tools->Board setting. -#endif - -#define NRF52_ISR_SERVO_VERSION_MIN_TARGET "NRF52_ISR_Servo v1.1.0" -#define NRF52_ISR_SERVO_VERSION_MIN 1001000 +#define NRF52_ISR_SERVO_VERSION_MIN_TARGET "NRF52_ISR_Servo v1.2.1" +#define NRF52_ISR_SERVO_VERSION_MIN 1002001 #include "multiFileProject.h" // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "NRF52_ISR_Servo.h" -void setup() +void setup() { Serial.begin(115200); - while (!Serial); - - Serial.println("\nStart multiFileProject"); + + while (!Serial && millis() < 5000); + + Serial.println("\nStart multiFileProjects on "); Serial.println(BOARD_NAME); Serial.println(NRF52_ISR_SERVO_VERSION); #if defined(NRF52_ISR_SERVO_VERSION_MIN) + if (NRF52_ISR_SERVO_VERSION_INT < NRF52_ISR_SERVO_VERSION_MIN) { Serial.print("Warning. Must use this example on Version equal or later than : "); Serial.println(NRF52_ISR_SERVO_VERSION_MIN_TARGET); } + #endif } -void loop() +void loop() { // put your main code here, to run repeatedly: } diff --git a/examples/nRF52_MultipleRandomServos/nRF52_MultipleRandomServos.ino b/examples/nRF52_MultipleRandomServos/nRF52_MultipleRandomServos.ino index 11931c6..916e30a 100644 --- a/examples/nRF52_MultipleRandomServos/nRF52_MultipleRandomServos.ino +++ b/examples/nRF52_MultipleRandomServos/nRF52_MultipleRandomServos.ino @@ -1,9 +1,9 @@ /**************************************************************************************************************************** NRF52_MultipleRandomServos.ino For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo @@ -30,7 +30,7 @@ considerable power, we will connect servo power to the VBat pin of the NRF52 (located near the USB connector). THIS IS ONLY APPROPRIATE FOR SMALL SERVOS. - We could also connect servo power to a separate external power source (as long as we connect all of + We could also connect servo power to a separate external power source (as long as we connect all of the grounds (NRF52, servo, and external power). In this example, we just connect NRF52 ground to servo ground. The servo signal pins connect to any available GPIO pins on the NRF52 (in this example, we use pins (D1-D6). @@ -42,13 +42,6 @@ Experimentally, 800 and 2450 are pretty close to 0 and 180. *****************************************************************************************************************************/ -#if !(defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \ - defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || \ - defined(NRF52840_CLUE) || defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || \ - defined(MDBT50Q_RX) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) ) - #error This code is designed to run on nRF52 platform! Please check your Tools->Board setting. -#endif - #define TIMER_INTERRUPT_DEBUG 4 #define ISR_SERVO_DEBUG 4 @@ -56,7 +49,7 @@ // Published values for SG90 servos; adjust if needed #define MIN_MICROS 800 -#define MAX_MICROS 2450 +#define MAX_MICROS 2450 #define SERVO_PIN_1 A0 #define SERVO_PIN_2 A1 @@ -80,9 +73,10 @@ ISR_servo_t ISR_servo[] = void setup() -{ +{ Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(200); @@ -95,12 +89,14 @@ void setup() if (ISR_servo[index].servoIndex != -1) { - Serial.print(F("Setup OK Servo index = ")); Serial.println(ISR_servo[index].servoIndex); + Serial.print(F("Setup OK Servo index = ")); + Serial.println(ISR_servo[index].servoIndex); NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, 0); } else { - Serial.print(F("Setup Failed Servo index = ")); Serial.println(ISR_servo[index].servoIndex); + Serial.print(F("Setup Failed Servo index = ")); + Serial.println(ISR_servo[index].servoIndex); } } } @@ -121,41 +117,42 @@ void loop() position = 0; Serial.println(F("Servos @ 0 degree")); - + for (int index = 0; index < NUM_SERVOS; index++) { NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position ); printServoInfo(index); } + // waits 5s between test delay(5000); position = 90; Serial.println(F("Servos @ 90 degree")); - + for (int index = 0; index < NUM_SERVOS; index++) { NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position ); printServoInfo(index); } - + // waits 5s between test delay(5000); position = 180; Serial.println(F("Servos @ 180 degree")); - + for (int index = 0; index < NUM_SERVOS; index++) { NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position ); printServoInfo(index); } - + // waits 5s between test delay(5000); Serial.println(F("Servos sweeps from 0-180 degree")); - + for (position = 0; position <= 180; position += 5) { // goes from 0 degrees to 180 degrees @@ -164,11 +161,11 @@ void loop() { NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position ); } - + // waits 0.1s for the servo to reach the position delay(100); } - + // waits 5s between test delay(5000); } diff --git a/examples/nRF52_MultipleServos/nRF52_MultipleServos.ino b/examples/nRF52_MultipleServos/nRF52_MultipleServos.ino index 6d5f34a..997903f 100644 --- a/examples/nRF52_MultipleServos/nRF52_MultipleServos.ino +++ b/examples/nRF52_MultipleServos/nRF52_MultipleServos.ino @@ -1,9 +1,9 @@ /**************************************************************************************************************************** NRF52_MultipleServos.ino For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo @@ -30,7 +30,7 @@ considerable power, we will connect servo power to the VBat pin of the NRF52 (located near the USB connector). THIS IS ONLY APPROPRIATE FOR SMALL SERVOS. - We could also connect servo power to a separate external power source (as long as we connect all of + We could also connect servo power to a separate external power source (as long as we connect all of the grounds (NRF52, servo, and external power). In this example, we just connect NRF52 ground to servo ground. The servo signal pins connect to any available GPIO pins on the NRF52 (in this example, we use pins (D1-D6). @@ -42,13 +42,6 @@ Experimentally, 800 and 2450 are pretty close to 0 and 180. *****************************************************************************************************************************/ -#if !(defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \ - defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || \ - defined(NRF52840_CLUE) || defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || \ - defined(MDBT50Q_RX) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) ) - #error This code is designed to run on nRF52 platform! Please check your Tools->Board setting. -#endif - #define TIMER_INTERRUPT_DEBUG 1 #define ISR_SERVO_DEBUG 1 @@ -79,27 +72,30 @@ ISR_servo_t ISR_servo[] = }; void setup() -{ +{ Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(200); Serial.print(F("\nStarting NRF52_MultipleServos on ")); Serial.println(BOARD_NAME); Serial.println(NRF52_ISR_SERVO_VERSION); - + for (int index = 0; index < NUM_SERVOS; index++) { ISR_servo[index].servoIndex = NRF52_ISR_Servos.setupServo(ISR_servo[index].servoPin, MIN_MICROS, MAX_MICROS); if (ISR_servo[index].servoIndex != -1) { - Serial.print(F("Setup OK, Servo index = ")); Serial.println(ISR_servo[index].servoIndex); + Serial.print(F("Setup OK, Servo index = ")); + Serial.println(ISR_servo[index].servoIndex); NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, 0); } else { - Serial.print(F("Setup Failed, Servo index = ")); Serial.println(ISR_servo[index].servoIndex); + Serial.print(F("Setup Failed, Servo index = ")); + Serial.println(ISR_servo[index].servoIndex); } } } @@ -116,7 +112,7 @@ void loop() { NRF52_ISR_Servos.setPosition(ISR_servo[index].servoIndex, position); } - + // waits 1s for the servo to reach the position delay(1000); } diff --git a/library.json b/library.json index 3c720b0..30c2571 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "NRF52_ISR_Servo", - "version": "1.2.0", + "version": "1.2.1", "keywords": "timing, device, control, timer, interrupt, isr, pwm, servo, isr-servo, hardware-timer, mission-critical, accuracy, precise, non-blocking, nrf52, nrf52840, nrf52832, feather-nrf52840, sparkfun-nrf52840, itsybitsy-nrf52840", "description": "This library enables you to use 1 Hardware PWM module on nRF52832/nRF52840-based board, such as AdaFruit Feather nRF52832, nRF52840 Express, Itsy-Bitsy nRF52840 Express, etc. to control up to 16 or more servo motors.", "authors": diff --git a/library.properties b/library.properties index 427095f..3b787ee 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=NRF52_ISR_Servo -version=1.2.0 +version=1.2.1 author=Khoi Hoang maintainer=Khoi Hoang license=MIT diff --git a/platformio/platformio.ini b/platformio/platformio.ini index 0d8a6b8..f6ac963 100644 --- a/platformio/platformio.ini +++ b/platformio/platformio.ini @@ -36,6 +36,8 @@ upload_speed = 921600 ; Checks for the compatibility with frameworks and dev/platforms lib_compat_mode = strict +lib_ldf_mode = chain+ +;lib_ldf_mode = deep+ lib_deps = diff --git a/src/NRF52_ISR_Servo.h b/src/NRF52_ISR_Servo.h index 22fd770..a059f26 100644 --- a/src/NRF52_ISR_Servo.h +++ b/src/NRF52_ISR_Servo.h @@ -1,21 +1,22 @@ /**************************************************************************************************************************** NRF52_ISR_Servo.h For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo Licensed under MIT license - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 22/08/2021 Initial coding for nRF52832/nRF52840 boards 1.1.0 K Hoang 03/03/2022 Convert to `h-only` style. Optimize code. Add support to `Sparkfun Pro nRF52840 Mini` 1.2.0 K Hoang 23/04/2022 Permit using servos with different pulse ranges simultaneously. Delete left-over `cpp` + 1.2.1 K Hoang 26/10/2022 Add support to Seeed_XIAO_NRF52840 and Seeed_XIAO_NRF52840_SENSE *****************************************************************************************************************************/ #pragma once diff --git a/src/NRF52_ISR_Servo.hpp b/src/NRF52_ISR_Servo.hpp index 88d3929..7c74399 100644 --- a/src/NRF52_ISR_Servo.hpp +++ b/src/NRF52_ISR_Servo.hpp @@ -9,13 +9,14 @@ Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo Licensed under MIT license - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 22/08/2021 Initial coding for nRF52832/nRF52840 boards 1.1.0 K Hoang 03/03/2022 Convert to `h-only` style. Optimize code. Add support to `Sparkfun Pro nRF52840 Mini` 1.2.0 K Hoang 23/04/2022 Permit using servos with different pulse ranges simultaneously. Delete left-over `cpp` + 1.2.1 K Hoang 26/10/2022 Add support to Seeed_XIAO_NRF52840 and Seeed_XIAO_NRF52840_SENSE *****************************************************************************************************************************/ #pragma once @@ -23,24 +24,39 @@ #ifndef NRF52_ISR_Servo_HPP #define NRF52_ISR_Servo_HPP +//////////////////////////////////////// + #if !(defined(NRF52840_FEATHER) || defined(NRF52832_FEATHER) || defined(NRF52_SERIES) || defined(ARDUINO_NRF52_ADAFRUIT) || \ defined(NRF52840_FEATHER_SENSE) || defined(NRF52840_ITSYBITSY) || defined(NRF52840_CIRCUITPLAY) || \ defined(NRF52840_CLUE) || defined(NRF52840_METRO) || defined(NRF52840_PCA10056) || defined(PARTICLE_XENON) || \ - defined(MDBT50Q_RX) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) ) - #error This code is designed to run on nRF52 platform! Please check your Tools->Board setting. + defined(NRF52840_LED_GLASSES) || defined(MDBT50Q_RX) || defined(NINA_B302_ublox) || defined(NINA_B112_ublox) || \ + defined(ARDUINO_Seeed_XIAO_nRF52840) || defined(ARDUINO_Seeed_XIAO_nRF52840_Sense) ) + #error This code is designed to run on Adafruit or Seeed nRF52 platform! Please check your Tools->Board setting. +#endif + +//////////////////////////////////////// + +#if !defined(BOARD_NAME) + #if defined(ARDUINO_Seeed_XIAO_nRF52840) + #define BOARD_NAME "Seeed_XIAO_nRF52840" + #elif defined(ARDUINO_Seeed_XIAO_nRF52840_Sense) + #define BOARD_NAME "Seeed_XIAO_nRF52840_Sense" + #endif #endif +//////////////////////////////////////// + #include "Arduino.h" #include #if !defined(NRF52_ISR_SERVO_VERSION) - #define NRF52_ISR_SERVO_VERSION "NRF52_ISR_Servo v1.2.0" + #define NRF52_ISR_SERVO_VERSION "NRF52_ISR_Servo v1.2.1" #define NRF52_ISR_SERVO_VERSION_MAJOR 1 #define NRF52_ISR_SERVO_VERSION_MINOR 2 - #define NRF52_ISR_SERVO_VERSION_PATCH 0 + #define NRF52_ISR_SERVO_VERSION_PATCH 1 - #define NRF52_ISR_SERVO_VERSION_INT 1002000 + #define NRF52_ISR_SERVO_VERSION_INT 1002001 #endif @@ -65,6 +81,8 @@ #define NRF52_MAX_PIN NUM_DIGITAL_PINS #define NRF52_WRONG_PIN 255 +//////////////////////////////////////// + // From Servo.h - Copyright (c) 2009 Michael Margolis. All right reserved. #define MIN_PULSE_WIDTH 800 // the shortest pulse sent to a servo @@ -72,6 +90,8 @@ #define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached #define REFRESH_INTERVAL 20000 // minumim time to refresh servos in microseconds +//////////////////////////////////////// + /** * NRF52 Only definitions * --------------------- @@ -83,11 +103,15 @@ #define MAXVALUE MAX_PULSE_WIDTH #define CLOCKDIV PWM_PRESCALER_PRESCALER_DIV_128 +//////////////////////////////////////// + enum { SERVO_TOKEN = 0x76726553 // 'S' 'e' 'r' 'v' }; +//////////////////////////////////////// + class NRF52_ISR_Servo { public: @@ -101,11 +125,10 @@ class NRF52_ISR_Servo ~NRF52_ISR_Servo() { } - - ////////////////////////////////////////////////// + + //////////////////////////////////////// // Bind servo to the timer and pin, return servoIndex - //int8_t setupServo(const uint8_t& pin, const uint16_t& minUs = MIN_PULSE_WIDTH, const uint16_t& maxUs = MAX_PULSE_WIDTH, int value = 0); int8_t setupServo(const uint8_t& pin, const uint16_t& minPulseUs = MIN_PULSE_WIDTH, const uint16_t& maxPulseUs = MAX_PULSE_WIDTH, uint16_t value = 0); @@ -157,8 +180,10 @@ class NRF52_ISR_Servo // returns the number of used servos int8_t getNumServos(); + //////////////////////////////////////// + // returns the number of available servos - int8_t getNumAvailableServos() + inline int8_t getNumAvailableServos() { if (numServos <= 0) return MAX_SERVOS; @@ -166,8 +191,12 @@ class NRF52_ISR_Servo return MAX_SERVOS - numServos; }; + //////////////////////////////////////// + private: + //////////////////////////////////////// + void init() { for (int8_t servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) @@ -181,14 +210,14 @@ class NRF52_ISR_Servo numServos = 0; } - - ////////////////////////////////////////////////// + + //////////////////////////////////////// // find the first available slot int8_t findFirstFreeSlot(); - - ////////////////////////////////////////////////// - + + //////////////////////////////////////// + typedef struct { uint8_t pin; // pin servo connected to @@ -200,14 +229,15 @@ class NRF52_ISR_Servo HardwarePWM* pwm; } servo_t; - - ////////////////////////////////////////////////// - + + //////////////////////////////////////// + volatile servo_t servo[MAX_SERVOS]; // actual number of servos in use (-1 means uninitialized) volatile int8_t numServos; }; +//////////////////////////////////////// #endif // NRF52_ISR_Servo_HPP diff --git a/src/NRF52_ISR_Servo_Debug.h b/src/NRF52_ISR_Servo_Debug.h index e058b1a..1363892 100644 --- a/src/NRF52_ISR_Servo_Debug.h +++ b/src/NRF52_ISR_Servo_Debug.h @@ -1,21 +1,22 @@ /**************************************************************************************************************************** NRF52_ISR_Servo_Debug.h For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo Licensed under MIT license - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 22/08/2021 Initial coding for nRF52832/nRF52840 boards 1.1.0 K Hoang 03/03/2022 Convert to `h-only` style. Optimize code. Add support to `Sparkfun Pro nRF52840 Mini` 1.2.0 K Hoang 23/04/2022 Permit using servos with different pulse ranges simultaneously. Delete left-over `cpp` + 1.2.1 K Hoang 26/10/2022 Add support to Seeed_XIAO_NRF52840 and Seeed_XIAO_NRF52840_SENSE *****************************************************************************************************************************/ #pragma once diff --git a/src/NRF52_ISR_Servo_Impl.h b/src/NRF52_ISR_Servo_Impl.h index 8af6406..ed87ab6 100644 --- a/src/NRF52_ISR_Servo_Impl.h +++ b/src/NRF52_ISR_Servo_Impl.h @@ -1,21 +1,22 @@ /**************************************************************************************************************************** NRF52_ISR_Servo_Impl.h For : - - nRF52832-based boards such as AdaFruit Feather nRF52832, + - nRF52832-based boards such as AdaFruit Feather nRF52832, - nRF52840-based boards such as Adafruit nRF52840 Express, Itsy-Bitsy nRF52840 Express, NINA_B302_ublox, etc. - + Written by Khoi Hoang Built by Khoi Hoang https://github.com/khoih-prog/NRF52_ISR_Servo Licensed under MIT license - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K Hoang 22/08/2021 Initial coding for nRF52832/nRF52840 boards 1.1.0 K Hoang 03/03/2022 Convert to `h-only` style. Optimize code. Add support to `Sparkfun Pro nRF52840 Mini` 1.2.0 K Hoang 23/04/2022 Permit using servos with different pulse ranges simultaneously. Delete left-over `cpp` + 1.2.1 K Hoang 26/10/2022 Add support to Seeed_XIAO_NRF52840 and Seeed_XIAO_NRF52840_SENSE *****************************************************************************************************************************/ #pragma once @@ -23,23 +24,29 @@ #ifndef NRF52_ISR_SERVO_IMPL_H #define NRF52_ISR_SERVO_IMPL_H +//////////////////////////////////////// + #include +//////////////////////////////////////// + #ifndef ISR_SERVO_DEBUG #define ISR_SERVO_DEBUG 1 #endif +//////////////////////////////////////// + #define DEFAULT_NRF52_TIMER_NO NRF_TIMER_1 // NRF_TIMER_1 for many boards static NRF52_ISR_Servo NRF52_ISR_Servos; // create servo object to control up to 16 servos -////////////////////////////////////////////////// +//////////////////////////////////////// NRF52_ISR_Servo::NRF52_ISR_Servo() : numServos (-1) { } -////////////////////////////////////////////////// +//////////////////////////////////////// // find the first available slot // return -1 if none found @@ -64,13 +71,14 @@ int8_t NRF52_ISR_Servo::findFirstFreeSlot() return -1; } -////////////////////////////////////////////////// +//////////////////////////////////////// //int8_t NRF52_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& minUs, const uint16_t& maxUs, int value) -int8_t NRF52_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& minPulseUs, const uint16_t& maxPulseUs, uint16_t value) +int8_t NRF52_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& minPulseUs, const uint16_t& maxPulseUs, + uint16_t value) { int8_t servoIndex; - + if (pin > NRF52_MAX_PIN) return -1; @@ -78,23 +86,23 @@ int8_t NRF52_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& minPulseU init(); servoIndex = findFirstFreeSlot(); - + if (servoIndex < 0) return -1; - + pinMode(pin, OUTPUT); - + servo[servoIndex].maxPulseUs = maxPulseUs; servo[servoIndex].minPulseUs = minPulseUs; - + servo[servoIndex].position = 0; numServos++; - + /////////////////////////////////////////// - + bool succeeded = false; - + // Adafruit, add pin to 1 of available Hw PWM // first, use existing HWPWM modules (already owned by Servo) for ( int i = 0; i < HWPWM_MODULE_NUM; i++ ) @@ -124,10 +132,10 @@ int8_t NRF52_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& minPulseU if ( succeeded ) { pinMode(pin, OUTPUT); - + servo[servoIndex].pin = pin; servo[servoIndex].enabled = true; - + servo[servoIndex].pwm->setMaxValue(MAXVALUE); servo[servoIndex].pwm->setClockDiv(CLOCKDIV); @@ -137,18 +145,19 @@ int8_t NRF52_ISR_Servo::setupServo(const uint8_t& pin, const uint16_t& minPulseU { return -1; } - + /////////////////////////////////////////// - + ISR_SERVO_LOGDEBUG1("Index =", servoIndex); ISR_SERVO_LOGDEBUG3("min =", servo[servoIndex].minPulseUs, ", max =", servo[servoIndex].maxPulseUs); - - Serial.print("setupServo Index ="); Serial.println(servoIndex); - + + Serial.print("setupServo Index ="); + Serial.println(servoIndex); + return servoIndex; } -///////////////////////////////////////////////////// +////////////////////////////////////////// void NRF52_ISR_Servo::write(const uint8_t& servoIndex, uint16_t value) { @@ -159,24 +168,24 @@ void NRF52_ISR_Servo::write(const uint8_t& servoIndex, uint16_t value) value = constrain(value, 0, 180); value = map(value, 0, 180, servo[servoIndex].minPulseUs, servo[servoIndex].maxPulseUs); } - + writeMicroseconds(servoIndex, value); } -///////////////////////////////////////////////////// +////////////////////////////////////////// -void NRF52_ISR_Servo::writeMicroseconds(const uint8_t& servoIndex, uint16_t value) +void NRF52_ISR_Servo::writeMicroseconds(const uint8_t& servoIndex, uint16_t value) { value = constrain(value, servo[servoIndex].minPulseUs, servo[servoIndex].maxPulseUs); servo[servoIndex].position = value; if ( (servo[servoIndex].enabled) && (servo[servoIndex].pwm) ) { - servo[servoIndex].pwm->writePin(servo[servoIndex].pin, value/DUTY_CYCLE_RESOLUTION); + servo[servoIndex].pwm->writePin(servo[servoIndex].pin, value / DUTY_CYCLE_RESOLUTION); } } -///////////////////////////////////////////////////// +////////////////////////////////////////// bool NRF52_ISR_Servo::setPosition(const uint8_t& servoIndex, uint16_t position) { @@ -185,20 +194,20 @@ bool NRF52_ISR_Servo::setPosition(const uint8_t& servoIndex, uint16_t position) // Updates interval of existing specified servo if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= NRF52_MAX_PIN) ) - { + { // treat any value less than MIN_PULSE_WIDTH as angle in degrees (values equal or larger are handled as microseconds) - if (position < MIN_PULSE_WIDTH) + if (position < MIN_PULSE_WIDTH) { // assumed to be 0-180 degrees servo position = constrain(position, 0, 180); position = map(position, 0, 180, servo[servoIndex].minPulseUs, servo[servoIndex].maxPulseUs); } - + servo[servoIndex].position = position; - + writeMicroseconds(servoIndex, position); - ISR_SERVO_LOGDEBUG3("Idx =", servoIndex, ", pos =",servo[servoIndex].position); + ISR_SERVO_LOGDEBUG3("Idx =", servoIndex, ", pos =", servo[servoIndex].position); return true; } @@ -207,7 +216,7 @@ bool NRF52_ISR_Servo::setPosition(const uint8_t& servoIndex, uint16_t position) return false; } -////////////////////////////////////////////////// +//////////////////////////////////////// // returns last position in degrees if success, or -1 on wrong servoIndex int NRF52_ISR_Servo::getPosition(const uint8_t& servoIndex) @@ -218,7 +227,7 @@ int NRF52_ISR_Servo::getPosition(const uint8_t& servoIndex) // Updates interval of existing specified servo if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= NRF52_MAX_PIN) ) { - ISR_SERVO_LOGERROR3("Idx =", servoIndex, ", pos =",servo[servoIndex].position); + ISR_SERVO_LOGERROR3("Idx =", servoIndex, ", pos =", servo[servoIndex].position); return (servo[servoIndex].position); } @@ -227,7 +236,7 @@ int NRF52_ISR_Servo::getPosition(const uint8_t& servoIndex) return -1; } -////////////////////////////////////////////////// +//////////////////////////////////////// // setPulseWidth will set servo PWM Pulse Width in microseconds, correcponding to certain position in degrees // by using PWM, turn HIGH 'pulseWidth' microseconds within REFRESH_INTERVAL (20000us) @@ -248,7 +257,7 @@ bool NRF52_ISR_Servo::setPulseWidth(const uint8_t& servoIndex, uint16_t& pulseWi servo[servoIndex].position = map(pulseWidth, servo[servoIndex].minPulseUs, servo[servoIndex].maxPulseUs, 0, 180); - ISR_SERVO_LOGERROR3("Idx =", servoIndex, ", pos =",servo[servoIndex].position); + ISR_SERVO_LOGERROR3("Idx =", servoIndex, ", pos =", servo[servoIndex].position); return true; } @@ -257,7 +266,7 @@ bool NRF52_ISR_Servo::setPulseWidth(const uint8_t& servoIndex, uint16_t& pulseWi return false; } -////////////////////////////////////////////////// +//////////////////////////////////////// // returns pulseWidth in microsecs (within min/max range) if success, or 0 on wrong servoIndex unsigned int NRF52_ISR_Servo::getPulseWidth(const uint8_t& servoIndex) @@ -268,7 +277,7 @@ unsigned int NRF52_ISR_Servo::getPulseWidth(const uint8_t& servoIndex) // Updates interval of existing specified servo if ( servo[servoIndex].enabled && (servo[servoIndex].pin <= NRF52_MAX_PIN) ) { - ISR_SERVO_LOGERROR3("Idx =", servoIndex, ", pos =",servo[servoIndex].position); + ISR_SERVO_LOGERROR3("Idx =", servoIndex, ", pos =", servo[servoIndex].position); return (servo[servoIndex].position); } @@ -277,7 +286,7 @@ unsigned int NRF52_ISR_Servo::getPulseWidth(const uint8_t& servoIndex) return 0; } -////////////////////////////////////////////////// +//////////////////////////////////////// void NRF52_ISR_Servo::deleteServo(const uint8_t& servoIndex) { @@ -299,13 +308,13 @@ void NRF52_ISR_Servo::deleteServo(const uint8_t& servoIndex) // update number of servos numServos--; - + // remove pin from HW PWM HardwarePWM * pwm = servo[servoIndex].pwm; servo[servoIndex].pwm = nullptr; pwm->removePin(servo[servoIndex].pin); - - if (pwm->usedChannelCount() == 0) + + if (pwm->usedChannelCount() == 0) { pwm->stop(); // disables peripheral so can release ownership pwm->releaseOwnership(SERVO_TOKEN); @@ -313,7 +322,7 @@ void NRF52_ISR_Servo::deleteServo(const uint8_t& servoIndex) } } -////////////////////////////////////////////////// +//////////////////////////////////////// bool NRF52_ISR_Servo::isEnabled(const uint8_t& servoIndex) { @@ -331,7 +340,7 @@ bool NRF52_ISR_Servo::isEnabled(const uint8_t& servoIndex) return servo[servoIndex].enabled; } -////////////////////////////////////////////////// +//////////////////////////////////////// bool NRF52_ISR_Servo::enable(const uint8_t& servoIndex) { @@ -352,7 +361,7 @@ bool NRF52_ISR_Servo::enable(const uint8_t& servoIndex) return true; } -////////////////////////////////////////////////// +//////////////////////////////////////// bool NRF52_ISR_Servo::disable(const uint8_t& servoIndex) { @@ -367,7 +376,7 @@ bool NRF52_ISR_Servo::disable(const uint8_t& servoIndex) return true; } -////////////////////////////////////////////////// +//////////////////////////////////////// void NRF52_ISR_Servo::enableAll() { @@ -375,15 +384,15 @@ void NRF52_ISR_Servo::enableAll() for (int8_t servoIndex = 0; servoIndex < MAX_SERVOS; servoIndex++) { - if ( (servo[servoIndex].position >= servo[servoIndex].minPulseUs) && !servo[servoIndex].enabled - && (servo[servoIndex].pin <= NRF52_MAX_PIN) ) + if ( (servo[servoIndex].position >= servo[servoIndex].minPulseUs) && !servo[servoIndex].enabled + && (servo[servoIndex].pin <= NRF52_MAX_PIN) ) { servo[servoIndex].enabled = true; } } } -////////////////////////////////////////////////// +//////////////////////////////////////// void NRF52_ISR_Servo::disableAll() { @@ -394,7 +403,7 @@ void NRF52_ISR_Servo::disableAll() } } -////////////////////////////////////////////////// +//////////////////////////////////////// bool NRF52_ISR_Servo::toggle(const uint8_t& servoIndex) { @@ -406,7 +415,7 @@ bool NRF52_ISR_Servo::toggle(const uint8_t& servoIndex) return true; } -////////////////////////////////////////////////// +//////////////////////////////////////// int8_t NRF52_ISR_Servo::getNumServos() { diff --git a/utils/astyle_library.conf b/utils/astyle_library.conf new file mode 100644 index 0000000..8a73bc2 --- /dev/null +++ b/utils/astyle_library.conf @@ -0,0 +1,70 @@ +# Code formatting rules for Arduino libraries, modified from for KH libraries: +# +# https://github.com/arduino/Arduino/blob/master/build/shared/examples_formatter.conf +# + +# astyle --style=allman -s2 -t2 -C -S -xW -Y -M120 -f -p -xg -H -xb -c --xC120 -xL *.h *.cpp *.ino + +--mode=c +--lineend=linux +--style=allman + +# -r or -R +#--recursive + +# -c => Converts tabs into spaces +convert-tabs + +# -s2 => 2 spaces indentation +--indent=spaces=2 + +# -t2 => tab =2 spaces +#--indent=tab=2 + +# -C +--indent-classes + +# -S +--indent-switches + +# -xW +--indent-preproc-block + +# -Y => indent classes, switches (and cases), comments starting at column 1 +--indent-col1-comments + +# -M120 => maximum of 120 spaces to indent a continuation line +--max-continuation-indent=120 + +# -xC120 => max‑code‑length will break a line if the code exceeds # characters +--max-code-length=120 + +# -f => +--break-blocks + +# -p => put a space around operators +--pad-oper + +# -xg => Insert space padding after commas +--pad-comma + +# -H => put a space after if/for/while +pad-header + +# -xb => Break one line headers (e.g. if/for/while) +--break-one-line-headers + +# -c => Converts tabs into spaces +#--convert-tabs + +# if you like one-liners, keep them +#keep-one-line-statements + +# -xV +--attach-closing-while + +#unpad-paren + +# -xp +remove-comment-prefix + diff --git a/utils/restyle.sh b/utils/restyle.sh new file mode 100644 index 0000000..bcd846f --- /dev/null +++ b/utils/restyle.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +for dir in . ; do + find $dir -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.ino" \) -exec astyle --suffix=none --options=./utils/astyle_library.conf \{\} \; +done +