From d5e83b0574adc9bb7388666ef83981331b3260e7 Mon Sep 17 00:00:00 2001 From: Khoi Hoang <57012152+khoih-prog@users.noreply.github.com> Date: Thu, 3 Mar 2022 23:51:58 -0500 Subject: [PATCH] v1.2.1 to fix DutyCycle bug, etc. ### Releases v1.2.1 1. Fix `DutyCycle` bug. Check [float precisison of DutyCycle only sometimes working #3](https://github.com/khoih-prog/SAMD_Slow_PWM/issues/3) 2. Fix `New Period` display bug. Check [random dropouts #4](https://github.com/khoih-prog/SAMD_Slow_PWM/issues/4) 3. Update examples --- CONTRIBUTING.md | 6 +- README.md | 611 ++--------------------------- changelog.md | 7 + library.json | 2 +- library.properties | 4 +- src/PWM_Generic_Debug.h | 3 +- src/nRF52_MBED_Slow_PWM.h | 3 +- src/nRF52_MBED_Slow_PWM.hpp | 9 +- src/nRF52_MBED_Slow_PWM_ISR.h | 3 +- src/nRF52_MBED_Slow_PWM_ISR.hpp | 20 +- src/nRF52_MBED_Slow_PWM_ISR_Impl.h | 3 +- src/nRF52_MBED_Slow_PWM_Impl.h | 3 +- 12 files changed, 78 insertions(+), 596 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 34d4fe8..a7f138f 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 -* Arduino `mbed` Core Version (e.g. Arduino `mbed` core v1.3.2 or Arduino `mbed_nano` core v2.6.1) +* Arduino `mbed` Core Version (e.g. Arduino `mbed` core v1.3.2 or Arduino `mbed_nano` core v2.7.2) * 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,9 +27,9 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.19 -Arduino mbed_nano` core v2.6.1 +Arduino mbed_nano` core v2.7.2 OS: Ubuntu 20.04 LTS -Linux xy-Inspiron-3593 5.4.0-97-generic #110-Ubuntu SMP Thu Jan 13 18:22:13 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux +Linux xy-Inspiron-3593 5.4.0-100-generic #113-Ubuntu SMP Thu Feb 3 18:43:29 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux Context: I encountered a crash while trying to use the Timer Interrupt. diff --git a/README.md b/README.md index 97fac1b..b70f2ea 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,8 @@ [![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](#Contributing) [![GitHub issues](https://img.shields.io/github/issues/khoih-prog/nRF52_MBED_Slow_PWM.svg)](http://github.com/khoih-prog/nRF52_MBED_Slow_PWM/issues) -Buy Me A Coffee +Donate to my libraries using BuyMeACoffee + --- --- @@ -138,7 +139,7 @@ The catch is **your function is now part of an ISR (Interrupt Service Routine), ## Prerequisites 1. [`Arduino IDE 1.8.19+` for Arduino](https://github.com/arduino/Arduino). [![GitHub release](https://img.shields.io/github/release/arduino/Arduino.svg)](https://github.com/arduino/Arduino/releases/latest) - 2. [`Arduino mbed_nano core 2.5.2+`](https://github.com/arduino/ArduinoCore-mbed) for NRF52-based board using mbed-RTOS such as Nano-33-BLE if you don't use `NRF_TIMER_1`. [![GitHub release](https://img.shields.io/github/release/arduino/ArduinoCore-mbed.svg)](https://github.com/arduino/ArduinoCore-mbed/releases/latest) + 2. [`Arduino mbed_nano core 2.7.2+`](https://github.com/arduino/ArduinoCore-mbed) for NRF52-based board using mbed-RTOS such as Nano-33-BLE if you don't use `NRF_TIMER_1`. [![GitHub release](https://img.shields.io/github/release/arduino/ArduinoCore-mbed.svg)](https://github.com/arduino/ArduinoCore-mbed/releases/latest) 3. [`Arduino mbed core v1.3.2-`](https://github.com/arduino/ArduinoCore-mbed/releases/tag/1.3.2) for NRF52-based board using mbed-RTOS such as Nano-33-BLE if you'd like to use `NRF_TIMER_1`. [![GitHub release](https://img.shields.io/github/release/arduino/ArduinoCore-mbed.svg)](https://github.com/arduino/ArduinoCore-mbed/releases/latest) 4. To use with certain example @@ -166,7 +167,7 @@ Another way to install is to: 1. Install [VS Code](https://code.visualstudio.com/) 2. Install [PlatformIO](https://platformio.org/platformio-ide) -3. Install [**nRF52_MBED_Slow_PWM** library](https://platformio.org/lib/show/12877/nRF52_MBED_Slow_PWM) by using [Library Manager](https://platformio.org/lib/show/12877/nRF52_MBED_Slow_PWM/installation). Search for **nRF52_MBED_Slow_PWM** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22) +3. Install [**nRF52_MBED_Slow_PWM** library](https://registry.platformio.org/libraries/khoih-prog/nRF52_MBED_Slow_PWM) by using [Library Manager](https://registry.platformio.org/libraries/khoih-prog/nRF52_MBED_Slow_PWM/installation). Search for **nRF52_MBED_Slow_PWM** in [Platform.io Author's Libraries](https://platformio.org/lib/search?query=author:%22Khoi%20Hoang%22) 4. Use included [platformio.ini](platformio/platformio.ini) file from examples to ensure that all dependent libraries will installed automatically. Please visit documentation for the other options and examples at [Project Configuration File](https://docs.platformio.org/page/projectconf.html) @@ -260,571 +261,9 @@ void setup() ### Example [ISR_16_PWMs_Array_Complex](examples/ISR_16_PWMs_Array_Complex) -``` -#if !( ARDUINO_ARCH_NRF52840 && TARGET_NAME == ARDUINO_NANO33BLE ) - #error This code is designed to run on nRF52-based Nano-33-BLE boards using mbed-RTOS platform! Please check your Tools->Board setting. -#endif - -// These define's must be placed at the beginning before #include "ESP32_PWM.h" -// _PWM_LOGLEVEL_ from 0 to 4 -// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system. -#define _PWM_LOGLEVEL_ 4 - -#define USING_MICROS_RESOLUTION true //false - -// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error -#include "nRF52_MBED_Slow_PWM.h" - -#include // https://github.com/jfturcot/SimpleTimer - -#define LED_OFF HIGH -#define LED_ON LOW - -#ifndef LED_BUILTIN - #define LED_BUILTIN 25 -#endif - -#ifndef LED_BLUE - #define LED_BLUE 10 -#endif - -#ifndef LED_RED - #define LED_RED 11 -#endif - -#define HW_TIMER_INTERVAL_US 10L - -volatile uint64_t startMicros = 0; - -// For mbed nRF52, you can only select NRF52 Hardware Timer NRF_TIMER_3-NRF_TIMER_4 (3 to 4) -// If you select the already-used NRF_TIMER_0-2, it'll be auto modified to use NRF_TIMER_3 - -// Init NRF52 timer NRF_TIMER3 -NRF52_MBED_Timer ITimer(NRF_TIMER_3); - -// Init nRF52_Slow_PWM, each can service 16 different ISR-based PWM channels -NRF52_MBED_Slow_PWM ISR_PWM; - -////////////////////////////////////////////////////// - -void TimerHandler() -{ - ISR_PWM.run(); -} - -///////////////////////////////////////////////// - -#define NUMBER_ISR_PWMS 16 - -#define PIN_D0 0 -#define PIN_D1 1 -#define PIN_D2 2 -#define PIN_D3 3 -#define PIN_D4 4 -#define PIN_D5 5 -#define PIN_D6 6 -#define PIN_D7 7 -#define PIN_D8 8 -#define PIN_D9 9 -#define PIN_D10 10 -#define PIN_D11 11 -#define PIN_D12 12 - -typedef void (*irqCallback) (); - -////////////////////////////////////////////////////// - -#define USE_COMPLEX_STRUCT true - -#define USING_PWM_FREQUENCY true - -////////////////////////////////////////////////////// - -#if USE_COMPLEX_STRUCT - -typedef struct -{ - uint32_t PWM_Pin; - irqCallback irqCallbackStartFunc; - irqCallback irqCallbackStopFunc; - -#if USING_PWM_FREQUENCY - float PWM_Freq; -#else - uint32_t PWM_Period; -#endif - - float PWM_DutyCycle; - - uint64_t deltaMicrosStart; - uint64_t previousMicrosStart; - - uint64_t deltaMicrosStop; - uint64_t previousMicrosStop; - -} ISR_PWM_Data; - -// In nRF52, avoid doing something fancy in ISR, for example Serial.print() -// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment -// Or you can get this run-time error / crash - -void doingSomethingStart(int index); - -void doingSomethingStop(int index); - -#else // #if USE_COMPLEX_STRUCT - -volatile unsigned long deltaMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -volatile unsigned long previousMicrosStart [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -volatile unsigned long deltaMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -volatile unsigned long previousMicrosStop [] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - -// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11 -uint32_t PWM_Pin[] = -{ - LED_BUILTIN, LED_BLUE, LED_RED, PIN_D0, PIN_D1, PIN_D2, PIN_D3, PIN_D4, - PIN_D5, PIN_D6, PIN_D7, PIN_D8, PIN_D9, PIN_D10, PIN_D11, PIN_D12 -}; - -// You can assign any interval for any timer here, in microseconds -uint32_t PWM_Period[] = -{ - 1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L, - 111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L -}; - -// You can assign any interval for any timer here, in Hz -float PWM_Freq[] = -{ - 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, - 9.0f, 10.0f, 15.0f, 20.0f, 25.0f, 30.0f, 40.0f, 50.0f -}; - -// You can assign any interval for any timer here, in milliseconds -float PWM_DutyCycle[] = -{ - 5.0, 10.0, 20.0, 30.0, 40.0, 45.0, 50.0, 55.0, - 60.0, 65.0, 70.0, 75.0, 80.0, 85.0, 90.0, 95.0 -}; - - -void doingSomethingStart(int index) -{ - unsigned long currentMicros = micros(); - - deltaMicrosStart[index] = currentMicros - previousMicrosStart[index]; - previousMicrosStart[index] = currentMicros; -} - -void doingSomethingStop(int index) -{ - unsigned long currentMicros = micros(); - - // Count from start to stop PWM pulse - deltaMicrosStop[index] = currentMicros - previousMicrosStart[index]; - previousMicrosStop[index] = currentMicros; -} - -#endif // #if USE_COMPLEX_STRUCT - -//////////////////////////////////// -// Shared -//////////////////////////////////// - -void doingSomethingStart0() -{ - doingSomethingStart(0); -} - -void doingSomethingStart1() -{ - doingSomethingStart(1); -} - -void doingSomethingStart2() -{ - doingSomethingStart(2); -} - -void doingSomethingStart3() -{ - doingSomethingStart(3); -} - -void doingSomethingStart4() -{ - doingSomethingStart(4); -} - -void doingSomethingStart5() -{ - doingSomethingStart(5); -} - -void doingSomethingStart6() -{ - doingSomethingStart(6); -} - -void doingSomethingStart7() -{ - doingSomethingStart(7); -} - -void doingSomethingStart8() -{ - doingSomethingStart(8); -} +https://github.com/khoih-prog/nRF52_MBED_Slow_PWM/blob/36036c9759ff4ea96a4b30e33242ca54ed49a7c4/examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino#L16-L578 -void doingSomethingStart9() -{ - doingSomethingStart(9); -} -void doingSomethingStart10() -{ - doingSomethingStart(10); -} - -void doingSomethingStart11() -{ - doingSomethingStart(11); -} - -void doingSomethingStart12() -{ - doingSomethingStart(12); -} - -void doingSomethingStart13() -{ - doingSomethingStart(13); -} - -void doingSomethingStart14() -{ - doingSomethingStart(14); -} - -void doingSomethingStart15() -{ - doingSomethingStart(15); -} - -////////////////////////////////////////////////////// - -void doingSomethingStop0() -{ - doingSomethingStop(0); -} - -void doingSomethingStop1() -{ - doingSomethingStop(1); -} - -void doingSomethingStop2() -{ - doingSomethingStop(2); -} - -void doingSomethingStop3() -{ - doingSomethingStop(3); -} - -void doingSomethingStop4() -{ - doingSomethingStop(4); -} - -void doingSomethingStop5() -{ - doingSomethingStop(5); -} - -void doingSomethingStop6() -{ - doingSomethingStop(6); -} - -void doingSomethingStop7() -{ - doingSomethingStop(7); -} - -void doingSomethingStop8() -{ - doingSomethingStop(8); -} - -void doingSomethingStop9() -{ - doingSomethingStop(9); -} - -void doingSomethingStop10() -{ - doingSomethingStop(10); -} - -void doingSomethingStop11() -{ - doingSomethingStop(11); -} - -void doingSomethingStop12() -{ - doingSomethingStop(12); -} - -void doingSomethingStop13() -{ - doingSomethingStop(13); -} - -void doingSomethingStop14() -{ - doingSomethingStop(14); -} - -void doingSomethingStop15() -{ - doingSomethingStop(15); -} - -////////////////////////////////////////////////////// - -#if USE_COMPLEX_STRUCT - - #if USING_PWM_FREQUENCY - - ISR_PWM_Data curISR_PWM_Data[] = - { - // pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Freq, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop - { LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1, 5, 0, 0, 0, 0 }, - { LED_BLUE, doingSomethingStart1, doingSomethingStop1, 2, 10, 0, 0, 0, 0 }, - { LED_RED, doingSomethingStart2, doingSomethingStop2, 3, 20, 0, 0, 0, 0 }, - { PIN_D0, doingSomethingStart3, doingSomethingStop3, 4, 30, 0, 0, 0, 0 }, - { PIN_D1, doingSomethingStart4, doingSomethingStop4, 5, 40, 0, 0, 0, 0 }, - { PIN_D2, doingSomethingStart5, doingSomethingStop5, 6, 45, 0, 0, 0, 0 }, - { PIN_D3, doingSomethingStart6, doingSomethingStop6, 7, 50, 0, 0, 0, 0 }, - { PIN_D4, doingSomethingStart7, doingSomethingStop7, 8, 55, 0, 0, 0, 0 }, - { PIN_D5, doingSomethingStart8, doingSomethingStop8, 9, 60, 0, 0, 0, 0 }, - { PIN_D6, doingSomethingStart9, doingSomethingStop9, 10, 65, 0, 0, 0, 0 }, - { PIN_D7, doingSomethingStart10, doingSomethingStop10, 15, 70, 0, 0, 0, 0 }, - { PIN_D8, doingSomethingStart11, doingSomethingStop11, 20, 75, 0, 0, 0, 0 }, - { PIN_D9, doingSomethingStart12, doingSomethingStop12, 25, 80, 0, 0, 0, 0 }, - { PIN_D10, doingSomethingStart13, doingSomethingStop13, 30, 85, 0, 0, 0, 0 }, - { PIN_D11, doingSomethingStart14, doingSomethingStop14, 40, 90, 0, 0, 0, 0 }, - { PIN_D12, doingSomethingStart15, doingSomethingStop15, 50, 95, 0, 0, 0, 0 } - }; - - #else // #if USING_PWM_FREQUENCY - - ISR_PWM_Data curISR_PWM_Data[] = - { - // pin, irqCallbackStartFunc, irqCallbackStopFunc, PWM_Period, PWM_DutyCycle, deltaMicrosStart, previousMicrosStart, deltaMicrosStop, previousMicrosStop - { LED_BUILTIN, doingSomethingStart0, doingSomethingStop0, 1000000L, 5, 0, 0, 0, 0 }, - { LED_BLUE, doingSomethingStart1, doingSomethingStop1, 500000L, 10, 0, 0, 0, 0 }, - { LED_RED, doingSomethingStart2, doingSomethingStop2, 333333L, 20, 0, 0, 0, 0 }, - { PIN_D0, doingSomethingStart3, doingSomethingStop3, 250000L, 30, 0, 0, 0, 0 }, - { PIN_D1, doingSomethingStart4, doingSomethingStop4, 200000L, 40, 0, 0, 0, 0 }, - { PIN_D2, doingSomethingStart5, doingSomethingStop5, 166667L, 45, 0, 0, 0, 0 }, - { PIN_D3, doingSomethingStart6, doingSomethingStop6, 142857L, 50, 0, 0, 0, 0 }, - { PIN_D4, doingSomethingStart7, doingSomethingStop7, 125000L, 55, 0, 0, 0, 0 }, - { PIN_D5, doingSomethingStart8, doingSomethingStop8, 111111L, 60, 0, 0, 0, 0 }, - { PIN_D6, doingSomethingStart9, doingSomethingStop9, 100000L, 65, 0, 0, 0, 0 }, - { PIN_D7, doingSomethingStart10, doingSomethingStop10, 66667L, 70, 0, 0, 0, 0 }, - { PIN_D8, doingSomethingStart11, doingSomethingStop11, 50000L, 75, 0, 0, 0, 0 }, - { PIN_D9, doingSomethingStart12, doingSomethingStop12, 40000L, 80, 0, 0, 0, 0 }, - { PIN_D10, doingSomethingStart13, doingSomethingStop13, 33333L, 85, 0, 0, 0, 0 }, - { PIN_D11, doingSomethingStart14, doingSomethingStop14, 25000L, 90, 0, 0, 0, 0 }, - { PIN_D12, doingSomethingStart15, doingSomethingStop15, 20000L, 95, 0, 0, 0, 0 } - }; - - #endif // #if USING_PWM_FREQUENCY - -void doingSomethingStart(int index) -{ - unsigned long currentMicros = micros(); - - curISR_PWM_Data[index].deltaMicrosStart = currentMicros - curISR_PWM_Data[index].previousMicrosStart; - curISR_PWM_Data[index].previousMicrosStart = currentMicros; -} - -void doingSomethingStop(int index) -{ - unsigned long currentMicros = micros(); - - //curISR_PWM_Data[index].deltaMicrosStop = currentMicros - curISR_PWM_Data[index].previousMicrosStop; - // Count from start to stop PWM pulse - curISR_PWM_Data[index].deltaMicrosStop = currentMicros - curISR_PWM_Data[index].previousMicrosStart; - curISR_PWM_Data[index].previousMicrosStop = currentMicros; -} - -#else // #if USE_COMPLEX_STRUCT - -irqCallback irqCallbackStartFunc[] = -{ - doingSomethingStart0, doingSomethingStart1, doingSomethingStart2, doingSomethingStart3, - doingSomethingStart4, doingSomethingStart5, doingSomethingStart6, doingSomethingStart7, - doingSomethingStart8, doingSomethingStart9, doingSomethingStart10, doingSomethingStart11, - doingSomethingStart12, doingSomethingStart13, doingSomethingStart14, doingSomethingStart15 -}; - -irqCallback irqCallbackStopFunc[] = -{ - doingSomethingStop0, doingSomethingStop1, doingSomethingStop2, doingSomethingStop3, - doingSomethingStop4, doingSomethingStop5, doingSomethingStop6, doingSomethingStop7, - doingSomethingStop8, doingSomethingStop9, doingSomethingStop10, doingSomethingStop11, - doingSomethingStop12, doingSomethingStop13, doingSomethingStop14, doingSomethingStop15 -}; - -#endif // #if USE_COMPLEX_STRUCT - -////////////////////////////////////////////////////// - -#define SIMPLE_TIMER_MS 2000L - -// Init SimpleTimer -SimpleTimer simpleTimer; - -// Here is software Timer, you can do somewhat fancy stuffs without many issues. -// But always avoid -// 1. Long delay() it just doing nothing and pain-without-gain wasting CPU power.Plan and design your code / strategy ahead -// 2. Very long "do", "while", "for" loops without predetermined exit time. -void simpleTimerDoingSomething2s() -{ - static unsigned long previousMicrosStart = startMicros; - - unsigned long currMicros = micros(); - - Serial.print(F("SimpleTimer (ms): ")); Serial.print(SIMPLE_TIMER_MS); - Serial.print(F(", us : ")); Serial.print(currMicros); - Serial.print(F(", Dus : ")); Serial.println(currMicros - previousMicrosStart); - - for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++) - { -#if USE_COMPLEX_STRUCT - Serial.print(F("PWM Channel : ")); Serial.print(i); - Serial.print(F(", programmed Period (us): ")); - - #if USING_PWM_FREQUENCY - Serial.print(1000000 / curISR_PWM_Data[i].PWM_Freq); - #else - Serial.print(curISR_PWM_Data[i].PWM_Period); - #endif - - Serial.print(F(", actual : ")); Serial.print(curISR_PWM_Data[i].deltaMicrosStart); - - Serial.print(F(", programmed DutyCycle : ")); - - Serial.print(curISR_PWM_Data[i].PWM_DutyCycle); - - Serial.print(F(", actual : ")); Serial.println((float) curISR_PWM_Data[i].deltaMicrosStop * 100.0f / curISR_PWM_Data[i].deltaMicrosStart); - -#else - - Serial.print(F("PWM Channel : ")); Serial.print(i); - - #if USING_PWM_FREQUENCY - Serial.print(1000000 / PWM_Freq[i]); - #else - Serial.print(PWM_Period[i]); - #endif - - Serial.print(F(", programmed Period (us): ")); Serial.print(PWM_Period[i]); - Serial.print(F(", actual : ")); Serial.print(deltaMicrosStart[i]); - - Serial.print(F(", programmed DutyCycle : ")); - - Serial.print(PWM_DutyCycle[i]); - - Serial.print(F(", actual : ")); Serial.println( (float) deltaMicrosStop[i] * 100.0f / deltaMicrosStart[i]); -#endif - } - - previousMicrosStart = currMicros; -} - -void setup() -{ - Serial.begin(115200); - while (!Serial); - - delay(2000); - - Serial.print(F("\nStarting ISR_16_PWMs_Array_Complex on ")); Serial.println(BOARD_NAME); - Serial.println(NRF52_MBED_SLOW_PWM_VERSION); - - // Interval in microsecs - if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler)) - { - startMicros = micros(); - Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); - } - else - Serial.println(F("Can't set ITimer. Select another freq. or timer")); - - startMicros = micros(); - - // Just to demonstrate, don't use too many ISR Timers if not absolutely necessary - // You can use up to 16 timer for each ISR_PWM - - for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++) - { -#if USE_COMPLEX_STRUCT - curISR_PWM_Data[i].previousMicrosStart = startMicros; - //ISR_PWM.setInterval(curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].irqCallbackStartFunc); - - //void setPWM(uint32_t pin, float frequency, float dutycycle - // , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr) - - #if USING_PWM_FREQUENCY - // You can use this with PWM_Freq in Hz - ISR_PWM.setPWM(curISR_PWM_Data[i].PWM_Pin, curISR_PWM_Data[i].PWM_Freq, curISR_PWM_Data[i].PWM_DutyCycle, - curISR_PWM_Data[i].irqCallbackStartFunc, curISR_PWM_Data[i].irqCallbackStopFunc); - #else - // Or You can use this with PWM_Period in us - ISR_PWM.setPWM_Period(curISR_PWM_Data[i].PWM_Pin, curISR_PWM_Data[i].PWM_Period, curISR_PWM_Data[i].PWM_DutyCycle, - curISR_PWM_Data[i].irqCallbackStartFunc, curISR_PWM_Data[i].irqCallbackStopFunc); - #endif - -#else - previousMicrosStart[i] = micros(); - - #if USING_PWM_FREQUENCY - // You can use this with PWM_Freq in Hz - ISR_PWM.setPWM(PWM_Pin[i], PWM_Freq[i], PWM_DutyCycle[i], irqCallbackStartFunc[i], irqCallbackStopFunc[i]); - #else - // Or You can use this with PWM_Period in us - ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i], PWM_DutyCycle[i], irqCallbackStartFunc[i], irqCallbackStopFunc[i]); - #endif - -#endif - } - - // You need this timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary. - simpleTimer.setInterval(SIMPLE_TIMER_MS, simpleTimerDoingSomething2s); -} - -#define BLOCKING_TIME_MS 10000L - -void loop() -{ - // This unadvised blocking task is used to demonstrate the blocking effects onto the execution and accuracy to Software timer - // You see the time elapse of ISR_PWM still accurate, whereas very unaccurate for Software Timer - // The time elapse for 2000ms software timer now becomes 3000ms (BLOCKING_TIME_MS) - // While that of ISR_PWM is still prefect. - delay(BLOCKING_TIME_MS); - - // You need this Software timer for non-critical tasks. Avoid abusing ISR if not absolutely necessary - // You don't need to and never call ISR_PWM.run() here in the loop(). It's already handled by ISR timer. - simpleTimer.run(); -} -``` --- --- @@ -837,7 +276,7 @@ The following is the sample terminal output when running example [ISR_16_PWMs_Ar ``` Starting ISR_16_PWMs_Array_Complex on Nano 33 BLE -NRF52_MBED_Slow_PWM v1.2.0 +NRF52_MBED_Slow_PWM v1.2.1 [PWM] Timer = NRF_TIMER3 , Timer Clock (Hz) = 16000000.00 [PWM] Frequency = 100000.00 , _count = 160 Starting ITimer OK, micros() = 2800208 @@ -918,7 +357,7 @@ The following is the sample terminal output when running example [**ISR_16_PWMs_ ``` Starting ISR_16_PWMs_Array on Nano 33 BLE -NRF52_MBED_Slow_PWM v1.2.0 +NRF52_MBED_Slow_PWM v1.2.1 [PWM] Timer = NRF_TIMER3 , Timer Clock (Hz) = 16000000.00 [PWM] Frequency = 100000.00 , _count = 160 Starting ITimer OK, micros() = 2802084 @@ -948,7 +387,7 @@ The following is the sample terminal output when running example [**ISR_16_PWMs_ ``` Starting ISR_16_PWMs_Array_Simple on Nano 33 BLE -NRF52_MBED_Slow_PWM v1.2.0 +NRF52_MBED_Slow_PWM v1.2.1 [PWM] Timer = NRF_TIMER3 , Timer Clock (Hz) = 16000000.00 [PWM] Frequency = 100000.00 , _count = 160 Starting ITimer OK, micros() = 3202330 @@ -978,14 +417,35 @@ The following is the sample terminal output when running example [ISR_Modify_PWM ``` Starting ISR_Modify_PWM on Nano 33 BLE -NRF52_MBED_Slow_PWM v1.2.0 +NRF52_MBED_Slow_PWM v1.2.1 [PWM] Timer = NRF_TIMER3 , Timer Clock (Hz) = 16000000.00 [PWM] Frequency = 50000.00 , _count = 320 Starting ITimer OK, micros() = 2703294 -Using PWM Freq = 1.00, PWM DutyCycle = 50.00 -Channel : 0 Period : 1000000 OnTime : 500000 Start_Time : 2705932 -Channel : 0 New Period : 500000 OnTime : 450000 Start_Time : 12706044 -Channel : 0 New Period : 1000000 OnTime : 500000 Start_Time : 22706410 +Using PWM Freq = 200.00, PWM DutyCycle = 1.00 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 3311523 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 13313476 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 23309570 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 33310546 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 43306640 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 53313476 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 63309570 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 73316406 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 83312500 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 93319335 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 103315429 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 113322265 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 123318359 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 133325195 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 143326171 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 153322265 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 163318359 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 173325195 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 183321289 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 193328125 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 203324218 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 213331054 +Channel : 0 Period : 5000 OnTime : 50 Start_Time : 223327148 +Channel : 0 Period : 10000 OnTime : 555 Start_Time : 233333984 ``` --- @@ -996,7 +456,7 @@ The following is the sample terminal output when running example [ISR_Changing_P ``` Starting ISR_Changing_PWM on Nano 33 BLE -NRF52_MBED_Slow_PWM v1.2.0 +NRF52_MBED_Slow_PWM v1.2.1 [PWM] Timer = NRF_TIMER3 , Timer Clock (Hz) = 16000000.00 [PWM] Frequency = 50000.00 , _count = 320 Starting ITimer OK, micros() = 3024808 @@ -1056,6 +516,7 @@ Submit issues to: [nRF52_MBED_Slow_PWM issues](https://github.com/khoih-prog/nRF 5. Optimize library code by using `reference-passing` instead of `value-passing` 6. Improve accuracy by using `float`, instead of `uint32_t` for `dutycycle` 7. DutyCycle to be optionally updated at the end current PWM period instead of immediately. +8. Display informational warning only when `_PWM_LOGLEVEL_` > 3 --- --- diff --git a/changelog.md b/changelog.md index afc1581..a016b1b 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) * [Initial Releases v1.0.0](#Initial-Releases-v100) @@ -21,6 +22,12 @@ ## Changelog +### Releases v1.2.1 + +1. Fix `DutyCycle` bug. Check [float precisison of DutyCycle only sometimes working #3](https://github.com/khoih-prog/SAMD_Slow_PWM/issues/3) +2. Fix `New Period` display bug. Check [random dropouts #4](https://github.com/khoih-prog/SAMD_Slow_PWM/issues/4) +3. Update examples + ### Releases v1.2.0 1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories diff --git a/library.json b/library.json index b63d642..d08b0d7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "nRF52_MBED_Slow_PWM", - "version": "1.2.0", + "version": "1.2.1", "keywords": "timing, device, control, timer, interrupt, hardware, isr, isr-based, hardware-timer, mission-critical, accuracy, precise, non-blocking, nrf52, mbed, mbed-nano, nano-33-ble", "description": "This library enables you to use ISR-based PWM channels on an nRF52-based board using Arduino-mbed mbed_nano core such as Nano-33-BLE to create and output PWM any GPIO pin. It now supports 16 ISR-based PWM channels, while consuming only 1 Hardware Timer. PWM channel interval can be very long (ulong microsecs / millisecs). The most important feature is they're ISR-based PWM channels, supporting lower PWM frequencies with suitable accuracy. Their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks. These ISR-based PWMs, still work even if other software functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software-based PWM using millis() or micros(). That's necessary if you need to control devices requiring high precision. Now you can change the PWM settings on-the-fly", "authors": diff --git a/library.properties b/library.properties index 717c832..bedcd68 100644 --- a/library.properties +++ b/library.properties @@ -1,10 +1,10 @@ name=nRF52_MBED_Slow_PWM -version=1.2.0 +version=1.2.1 author=Khoi Hoang maintainer=Khoi Hoang sentence=This library enables you to use ISR-based PWM channels on an nRF52-based board using Arduino-mbed mbed_nano core such as Nano-33-BLE to create and output PWM any GPIO pin. paragraph=It now supports 16 ISR-based PWM channels, while consuming only 1 Hardware Timer. PWM channel interval can be very long (ulong microsecs / millisecs). The most important feature is they are ISR-based PWM channels, supporting lower PWM frequencies with suitable accuracy. Their executions are not blocked by bad-behaving functions or tasks. This important feature is absolutely necessary for mission-critical tasks. These ISR-based PWMs, still work even if other software functions are blocking. Moreover, they are much more precise (certainly depending on clock frequency accuracy) than other software-based PWM using millis() or micros(). That is necessary if you need to control devices requiring high precision. Now you can change the PWM settings on-the-fly -category=Timing,Control,Device,Time,Timer,NRF52,interrupt,mbed +category=Device Control url=https://github.com/khoih-prog/nRF52_MBED_Slow_PWM architectures=mbed,mbed_nano,nrf52 repository=https://github.com/khoih-prog/nRF52_MBED_Slow_PWM diff --git a/src/PWM_Generic_Debug.h b/src/PWM_Generic_Debug.h index 4a7c0e3..0151543 100644 --- a/src/PWM_Generic_Debug.h +++ b/src/PWM_Generic_Debug.h @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM.h b/src/nRF52_MBED_Slow_PWM.h index ebbc4eb..b3cc6d6 100644 --- a/src/nRF52_MBED_Slow_PWM.h +++ b/src/nRF52_MBED_Slow_PWM.h @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM.hpp b/src/nRF52_MBED_Slow_PWM.hpp index f665769..5988718 100644 --- a/src/nRF52_MBED_Slow_PWM.hpp +++ b/src/nRF52_MBED_Slow_PWM.hpp @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ /* @@ -70,13 +71,13 @@ #endif #ifndef NRF52_MBED_SLOW_PWM_VERSION - #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.0" + #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.1" #define NRF52_MBED_SLOW_PWM_VERSION_MAJOR 1 #define NRF52_MBED_SLOW_PWM_VERSION_MINOR 2 - #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 0 + #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 1 - #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002000 + #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002001 #endif #ifndef _PWM_LOGLEVEL_ diff --git a/src/nRF52_MBED_Slow_PWM_ISR.h b/src/nRF52_MBED_Slow_PWM_ISR.h index 08c94eb..e2531cc 100644 --- a/src/nRF52_MBED_Slow_PWM_ISR.h +++ b/src/nRF52_MBED_Slow_PWM_ISR.h @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM_ISR.hpp b/src/nRF52_MBED_Slow_PWM_ISR.hpp index c6ee641..1871111 100644 --- a/src/nRF52_MBED_Slow_PWM_ISR.hpp +++ b/src/nRF52_MBED_Slow_PWM_ISR.hpp @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ #pragma once @@ -31,13 +32,13 @@ #endif #ifndef NRF52_MBED_SLOW_PWM_VERSION - #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.0" + #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.1" #define NRF52_MBED_SLOW_PWM_VERSION_MAJOR 1 #define NRF52_MBED_SLOW_PWM_VERSION_MINOR 2 - #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 0 + #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 1 - #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002000 + #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002001 #endif #ifndef _PWM_LOGLEVEL_ @@ -64,12 +65,19 @@ typedef void (*timer_callback)(); typedef void (*timer_callback_p)(void *); #if !defined(USING_MICROS_RESOLUTION) - #warning Not USING_MICROS_RESOLUTION, using millis resolution + + #if (_PWM_LOGLEVEL_ > 3) + #warning Not USING_MICROS_RESOLUTION, using millis resolution + #endif + #define USING_MICROS_RESOLUTION false #endif #if !defined(CHANGING_PWM_END_OF_CYCLE) - #warning Using default CHANGING_PWM_END_OF_CYCLE == true + #if (_PWM_LOGLEVEL_ > 3) + #warning Using default CHANGING_PWM_END_OF_CYCLE == true + #endif + #define CHANGING_PWM_END_OF_CYCLE true #endif diff --git a/src/nRF52_MBED_Slow_PWM_ISR_Impl.h b/src/nRF52_MBED_Slow_PWM_ISR_Impl.h index c49d728..c85b264 100644 --- a/src/nRF52_MBED_Slow_PWM_ISR_Impl.h +++ b/src/nRF52_MBED_Slow_PWM_ISR_Impl.h @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM_Impl.h b/src/nRF52_MBED_Slow_PWM_Impl.h index 5c7ecc7..32481e2 100644 --- a/src/nRF52_MBED_Slow_PWM_Impl.h +++ b/src/nRF52_MBED_Slow_PWM_Impl.h @@ -12,13 +12,14 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.0 + Version: 1.2.1 Version Modified By Date Comments ------- ----------- ---------- ----------- 1.0.0 K.Hoang 25/09/2021 Initial coding for nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE 1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly 1.2.0 K.Hoang 07/02/2022 Fix `multiple-definitions` linker error. Improve accuracy. Optimize code. Fix bug + 1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3 *****************************************************************************************************************************/ /*