Skip to content

Commit f6892c7

Browse files
authored
Merge pull request #701 from ckormanyos/examples_tuning
2 parents 29a9a3b + 3672cec commit f6892c7

File tree

6 files changed

+73
-120
lines changed

6 files changed

+73
-120
lines changed

examples/chapter09_08a/src/app/led/app_led.cpp

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -21,28 +21,25 @@ namespace app
2121
}
2222
}
2323

24-
namespace
25-
{
26-
using app_led_monochrome_timer_type = util::timer<std::uint32_t>;
27-
using app_led_rgb_timer_type = util::timer<std::uint16_t>;
28-
29-
auto app_led_monochrome_timer = static_cast<app_led_monochrome_timer_type>(app_led_monochrome_timer_type::seconds(UINT8_C(1)));
30-
auto app_led_rgb_timer = static_cast<app_led_rgb_timer_type>(app_led_rgb_timer_type::milliseconds(UINT8_C(30)));
31-
32-
std::uint_fast8_t app_led_hue_r { UINT8_C(255) };
33-
std::uint_fast8_t app_led_hue_g { UINT8_C(0) };
34-
std::uint_fast8_t app_led_hue_b { UINT8_C(0) };
35-
}
36-
3724
auto app::led::task_init() -> void
3825
{
3926
mcal::led::led0().toggle();
4027

41-
mcal::led::led_rgb0().set_color(app_led_hue_r, app_led_hue_g, app_led_hue_b);
28+
mcal::led::led_rgb0().set_color(UINT8_C(255), UINT8_C(0), UINT8_C(0));
4229
}
4330

4431
auto app::led::task_func() -> void
4532
{
33+
using app_led_monochrome_timer_type = util::timer<std::uint32_t>;
34+
using app_led_rgb_timer_type = util::timer<std::uint16_t>;
35+
36+
static auto app_led_monochrome_timer = static_cast<app_led_monochrome_timer_type>(app_led_monochrome_timer_type::seconds(UINT8_C(1)));
37+
static auto app_led_rgb_timer = static_cast<app_led_rgb_timer_type>(app_led_rgb_timer_type::milliseconds(UINT8_C(30)));
38+
39+
static std::uint_fast8_t app_led_hue_r { UINT8_C(255) };
40+
static std::uint_fast8_t app_led_hue_g { UINT8_C(0) };
41+
static std::uint_fast8_t app_led_hue_b { UINT8_C(0) };
42+
4643
if(app_led_monochrome_timer.timeout())
4744
{
4845
// Toggle the monochrome user LED at 1/2 Hz.
@@ -52,27 +49,28 @@ auto app::led::task_func() -> void
5249
app_led_monochrome_timer.start_interval(app_led_monochrome_timer_type::seconds(1U));
5350
}
5451

52+
// Define the color transition states.
53+
enum class color_transition_type
54+
{
55+
red_to_yellow,
56+
yellow_to_green,
57+
green_to_cyan,
58+
cyan_to_blue,
59+
blue_to_magenta,
60+
magenta_to_red
61+
};
62+
63+
64+
// Initialize the color transition state.
65+
static auto color_transition_state = color_transition_type::red_to_yellow;
66+
5567
if(app_led_rgb_timer.timeout())
5668
{
5769
// Animate the RGB LED with the colors of the spectrum.
5870

5971
// Implement the enhanced RGB-color-light-show mentioned
6072
// in the readme markdown of this example.
6173

62-
// Define the color transition states.
63-
enum class color_transition_type
64-
{
65-
red_to_yellow,
66-
yellow_to_green,
67-
green_to_cyan,
68-
cyan_to_blue,
69-
blue_to_magenta,
70-
magenta_to_red
71-
};
72-
73-
// Initialize the color transition state.
74-
static auto color_transition_state = color_transition_type::red_to_yellow;
75-
7674
const auto rgb_hue_sum =
7775
static_cast<std::uint_fast16_t>
7876
(

examples/chapter09_08a/src/mcal/avr/mcal_led_rgb_ws2812.h

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,26 @@
4545
}
4646
};
4747

48-
// Timing of WS2812.
48+
// Timing of WS2812B.
4949

5050
// Next bit is 0:
51-
// T0H = 0.35us
52-
// T0L = 0.80us
51+
// T0H = 220-380ns
52+
// T0L = 580ns - 1us
5353

5454
// Next bit is 1:
55-
// T1H = 0.70us
56-
// T1L = 0.60us
55+
// T1H = 580ns - 1us
56+
// T1L = 220-420ns
5757

58+
#define MCAL_LED_RGB_WS2812_NOPS_01 { asm volatile("nop"); }
5859
#define MCAL_LED_RGB_WS2812_NOPS_02 { asm volatile("nop"); asm volatile("nop"); }
59-
#define MCAL_LED_RGB_WS2812_NOPS_06 { MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_02 }
60-
#define MCAL_LED_RGB_WS2812_NOPS_11 { MCAL_LED_RGB_WS2812_NOPS_06 MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_02 asm volatile("nop"); }
60+
#define MCAL_LED_RGB_WS2812_NOPS_03 { MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_01 }
61+
#define MCAL_LED_RGB_WS2812_NOPS_06 { MCAL_LED_RGB_WS2812_NOPS_03 MCAL_LED_RGB_WS2812_NOPS_03 }
62+
#define MCAL_LED_RGB_WS2812_NOPS_08 { MCAL_LED_RGB_WS2812_NOPS_06 MCAL_LED_RGB_WS2812_NOPS_02 }
63+
#define MCAL_LED_RGB_WS2812_NOPS_11 { MCAL_LED_RGB_WS2812_NOPS_08 MCAL_LED_RGB_WS2812_NOPS_03 }
6164

6265
#define MCAL_LED_RGB_WS2812_PUSH_DATA(next_bit_is_zero) port_pin_type::set_pin_high(); \
63-
if (next_bit_is_zero) { MCAL_LED_RGB_WS2812_NOPS_02 port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_11 } \
64-
else { MCAL_LED_RGB_WS2812_NOPS_06 port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_06 }
66+
if (next_bit_is_zero) { MCAL_LED_RGB_WS2812_NOPS_01 port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_11 } \
67+
else { MCAL_LED_RGB_WS2812_NOPS_08 port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_02 }
6568

6669
template<typename PortPinType,
6770
const unsigned LedCount> auto led_rgb_ws2812<PortPinType, LedCount>::push_color() -> void
@@ -104,21 +107,14 @@
104107
mcal::irq::enable_all();
105108
}
106109

