Skip to content

Commit 987b5fb

Browse files
committed
Merge branch 'poc-pal'
2 parents fd92f37 + 849e7c2 commit 987b5fb

File tree

9 files changed

+330
-49
lines changed

9 files changed

+330
-49
lines changed

src/MoonBase/Char.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
#pragma once
1313

14-
#include <Arduino.h>
15-
1614
#include "ArduinoJson.h"
1715

1816
// See https://discord.com/channels/473448917040758787/718943978636050542/1357670679196991629

src/MoonBase/Utilities.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
#pragma once
1313

14-
#include <Arduino.h>
1514
#include <ESPFS.h>
1615

1716
#include "ArduinoJson.h"

src/MoonBase/pal.h

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
/**
2+
@title MoonBase
3+
@file pal.h
4+
@repo https://github.com/MoonModules/MoonLight, submit changes to this file as PRs
5+
@Authors https://github.com/MoonModules/MoonLight/commits/main
6+
@Doc https://moonmodules.org/MoonLight/moonlight/overview/
7+
@Copyright © 2025 Github MoonLight Commit Authors
8+
@license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
9+
@license For non GPL-v3 usage, commercial licenses must be purchased. Contact us for more information.
10+
**/
11+
12+
/**
13+
Platform Abstraction Layer (PAL)
14+
15+
Goal:
16+
* not depending on Arduino.h
17+
* use esp-idf functions (instead of arduino.h)
18+
* in a way to not create a new dependency on esp-idf
19+
20+
Approach
21+
* Incremental changes: you can still do it the old way but the new way is available as well
22+
23+
Benefits
24+
* Common way of working, within one repository, Possibly between different repo's
25+
* No mix of arduino and esp-idf code in different places
26+
* platform Arduino can be removed in the future
27+
* Automated testing e.g. on Linux
28+
**/
29+
30+
#pragma once
31+
32+
#include <stddef.h>
33+
#include <stdint.h>
34+
35+
namespace pal {
36+
37+
/* =================================================
38+
* Basic types
39+
* ================================================= */
40+
41+
struct rgb_t {
42+
uint8_t r;
43+
uint8_t g;
44+
uint8_t b;
45+
};
46+
47+
/* =================================================
48+
* Time
49+
* ================================================= */
50+
51+
uint32_t millis();
52+
uint64_t micros();
53+
void delay_ms(uint32_t ms);
54+
55+
/* =================================================
56+
* LED output (hot path)
57+
* ================================================= */
58+
59+
void led_submit(const rgb_t* buffer, size_t led_count);
60+
void led_set_brightness(uint8_t brightness);
61+
62+
/* =================================================
63+
* Memory
64+
* ================================================= */
65+
66+
void* malloc(size_t size);
67+
void free(void* ptr);
68+
69+
/* =================================================
70+
* Logging
71+
* ================================================= */
72+
73+
enum class LogLevel : uint8_t { Error, Warn, Info, Debug };
74+
75+
void log(LogLevel level, const char* tag, const char* message);
76+
77+
/* =================================================
78+
* Capability hints (0 = no, 1 = yes)
79+
* ================================================= */
80+
81+
int cap_led_dma();
82+
int cap_led_parallel();
83+
84+
/* =================================================
85+
* UDP socket (stateful)
86+
* ================================================= */
87+
88+
class UdpSocket {
89+
public:
90+
virtual ~UdpSocket() = default;
91+
92+
virtual bool open(uint16_t local_port) = 0;
93+
virtual int send_to(const char* ip, uint16_t port, const uint8_t* data, size_t len) = 0;
94+
virtual int recv_from(uint8_t* buffer, size_t max_len,
95+
char* src_ip, // out
96+
uint16_t* src_port // out
97+
) = 0;
98+
virtual void close() = 0;
99+
};
100+
101+
UdpSocket* udp_socket_create();
102+
void udp_socket_destroy(UdpSocket* socket);
103+
104+
} // namespace pal

