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

Commit 682cb6d

Browse files
authored
v1.2.0 to fix multiple-definitions linker error
### 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`
1 parent 7c90680 commit 682cb6d

29 files changed

+2917
-1665
lines changed

CONTRIBUTING.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p
1414

1515
Please ensure to specify the following:
1616

17-
* Arduino IDE version (e.g. 1.8.16) or Platform.io version
18-
* `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)
17+
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
18+
* `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)
1919
* Board type and relevant info
2020
* Contextual information (e.g. what you were trying to achieve)
2121
* Simplest possible steps to reproduce
@@ -27,11 +27,11 @@ Please ensure to specify the following:
2727
### Example
2828

2929
```
30-
Arduino IDE version: 1.8.16
31-
Arduino SAMD Core Version 1.8.11
30+
Arduino IDE version: 1.8.19
31+
Arduino SAMD Core Version 1.8.12
3232
SAMD_NANO_33_IOT
3333
OS: Ubuntu 20.04 LTS
34-
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
34+
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
3535
3636
Context:
3737
I encountered a crash while using SAMD_Slow_PWM.
@@ -52,3 +52,4 @@ There are usually some outstanding feature requests in the [existing issues list
5252
### Sending Pull Requests
5353

5454
Pull Requests with changes and fixes are also welcome!
55+

README.md

Lines changed: 253 additions & 245 deletions
Large diffs are not rendered by default.

changelog.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
## Table of Contents
1313

1414
* [Changelog](#changelog)
15+
* [Releases v1.2.0](#releases-v120)
1516
* [Releases v1.1.0](#releases-v110)
1617
* [Initial Releases v1.0.0](#Initial-Releases-v100)
1718

@@ -20,6 +21,17 @@
2021

2122
## Changelog
2223

24+
### Releases v1.2.0
25+
26+
1. Fix `multiple-definitions` linker error. Drop `src_cpp` and `src_h` directories
27+
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)
28+
3. Add examples [SAMD21 multiFileProject](examples/SAMD21/multiFileProject) and [SAMD51 multiFileProject](examples/SAMD51/multiFileProject)to demo for multiple-file project
29+
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)
30+
5. Optimize library code by using `reference-passing` instead of `value-passing`
31+
6. Add support to many more boards, such as `SAMD21E1xA`, `SAMD21G1xA` and`SAMD21J1xA`
32+
7. Update examples accordingly
33+
8. Update `Packages' Patches`
34+
2335
### Releases v1.1.0
2436