107-
#if defined(MCAL_LED_RGB_WS2812_PUSH_DATA)
108110
#undef MCAL_LED_RGB_WS2812_PUSH_DATA
109-
#endif
110111

111-
#if defined(MCAL_LED_RGB_WS2812_NOPS_02)
112+
#undef MCAL_LED_RGB_WS2812_NOPS_01
112113
#undef MCAL_LED_RGB_WS2812_NOPS_02
113-
#endif
114-
115-
#if defined(MCAL_LED_RGB_WS2812_NOPS_06)
114+
#undef MCAL_LED_RGB_WS2812_NOPS_03
116115
#undef MCAL_LED_RGB_WS2812_NOPS_06
117-
#endif
118-
119-
#if defined(MCAL_LED_RGB_WS2812_NOPS_11)
116+
#undef MCAL_LED_RGB_WS2812_NOPS_08
120117
#undef MCAL_LED_RGB_WS2812_NOPS_11
121-
#endif
122118

123119
} } // namespace mcal::led
124120

examples/chapter09_08a/src/mcal/mcal_gcc_cxx_completion.cpp

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -16,33 +16,6 @@
1616
#pragma GCC diagnostic ignored "-Wmissing-declarations"
1717
#endif
1818

19-
// Implement std::chrono::high_resolution_clock::now()
20-
// for the standard library's high-resolution clock.
21-
namespace std
22-
{
23-
namespace chrono
24-
{
25-
high_resolution_clock::time_point high_resolution_clock::now() noexcept
26-
{
27-
// The source of the high-resolution clock is microseconds.
28-
using microsecond_time_point_type =
29-
std::chrono::time_point<high_resolution_clock,
30-
std::chrono::microseconds>;
31-
32-
// Get the consistent system tick (having microsecond resolution).
33-
const mcal::gpt::value_type microsecond_tick =
34-
mcal::gpt::secure::get_time_elapsed();
35-
36-
// Obtain a time-point with microsecond resolution.
37-
const auto time_point_in_microseconds =
38-
microsecond_time_point_type(std::chrono::microseconds(microsecond_tick));
39-
40-
// And return the corresponding duration with microsecond resolution.
41-
return time_point_cast<duration>(time_point_in_microseconds);
42-
}
43-
}
44-
}
45-
4619
void* operator new(std::size_t size)
4720
{
4821
// This is a naive and not completely functional

examples/chapter09_08b/readme.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ the commercially-available, open-platform
1313
[STM32F100 Value Line Discovery Kit](https://www.st.com/en/evaluation-tools/stm32vldiscovery.html)
1414
with soldered-on pins fitted on a breadboard.
1515

16-
The wiring is straightforward. The blinking LED uses the blue colored
17-
user LED controlled by pin `portc.8`. The LED digital control signal
18-
is on `portb.9`. The microcontroller is clocked at $24~\text{MHz}$.
16+
The wiring is straightforward. The blinking LED at $\frac{1}{2}~\text{Hz}$
17+
uses the blue colored user-LED controlled by pin `portc.8`.
18+
The RGB LED digital control signal is on `portb.9`.
19+
A logic-AND gate shifts the microcontroller pin's level
20+
from $3.3~\text{V}$ to $5~\text{V}$.
21+
The microcontroller is clocked at $24~\text{MHz}$.

examples/chapter09_08b/src/mcal/mcal_reg_access_static.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
///////////////////////////////////////////////////////////////////////////////
2-
// Copyright Christopher Kormanyos 2007 - 2024.
2+
// Copyright Christopher Kormanyos 2007 - 2025.
33
// Distributed under the Boost Software License,
44
// Version 1.0. (See accompanying file LICENSE_1_0.txt
55
// or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -26,28 +26,28 @@
2626
using register_value_type = RegisterValueType;
2727
using register_address_type = RegisterAddressType;
2828

29-
static auto reg_get() -> register_value_type { volatile register_value_type* pa = reinterpret_cast<register_value_type*>(address); return *pa; }
30-
static auto reg_set() -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = value; }
31-
static auto reg_and() -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = static_cast<register_value_type>(*pa & value); }
32-
static auto reg_or () -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = static_cast<register_value_type>(*pa | value); }
33-
static auto reg_not() -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = static_cast<register_value_type>(*pa & static_cast<register_value_type>(~value)); }
29+
static auto reg_get() -> register_value_type { volatile register_value_type* p_addr = reinterpret_cast<register_value_type*>(address); return *p_addr; }
30+
static auto reg_set() -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = value; }
31+
static auto reg_and() -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = static_cast<register_value_type>(*p_addr & value); }
32+
static auto reg_or () -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = static_cast<register_value_type>(*p_addr | value); }
33+
static auto reg_not() -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = static_cast<register_value_type>(*p_addr & static_cast<register_value_type>(~value)); }
3434