src/MoonBase/pal_espidf.cpp

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/**
2+
@title MoonBase
3+
@file pal_espidf.cpp
4+
@repo https://github.com/MoonModules/MoonLight, submit changes to this file as PRs
5+
@Authors https://github.com/MoonModules/MoonLight/commits/main
6+
@Doc https://moonmodules.org/MoonLight/moonlight/overview/
7+
@Copyright © 2025 Github MoonLight Commit Authors
8+
@license GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
9+
@license For non GPL-v3 usage, commercial licenses must be purchased. Contact us for more information.
10+
**/
11+
12+
#include <esp_heap_caps.h>
13+
#include <esp_log.h>
14+
#include <esp_timer.h>
15+
#include <freertos/FreeRTOS.h>
16+
#include <freertos/task.h>
17+
#include <lwip/inet.h>
18+
#include <lwip/sockets.h>
19+
#include <string.h>
20+
21+
#include "pal.h"
22+
23+
namespace pal {
24+
25+
/* =================================================
26+
* Time
27+
* ================================================= */
28+
29+
uint32_t millis() { return static_cast<uint32_t>(esp_timer_get_time() / 1000ULL); }
30+
31+
uint64_t micros() { return static_cast<uint64_t>(esp_timer_get_time()); }
32+
33+
void delay_ms(uint32_t ms) { vTaskDelay(pdMS_TO_TICKS(ms)); }
34+
35+
/* =================================================
36+
* LED output (ESP-IDF backend placeholder)
37+
* ================================================= */
38+
39+
// below functions is poc code. Need to be verified when actually used
40+
41+
static uint8_t s_led_brightness = 255; // brightness control will be implemented when the actual LED driver is added.
42+
43+
void led_submit(const rgb_t* buffer, size_t led_count) {
44+
/* To be implemented with:
45+
- RMT
46+
- PARLIO
47+
- DMA / PPA
48+
- or external driver
49+
*/
50+
(void)buffer;
51+
(void)led_count;
52+
}
53+
54+
void led_set_brightness(uint8_t brightness) { s_led_brightness = brightness; }
55+
56+
/* =================================================
57+
* Memory
58+
* ================================================= */
59+
60+
void* malloc(size_t size) { return heap_caps_malloc(size, MALLOC_CAP_8BIT); }
61+
62+
void free(void* ptr) { heap_caps_free(ptr); }
63+
64+
/* =================================================
65+
* Logging
66+
* ================================================= */
67+
68+
void log(LogLevel level, const char* tag, const char* message) {
69+
esp_log_level_t esp_level = ESP_LOG_INFO;
70+
71+
switch (level) {
72+
case LogLevel::Error:
73+
esp_level = ESP_LOG_ERROR;
74+
break;
75+
case LogLevel::Warn:
76+
esp_level = ESP_LOG_WARN;
77+
break;
78+
case LogLevel::Info:
79+
esp_level = ESP_LOG_INFO;
80+
break;
81+
case LogLevel::Debug:
82+
esp_level = ESP_LOG_DEBUG;
83+
break;
84+
}
85+
86+
esp_log_write(esp_level, tag, "%s\n", message);
87+
}
88+
89+
/* =================================================
90+
* Capabilities
91+
* ================================================= */
92+
93+
int cap_led_dma() { return 1; /* ESP32 supports DMA */ }
94+
95+
int cap_led_parallel() { return 1; /* ESP32 generally supports parallel output */ }
96+
97+
/* =================================================
98+
* UDP socket (ESP-IDF / lwIP)
99+
* ================================================= */
100+
101+
class EspIdfUdpSocket : public UdpSocket {
102+
public:
103+
EspIdfUdpSocket() : sock_(-1) {}
104+
105+
~EspIdfUdpSocket() override { close(); }
106+
107+
// below functions is poc code. Need to be verified when actually used
108+
109+
bool open(uint16_t local_port) override {
110+
sock_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
111+
if (sock_ < 0) {
112+
return false;
113+
}
114+
115+
sockaddr_in addr{};
116+
addr.sin_family = AF_INET;
117+
addr.sin_port = htons(local_port);
118+
addr.sin_addr.s_addr = INADDR_ANY;
119+
120+
if (bind(sock_, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) != 0) {
121+
::close(sock_);
122+
sock_ = -1;
123+
return false;
124+
}
125+
return true;
126+
}
127+
128+
int send_to(const char* ip, uint16_t port, const uint8_t* data, size_t len) override {
129+
sockaddr_in dest{};
130+
dest.sin_family = AF_INET;
131+
dest.sin_port = htons(port);
132+
if (inet_aton(ip, &dest.sin_addr) == 0) {
133+
return -1; // Invalid IP address
134+
}
135+
136+
return sendto(sock_, data, len, 0, reinterpret_cast<sockaddr*>(&dest), sizeof(dest));
137+
}
138+
139+
int recv_from(uint8_t* buffer, size_t max_len,
140+
char* src_ip, // out: must be at least 16 bytes (INET_ADDRSTRLEN)
141+
uint16_t* src_port // out
142+
) {
143+
sockaddr_in src_addr{};
144+
socklen_t src_len = sizeof(src_addr);
145+
146+
int received = recvfrom(sock_, buffer, max_len, 0, reinterpret_cast<sockaddr*>(&src_addr), &src_len);
147+
148+
if (received >= 0 && src_ip && src_port) {
149+
inet_ntoa_r(src_addr.sin_addr, src_ip, 16);
150+
*src_port = ntohs(src_addr.sin_port);
151+
}
152+
153+
return received;
154+
}
155+
156+
void close() override {
157+
if (sock_ >= 0) {
158+
::close(sock_);
159+
sock_ = -1;
160+
}
161+
}
162+
163+
private:
164+
int sock_;
165+
};
166+
167+
/* =================================================
168+
* Factory
169+
* ================================================= */
170+
171+
UdpSocket* udp_socket_create() { return new EspIdfUdpSocket(); }
172+
173+
void udp_socket_destroy(UdpSocket* socket) { delete socket; }
174+
175+
} // namespace pal

src/MoonLight/Layers/PhysicalLayer.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
#if FT_MOONLIGHT
1515

16-
#include <Arduino.h>
17-
1816
#include <vector>
1917

2018
#include "FastLED.h"

src/MoonLight/Layers/VirtualLayer.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
#if FT_MOONLIGHT
1515

16-
#include <Arduino.h>
1716
#include <FastLED.h>
1817

1918
#include <vector>

src/MoonLight/Nodes/Drivers/parlio.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
#include "parlio.h" //so it is compiled before Parallel LED Driver use it
1313

14+
#include "soc/soc_caps.h" // for SOC_PARLIO_SUPPORTED
15+
1416
#ifdef SOC_PARLIO_SUPPORTED
1517

1618
#include "driver/parlio_tx.h"

src/MoonLight/Nodes/Drivers/parlio.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
**/
1111

1212
#pragma once
13-
#include <Arduino.h>
13+
#include <stdint.h> // uint8...
1414

1515
#if FT_MOONLIGHT
1616

0 commit comments

Comments
 (0)