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

Commit dd31a81

Browse files
authored
v1.3.0 to fix accuracy bug
### Releases v1.3.0 1. Fix `poor-timer-accuracy` bug. Check [Poor accuracy on timer interrupt frequency or interval. #4](khoih-prog/MBED_RPI_PICO_TimerInterrupt#4)
1 parent 90a2b36 commit dd31a81

13 files changed

+221
-113
lines changed

CONTRIBUTING.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ If you don't find anything, please [open a new issue](https://github.com/khoih-p
1515
Please ensure to specify the following:
1616

1717
* Arduino IDE version (e.g. 1.8.19) or Platform.io version
18-
* `RP2040` Core Version (e.g. Arduino-mbed RP2040 v2.7.2)
19-
* `RP2040` Board type (e.g. NANO_RP2040_CONNECT, RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040, GENERIC_RP2040, etc.)
18+
* `Arduino mbed_rp2040` Core Version (e.g. Arduino mbed_rp2040 core v3.3.0)
19+
* `RP2040` Board type (e.g. Nano_RP2040_Connect, RASPBERRY_PI_PICO, ADAFRUIT_FEATHER_RP2040, GENERIC_RP2040, etc.)
2020
* Contextual information (e.g. what you were trying to achieve)
2121
* Simplest possible steps to reproduce
2222
* Anything that might be relevant in your opinion, such as:
@@ -28,13 +28,13 @@ Please ensure to specify the following:
2828