3535
template<const register_value_type mask_value>
3636
static auto reg_msk() -> void
3737
{
38-
volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address);
38+
volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address);
3939

40-
*pa =
40+
*p_addr =
4141
static_cast<register_value_type>
4242
(
4343
static_cast<register_value_type>(reg_get() & static_cast<register_value_type>(~mask_value))
4444
| value
4545
);
4646
}
4747

48-
static auto bit_set() -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = static_cast<register_value_type>(*pa | static_cast<register_value_type>(1ULL << value)); }
49-
static auto bit_clr() -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = static_cast<register_value_type>(*pa & static_cast<register_value_type>(~static_cast<register_value_type>(1ULL << value))); }
50-
static auto bit_not() -> void { volatile register_value_type* pa = reinterpret_cast<volatile register_value_type*>(address); *pa = static_cast<register_value_type>(*pa ^ static_cast<register_value_type>(1ULL << value)); }
48+
static auto bit_set() -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = static_cast<register_value_type>(*p_addr | static_cast<register_value_type>(1ULL << value)); }
49+
static auto bit_clr() -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = static_cast<register_value_type>(*p_addr & static_cast<register_value_type>(~static_cast<register_value_type>(1ULL << value))); }
50+
static auto bit_not() -> void { volatile register_value_type* p_addr = reinterpret_cast<volatile register_value_type*>(address); *p_addr = static_cast<register_value_type>(*p_addr ^ static_cast<register_value_type>(1ULL << value)); }
5151
static auto bit_get() -> bool { return (static_cast<register_value_type>(reg_get() & static_cast<register_value_type>(1ULL << value)) != static_cast<register_value_type>(0U)); }
5252
};
5353
}

examples/chapter09_08b/src/mcal/stm32f100/mcal_led_rgb_ws2812.h

