Skip to content

Commit

Permalink
Make JLed::Update(uint32_t t) public (#130)
Browse files Browse the repository at this point in the history
* make JLed::Update(uint32_t t) public allowing minor optimizations and simpler tests
* optionally install build tools using devbox
* upgrade cpplint
* fix linter findings
* don't run CI jobs concurrently
  • Loading branch information
jandelgado authored Nov 10, 2024
1 parent 1c79299 commit 41e5276
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 52 deletions.
7 changes: 6 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ on:
- master

name: run tests

concurrency:
group: ${{ github.head_ref }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
Expand All @@ -21,7 +26,7 @@ jobs:

- name: linter
run: |
pip install cpplint
pip install cpplint==2.0.0
make lint
test:
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# JLed changelog (github.com/jandelgado/jled)

## [2024-09-21] 4.14

* new: make `Jled::Update(unit32_t t)` public, allowing optimizations and
simplified tests

## [2023-09-10] 4.13.1

* fix: `Update()` sometimes returning wrong state (https://github.com/jandelgado/jled/issues/122)
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ hardware abstraction, which might scale it to the resolution used by the actual
device (e.g. 10 bits for an ESP8266). Finally the brightness value is written
out to the configure GPIO.

```
```text
┌───────────┐ ┌────────────┐ ┌─────────┐ ┌────────┐ ┌─────────┐ ┌────────┐
│ Evaluate │ │ Scale to │ │ Low │YES │ Invert │ │Scale for│ │Write to│
│ effect(t) ├───►│ [min, max] ├───►│ active? ├───►│ signal ├───►│Hardware ├───►│ GPIO │
Expand Down Expand Up @@ -410,8 +410,10 @@ specified by `DelayAfter()` method.
##### Update
Call `Update()` periodically to update the state of the LED. `Update` returns
`true` if the effect is active, and `false` when it finished.
Call `Update()` or `Update(uint32_t t)` periodically to update the state of the
LED. `Update` returns `true` if the effect is active, and `false` when it
finished. `Update()` is a shortcut to call `Update(uint32_t t)` with the
current time.
##### IsRunning
Expand Down
18 changes: 18 additions & 0 deletions devbox.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"packages": [
"python@3.11",
"lcov@1.16",
"pipx",
"cpplint@2.0.0"
],
"shell": {
"init_hook": [
"echo 'Welcome to devbox!' > /dev/null"
],
"scripts": {
"test": [
"echo \"Error: no test specified\" && exit 1"
]
}
}
}
114 changes: 114 additions & 0 deletions devbox.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
{
"lockfile_version": "1",
"packages": {
"cpplint@2.0.0": {
"last_modified": "2024-11-03T14:18:04Z",
"resolved": "github:NixOS/nixpkgs/4ae2e647537bcdbb82265469442713d066675275#cpplint",
"source": "devbox-search",
"version": "2.0.0",
"systems": {
"aarch64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/70gc21bl3grda63djlks6x1f5g8h89xk-cpplint-2.0.0",
"default": true
},
{
"name": "dist",
"path": "/nix/store/3sq5396dcbg3r06g9zci1w4rxql1xf0k-cpplint-2.0.0-dist"
}
],
"store_path": "/nix/store/70gc21bl3grda63djlks6x1f5g8h89xk-cpplint-2.0.0"
},
"aarch64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/3fcbszvn75zwim2n3785bflrwww38l42-cpplint-2.0.0",
"default": true
},
{
"name": "dist",
"path": "/nix/store/fqrmkx6q4q290hildy4l6gi2pzwzwinw-cpplint-2.0.0-dist"
}
],
"store_path": "/nix/store/3fcbszvn75zwim2n3785bflrwww38l42-cpplint-2.0.0"
},
"x86_64-darwin": {
"outputs": [
{
"name": "out",
"path": "/nix/store/m675bxwgh3wmr0gix5g6xnhkidlql0ii-cpplint-2.0.0",
"default": true
},
{
"name": "dist",
"path": "/nix/store/2bpdwa3r1kfzf4jkd4i24njxy3pr3xnv-cpplint-2.0.0-dist"
}
],
"store_path": "/nix/store/m675bxwgh3wmr0gix5g6xnhkidlql0ii-cpplint-2.0.0"
},
"x86_64-linux": {
"outputs": [
{
"name": "out",
"path": "/nix/store/vrv52827v0b6h4k3nl7k9zg4ld182khg-cpplint-2.0.0",
"default": true
},
{
"name": "dist",
"path": "/nix/store/132q2dd3wkkgdpybwzhybm7hbad0g097-cpplint-2.0.0-dist"
}
],
"store_path": "/nix/store/vrv52827v0b6h4k3nl7k9zg4ld182khg-cpplint-2.0.0"
}
}
},
"lcov@1.16": {
"last_modified": "2024-03-22T11:26:23Z",
"resolved": "github:NixOS/nixpkgs/a3ed7406349a9335cb4c2a71369b697cecd9d351#lcov",
"source": "devbox-search",
"version": "1.16",
"systems": {
"aarch64-darwin": {
"store_path": "/nix/store/cwjgl90nkg79za5gx41yg4663w7iyj0y-lcov-1.16"
},
"aarch64-linux": {
"store_path": "/nix/store/81axjrgg3cjx09kdb25psiiyz60zacqw-lcov-1.16"
},
"x86_64-darwin": {
"store_path": "/nix/store/5jir4n0q72z9p2h9sxwb2rcam3j165wp-lcov-1.16"
},
"x86_64-linux": {
"store_path": "/nix/store/qfdwnjp77xlvg0jqfv1dl8b40xpv230k-lcov-1.16"
}
}
},
"pipx": {
"resolved": "github:NixOS/nixpkgs/75a52265bda7fd25e06e3a67dee3f0354e73243c#pipx",
"source": "nixpkg"
},
"python@3.11": {
"last_modified": "2024-03-22T11:26:23Z",
"plugin_version": "0.0.3",
"resolved": "github:NixOS/nixpkgs/a3ed7406349a9335cb4c2a71369b697cecd9d351#python3",
"source": "devbox-search",
"version": "3.11.8",
"systems": {
"aarch64-darwin": {
"store_path": "/nix/store/c05vbvkjxarxkws9zkwrcwrzlsx9nd68-python3-3.11.8"
},
"aarch64-linux": {
"store_path": "/nix/store/pxzzyri1wbq7kc7pain665g94afkl4ww-python3-3.11.8"
},
"x86_64-darwin": {
"store_path": "/nix/store/1zaap1xxxvw2ypsgh1mfxb3wzdd49873-python3-3.11.8"
},
"x86_64-linux": {
"store_path": "/nix/store/7wz6hm9i8wljz0hgwz1wqmn2zlbgavrq-python3-3.11.8"
}
}
}
}
}
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "JLed",
"version": "4.13.1",
"version": "4.14",
"description": "An embedded library to control LEDs",
"license": "MIT",
"frameworks": ["espidf", "arduino", "mbed"],
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=JLed
version=4.13.1
version=4.14
author=Jan Delgado <jdelgado[at]gmx.net>
maintainer=Jan Delgado <jdelgado[at]gmx.net>
sentence=An Arduino library to control LEDs
Expand Down
2 changes: 1 addition & 1 deletion src/esp32_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ class Esp32Hal {
}

