Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Commit

Permalink
v1.2.0 to fix multiple-definitions linker error
Browse files Browse the repository at this point in the history
### Releases v1.2.0

1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
2. DutyCycle to be optionally updated at the end current PWM period instead of immediately. Check [DutyCycle to be updated at the end current PWM period #2](khoih-prog/ESP8266_PWM#2)
3. Add examples [SAMD21 multiFileProject](examples/SAMD21/multiFileProject) and [SAMD51 multiFileProject](examples/SAMD51/multiFileProject)to demo for multiple-file project
4. Improve accuracy by using `double`, instead of `uint32_t` for `dutycycle`, `period`. Check [Change Duty Cycle #1](khoih-prog/ESP8266_PWM#1 (comment))
5. Optimize library code by using `reference-passing` instead of `value-passing`
6. Add support to many more boards, such as `SAMD21E1xA`, `SAMD21G1xA` and`SAMD21J1xA`
7. Update examples accordingly
8. Update `Packages' Patches`
  • Loading branch information
khoih-prog authored Feb 1, 2022
1 parent 7c90680 commit 682cb6d
Show file tree
Hide file tree
Showing 29 changed files with 2,917 additions and 1,665 deletions.
11 changes: 6 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,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.16) or Platform.io version
* `SAMD` Core Version (e.g. Arduino SAMD core v1.8.11, Adafruit SAMD core v1.7.5, Seeed Studio SAMD v1.8.2, Sparkfun SAMD v1.8.1)
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
* `SAMD` Core Version (e.g. Arduino SAMD core v1.8.12, Adafruit SAMD core v1.7.8, Seeed Studio SAMD v1.8.2, Sparkfun SAMD v1.8.3)
* Board type and relevant info
* Contextual information (e.g. what you were trying to achieve)
* Simplest possible steps to reproduce
Expand All @@ -27,11 +27,11 @@ Please ensure to specify the following:
### Example

```
Arduino IDE version: 1.8.16
Arduino SAMD Core Version 1.8.11
Arduino IDE version: 1.8.19
Arduino SAMD Core Version 1.8.12
SAMD_NANO_33_IOT
OS: Ubuntu 20.04 LTS
Linux xy-Inspiron-3593 5.4.0-90-generic #101-Ubuntu SMP Fri Oct 15 20:00:55 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
Linux xy-Inspiron-3593 5.4.0-96-generic #109-Ubuntu SMP Wed Jan 12 16:49:16 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
Context:
I encountered a crash while using SAMD_Slow_PWM.
Expand All @@ -52,3 +52,4 @@ There are usually some outstanding feature requests in the [existing issues list
### Sending Pull Requests

Pull Requests with changes and fixes are also welcome!

498 changes: 253 additions & 245 deletions README.md

Large diffs are not rendered by default.

12 changes: 12 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
## Table of Contents

* [Changelog](#changelog)
* [Releases v1.2.0](#releases-v120)
* [Releases v1.1.0](#releases-v110)
* [Initial Releases v1.0.0](#Initial-Releases-v100)

Expand All @@ -20,6 +21,17 @@

## Changelog

### Releases v1.2.0

1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
2. DutyCycle to be optionally updated at the end current PWM period instead of immediately. Check [DutyCycle to be updated at the end current PWM period #2](https://github.com/khoih-prog/ESP8266_PWM/issues/2)
3. Add examples [SAMD21 multiFileProject](examples/SAMD21/multiFileProject) and [SAMD51 multiFileProject](examples/SAMD51/multiFileProject)to demo for multiple-file project
4. Improve accuracy by using `double`, instead of `uint32_t` for `dutycycle`, `period`. Check [Change Duty Cycle #1](https://github.com/khoih-prog/ESP8266_PWM/issues/1#issuecomment-1024969658)
5. Optimize library code by using `reference-passing` instead of `value-passing`
6. Add support to many more boards, such as `SAMD21E1xA`, `SAMD21G1xA` and`SAMD21J1xA`
7. Update examples accordingly
8. Update `Packages' Patches`

### Releases v1.1.0

1. Add functions to modify PWM settings on-the-fly
Expand Down
186 changes: 186 additions & 0 deletions examples/SAMD21/ISR_4_PWMs_Array/ISR_4_PWMs_Array.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
/****************************************************************************************************************************
ISR_4_PWMs_Array.ino
For SAMD21/SAMD51 boards
Written by Khoi Hoang
Built by Khoi Hoang https://github.com/khoih-prog/SAMD_Slow_PWM
Licensed under MIT license
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
unsigned long miliseconds), you just consume only one SAMD timer and avoid conflicting with other cores' tasks.
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
Therefore, their executions are not blocked by bad-behaving functions / tasks.
This important feature is absolutely necessary for mission-critical tasks.
*****************************************************************************************************************************/

#if !( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21G18A__) )
#error This code is designed to run on SAMD21 platform! Please check your Tools->Board setting.
#endif

// These define's must be placed at the beginning before #include "SAMD_Slow_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

// Default is true, uncomment to false
//#define CHANGING_PWM_END_OF_CYCLE false

#define MAX_SAMD_PWM_FREQ 1000

// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
#include "SAMD_Slow_PWM.h"

#define LED_OFF LOW
#define LED_ON HIGH

#ifndef LED_BUILTIN
#define LED_BUILTIN 13
#endif

// Use 50uS for slow SAMD21
#define HW_TIMER_INTERVAL_US 50L

uint64_t startMicros = 0;

// Init SAMD timer TIMER_TC3
SAMDTimer ITimer(TIMER_TC3);

// Init SAMD timer TIMER_TCC
//SAMDTimer ITimer(TIMER_TCC);

// Init SAMD_Slow_PWM
SAMD_Slow_PWM ISR_PWM;

//////////////////////////////////////////////////////

void TimerHandler()
{
ISR_PWM.run();
}

//////////////////////////////////////////////////////

// Use max 4 for slow SAMD21
#define NUMBER_ISR_PWMS 4

#define PIN_D2 2
#define PIN_D7 7
#define PIN_D8 8
#define PIN_D9 9
#define PIN_D10 10
#define PIN_D11 11
#define PIN_D12 12

//////////////////////////////////////////////////////

#define USING_PWM_FREQUENCY true

//////////////////////////////////////////////////////

// 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, PIN_D2, PIN_D7, PIN_D8
};

// You can assign any interval for any timer here, in microseconds
double PWM_Period[] =
{
1000000.0, 500000.0, 333333.333, 50000.0
};

// You can assign any interval for any timer here, in Hz
double PWM_Freq[] =
{
1.0, 2.0, 3.0, 4.0
};

// You can assign any interval for any timer here, in milliseconds
double PWM_DutyCycle[] =
{
40.00, 45.00, 50.00, 55.00
};

typedef void (*irqCallback) ();


// In SAMD, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
// 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 doingSomething0()
{
}

void doingSomething1()
{
}

void doingSomething2()
{
}

void doingSomething3()
{
}


irqCallback irqCallbackStartFunc[] =
{
doingSomething0, doingSomething1, doingSomething2, doingSomething3
};

////////////////////////////////////////////////

void setup()
{
Serial.begin(115200);
while (!Serial);

delay(2000);

Serial.print(F("\nStarting ISR_4_PWMs_Array on ")); Serial.println(BOARD_NAME);
Serial.println(SAMD_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"));

#if 1
// 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++)
{
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t 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(PWM_Pin[i], PWM_Freq[i], PWM_DutyCycle[i], irqCallbackStartFunc[i]);

#else
#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
// 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
}

void loop()
{
}
Loading

0 comments on commit 682cb6d

Please sign in to comment.