2537
1. Add functions to modify PWM settings on-the-fly
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/****************************************************************************************************************************
2+
ISR_4_PWMs_Array.ino
3+
For SAMD21/SAMD51 boards
4+
Written by Khoi Hoang
5+
6+
Built by Khoi Hoang https://github.com/khoih-prog/SAMD_Slow_PWM
7+
Licensed under MIT license
8+
9+
Now even you use all these new 16 ISR-based timers,with their maximum interval practically unlimited (limited only by
10+
unsigned long miliseconds), you just consume only one SAMD timer and avoid conflicting with other cores' tasks.
11+
The accuracy is nearly perfect compared to software timers. The most important feature is they're ISR-based timers
12+
Therefore, their executions are not blocked by bad-behaving functions / tasks.
13+
This important feature is absolutely necessary for mission-critical tasks.
14+
*****************************************************************************************************************************/
15+
16+
#if !( defined(ARDUINO_SAMD_ZERO) || defined(ARDUINO_SAMD_MKR1000) || defined(ARDUINO_SAMD_MKRWIFI1010) \
17+
|| defined(ARDUINO_SAMD_NANO_33_IOT) || defined(ARDUINO_SAMD_MKRFox1200) || defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) \
18+
|| defined(ARDUINO_SAMD_MKRGSM1400) || defined(ARDUINO_SAMD_MKRNB1500) || defined(ARDUINO_SAMD_MKRVIDOR4000) || defined(__SAMD21G18A__) \
19+
|| defined(ARDUINO_SAMD_CIRCUITPLAYGROUND_EXPRESS) || defined(__SAMD21G18A__) )
20+
#error This code is designed to run on SAMD21 platform! Please check your Tools->Board setting.
21+
#endif
22+
23+
// These define's must be placed at the beginning before #include "SAMD_Slow_PWM.h"
24+
// _PWM_LOGLEVEL_ from 0 to 4
25+
// Don't define _PWM_LOGLEVEL_ > 0. Only for special ISR debugging only. Can hang the system.
26+
#define _PWM_LOGLEVEL_ 4
27+
28+
#define USING_MICROS_RESOLUTION true //false
29+
30+
// Default is true, uncomment to false
31+
//#define CHANGING_PWM_END_OF_CYCLE false
32+
33+
#define MAX_SAMD_PWM_FREQ 1000
34+
35+
// To be included only in main(), .ino with setup() to avoid `Multiple Definitions` Linker Error
36+
#include "SAMD_Slow_PWM.h"
37+
38+
#define LED_OFF LOW
39+
#define LED_ON HIGH
40+
41+
#ifndef LED_BUILTIN
42+
#define LED_BUILTIN 13
43+
#endif
44+
45+
// Use 50uS for slow SAMD21
46+
#define HW_TIMER_INTERVAL_US 50L
47+
48+
uint64_t startMicros = 0;
49+
50+
// Init SAMD timer TIMER_TC3
51+
SAMDTimer ITimer(TIMER_TC3);
52+
53+
// Init SAMD timer TIMER_TCC
54+
//SAMDTimer ITimer(TIMER_TCC);
55+
56+
// Init SAMD_Slow_PWM
57+
SAMD_Slow_PWM ISR_PWM;
58+
59+
//////////////////////////////////////////////////////
60+
61+
void TimerHandler()
62+
{
63+
ISR_PWM.run();
64+
}
65+
66+
//////////////////////////////////////////////////////
67+
68+
// Use max 4 for slow SAMD21
69+
#define NUMBER_ISR_PWMS 4
70+
71+
#define PIN_D2 2
72+
#define PIN_D7 7
73+
#define PIN_D8 8
74+
#define PIN_D9 9
75+
#define PIN_D10 10
76+
#define PIN_D11 11
77+
#define PIN_D12 12
78+
79+
//////////////////////////////////////////////////////
80+
81+
#define USING_PWM_FREQUENCY true
82+
83+
//////////////////////////////////////////////////////
84+
85+
// You can assign pins here. Be carefull to select good pin to use or crash, e.g pin 6-11
86+
uint32_t PWM_Pin[] =
87+
{
88+
LED_BUILTIN, PIN_D2, PIN_D7, PIN_D8
89+
};
90+
91+
// You can assign any interval for any timer here, in microseconds
92+
double PWM_Period[] =
93+
{
94+
1000000.0, 500000.0, 333333.333, 50000.0
95+
};
96+
97+
// You can assign any interval for any timer here, in Hz
98+
double PWM_Freq[] =
99+
{
100+
1.0, 2.0, 3.0, 4.0
101+
};
102+
103+
// You can assign any interval for any timer here, in milliseconds
104+
double PWM_DutyCycle[] =
105+
{
106+
40.00, 45.00, 50.00, 55.00
107+
};
108+
109+
typedef void (*irqCallback) ();
110+
111+
112+
// In SAMD, avoid doing something fancy in ISR, for example complex Serial.print with String() argument
113+
// The pure simple Serial.prints here are just for demonstration and testing. Must be eliminate in working environment
114+
// Or you can get this run-time error / crash
115+
void doingSomething0()
116+
{
117+
}
118+
119+
void doingSomething1()
120+
{
121+
}
122+
123+
void doingSomething2()
124+
{
125+
}
126+
127+
void doingSomething3()
128+
{
129+
}
130+
131+
132+
irqCallback irqCallbackStartFunc[] =
133+
{
134+
doingSomething0, doingSomething1, doingSomething2, doingSomething3
135+
};
136+
137+
////////////////////////////////////////////////
138+
139+
void setup()
140+
{
141+
Serial.begin(115200);
142+
while (!Serial);
143+
144+
delay(2000);
145+
146+
Serial.print(F("\nStarting ISR_4_PWMs_Array on ")); Serial.println(BOARD_NAME);
147+
Serial.println(SAMD_SLOW_PWM_VERSION);
148+
149+
// Interval in microsecs
150+
if (ITimer.attachInterruptInterval(HW_TIMER_INTERVAL_US, TimerHandler))
151+
{
152+
startMicros = micros();
153+
Serial.print(F("Starting ITimer OK, micros() = ")); Serial.println(startMicros);
154+
}
155+
else
156+
Serial.println(F("Can't set ITimer. Select another freq. or timer"));
157+
158+
#if 1
159+
// Just to demonstrate, don't use too many ISR Timers if not absolutely necessary
160+
// You can use up to 16 timer for each ISR_PWM
161+
for (uint16_t i = 0; i < NUMBER_ISR_PWMS; i++)
162+
{
163+
//void setPWM(uint32_t pin, uint32_t frequency, uint32_t dutycycle
164+
// , timer_callback_p StartCallback = nullptr, timer_callback_p StopCallback = nullptr)
165+
166+
#if USING_PWM_FREQUENCY
167+
168+
// You can use this with PWM_Freq in Hz
169+
ISR_PWM.setPWM(PWM_Pin[i], PWM_Freq[i], PWM_DutyCycle[i], irqCallbackStartFunc[i]);
170+
171+
#else
172+
#if USING_MICROS_RESOLUTION
173+
// Or using period in microsecs resolution
174+
ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i], PWM_DutyCycle[i], irqCallbackStartFunc[i]);
175+
#else
176+
// Or using period in millisecs resolution
177+
ISR_PWM.setPWM_Period(PWM_Pin[i], PWM_Period[i] / 1000, PWM_DutyCycle[i], irqCallbackStartFunc[i]);
178+
#endif
179+
#endif
180+
}
181+
#endif
182+
}
183+
184+
void loop()
185+
{
186+
}

0 commit comments

Comments
 (0)