diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a7f138f..8d4a7b9 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -15,7 +15,8 @@ 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.7.2) +* `nRF52840 mbed` Core Version (e.g. Arduino mbed_nano core v3.4.1, Seeeduino mbed core v2.7.2) +* `nRF52840-based Nano_33_BLE` Board type (e.g. Nano_33_BLE, Nano_33_BLE_Sense, SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE, etc.) * 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 +28,13 @@ Please ensure to specify the following: ``` Arduino IDE version: 1.8.19 -Arduino mbed_nano` core v2.7.2 +Arduino mbed_nano core v3.4.1 +Nano_33_BLE board OS: Ubuntu 20.04 LTS -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 +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 +43,31 @@ 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_MBED_Slow_PWM/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_MBED_Slow_PWM_GitHub/ +xy@xy-Inspiron-3593:~/Arduino/xy/nRF52_MBED_Slow_PWM_GitHub$ +``` + +2. Issue astyle command + +``` +xy@xy-Inspiron-3593:~/Arduino/xy/nRF52_MBED_Slow_PWM_GitHub$ bash utils/restyle.sh +``` diff --git a/changelog.md b/changelog.md index a016b1b..d44b442 100644 --- a/changelog.md +++ b/changelog.md @@ -12,6 +12,7 @@ ## Table of Contents * [Changelog](#changelog) + * [Releases v1.2.2](#releases-v122) * [Releases v1.2.1](#releases-v121) * [Releases v1.2.0](#releases-v120) * [Releases v1.1.0](#releases-v110) @@ -22,6 +23,11 @@ ## Changelog +### Releases v1.2.2 + +1. Add support to Seeeduino nRF52840-based boards such as **SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE**, etc. using Seeeduino `mbed` core +2. Add astyle using `allman` style. Restyle the library + ### 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) diff --git a/examples/ISR_16_PWMs_Array/ISR_16_PWMs_Array.ino b/examples/ISR_16_PWMs_Array/ISR_16_PWMs_Array.ino index bad31ea..1a07a4f 100644 --- a/examples/ISR_16_PWMs_Array/ISR_16_PWMs_Array.ino +++ b/examples/ISR_16_PWMs_Array/ISR_16_PWMs_Array.ino @@ -58,7 +58,7 @@ NRF52_MBED_Slow_PWM ISR_PWM; ////////////////////////////////////////////////////// void TimerHandler() -{ +{ ISR_PWM.run(); } @@ -89,15 +89,15 @@ void TimerHandler() // 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 + 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 + 111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L }; // You can assign any interval for any timer here, in Hz @@ -110,7 +110,7 @@ float PWM_Freq[] = // 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, + 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 }; @@ -186,8 +186,8 @@ void doingSomething15() irqCallback irqCallbackStartFunc[] = { - doingSomething0, doingSomething1, doingSomething2, doingSomething3, - doingSomething4, doingSomething5, doingSomething6, doingSomething7, + doingSomething0, doingSomething1, doingSomething2, doingSomething3, + doingSomething4, doingSomething5, doingSomething6, doingSomething7, doingSomething8, doingSomething9, doingSomething10, doingSomething11, doingSomething12, doingSomething13, doingSomething14, doingSomething15 }; @@ -195,9 +195,10 @@ irqCallback irqCallbackStartFunc[] = //////////////////////////////////////////////// void setup() -{ +{ Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(2000); @@ -208,7 +209,8 @@ void setup() if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler)) { startMicros = micros(); - Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); + Serial.print(F("Starting ITimer OK, micros() = ")); + Serial.println(startMicros); } else Serial.println(F("Can't set ITimer. Select another freq. or timer")); @@ -226,13 +228,13 @@ void setup() ISR_PWM.setPWM(PWM_Pin[i], PWM_Freq[i], PWM_DutyCycle[i], irqCallbackStartFunc[i]); #else - #if USING_MICROS_RESOLUTION +#if USING_MICROS_RESOLUTION // Or using period in microsecs resolution ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i], PWM_DutyCycle[i], irqCallbackStartFunc[i]); - #else +#else // Or using period in millisecs resolution ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i] / 1000, PWM_DutyCycle[i], irqCallbackStartFunc[i]); - #endif +#endif #endif } } diff --git a/examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino b/examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino index 0b86c84..023256a 100644 --- a/examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino +++ b/examples/ISR_16_PWMs_Array_Complex/ISR_16_PWMs_Array_Complex.ino @@ -60,7 +60,7 @@ NRF52_MBED_Slow_PWM ISR_PWM; ////////////////////////////////////////////////////// void TimerHandler() -{ +{ ISR_PWM.run(); } @@ -100,20 +100,20 @@ typedef struct irqCallback irqCallbackStartFunc; irqCallback irqCallbackStopFunc; -#if USING_PWM_FREQUENCY +#if USING_PWM_FREQUENCY float PWM_Freq; -#else +#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() @@ -135,15 +135,15 @@ volatile unsigned long previousMicrosStop [] = { 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 + 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 + 111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L }; // You can assign any interval for any timer here, in Hz @@ -156,7 +156,7 @@ float PWM_Freq[] = // 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, + 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 }; @@ -350,53 +350,53 @@ void doingSomethingStop15() #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 +#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) { @@ -453,48 +453,58 @@ void simpleTimerDoingSomething2s() 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); + 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("PWM Channel : ")); + Serial.print(i); Serial.print(F(", programmed Period (us): ")); - #if USING_PWM_FREQUENCY +#if USING_PWM_FREQUENCY Serial.print(1000000 / curISR_PWM_Data[i].PWM_Freq); - #else +#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 : ")); +#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); - + + 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(F("PWM Channel : ")); + Serial.print(i); + +#if USING_PWM_FREQUENCY Serial.print(1000000 / PWM_Freq[i]); - #else +#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]); +#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(F(", programmed DutyCycle : ")); - Serial.print(PWM_DutyCycle[i]); - - Serial.print(F(", actual : ")); Serial.println( (float) deltaMicrosStop[i] * 100.0f / deltaMicrosStart[i]); + + Serial.print(F(", actual : ")); + Serial.println( (float) deltaMicrosStop[i] * 100.0f / deltaMicrosStart[i]); #endif } @@ -504,7 +514,8 @@ void simpleTimerDoingSomething2s() void setup() { Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(2000); @@ -515,7 +526,8 @@ void setup() if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler)) { startMicros = micros(); - Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); + Serial.print(F("Starting ITimer OK, micros() = ")); + Serial.println(startMicros); } else Serial.println(F("Can't set ITimer. Select another freq. or timer")); @@ -524,7 +536,7 @@ void setup() // 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 @@ -534,27 +546,27 @@ void setup() //void setPWM(uint32_t pin, float frequency, float dutycycle // , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr) - #if USING_PWM_FREQUENCY +#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, + 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 +#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, + 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 - +#endif + #else previousMicrosStart[i] = micros(); - - #if USING_PWM_FREQUENCY + +#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 +#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 + #endif } diff --git a/examples/ISR_16_PWMs_Array_Simple/ISR_16_PWMs_Array_Simple.ino b/examples/ISR_16_PWMs_Array_Simple/ISR_16_PWMs_Array_Simple.ino index 0b1c783..16ec91e 100644 --- a/examples/ISR_16_PWMs_Array_Simple/ISR_16_PWMs_Array_Simple.ino +++ b/examples/ISR_16_PWMs_Array_Simple/ISR_16_PWMs_Array_Simple.ino @@ -59,7 +59,7 @@ NRF52_MBED_Slow_PWM ISR_PWM; ////////////////////////////////////////////////////// void TimerHandler() -{ +{ ISR_PWM.run(); } @@ -90,15 +90,15 @@ void TimerHandler() // You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11 uint32_t PWM_Pin[NUMBER_ISR_PWMS] = { - 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 + 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[NUMBER_ISR_PWMS] = { 1000000L, 500000L, 333333L, 250000L, 200000L, 166667L, 142857L, 125000L, - 111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L + 111111L, 100000L, 66667L, 50000L, 40000L, 33333L, 25000L, 20000L }; // You can assign any interval for any timer here, in Hz @@ -111,7 +111,7 @@ float PWM_Freq[] = // 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, + 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 }; @@ -120,7 +120,8 @@ float PWM_DutyCycle[] = void setup() { Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(2000); @@ -131,7 +132,8 @@ void setup() if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler)) { startMicros = micros(); - Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); + Serial.print(F("Starting ITimer OK, micros() = ")); + Serial.println(startMicros); } else Serial.println(F("Can't set ITimer. Select another freq. or timer")); @@ -149,13 +151,13 @@ void setup() ISR_PWM.setPWM(PWM_Pin[i], PWM_Freq[i], PWM_DutyCycle[i]); #else - #if USING_MICROS_RESOLUTION +#if USING_MICROS_RESOLUTION // Or using period in microsecs resolution ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i], PWM_DutyCycle[i]); - #else +#else // Or using period in millisecs resolution ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i] / 1000, PWM_DutyCycle[i]); - #endif +#endif #endif } } diff --git a/examples/ISR_Changing_PWM/ISR_Changing_PWM.ino b/examples/ISR_Changing_PWM/ISR_Changing_PWM.ino index 2888562..2049714 100644 --- a/examples/ISR_Changing_PWM/ISR_Changing_PWM.ino +++ b/examples/ISR_Changing_PWM/ISR_Changing_PWM.ino @@ -58,7 +58,7 @@ NRF52_MBED_Slow_PWM ISR_PWM; ////////////////////////////////////////////////////// void TimerHandler() -{ +{ ISR_PWM.run(); } @@ -94,7 +94,8 @@ int channelNum; void setup() { Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(2000); @@ -105,7 +106,8 @@ void setup() if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler)) { startMicros = micros(); - Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); + Serial.print(F("Starting ITimer OK, micros() = ")); + Serial.println(startMicros); } else Serial.println(F("Can't set ITimer. Select another freq. or timer")); @@ -118,7 +120,10 @@ void setup() void loop() { - Serial.print(F("Using PWM Freq = ")); Serial.print(PWM_Freq1); Serial.print(F(", PWM DutyCycle = ")); Serial.println(PWM_DutyCycle1); + Serial.print(F("Using PWM Freq = ")); + Serial.print(PWM_Freq1); + Serial.print(F(", PWM DutyCycle = ")); + Serial.println(PWM_DutyCycle1); #if USING_PWM_FREQUENCY @@ -139,7 +144,10 @@ void loop() ISR_PWM.deleteChannel((unsigned) channelNum); - Serial.print(F("Using PWM Freq = ")); Serial.print(PWM_Freq2); Serial.print(F(", PWM DutyCycle = ")); Serial.println(PWM_DutyCycle2); + Serial.print(F("Using PWM Freq = ")); + Serial.print(PWM_Freq2); + Serial.print(F(", PWM DutyCycle = ")); + Serial.println(PWM_DutyCycle2); #if USING_PWM_FREQUENCY diff --git a/examples/ISR_Modify_PWM/ISR_Modify_PWM.ino b/examples/ISR_Modify_PWM/ISR_Modify_PWM.ino index d0f079f..a8b850a 100644 --- a/examples/ISR_Modify_PWM/ISR_Modify_PWM.ino +++ b/examples/ISR_Modify_PWM/ISR_Modify_PWM.ino @@ -58,7 +58,7 @@ NRF52_MBED_Slow_PWM ISR_PWM; ////////////////////////////////////////////////////// void TimerHandler() -{ +{ ISR_PWM.run(); } @@ -94,7 +94,8 @@ int channelNum; void setup() { Serial.begin(115200); - while (!Serial); + + while (!Serial && millis() < 5000); delay(2000); @@ -105,7 +106,8 @@ void setup() if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler)) { startMicros = micros(); - Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros); + Serial.print(F("Starting ITimer OK, micros() = ")); + Serial.println(startMicros); } else Serial.println(F("Can't set ITimer. Select another freq. or timer")); @@ -114,7 +116,10 @@ void setup() // You can use up to 16 timer for each ISR_PWM //void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle // , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr) - Serial.print(F("Using PWM Freq = ")); Serial.print(PWM_Freq1); Serial.print(F(", PWM DutyCycle = ")); Serial.println(PWM_DutyCycle1); + Serial.print(F("Using PWM Freq = ")); + Serial.print(PWM_Freq1); + Serial.print(F(", PWM DutyCycle = ")); + Serial.println(PWM_DutyCycle1); #if USING_PWM_FREQUENCY diff --git a/examples/multiFileProject/multiFileProject.cpp b/examples/multiFileProject/multiFileProject.cpp index f0248d1..8856aa9 100644 --- a/examples/multiFileProject/multiFileProject.cpp +++ b/examples/multiFileProject/multiFileProject.cpp @@ -1,6 +1,6 @@ /**************************************************************************************************************************** multiFileProject.cpp - + For nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE Written by Khoi Hoang diff --git a/examples/multiFileProject/multiFileProject.h b/examples/multiFileProject/multiFileProject.h index 00ce3f5..fc59e15 100644 --- a/examples/multiFileProject/multiFileProject.h +++ b/examples/multiFileProject/multiFileProject.h @@ -1,6 +1,6 @@ /**************************************************************************************************************************** multiFileProject.h - + For nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE Written by Khoi Hoang diff --git a/examples/multiFileProject/multiFileProject.ino b/examples/multiFileProject/multiFileProject.ino index 350cd53..c2918d2 100644 --- a/examples/multiFileProject/multiFileProject.ino +++ b/examples/multiFileProject/multiFileProject.ino @@ -1,6 +1,6 @@ /**************************************************************************************************************************** multiFileProject.ino - + For nRF52-based boards using Arduino mbed_nano core, such as Nano_33_BLE Written by Khoi Hoang @@ -14,32 +14,35 @@ #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 -#define NRF52_MBED_SLOW_PWM_VERSION_MIN_TARGET F("megaAVR_SLOW_PWM v1.2.1") -#define NRF52_MBED_SLOW_PWM_VERSION_MIN 1002001 +#define NRF52_MBED_SLOW_PWM_VERSION_MIN_TARGET F("megaAVR_SLOW_PWM v1.2.2") +#define NRF52_MBED_SLOW_PWM_VERSION_MIN 1002002 #include "multiFileProject.h" // To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error #include "nRF52_MBED_Slow_PWM.h" -void setup() +void setup() { Serial.begin(115200); - while (!Serial); - - Serial.println("\nStart multiFileProject"); + + while (!Serial && millis() < 5000); + + Serial.println("\nStart multiFileProject on "); Serial.println(BOARD_NAME); Serial.println(NRF52_MBED_SLOW_PWM_VERSION); #if defined(NRF52_MBED_SLOW_PWM_VERSION_MIN) + if (NRF52_MBED_SLOW_PWM_VERSION_INT < NRF52_MBED_SLOW_PWM_VERSION_MIN) { Serial.print("Warning. Must use this example on Version equal or later than : "); Serial.println(NRF52_MBED_SLOW_PWM_VERSION_MIN_TARGET); } + #endif } -void loop() +void loop() { // put your main code here, to run repeatedly: } diff --git a/library.json b/library.json index d08b0d7..052024d 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "nRF52_MBED_Slow_PWM", - "version": "1.2.1", + "version": "1.2.2", "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 bedcd68..7130636 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=nRF52_MBED_Slow_PWM -version=1.2.1 +version=1.2.2 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. 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/PWM_Generic_Debug.h b/src/PWM_Generic_Debug.h index 0151543..9cb34d7 100644 --- a/src/PWM_Generic_Debug.h +++ b/src/PWM_Generic_Debug.h @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,6 +20,7 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM.h b/src/nRF52_MBED_Slow_PWM.h index b3cc6d6..fbd4ae1 100644 --- a/src/nRF52_MBED_Slow_PWM.h +++ b/src/nRF52_MBED_Slow_PWM.h @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,6 +20,7 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM.hpp b/src/nRF52_MBED_Slow_PWM.hpp index 5988718..da1cbba 100644 --- a/src/nRF52_MBED_Slow_PWM.hpp +++ b/src/nRF52_MBED_Slow_PWM.hpp @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,6 +20,7 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ /* @@ -71,13 +72,13 @@ #endif #ifndef NRF52_MBED_SLOW_PWM_VERSION - #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.1" + #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.2" #define NRF52_MBED_SLOW_PWM_VERSION_MAJOR 1 #define NRF52_MBED_SLOW_PWM_VERSION_MINOR 2 - #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 1 + #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 2 - #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002001 + #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002002 #endif #ifndef _PWM_LOGLEVEL_ diff --git a/src/nRF52_MBED_Slow_PWM_ISR.h b/src/nRF52_MBED_Slow_PWM_ISR.h index e2531cc..cb7e557 100644 --- a/src/nRF52_MBED_Slow_PWM_ISR.h +++ b/src/nRF52_MBED_Slow_PWM_ISR.h @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,6 +20,7 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ #pragma once diff --git a/src/nRF52_MBED_Slow_PWM_ISR.hpp b/src/nRF52_MBED_Slow_PWM_ISR.hpp index 1871111..c0c0c82 100644 --- a/src/nRF52_MBED_Slow_PWM_ISR.hpp +++ b/src/nRF52_MBED_Slow_PWM_ISR.hpp @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,6 +20,7 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ #pragma once @@ -32,13 +33,13 @@ #endif #ifndef NRF52_MBED_SLOW_PWM_VERSION - #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.1" + #define NRF52_MBED_SLOW_PWM_VERSION "NRF52_MBED_Slow_PWM v1.2.2" #define NRF52_MBED_SLOW_PWM_VERSION_MAJOR 1 #define NRF52_MBED_SLOW_PWM_VERSION_MINOR 2 - #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 1 + #define NRF52_MBED_SLOW_PWM_VERSION_PATCH 2 - #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002001 + #define NRF52_MBED_SLOW_PWM_VERSION_INT 1002002 #endif #ifndef _PWM_LOGLEVEL_ diff --git a/src/nRF52_MBED_Slow_PWM_ISR_Impl.h b/src/nRF52_MBED_Slow_PWM_ISR_Impl.h index c85b264..2336724 100644 --- a/src/nRF52_MBED_Slow_PWM_ISR_Impl.h +++ b/src/nRF52_MBED_Slow_PWM_ISR_Impl.h @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,6 +20,7 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ #pragma once @@ -29,18 +30,18 @@ #include -/////////////////////////////////////////////////// +/////////////////////////////////////////////////// uint64_t timeNow() { -#if USING_MICROS_RESOLUTION +#if USING_MICROS_RESOLUTION return ( (uint64_t) micros() ); #else return ( (uint64_t) millis() ); -#endif +#endif } - -/////////////////////////////////////////////////// + +/////////////////////////////////////////////////// NRF52_MBED_Slow_PWM_ISR::NRF52_MBED_Slow_PWM_ISR() : numChannels (-1) @@ -49,40 +50,40 @@ NRF52_MBED_Slow_PWM_ISR::NRF52_MBED_Slow_PWM_ISR() /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::init() +void NRF52_MBED_Slow_PWM_ISR::init() { uint64_t currentTime = timeNow(); - - for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) + + for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) { memset((void*) &PWM[channelNum], 0, sizeof (PWM_t)); PWM[channelNum].prevTime = currentTime; PWM[channelNum].pin = INVALID_NRF52_MBED_PIN; } - + numChannels = 0; } /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::run() -{ +void NRF52_MBED_Slow_PWM_ISR::run() +{ uint64_t currentTime = timeNow(); - for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) + for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) { // If enabled => check // start period / dutyCycle => digitalWrite HIGH // end dutyCycle => digitalWrite LOW - if (PWM[channelNum].enabled) + if (PWM[channelNum].enabled) { - if ( (uint32_t) (currentTime - PWM[channelNum].prevTime) <= PWM[channelNum].onTime ) - { + if ( (uint32_t) (currentTime - PWM[channelNum].prevTime) <= PWM[channelNum].onTime ) + { if (!PWM[channelNum].pinHigh) { digitalWrite(PWM[channelNum].pin, HIGH); PWM[channelNum].pinHigh = true; - + // callbackStart if (PWM[channelNum].callbackStart != nullptr) { @@ -90,13 +91,13 @@ void NRF52_MBED_Slow_PWM_ISR::run() } } } - else if ( (uint32_t) (currentTime - PWM[channelNum].prevTime) < PWM[channelNum].period ) + else if ( (uint32_t) (currentTime - PWM[channelNum].prevTime) < PWM[channelNum].period ) { if (PWM[channelNum].pinHigh) { digitalWrite(PWM[channelNum].pin, LOW); PWM[channelNum].pinHigh = false; - + // callback when PWM pulse stops (LOW) if (PWM[channelNum].callbackStop != nullptr) { @@ -104,22 +105,24 @@ void NRF52_MBED_Slow_PWM_ISR::run() } } } - //else - else if ( (uint32_t) (currentTime - PWM[channelNum].prevTime) >= PWM[channelNum].period ) + //else + else if ( (uint32_t) (currentTime - PWM[channelNum].prevTime) >= PWM[channelNum].period ) { PWM[channelNum].prevTime = currentTime; - + #if CHANGING_PWM_END_OF_CYCLE + // Only update whenever having newPeriod if (PWM[channelNum].newPeriod != 0) { PWM[channelNum].period = PWM[channelNum].newPeriod; PWM[channelNum].newPeriod = 0; - + PWM[channelNum].onTime = PWM[channelNum].newOnTime; } -#endif - } + +#endif + } } } } @@ -129,16 +132,16 @@ void NRF52_MBED_Slow_PWM_ISR::run() // find the first available slot // return -1 if none found -int NRF52_MBED_Slow_PWM_ISR::findFirstFreeSlot() +int NRF52_MBED_Slow_PWM_ISR::findFirstFreeSlot() { // all slots are used - if (numChannels >= MAX_NUMBER_CHANNELS) + if (numChannels >= MAX_NUMBER_CHANNELS) { return -1; } // return the first slot with no callbackStart (i.e. free) - for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) + for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) { if ( (PWM[channelNum].period == 0) && !PWM[channelNum].enabled ) { @@ -152,10 +155,11 @@ int NRF52_MBED_Slow_PWM_ISR::findFirstFreeSlot() /////////////////////////////////////////////////// -int NRF52_MBED_Slow_PWM_ISR::setupPWMChannel(const uint32_t& pin, const uint32_t& period, const float& dutycycle, void* cbStartFunc, void* cbStopFunc) +int NRF52_MBED_Slow_PWM_ISR::setupPWMChannel(const uint32_t& pin, const uint32_t& period, const float& dutycycle, + void* cbStartFunc, void* cbStopFunc) { int channelNum; - + // Invalid input, such as period = 0, etc if ( (period == 0) || (dutycycle < 0.0) || (dutycycle > 100.0) ) { @@ -163,50 +167,55 @@ int NRF52_MBED_Slow_PWM_ISR::setupPWMChannel(const uint32_t& pin, const uint32_t return -1; } - if (numChannels < 0) + if (numChannels < 0) { init(); } - + channelNum = findFirstFreeSlot(); - - if (channelNum < 0) + + if (channelNum < 0) { return -1; } PWM[channelNum].pin = pin; PWM[channelNum].period = period; - + // Must be 0 for new PWM channel PWM[channelNum].newPeriod = 0; - + PWM[channelNum].onTime = ( period * dutycycle ) / 100; - + pinMode(pin, OUTPUT); digitalWrite(pin, HIGH); PWM[channelNum].pinHigh = true; - + PWM[channelNum].prevTime = timeNow(); - + PWM[channelNum].callbackStart = cbStartFunc; PWM[channelNum].callbackStop = cbStopFunc; - - PWM_LOGINFO0("Channel : "); PWM_LOGINFO0(channelNum); - PWM_LOGINFO0("\t Period : "); PWM_LOGINFO0(PWM[channelNum].period); - PWM_LOGINFO0("\t\tOnTime : "); PWM_LOGINFO0(PWM[channelNum].onTime); - PWM_LOGINFO0("\tStart_Time : "); PWM_LOGINFOLN0(PWM[channelNum].prevTime); - + + PWM_LOGINFO0("Channel : "); + PWM_LOGINFO0(channelNum); + PWM_LOGINFO0("\t Period : "); + PWM_LOGINFO0(PWM[channelNum].period); + PWM_LOGINFO0("\t\tOnTime : "); + PWM_LOGINFO0(PWM[channelNum].onTime); + PWM_LOGINFO0("\tStart_Time : "); + PWM_LOGINFOLN0(PWM[channelNum].prevTime); + numChannels++; - + PWM[channelNum].enabled = true; - + return channelNum; } /////////////////////////////////////////////////// -bool NRF52_MBED_Slow_PWM_ISR::modifyPWMChannel_Period(const uint8_t& channelNum, const uint32_t& pin, const uint32_t& period, const float& dutycycle) +bool NRF52_MBED_Slow_PWM_ISR::modifyPWMChannel_Period(const uint8_t& channelNum, const uint32_t& pin, + const uint32_t& period, const float& dutycycle) { // Invalid input, such as period = 0, etc if ( (period == 0) || (dutycycle < 0.0) || (dutycycle > 100.0) ) @@ -215,54 +224,62 @@ bool NRF52_MBED_Slow_PWM_ISR::modifyPWMChannel_Period(const uint8_t& channelNum, return false; } - if (channelNum > MAX_NUMBER_CHANNELS) + if (channelNum > MAX_NUMBER_CHANNELS) { PWM_LOGERROR("Error: channelNum > MAX_NUMBER_CHANNELS"); return false; } - - if (PWM[channelNum].pin != pin) + + if (PWM[channelNum].pin != pin) { PWM_LOGERROR("Error: channelNum and pin mismatched"); return false; } - + #if CHANGING_PWM_END_OF_CYCLE PWM[channelNum].newPeriod = period; PWM[channelNum].newDutyCycle = dutycycle; PWM[channelNum].newOnTime = ( period * dutycycle ) / 100; - - PWM_LOGINFO0("Channel : "); PWM_LOGINFO0(channelNum); - PWM_LOGINFO0("\tNew Period : "); PWM_LOGINFO0(PWM[channelNum].newPeriod); - PWM_LOGINFO0("\t\tOnTime : "); PWM_LOGINFO0(PWM[channelNum].newOnTime); - PWM_LOGINFO0("\tStart_Time : "); PWM_LOGINFOLN0(PWM[channelNum].prevTime); - + + PWM_LOGINFO0("Channel : "); + PWM_LOGINFO0(channelNum); + PWM_LOGINFO0("\tNew Period : "); + PWM_LOGINFO0(PWM[channelNum].newPeriod); + PWM_LOGINFO0("\t\tOnTime : "); + PWM_LOGINFO0(PWM[channelNum].newOnTime); + PWM_LOGINFO0("\tStart_Time : "); + PWM_LOGINFOLN0(PWM[channelNum].prevTime); + #else - PWM[channelNum].period = period; + PWM[channelNum].period = period; PWM[channelNum].onTime = ( period * dutycycle ) / 100; - + digitalWrite(pin, HIGH); PWM[channelNum].pinHigh = true; - + PWM[channelNum].prevTime = timeNow(); - - PWM_LOGINFO0("Channel : "); PWM_LOGINFO0(channelNum); - PWM_LOGINFO0("\t Period : "); PWM_LOGINFO0(PWM[channelNum].period); - PWM_LOGINFO0("\t\tOnTime : "); PWM_LOGINFO0(PWM[channelNum].onTime); - PWM_LOGINFO0("\tStart_Time : "); PWM_LOGINFOLN0(PWM[channelNum].prevTime); - + + PWM_LOGINFO0("Channel : "); + PWM_LOGINFO0(channelNum); + PWM_LOGINFO0("\t Period : "); + PWM_LOGINFO0(PWM[channelNum].period); + PWM_LOGINFO0("\t\tOnTime : "); + PWM_LOGINFO0(PWM[channelNum].onTime); + PWM_LOGINFO0("\tStart_Time : "); + PWM_LOGINFOLN0(PWM[channelNum].prevTime); + #endif - + return true; } /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::deleteChannel(const uint8_t& channelNum) +void NRF52_MBED_Slow_PWM_ISR::deleteChannel(const uint8_t& channelNum) { // nothing to delete if no timers are in use if ( (channelNum >= MAX_NUMBER_CHANNELS) || (numChannels == 0) ) @@ -274,9 +291,9 @@ void NRF52_MBED_Slow_PWM_ISR::deleteChannel(const uint8_t& channelNum) if ( (PWM[channelNum].pin != INVALID_NRF52_MBED_PIN) && (PWM[channelNum].period != 0) ) { memset((void*) &PWM[channelNum], 0, sizeof (PWM_t)); - + PWM[channelNum].pin = INVALID_NRF52_MBED_PIN; - + // update number of timers numChannels--; } @@ -284,9 +301,9 @@ void NRF52_MBED_Slow_PWM_ISR::deleteChannel(const uint8_t& channelNum) /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::restartChannel(const uint8_t& channelNum) +void NRF52_MBED_Slow_PWM_ISR::restartChannel(const uint8_t& channelNum) { - if (channelNum >= MAX_NUMBER_CHANNELS) + if (channelNum >= MAX_NUMBER_CHANNELS) { return; } @@ -296,9 +313,9 @@ void NRF52_MBED_Slow_PWM_ISR::restartChannel(const uint8_t& channelNum) /////////////////////////////////////////////////// -bool NRF52_MBED_Slow_PWM_ISR::isEnabled(const uint8_t& channelNum) +bool NRF52_MBED_Slow_PWM_ISR::isEnabled(const uint8_t& channelNum) { - if (channelNum >= MAX_NUMBER_CHANNELS) + if (channelNum >= MAX_NUMBER_CHANNELS) { return false; } @@ -308,9 +325,9 @@ bool NRF52_MBED_Slow_PWM_ISR::isEnabled(const uint8_t& channelNum) /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::enable(const uint8_t& channelNum) +void NRF52_MBED_Slow_PWM_ISR::enable(const uint8_t& channelNum) { - if (channelNum >= MAX_NUMBER_CHANNELS) + if (channelNum >= MAX_NUMBER_CHANNELS) { return; } @@ -320,9 +337,9 @@ void NRF52_MBED_Slow_PWM_ISR::enable(const uint8_t& channelNum) /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::disable(const uint8_t& channelNum) +void NRF52_MBED_Slow_PWM_ISR::disable(const uint8_t& channelNum) { - if (channelNum >= MAX_NUMBER_CHANNELS) + if (channelNum >= MAX_NUMBER_CHANNELS) { return; } @@ -332,11 +349,11 @@ void NRF52_MBED_Slow_PWM_ISR::disable(const uint8_t& channelNum) /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::enableAll() +void NRF52_MBED_Slow_PWM_ISR::enableAll() { // Enable all timers with a callbackStart assigned (used) - for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) + for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) { if (PWM[channelNum].period != 0) { @@ -347,10 +364,10 @@ void NRF52_MBED_Slow_PWM_ISR::enableAll() /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::disableAll() +void NRF52_MBED_Slow_PWM_ISR::disableAll() { // Disable all timers with a callbackStart assigned (used) - for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) + for (uint8_t channelNum = 0; channelNum < MAX_NUMBER_CHANNELS; channelNum++) { if (PWM[channelNum].period != 0) { @@ -361,9 +378,9 @@ void NRF52_MBED_Slow_PWM_ISR::disableAll() /////////////////////////////////////////////////// -void NRF52_MBED_Slow_PWM_ISR::toggle(const uint8_t& channelNum) +void NRF52_MBED_Slow_PWM_ISR::toggle(const uint8_t& channelNum) { - if (channelNum >= MAX_NUMBER_CHANNELS) + if (channelNum >= MAX_NUMBER_CHANNELS) { return; } @@ -373,7 +390,7 @@ void NRF52_MBED_Slow_PWM_ISR::toggle(const uint8_t& channelNum) /////////////////////////////////////////////////// -int8_t NRF52_MBED_Slow_PWM_ISR::getnumChannels() +int8_t NRF52_MBED_Slow_PWM_ISR::getnumChannels() { return numChannels; } diff --git a/src/nRF52_MBED_Slow_PWM_Impl.h b/src/nRF52_MBED_Slow_PWM_Impl.h index 32481e2..22e4fa9 100644 --- a/src/nRF52_MBED_Slow_PWM_Impl.h +++ b/src/nRF52_MBED_Slow_PWM_Impl.h @@ -12,7 +12,7 @@ Therefore, their executions are not blocked by bad-behaving functions / tasks. This important feature is absolutely necessary for mission-critical tasks. - Version: 1.2.1 + Version: 1.2.2 Version Modified By Date Comments ------- ----------- ---------- ----------- @@ -20,14 +20,15 @@ 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 + 1.2.2 K Hoang 26/10/2022 Add support to SEEED_XIAO_NRF52840 and SEEED_XIAO_NRF52840_SENSE using mbed *****************************************************************************************************************************/ /* nRF52 has 5 Hardware TIMERs: NRF_TIMER0-NRF_TIMER4 NRF_TIMER0 is used by the soft device, NRF_TIMER1-NRF_TIMER4 are available - + Defined in file ./adafruit/hardware/nrf52/0.21.0/cores/nRF5/nordic/nrfx/mdk/nrf52.h - + #define NRF_TIMER0_BASE 0x40008000UL #define NRF_TIMER1_BASE 0x40009000UL #define NRF_TIMER2_BASE 0x4000A000UL @@ -41,9 +42,9 @@ #define NRF_TIMER4 ((NRF_TIMER_Type*) NRF_TIMER4_BASE) =============================================================================== - + Defined in ./adafruit/hardware/nrf52/0.21.0/cores/nRF5/nordic/nrfx/hal/nrf_timer.h - + Timer prescalers typedef enum { @@ -58,7 +59,7 @@ NRF_TIMER_FREQ_62500Hz, ///< Timer frequency 62500 Hz. NRF_TIMER_FREQ_31250Hz ///< Timer frequency 31250 Hz. } nrf_timer_frequency_t; - + */ #pragma once @@ -71,36 +72,36 @@ // only Timer 1, 3 and 4 are available extern "C" void TIMER1_IRQHandler_v() { - if (nRF52Timers[1]) + if (nRF52Timers[1]) { nRF52Timers[1]->detachInterrupt(); - + (*(nRF52Timers[1]->getCallback()))(); - + nRF52Timers[1]->enableTimer(); } } -extern "C" void TIMER3_IRQHandler_v() +extern "C" void TIMER3_IRQHandler_v() { - if (nRF52Timers[3]) + if (nRF52Timers[3]) { nRF52Timers[3]->detachInterrupt(); - + (*(nRF52Timers[3]->getCallback()))(); - + nRF52Timers[3]->enableTimer(); } } -extern "C" void TIMER4_IRQHandler_v() +extern "C" void TIMER4_IRQHandler_v() { - if (nRF52Timers[4]) + if (nRF52Timers[4]) { nRF52Timers[4]->detachInterrupt(); - + (*(nRF52Timers[4]->getCallback()))(); - + nRF52Timers[4]->enableTimer(); } } 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 +