2929
```
3030
Arduino IDE version: 1.8.19
31-
Arduino-mbed mbed_nano v2.7.2
32-
NANO_RP2040_CONNECT Module
31+
Arduino mbed_rp2040 core v3.3.0
32+
RASPBERRY_PI_PICO board
3333
OS: Ubuntu 20.04 LTS
34-
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
34+
Linux xy-Inspiron-3593 5.15.0-48-generic #54~20.04.1-Ubuntu SMP Thu Sep 1 16:17:26 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
3535
3636
Context:
37-
I encountered a crash while using TimerInterrupt.
37+
I encountered a crash while using this library
3838
3939
Steps to reproduce:
4040
1. ...

README.md

Lines changed: 102 additions & 80 deletions
Large diffs are not rendered by default.

changelog.md

Lines changed: 5 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.3.0](#releases-v130)
1516
* [Releases v1.2.1](#releases-v121)
1617
* [Releases v1.2.0](#releases-v120)
1718
* [Releases v1.1.0](#releases-v110)
@@ -23,6 +24,10 @@
2324

2425
## Changelog
2526

27+
### Releases v1.3.0
28+
29+
1. Fix `poor-timer-accuracy` bug. Check [Poor accuracy on timer interrupt frequency or interval. #4](https://github.com/khoih-prog/MBED_RPI_PICO_TimerInterrupt/issues/4)
30+
2631
### Releases v1.2.1
2732

2833
1. Fix `New Period` display bug. Check [random dropouts #4](https://github.com/khoih-prog/SAMD_Slow_PWM/issues/4)

library.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "MBED_RP2040_Slow_PWM",
3-
"version": "1.2.1",
3+
"version": "1.3.0",
44
"keywords": "timing, device, control, hardware-timer, pwm, ISR-based-pwm, multi-channel-pwm, low-frequency-pwm, mission-critical, accuracy, non-blocking, mbed, mbed-nano, mbed-rp2040, rpi-pico, rp2040, nano-rp2040-connect, precise, arduino-mbed",
55
"description": "This library enables you to use ISR-based PWM channels on RP2040-based boards, such as Nano_RP2040_Connect, RASPBERRY_PI_PICO, with Arduino-mbed (mbed_nano or mbed_rp2040) core to create and output PWM any GPIO pin. 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",
66
"authors":

library.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
name=MBED_RP2040_Slow_PWM
2-
version=1.2.1
2+
version=1.3.0
33
author=Khoi Hoang <[email protected]>
44
maintainer=Khoi Hoang <[email protected]>
55
sentence=This library enables you to use ISR-based PWM channels on RP2040-based boards, such as Nano_RP2040_Connect, RASPBERRY_PI_PICO, with Arduino-mbed (mbed_nano or mbed_rp2040) core to create and output PWM any GPIO pin.
66
paragraph=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
77
category=Device Control
88
url=https://github.com/khoih-prog/MBED_RP2040_Slow_PWM
9-
architectures=mbed,mbed_nano,ArduinoCore-mbed,mbed_rp2040
9+
architectures=mbed,mbed_nano,mbed_rp2040
1010
repository=https://github.com/khoih-prog/MBED_RP2040_Slow_PWM
1111
license=MIT
1212
includes=MBED_RP2040_Slow_PWM.h,MBED_RP2040_Slow_PWM.hpp

platformio/platformio.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,10 @@ upload_speed = 921600
3838
;monitor_port = COM11
3939

4040
; Checks for the compatibility with frameworks and dev/platforms
41+
; To adjust as necessary
4142
lib_compat_mode = strict
43+
lib_ldf_mode = chain+
44+
;lib_ldf_mode = deep+
4245

4346
lib_deps =
4447

src/MBED_RP2040_Slow_PWM.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Therefore, their executions are not blocked by bad-behaving functions / tasks.
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
15-
Version: 1.2.1
15+
Version: 1.3.0
1616
1717
Version Modified By Date Comments
1818
------- ----------- ---------- -----------
@@ -21,6 +21,7 @@
2121
1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly
2222
1.2.0 K Hoang 02/02/2022 Fix multiple-definitions linker error. Improve accuracy. Optimize code
2323
1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3
24+
1.3.0 K.Hoang 12/10/2022 Fix poor timer accuracy bug
2425
*****************************************************************************************************************************/
2526

2627
#pragma once

src/MBED_RP2040_Slow_PWM.hpp

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Therefore, their executions are not blocked by bad-behaving functions / tasks.
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
15-
Version: 1.2.1
15+
Version: 1.3.0
1616
1717
Version Modified By Date Comments
1818
------- ----------- ---------- -----------
@@ -21,13 +21,16 @@
2121
1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly
2222
1.2.0 K Hoang 02/02/2022 Fix multiple-definitions linker error. Improve accuracy. Optimize code
2323
1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3
24+
1.3.0 K.Hoang 12/10/2022 Fix poor timer accuracy bug
2425
*****************************************************************************************************************************/
2526

2627
#pragma once
2728

2829
#ifndef MBED_RP2040_SLOW_PWM_HPP
2930
#define MBED_RP2040_SLOW_PWM_HPP
3031

32+
////////////////////////////////////////////
33+
3134
#if ( defined(ARDUINO_NANO_RP2040_CONNECT) || defined(ARDUINO_RASPBERRY_PI_PICO) || defined(ARDUINO_ADAFRUIT_FEATHER_RP2040) || \
3235
defined(ARDUINO_GENERIC_RP2040) ) && defined(ARDUINO_ARCH_MBED)
3336

@@ -39,16 +42,20 @@
3942
#error This code is intended to run on the MBED RASPBERRY_PI_PICO platform! Please check your Tools->Board setting.
4043
#endif
4144

45+
////////////////////////////////////////////
46+
4247
#ifndef MBED_RP2040_SLOW_PWM_VERSION
43-
#define MBED_RP2040_SLOW_PWM_VERSION "MBED_RP2040_Slow_PWM v1.2.1"
48+
#define MBED_RP2040_SLOW_PWM_VERSION "MBED_RP2040_Slow_PWM v1.3.0"
4449

4550
#define MBED_RP2040_SLOW_PWM_VERSION_MAJOR 1
46-
#define MBED_RP2040_SLOW_PWM_VERSION_MINOR 2
47-
#define MBED_RP2040_SLOW_PWM_VERSION_PATCH 1
51+
#define MBED_RP2040_SLOW_PWM_VERSION_MINOR 3
52+
#define MBED_RP2040_SLOW_PWM_VERSION_PATCH 0
4853

49-
#define MBED_RP2040_SLOW_PWM_VERSION_INT 1002001
54+
#define MBED_RP2040_SLOW_PWM_VERSION_INT 1003000
5055
#endif
5156

57+
////////////////////////////////////////////
58+
5259
#if defined(ARDUINO)
5360
#if ARDUINO >= 100
5461
#include <Arduino.h>
@@ -57,10 +64,14 @@
5764
#endif
5865
#endif
5966

67+
////////////////////////////////////////////
68+
6069
#ifndef _PWM_LOGLEVEL_
6170
#define _PWM_LOGLEVEL_ 1
6271
#endif
6372

73+
////////////////////////////////////////////
74+
6475
#include "PWM_Generic_Debug.h"
6576

6677
/*
@@ -93,6 +104,8 @@ void TIMER_ISR_END(uint alarm_num);
93104
class MBED_RP2040_TimerInterrupt;
94105

95106
typedef MBED_RP2040_TimerInterrupt MBED_RP2040_Timer;
107+
108+
////////////////////////////////////////////
96109

97110
class MBED_RP2040_TimerInterrupt
98111
{
@@ -104,14 +117,20 @@ class MBED_RP2040_TimerInterrupt
104117

105118
public:
106119

120+
////////////////////////////////////////////
121+
107122
MBED_RP2040_TimerInterrupt(uint8_t timerNo)
108123
{
109124
_timerNo = timerNo;
110125
_callback = NULL;
111126
};
127+
128+
////////////////////////////////////////////
112129

113130
#define TIM_CLOCK_FREQ ( (float) 1000000.0f )
114131

132+
////////////////////////////////////////////
133+
115134
// frequency (in hertz) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
116135
// No params and duration now. To be added in the future by adding similar functions here
117136
bool setFrequency(const float& frequency, hardware_alarm_callback_t callback)
@@ -127,10 +146,13 @@ class MBED_RP2040_TimerInterrupt
127146

128147
// Hardware timer is preset in RP2040 at 1MHz / 1uS
129148
_frequency = frequency;
130-
_timerCount[_timerNo] = (uint64_t) TIM_CLOCK_FREQ / frequency;
149+
150+
//_timerCount[_timerNo] = (uint64_t) TIM_CLOCK_FREQ / frequency;
151+
// Ref: https://github.com/khoih-prog/MBED_RPI_PICO_TimerInterrupt/issues/4
152+
_timerCount[_timerNo] = (uint64_t) ( ( float) TIM_CLOCK_FREQ / frequency ) - 1;
131153

132154
PWM_LOGWARN5(F("_timerNo = "), _timerNo, F(", Clock (Hz) = "), TIM_CLOCK_FREQ, F(", _fre (Hz) = "), _frequency);
133-
PWM_LOGWARN3(F("_count = "), (uint32_t) (_timerCount[_timerNo] >> 32) , F("-"), (uint32_t) (_timerCount[_timerNo]));
155+
PWM_LOGWARN3(F("_count = "), (uint32_t) (_timerCount[_timerNo] >> 32) , F("-"), (uint32_t) (_timerCount[_timerNo]) + 1);
134156

135157
_callback = callback;
136158

@@ -143,7 +165,7 @@ class MBED_RP2040_TimerInterrupt
143165
//bool hardware_alarm_set_target(uint alarm_num, absolute_time_t t);
144166
hardware_alarm_set_target(_timerNo, absAlarmTime[_timerNo]);
145167

146-
PWM_LOGWARN1(F("hardware_alarm_set_target, uS = "), _timerCount[_timerNo]);
168+
PWM_LOGWARN1(F("hardware_alarm_set_target, uS = "), _timerCount[_timerNo] + 1);
147169

148170
return true;
149171
}
@@ -157,66 +179,89 @@ class MBED_RP2040_TimerInterrupt
157179
TIMER_ISR_END(_timerNo);
158180
}
159181

182+
////////////////////////////////////////////
183+
160184
// interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
161185
// No params and duration now. To be added in the future by adding similar functions here
162186
bool setInterval(const unsigned long& interval, hardware_alarm_callback_t callback)
163187
{
164188
return setFrequency((float) (1000000.0f / interval), callback);
165189
}
166190

191+
////////////////////////////////////////////
192+
167193
bool attachInterrupt(const float& frequency, hardware_alarm_callback_t callback)
168194
{
169195
return setFrequency(frequency, callback);
170196
}
171197

198+
////////////////////////////////////////////
199+
172200
// interval (in microseconds) and duration (in milliseconds). Duration = 0 or not specified => run indefinitely
173201
// No params and duration now. To be added in the future by adding similar functions here
174202
bool attachInterruptInterval(const unsigned long& interval, hardware_alarm_callback_t callback)
175203
{
176204
return setFrequency( (float) ( 1000000.0f / interval), callback);
177205
}
178206

207+
////////////////////////////////////////////
208+
179209
void detachInterrupt()
180210
{
181211
hardware_alarm_set_callback(_timerNo, NULL);
182212
}
183213

214+
////////////////////////////////////////////
215+
184216
void disableTimer()
185217
{
186218
hardware_alarm_set_callback(_timerNo, NULL);
187219
}
188220

221+
////////////////////////////////////////////
222+
189223
// Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
190224
void reattachInterrupt()
191225
{
192226
TIMER_ISR_START(_timerNo);
193227
hardware_alarm_set_callback(_timerNo, _callback);
194228
}
195229

230+
////////////////////////////////////////////
231+
196232
// Duration (in milliseconds). Duration = 0 or not specified => run indefinitely
197233
void enableTimer()
198234
{
199235
TIMER_ISR_START(_timerNo);
200236
hardware_alarm_set_callback(_timerNo, _callback);
201237
}
202238

239+
////////////////////////////////////////////
240+
203241
// Just stop clock source, clear the count
204242
void stopTimer()
205243
{
206244
hardware_alarm_set_callback(_timerNo, NULL);
207245
}
208246

247+
////////////////////////////////////////////
248+
209249
// Just reconnect clock source, start current count from 0
210250
void restartTimer()
211251
{
212252
TIMER_ISR_START(_timerNo);
213253
hardware_alarm_set_callback(_timerNo, _callback);
214254
}
215255

256+
////////////////////////////////////////////
257+
216258
int8_t getTimer() __attribute__((always_inline))
217259
{
218260
return _timerNo;
219261
}
262+
263+
////////////////////////////////////////////
264+
220265
}; // class MBED_RP2040_TimerInterrupt
221266

222267

src/MBED_RP2040_Slow_PWM_ISR.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
Therefore, their executions are not blocked by bad-behaving functions / tasks.
1313
This important feature is absolutely necessary for mission-critical tasks.
1414
15-
Version: 1.2.1
15+
Version: 1.3.0
1616
1717
Version Modified By Date Comments
1818
------- ----------- ---------- -----------
@@ -21,6 +21,7 @@
2121
1.1.0 K Hoang 10/11/2021 Add functions to modify PWM settings on-the-fly
2222
1.2.0 K Hoang 02/02/2022 Fix multiple-definitions linker error. Improve accuracy. Optimize code
2323
1.2.1 K Hoang 03/03/2022 Fix `DutyCycle` and `New Period` display bugs. Display warning only when debug level > 3
24+
1.3.0 K.Hoang 12/10/2022 Fix poor timer accuracy bug
2425
*****************************************************************************************************************************/
2526

2627
#pragma once

0 commit comments

Comments
 (0)