Lines changed: 15 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -45,25 +45,26 @@
4545
}
4646
};
4747

48-
// Timing of WS2812.
48+
// Timing of WS2812B.
4949

5050
// Next bit is 0:
51-
// T0H = 0.35us
52-
// T0L = 0.80us
51+
// T0H = 220-380ns
52+
// T0L = 580ns - 1us
5353

5454
// Next bit is 1:
55-
// T1H = 0.70us
56-
// T1L = 0.60us
55+
// T1H = 580ns - 1us
56+
// T1L = 220-420ns
5757

5858
#define MCAL_LED_RGB_WS2812_NOPS_01 { asm volatile("nop"); }
5959
#define MCAL_LED_RGB_WS2812_NOPS_02 { MCAL_LED_RGB_WS2812_NOPS_01 MCAL_LED_RGB_WS2812_NOPS_01 }
60-
#define MCAL_LED_RGB_WS2812_NOPS_05 { MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_01 }
61-
#define MCAL_LED_RGB_WS2812_NOPS_06 { MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_02 }
62-
#define MCAL_LED_RGB_WS2812_NOPS_10 { MCAL_LED_RGB_WS2812_NOPS_05 MCAL_LED_RGB_WS2812_NOPS_05 }
60+
#define MCAL_LED_RGB_WS2812_NOPS_03 { MCAL_LED_RGB_WS2812_NOPS_02 MCAL_LED_RGB_WS2812_NOPS_01 }
61+
#define MCAL_LED_RGB_WS2812_NOPS_09 { MCAL_LED_RGB_WS2812_NOPS_03 MCAL_LED_RGB_WS2812_NOPS_03 MCAL_LED_RGB_WS2812_NOPS_03 }
62+
#define MCAL_LED_RGB_WS2812_NOPS_12 { MCAL_LED_RGB_WS2812_NOPS_09 MCAL_LED_RGB_WS2812_NOPS_03 }
6363

64-
#define MCAL_LED_RGB_WS2812_PUSH_DATA(next_bit_is_zero) port_pin_type::set_pin_high(); \
65-
if (next_bit_is_zero) { port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_10 MCAL_LED_RGB_WS2812_NOPS_02 } \
66-
else { MCAL_LED_RGB_WS2812_NOPS_06 MCAL_LED_RGB_WS2812_NOPS_02 port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_05 }
64+
#define MCAL_LED_RGB_WS2812_PUSH_DATA(next_bit_is_zero) \
65+
port_pin_type::set_pin_high(); \
66+
if (next_bit_is_zero) { port_pin_type::set_pin_low(); MCAL_LED_RGB_WS2812_NOPS_12 } \
67+
else { MCAL_LED_RGB_WS2812_NOPS_09 port_pin_type::set_pin_low(); }
6768

6869
template<typename PortPinType,
6970
const unsigned LedCount> auto led_rgb_ws2812<PortPinType, LedCount>::push_color() -> void
@@ -106,29 +107,11 @@
106107
mcal::irq::enable_all();
107108
}
108109

109-
#if defined(MCAL_LED_RGB_WS2812_PUSH_DATA)
110-
#undef MCAL_LED_RGB_WS2812_PUSH_DATA
111-
#endif
112-
113-
#if defined(MCAL_LED_RGB_WS2812_NOPS_01)
114110
#undef MCAL_LED_RGB_WS2812_NOPS_01
115-
#endif
116-
117-
#if defined(MCAL_LED_RGB_WS2812_NOPS_02)
118111
#undef MCAL_LED_RGB_WS2812_NOPS_02
119-
#endif
120-
121-
#if defined(MCAL_LED_RGB_WS2812_NOPS_05)
122-
#undef MCAL_LED_RGB_WS2812_NOPS_05
123-
#endif
124-
125-
#if defined(MCAL_LED_RGB_WS2812_NOPS_06)
126-
#undef MCAL_LED_RGB_WS2812_NOPS_06
127-
#endif
128-
129-
#if defined(MCAL_LED_RGB_WS2812_NOPS_10)
130-
#undef MCAL_LED_RGB_WS2812_NOPS_10
131-
#endif
112+
#undef MCAL_LED_RGB_WS2812_NOPS_03
113+
#undef MCAL_LED_RGB_WS2812_NOPS_09
114+
#undef MCAL_LED_RGB_WS2812_NOPS_12
132115

133116
} } // namespace mcal::led
134117

0 commit comments

Comments
 (0)