TLE92466ED Driver 0.1.0-preview
Modern C++23 driver for Infineon TLE92466ED Six-Channel Low-Side Solenoid Driver
Loading...
Searching...
No Matches
TLE92466ED_TestFramework.hpp
Go to the documentation of this file.
1
19#pragma once
20
21#include "esp_log.h"
22#include "esp_timer.h"
23#include "freertos/FreeRTOS.h"
24#include "freertos/task.h"
25#include "freertos/semphr.h"
26#include "driver/gpio.h"
27
28//=============================================================================
29// GPIO14 TEST PROGRESSION INDICATOR
30//=============================================================================
31
32static constexpr gpio_num_t TEST_PROGRESS_PIN = GPIO_NUM_14;
33static bool g_gpio14_initialized = false;
34static bool g_gpio14_state = false;
35
39inline bool init_test_progress_indicator() noexcept {
41 return true;
42 }
43
44 gpio_config_t io_conf = {};
45 io_conf.pin_bit_mask = (1ULL << TEST_PROGRESS_PIN);
46 io_conf.mode = GPIO_MODE_OUTPUT;
47 io_conf.pull_up_en = GPIO_PULLUP_DISABLE;
48 io_conf.pull_down_en = GPIO_PULLDOWN_ENABLE;
49 io_conf.intr_type = GPIO_INTR_DISABLE;
50
51 if (gpio_config(&io_conf) != ESP_OK) {
52 return false;
53 }
54
55 gpio_set_level(TEST_PROGRESS_PIN, 0);
56 g_gpio14_state = false;
58
59 return true;
60}
61
65inline void flip_test_progress_indicator() noexcept {
67 return;
68 }
69
71 gpio_set_level(TEST_PROGRESS_PIN, g_gpio14_state ? 1 : 0);
72 vTaskDelay(pdMS_TO_TICKS(50));
73}
74
78inline void output_section_indicator(uint8_t blink_count = 5) noexcept {
80 return;
81 }
82
83 for (uint8_t i = 0; i < blink_count; ++i) {
84 gpio_set_level(TEST_PROGRESS_PIN, 1);
85 vTaskDelay(pdMS_TO_TICKS(50));
86 gpio_set_level(TEST_PROGRESS_PIN, 0);
87 vTaskDelay(pdMS_TO_TICKS(50));
88 }
89
90 g_gpio14_state = false;
91}
92
96inline void cleanup_test_progress_indicator() noexcept {
98 gpio_set_level(TEST_PROGRESS_PIN, 0);
99 gpio_reset_pin(TEST_PROGRESS_PIN);
100 g_gpio14_initialized = false;
101 g_gpio14_state = false;
102 }
103}
104
108inline void ensure_gpio14_initialized() noexcept {
111 }
112}
113
114//=============================================================================
115// TEST RESULT TRACKING
116//=============================================================================
117
122 int total_tests = 0;
126
127 void add_result(bool passed, uint64_t execution_time) noexcept {
128 total_tests++;
129 total_execution_time_us += execution_time;
130 if (passed) {
131 passed_tests++;
132 } else {
133 failed_tests++;
134 }
135 }
136
137 double get_success_percentage() const noexcept {
138 return total_tests > 0 ? (static_cast<double>(passed_tests) / total_tests * 100.0) : 0.0;
139 }
140
141 double get_total_time_ms() const noexcept {
142 return total_execution_time_us / 1000.0;
143 }
144
145 void print_summary(const char* tag) const noexcept {
146 ESP_LOGI(tag, "");
147 ESP_LOGI(tag, "╔══════════════════════════════════════════════════════════════════════════════╗");
148 ESP_LOGI(tag, "║ TEST RESULTS SUMMARY ║");
149 ESP_LOGI(tag, "╠══════════════════════════════════════════════════════════════════════════════╣");
150 ESP_LOGI(tag, "║ Total Tests: %-56d ║", total_tests);
151 ESP_LOGI(tag, "║ Passed: %-56d ║", passed_tests);
152 ESP_LOGI(tag, "║ Failed: %-56d ║", failed_tests);
153 ESP_LOGI(tag, "║ Success Rate: %-55.2f%% ║", get_success_percentage());
154 ESP_LOGI(tag, "║ Total Time: %-52.2f ms ║", get_total_time_ms());
155 ESP_LOGI(tag, "╚══════════════════════════════════════════════════════════════════════════════╝");
156 ESP_LOGI(tag, "");
157 }
158};
159
160// Global test results
162
163//=============================================================================
164// TEST EXECUTION MACROS
165//=============================================================================
166
170#define RUN_TEST(test_func) \
171do { \
172 ensure_gpio14_initialized(); \
173 ESP_LOGI(TAG, ""); \
174 ESP_LOGI(TAG, "╔══════════════════════════════════════════════════════════════════════════════╗"); \
175 ESP_LOGI(TAG, "║ Running: " #test_func " "); \
176 ESP_LOGI(TAG, "╚══════════════════════════════════════════════════════════════════════════════╝"); \
177 uint64_t start_time = esp_timer_get_time(); \
178 bool result = test_func(); \
179 uint64_t end_time = esp_timer_get_time(); \
180 uint64_t execution_time = end_time - start_time; \
181 g_test_results.add_result(result, execution_time); \
182 if (result) { \
183 ESP_LOGI(TAG, "[SUCCESS] PASSED: " #test_func " (%.2f ms)", execution_time / 1000.0); \
184 } else { \
185 ESP_LOGE(TAG, "[FAILED] FAILED: " #test_func " (%.2f ms)", execution_time / 1000.0); \
186 } \
187 flip_test_progress_indicator(); \
188 vTaskDelay(pdMS_TO_TICKS(100)); \
189} while (0)
190
195 const char* test_name;
196 bool (*test_func)() noexcept;
198 const char* tag;
199 SemaphoreHandle_t completion_semaphore;
200};
201
205inline void test_task_trampoline(void* param) {
206 TestTaskContext* ctx = static_cast<TestTaskContext*>(param);
207 ESP_LOGI(ctx->tag, "");
208 ESP_LOGI(ctx->tag, "╔══════════════════════════════════════════════════════════════════════════════╗");
209 ESP_LOGI(ctx->tag, "║ Running (task): %-62s║", ctx->test_name);
210 ESP_LOGI(ctx->tag, "╚══════════════════════════════════════════════════════════════════════════════╝");
211
212 uint64_t start_time = esp_timer_get_time();
213 bool result = ctx->test_func();
214 uint64_t end_time = esp_timer_get_time();
215 uint64_t execution_time = end_time - start_time;
216
217 ctx->results->add_result(result, execution_time);
218
219 if (result) {
220 ESP_LOGI(ctx->tag, "[SUCCESS] PASSED (task): %s (%.2f ms)",
221 ctx->test_name, execution_time / 1000.0);
222 } else {
223 ESP_LOGE(ctx->tag, "[FAILED] FAILED (task): %s (%.2f ms)",
224 ctx->test_name, execution_time / 1000.0);
225 }
226
227 xSemaphoreGive(ctx->completion_semaphore);
228 vTaskDelete(nullptr);
229}
230
234#define RUN_TEST_IN_TASK(name, func, stack_size_bytes, priority) \
235do { \
236 ensure_gpio14_initialized(); \
237 static TestTaskContext ctx; \
238 ctx.test_name = name; \
239 ctx.test_func = func; \
240 ctx.results = &g_test_results; \
241 ctx.tag = TAG; \
242 ctx.completion_semaphore = xSemaphoreCreateBinary(); \
243 if (ctx.completion_semaphore == nullptr) { \
244 ESP_LOGE(TAG, "Failed to create semaphore for test: %s", name); \
245 RUN_TEST(func); \
246 } else { \
247 BaseType_t created = xTaskCreate(test_task_trampoline, name, \
248 (stack_size_bytes) / sizeof(StackType_t), \
249 &ctx, (priority), nullptr); \
250 if (created != pdPASS) { \
251 ESP_LOGE(TAG, "Failed to create test task: %s", name); \
252 vSemaphoreDelete(ctx.completion_semaphore); \
253 RUN_TEST(func); \
254 } else { \
255 if (xSemaphoreTake(ctx.completion_semaphore, pdMS_TO_TICKS(30000)) == pdTRUE) { \
256 ESP_LOGI(TAG, "Test task completed: %s", name); \
257 } else { \
258 ESP_LOGW(TAG, "Test task timeout: %s", name); \
259 } \
260 vSemaphoreDelete(ctx.completion_semaphore); \
261 flip_test_progress_indicator(); \
262 vTaskDelay(pdMS_TO_TICKS(100)); \
263 } \
264 } \
265} while (0)
266
270#define RUN_TEST_SECTION_IF_ENABLED(enabled, section_name, ...) \
271do { \
272 if (enabled) { \
273 ESP_LOGI(TAG, ""); \
274 ESP_LOGI(TAG, "╔══════════════════════════════════════════════════════════════════════════════╗"); \
275 ESP_LOGI(TAG, "║ SECTION: %-69s║", section_name); \
276 ESP_LOGI(TAG, "╚══════════════════════════════════════════════════════════════════════════════╝"); \
277 output_section_indicator(5); \
278 __VA_ARGS__ \
279 } \
280} while (0)
281
285#define RUN_TEST_SECTION_IF_ENABLED_WITH_PATTERN(enabled, section_name, blink_count, ...) \
286do { \
287 if (enabled) { \
288 ESP_LOGI(TAG, ""); \
289 ESP_LOGI(TAG, "╔══════════════════════════════════════════════════════════════════════════════╗"); \
290 ESP_LOGI(TAG, "║ SECTION: %-69s║", section_name); \
291 ESP_LOGI(TAG, "╚══════════════════════════════════════════════════════════════════════════════╝"); \
292 output_section_indicator(blink_count); \
293 __VA_ARGS__ \
294 } \
295} while (0)
296
297//=============================================================================
298// TEST REPORTING
299//=============================================================================
300
304inline void print_test_section_status(const char* tag, const char* module_name) {
305 ESP_LOGI(tag, "");
306 ESP_LOGI(tag, "╔══════════════════════════════════════════════════════════════════════════════╗");
307 ESP_LOGI(tag, "║ %s TEST CONFIGURATION ", module_name);
308 ESP_LOGI(tag, "╠══════════════════════════════════════════════════════════════════════════════╣");
309 ESP_LOGI(tag, "║ Test sections will execute based on compile-time configuration ║");
310 ESP_LOGI(tag, "║ GPIO14 test progression indicator: ENABLED ║");
311 ESP_LOGI(tag, "╚══════════════════════════════════════════════════════════════════════════════╝");
312 ESP_LOGI(tag, "");
313}
314
static constexpr gpio_num_t TEST_PROGRESS_PIN
Definition TLE92466ED_TestFramework.hpp:32
void output_section_indicator(uint8_t blink_count=5) noexcept
Blink GPIO14 to indicate section start/end.
Definition TLE92466ED_TestFramework.hpp:78
static bool g_gpio14_state
Definition TLE92466ED_TestFramework.hpp:34
bool init_test_progress_indicator() noexcept
Initialize GPIO14 as test progression indicator.
Definition TLE92466ED_TestFramework.hpp:39
void ensure_gpio14_initialized() noexcept
Ensure GPIO14 is initialized.
Definition TLE92466ED_TestFramework.hpp:108
void cleanup_test_progress_indicator() noexcept
Cleanup GPIO14 indicator.
Definition TLE92466ED_TestFramework.hpp:96
void flip_test_progress_indicator() noexcept
Toggle GPIO14 to indicate test progression.
Definition TLE92466ED_TestFramework.hpp:65
void print_test_section_status(const char *tag, const char *module_name)
Print section configuration status.
Definition TLE92466ED_TestFramework.hpp:304
static TestResults g_test_results
Definition TLE92466ED_TestFramework.hpp:161
void test_task_trampoline(void *param)
FreeRTOS task trampoline for test execution.
Definition TLE92466ED_TestFramework.hpp:205
static bool g_gpio14_initialized
Definition TLE92466ED_TestFramework.hpp:33
Test execution tracking and results accumulation.
Definition TLE92466ED_TestFramework.hpp:121
int failed_tests
Definition TLE92466ED_TestFramework.hpp:124
void add_result(bool passed, uint64_t execution_time) noexcept
Definition TLE92466ED_TestFramework.hpp:127
int passed_tests
Definition TLE92466ED_TestFramework.hpp:123
void print_summary(const char *tag) const noexcept
Definition TLE92466ED_TestFramework.hpp:145
double get_total_time_ms() const noexcept
Definition TLE92466ED_TestFramework.hpp:141
uint64_t total_execution_time_us
Definition TLE92466ED_TestFramework.hpp:125
double get_success_percentage() const noexcept
Definition TLE92466ED_TestFramework.hpp:137
int total_tests
Definition TLE92466ED_TestFramework.hpp:122
Context for test task.
Definition TLE92466ED_TestFramework.hpp:194
TestResults * results
Definition TLE92466ED_TestFramework.hpp:197
bool(* test_func)() noexcept
Definition TLE92466ED_TestFramework.hpp:196
SemaphoreHandle_t completion_semaphore
Definition TLE92466ED_TestFramework.hpp:199
const char * test_name
Definition TLE92466ED_TestFramework.hpp:195
const char * tag
Definition TLE92466ED_TestFramework.hpp:198