uint32_t millis() const {
return (uint32_t)(esp_timer_get_time() / 1000ULL);
return static_cast<uint32_t>(esp_timer_get_time() / 1000ULL);
}

PinType chan() const { return chan_; }
Expand Down
4 changes: 2 additions & 2 deletions src/jled_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ namespace jled {
// fade-off and breath functions are all derived from fade-on, see
// below.
static constexpr uint8_t kFadeOnTable[] = {0, 3, 13, 33, 68,
118, 179, 232, 255};
118, 179, 232, 255}; // NOLINT

// https://www.wolframalpha.com/input/?i=plot+(exp(sin((x-100%2F2.)*PI%2F100))-0.36787944)*108.0++x%3D0+to+100
// The fade-on func is an approximation of
Expand Down Expand Up @@ -70,7 +70,7 @@ uint8_t rand8() {
// scale8(0, f) == 0 for all f
// scale8(x, 255) == x for all x
uint8_t scale8(uint8_t val, uint8_t factor) {
return ((uint16_t)val * (uint16_t)(1 + factor)) >> 8;
return (static_cast<uint16_t>(val)*static_cast<uint16_t>(1 + factor)) >> 8;
}

// interpolate a byte (val) to the interval [a,b].
Expand Down
37 changes: 19 additions & 18 deletions src/jled_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,6 @@ class TJLed {

HalType& Hal() { return hal_; }

bool Update() { return Update(hal_.millis()); }

// Set physical LED polarity to be low active. This inverts every
// signal physically output to a pin.
B& LowActive() {
Expand Down Expand Up @@ -378,14 +376,6 @@ class TJLed {
// Returns current maximum brightness level.
uint8_t MaxBrightness() const { return maxBrightness_; }

protected:
// test if time stored in last_update_time_ differs from provided timestamp.
bool inline timeChangedSinceLastUpdate(uint32_t now) {
return (now & 255) != last_update_time_;
}

void trackLastUpdateTime(uint32_t t) { last_update_time_ = (t & 255); }

// update brightness of LED using the given brightness evaluator
// (brightness) ________________
// on 255 | ¸-'
Expand All @@ -395,6 +385,8 @@ class TJLed {
// |<-delay before->|<--period-->|<-delay after-> (time)
// | func(t) |
// |<- num_repetitions times ->
bool Update() { return Update(hal_.millis()); }

bool Update(uint32_t now) {
if (state_ == ST_STOPPED || !brightness_eval_) return false;

Expand All @@ -408,18 +400,18 @@ class TJLed {

trackLastUpdateTime(now);

if ((int32_t)(now - time_start_) < 0) return true;
if (static_cast<int32_t>(now - time_start_) < 0) return true;

// t cycles in range [0..period+delay_after-1]
const auto period = brightness_eval_->Period();
const auto t = (now - time_start_) % (period + delay_after_);

if (!IsForever()) {
const auto time_end =
time_start_ +
(uint32_t)(period + delay_after_) * num_repetitions_ - 1;
const auto time_end = time_start_ +
static_cast<uint32_t>(period + delay_after_) *
num_repetitions_ - 1;

if ((int32_t)(now - time_end) >= 0) {
if (static_cast<int32_t>(now - time_end) >= 0) {
// make sure final value of t = (period-1) is set
state_ = ST_STOPPED;
const auto val = Eval(period - 1);
Expand All @@ -442,6 +434,14 @@ class TJLed {
return true;
}

protected:
// test if time stored in last_update_time_ differs from provided timestamp.
bool inline timeChangedSinceLastUpdate(uint32_t now) {
return (now & 255) != last_update_time_;
}

void trackLastUpdateTime(uint32_t t) { last_update_time_ = (t & 255); }

B& SetBrightnessEval(BrightnessEvaluator* be) {
brightness_eval_ = be;
// start over after the brightness evaluator changed
Expand Down Expand Up @@ -504,8 +504,9 @@ class TJLedSequence {
// active, else false
bool UpdateParallel() {
auto result = false;
uint32_t t = ptr(leds_[0])->Hal().millis();
for (auto i = 0u; i < n_; i++) {
result |= ptr(leds_[i])->Update();
result |= ptr(leds_[i])->Update(t);
}
return result;
}
Expand Down Expand Up @@ -536,7 +537,7 @@ class TJLedSequence {
: mode_{mode}, leds_{leds}, cur_{0}, n_{n} {}

bool Update() {
if (!is_running_) {
if (!is_running_ || n_ < 1) {
return false;
}

Expand Down Expand Up @@ -592,5 +593,5 @@ class TJLedSequence {
bool is_running_ = true;
};

}; // namespace jled
}; // namespace jled
#endif // SRC_JLED_BASE_H_
5 changes: 3 additions & 2 deletions src/pico_hal.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ class PicoHal {
uint32_t *top_) {
// Set the frequency, making "top_" as large as possible for maximum
// resolution.
*div = (uint32_t)(16 * clock_get_hz(clk_sys) / (uint32_t)freq);
*div = static_cast<uint32_t>(16 * clock_get_hz(clk_sys) /
static_cast<uint32_t>(freq));
*top_ = 1;
for (;;) {
// Try a few small prime factors to get close to the desired
Expand Down Expand Up @@ -100,7 +101,7 @@ class PicoHal {

void analogWrite(uint8_t val) const {
set_pwm_duty(slice_num_, channel_, top_,
(uint32_t)(DUTY_100_PCT / 255) * val);
static_cast<uint32_t>(DUTY_100_PCT / 255) * val);
}

uint32_t millis() const { return to_ms_since_boot(get_absolute_time()); }
Expand Down
Loading

0 comments on commit 41e5276

Please sign in to comment.