Skip to content

Commit 5f846fe

Browse files
authored
Merge pull request #45 from stevenewald/echavemann/led-matrix-redo
LED Matrix Controller
2 parents a7177f4 + ae488e1 commit 5f846fe

12 files changed

+95
-74
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ SOFTDEVICE_MODEL = blank
77

88
# ETL
99
ETL_INCLUDES = ./external/etl/include/etl/array.h
10+
ETL_INCLUDES = ./external/etl/include/etl/variant.h
1011
ETL_INCLUDES += ./external/etl/include/etl/vector.h
1112
ETL_INCLUDES += ./external/etl/include/etl/optional.h
1213
ETL_INCLUDES += ./external/etl/include/etl/string.h

include/drivers/driver_commands.hpp

-3
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,6 @@
66

77
namespace edge::drivers {
88

9-
// SHOULD BE DEPRECATED SOON
10-
void do_async_work();
11-
129
etl::optional<int> handle_command(DriverCommand type, int arg1, int arg2, int arg3);
1310

1411
etl::optional<int> handle_subscribe(

include/drivers/led_display.hpp include/drivers/led_matrix_controller.hpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#pragma once
22
#include "drivers/gpio_pin.hpp"
3+
#include "drivers/virtual_timer_controller.hpp"
34
#include "microbit_v2.h"
45

56
namespace edge::drivers {
67

78
// Synchronous
8-
class LedDisplay {
9+
class LedMatrixController {
910
static constexpr uint8_t WIDTH = 5;
1011
static constexpr uint8_t HEIGHT = 5;
1112

@@ -27,15 +28,21 @@ class LedDisplay {
2728
GPIOPin{LED_COL5, GPIOConfiguration::OUT}
2829
};
2930

30-
void set_output(uint8_t row, uint8_t col, bool enabled);
31-
3231
public:
33-
LedDisplay();
32+
static LedMatrixController& get();
3433

3534
void set_led(uint8_t row, uint8_t col, bool enabled);
3635

37-
void do_async_work();
36+
LedMatrixController(LedMatrixController&) = delete;
37+
LedMatrixController(LedMatrixController&&) = delete;
38+
LedMatrixController& operator=(VirtualTimerController&) = delete;
39+
LedMatrixController& operator=(VirtualTimerController&&) = delete;
40+
41+
friend void handle_matrix_controller();
42+
43+
private:
44+
LedMatrixController();
45+
~LedMatrixController() = default;
3846
};
3947

40-
extern LedDisplay led_display;
4148
} // namespace edge::drivers

include/drivers/virtual_timer_controller.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ void TIMER3_IRQHandler(void);
1212
struct timer {
1313
uint32_t id;
1414

15-
ProcessCallbackPtr callback;
15+
etl::variant<KernelCallbackPtr, ProcessCallbackPtr> callback;
1616

1717
uint32_t timer_value;
1818
ProcessId process_id;
@@ -35,8 +35,9 @@ class VirtualTimerController {
3535

3636
public:
3737
uint32_t virtual_timer_start(
38-
uint32_t microseconds, ProcessCallbackPtr callback, ProcessId timer_creator,
39-
bool periodic
38+
uint32_t microseconds,
39+
etl::variant<KernelCallbackPtr, ProcessCallbackPtr> callback,
40+
ProcessId timer_creator, bool periodic
4041
);
4142
void virtual_timer_cancel(uint32_t timer_id);
4243

include/util.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ namespace edge {
77

88
// Arg1 and arg2 are optional
99
using ProcessCallbackPtr = void (*)(int arg1, int arg2);
10+
using KernelCallbackPtr = etl::delegate<void()>;
1011

1112
using ProcessId = uint8_t;
1213

src/drivers/driver_commands.cpp

+4-9
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,19 @@
22

33
#include "drivers/button_driver.hpp"
44
#include "drivers/driver_enums.hpp"
5-
#include "drivers/led_display.hpp"
5+
#include "drivers/led_matrix_controller.hpp"
66
#include "drivers/virtual_timer_controller.hpp"
7+
#include "util.hpp"
78

89
#include <stdio.h>
910

1011
namespace edge::drivers {
1112

12-
// Runs on context switch
13-
void do_async_work()
14-
{
15-
led_display.do_async_work();
16-
}
17-
1813
etl::optional<int> handle_command(DriverCommand type, int arg1, int arg2, int arg3)
1914
{
2015
switch (type) {
2116
case DriverCommand::LED_DISPLAY:
22-
led_display.set_led(arg1, arg2, arg3);
17+
LedMatrixController::get().set_led(arg1, arg2, arg3);
2318
break;
2419
case DriverCommand::GET_TIME:
2520
return VirtualTimerController::get().read_timer();
@@ -52,7 +47,7 @@ etl::optional<int> handle_subscribe(
5247
break;
5348
case DriverSubscribe::TIMER_START:
5449
return VirtualTimerController::get().virtual_timer_start(
55-
static_cast<uint32_t>(arg1), callback, process_id, arg2
50+
static_cast<uint32_t>(arg1), callback, 0, arg2
5651
);
5752
}
5853
return etl::nullopt;

src/drivers/led_display.cpp

-39
This file was deleted.

src/drivers/led_matrix_controller.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#include "drivers/led_matrix_controller.hpp"
2+
3+
#include "drivers/virtual_timer_controller.hpp"
4+
#include "nrf_delay.h"
5+
#include "userlib/syscalls.hpp"
6+
#include "util.hpp"
7+
8+
namespace edge::drivers {
9+
10+
void handle_matrix_controller()
11+
{
12+
static uint8_t row_index = 0;
13+
LedMatrixController& controller = LedMatrixController::get();
14+
15+
etl::for_each(
16+
controller.led_rows.begin(), controller.led_rows.end(),
17+
[](auto& led_row) { led_row.clear(); }
18+
);
19+
20+
for (uint8_t col_index = 0; col_index < 5; ++col_index) {
21+
bool state = controller.led_enabled[row_index][col_index];
22+
if (!state) {
23+
controller.led_cols[col_index].set();
24+
}
25+
else {
26+
controller.led_cols[col_index].clear();
27+
}
28+
}
29+
controller.led_rows[row_index].set();
30+
row_index++;
31+
row_index = row_index % 5;
32+
}
33+
34+
LedMatrixController::LedMatrixController()
35+
{
36+
etl::for_each(led_rows.begin(), led_rows.end(), [](auto& row) { row.clear(); });
37+
etl::for_each(led_cols.begin(), led_cols.end(), [](auto& col) { col.set(); });
38+
VirtualTimerController::get().virtual_timer_start(
39+
100, etl::delegate<void()>::create<handle_matrix_controller>(), 0, true
40+
);
41+
}
42+
43+
LedMatrixController& LedMatrixController::get()
44+
{
45+
static LedMatrixController controller;
46+
return controller;
47+
}
48+
49+
void LedMatrixController::set_led(uint8_t row, uint8_t col, bool enabled)
50+
{
51+
led_enabled[row][col] = enabled;
52+
}
53+
54+
} // namespace edge::drivers

src/drivers/virtual_timer_controller.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,15 @@ void VirtualTimerController::trigger_ready_timers()
4747
etl::optional<timer> ready_timer_opt = get_ready_timer();
4848
while (ready_timer_opt.has_value()) {
4949
timer& ready_timer = ready_timer_opt.value();
50-
PendingProcessCallbacks::get().add_ready_callback(
51-
ready_timer.process_id, ready_timer.callback, ready_timer.id
52-
);
50+
if (etl::holds_alternative<KernelCallbackPtr>(ready_timer.callback)) {
51+
etl::get<KernelCallbackPtr>(ready_timer.callback)();
52+
}
53+
else {
54+
PendingProcessCallbacks::get().add_ready_callback(
55+
ready_timer.process_id,
56+
etl::get<ProcessCallbackPtr>(ready_timer.callback), ready_timer.id
57+
);
58+
}
5359
if (ready_timer.periodic) {
5460
ready_timer.timer_value += ready_timer.duration;
5561
virtual_timer_start(ready_timer);
@@ -79,7 +85,8 @@ uint32_t VirtualTimerController::virtual_timer_start(const timer& timer)
7985
}
8086

8187
uint32_t VirtualTimerController::virtual_timer_start(
82-
uint32_t microseconds, ProcessCallbackPtr cb, ProcessId timer_creator, bool periodic
88+
uint32_t microseconds, etl::variant<KernelCallbackPtr, ProcessCallbackPtr> cb,
89+
ProcessId timer_creator, bool periodic
8390
)
8491
{
8592
static uint32_t timer_offset = 0;

src/entrypoint.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ int main(void)
1616

1717
edge::FaultHandler::get();
1818

19-
// edge::scheduler.add_task(exception_task);
19+
edge::scheduler.add_task(exception_task);
2020

2121
edge::scheduler.add_task(ipc_part1);
2222
edge::scheduler.add_task(ipc_part2);

src/scheduler/scheduler.cpp

-3
Original file line numberDiff line numberDiff line change
@@ -99,9 +99,6 @@ __attribute__((naked, used)) void PendSV_Handler()
9999

100100
asm volatile("CPSIE I");
101101

102-
// Always want to call drivers on context switch
103-
drivers::do_async_work();
104-
105102
// Return in thumb/process mode and restore using extended stack frame
106103
asm volatile("ldr r0,=0xffffffed\n"
107104
"bx r0");

src/user_programs/user_program_exception.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,16 @@
44

55
void callback(uint32_t id)
66
{
7-
static int b = 0;
8-
edge::userlib::set_led(3, 3, ++b % 2 == 0);
7+
static bool b = false;
8+
edge::userlib::set_led(2, 2, b);
9+
b=!b;
910
}
1011

1112
void callback2(uint32_t id)
1213
{
13-
static int b = 0;
14-
edge::userlib::set_led(1, 1, ++b % 2 == 0);
14+
static bool b = false;
15+
edge::userlib::set_led(2, 2, b);
16+
b=!b;
1517
}
1618

1719
void exception_task(void)
@@ -47,8 +49,6 @@ void exception_task(void)
4749
auto id2 = start_timer(callback2, 750000, true);
4850
cancel_timer(id2);
4951

50-
set_led(2, 2, true);
51-
5252
while (1) {
5353
yield();
5454
}

0 commit comments

Comments
 (0)