Skip to content

Commit 0a0f160

Browse files
committed
dma: dynamically assign streams/channels
1 parent 2ac1909 commit 0a0f160

35 files changed

+1329
-1040
lines changed

script/device_gen.py

Lines changed: 112 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import glob
22
import hashlib
3-
import yaml
4-
import os
3+
import re
54

65
import modm_devices
76

@@ -106,6 +105,66 @@ def __getitem__(self, item) -> modm_devices.device.Device:
106105
return value
107106

108107

108+
def map_signal(s):
109+
if s is None:
110+
return None
111+
112+
if s["driver"] == "tim" and s["name"].startswith("ch"):
113+
return {
114+
"func": "timer",
115+
"af": int(s.get("af", "-1")),
116+
"instance": int(s["instance"]),
117+
"name": s["name"],
118+
}
119+
elif s["driver"] == "spi" and (
120+
s["name"] == "sck"
121+
or s["name"] == "mosi"
122+
or s["name"] == "miso"
123+
or s["name"] == "tx"
124+
or s["name"] == "rx"
125+
):
126+
return {
127+
"func": "spi",
128+
"af": int(s.get("af", "-1")),
129+
"instance": int(s["instance"]),
130+
"name": {"tx": "mosi", "rx": "miso"}.get(s["name"], s["name"]),
131+
}
132+
elif (s["driver"] == "uart" or s["driver"] == "usart") and (
133+
s["name"] == "rx" or s["name"] == "tx"
134+
):
135+
return {
136+
"func": "serial",
137+
"af": int(s.get("af", "-1")),
138+
"instance": int(s["instance"]),
139+
"name": s["name"],
140+
}
141+
elif s["driver"] == "adc" and re.match(r"in\d+", s.get("name", "in0")):
142+
return {
143+
"func": "adc",
144+
"af": -1,
145+
"instance": int(s["instance"]),
146+
"name": s.get("name", "in0xff")[2:],
147+
}
148+
else:
149+
return None
150+
151+
152+
def map_tag(f):
153+
if f is None:
154+
return None
155+
156+
if f["func"] == "timer":
157+
return f"TIMER_TAG(TIMER{f['instance']}, TIMER_{f['name']})".upper()
158+
elif f["func"] == "spi":
159+
return f"SPI_TAG(SPI_PORT{f['instance']}, RES_SPI_{f['name']})".upper()
160+
elif f["func"] == "serial":
161+
return f"SERIAL_TAG(SERIAL_PORT{f['instance']}, RES_SERIAL_{f['name']})".upper()
162+
elif f["func"] == "adc":
163+
return f"ADC_TAG(ADC_DEVICE{f['instance']}, {f['name']})".upper()
164+
else:
165+
return None
166+
167+
109168
devices = [
110169
"stm32f405rg",
111170
"stm32f411re",
@@ -123,100 +182,58 @@ def __getitem__(self, item) -> modm_devices.device.Device:
123182
pins = {}
124183
key = next((x for x in caches.keys() if x.startswith(device)), None)
125184

126-
for driver in caches[key].get_all_drivers("gpio"):
127-
for pin in driver["gpio"]:
128-
funcs = []
185+
with open(f"src/system/{device[:9]}/gpio_pins.in", "w") as file:
186+
for driver in caches[key].get_all_drivers("gpio"):
187+
for pin in driver["gpio"]:
188+
file.write(f"GPIO_PIN({pin['port']}, {pin['pin']})\n".upper())
189+
if "signal" not in pin:
190+
continue
129191

130-
if "signal" in pin:
131192
for s in pin["signal"]:
132-
if s["driver"] == "tim" and s["name"].startswith("ch"):
133-
funcs.append(
134-
{
135-
"func": "timer",
136-
"af": int(s["af"]),
137-
"instance": int(s["instance"]),
138-
"name": s["name"],
139-
}
140-
)
141-
142-
if s["driver"] == "spi" and (
143-
s["name"] == "sck" or s["name"] == "mosi" or s["name"] == "miso"
144-
):
145-
funcs.append(
146-
{
147-
"func": "spi",
148-
"af": int(s["af"]),
149-
"instance": int(s["instance"]),
150-
"name": s["name"],
151-
}
152-
)
153-
154-
if (s["driver"] == "uart" or s["driver"] == "usart") and (
155-
s["name"] == "rx" or s["name"] == "tx"
156-
):
157-
funcs.append(
158-
{
159-
"func": "serial",
160-
"af": int(s["af"]),
161-
"instance": int(s["instance"]),
162-
"name": s["name"],
163-
}
164-
)
165-
166-
if s["driver"] == "adc" and not (
167-
s["name"].startswith("inp") or s["name"].startswith("inn")
168-
):
169-
funcs.append(
170-
{
171-
"func": "adc",
172-
"af": -1,
173-
"instance": int(s["instance"]),
174-
"name": s["name"][2:],
175-
}
176-
)
177-
178-
pins[f"P{pin['port']}{pin['pin']}".upper()] = funcs
179-
180-
with open(f"src/system/{device[:9]}/gpio_pins.yaml", "w") as file:
181-
documents = yaml.dump(pins, file, sort_keys=False)
182-
183-
for filename in glob.glob("src/system/*/gpio_pins.yaml"):
184-
dir = os.path.dirname(filename)
185-
186-
with open(filename, "r") as f:
187-
pins = yaml.load(f, Loader=yaml.Loader)
188-
189-
with open(f"{dir}/gpio_pins.in", "w") as file:
190-
for k, funcs in pins.items():
191-
port = k[1]
192-
pin = k[2:]
193-
file.write(f"GPIO_PIN({port}, {pin})\n")
194-
195-
for f in funcs:
196-
line = f"GPIO_AF(PIN_{port}{pin}, {f['af']}, "
197-
198-
if f["func"] == "timer":
199-
line = (
200-
line
201-
+ f"TIMER_TAG(TIMER{f['instance']}, TIMER_{f['name'].upper()}))\n"
202-
)
203-
204-
if f["func"] == "spi":
205-
line = (
206-
line
207-
+ f"SPI_TAG(SPI_PORT{f['instance']}, RES_SPI_{f['name'].upper()}))\n"
208-
)
209-
210-
if f["func"] == "serial":
211-
line = (
212-
line
213-
+ f"SERIAL_TAG(SERIAL_PORT{f['instance']}, RES_SERIAL_{f['name'].upper()}))\n"
214-
)
215-
216-
if f["func"] == "adc":
217-
line = (
218-
line
219-
+ f"ADC_TAG(ADC_DEVICE{f['instance']}, {f['name'].upper()}))\n"
193+
f = map_signal(s)
194+
s = map_tag(f)
195+
if s is None:
196+
continue
197+
file.write(
198+
f"GPIO_AF(PIN_{pin['port']}{pin['pin']}, {f['af']}, {s})\n".upper()
220199
)
221200

222-
file.write(line)
201+
with open(f"src/system/{device[:9]}/dma.in", "w") as file:
202+
for driver in caches[key].get_all_drivers("dma"):
203+
if "streams" in driver:
204+
for dma in driver["streams"]:
205+
for stream in dma["stream"]:
206+
for channel in stream["channel"]:
207+
funcs = [
208+
r
209+
for s in channel["signal"]
210+
if (r := map_tag(map_signal(s))) is not None
211+
]
212+
for func in funcs:
213+
entry = ", ".join(
214+
[
215+
f".tag = {func}",
216+
f".port_index = {dma['instance']}",
217+
f".stream_index = {stream['position']}",
218+
f".channel = LL_DMA_CHANNEL_{channel['position']}",
219+
]
220+
)
221+
file.write("{ " + entry + " },\n")
222+
if "requests" in driver:
223+
for dma in driver["requests"]:
224+
for request in dma["request"]:
225+
funcs = [
226+
r
227+
for s in request["signal"]
228+
if (r := map_tag(map_signal(s))) is not None
229+
]
230+
for func in funcs:
231+
entry = ", ".join(
232+
[
233+
f".tag = {func}",
234+
f".port_index = -1",
235+
f".stream_index = -1",
236+
f".request = {request['position']}",
237+
]
238+
)
239+
file.write("{ " + entry + " },\n")

src/config/feature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#define USE_VTX
1313
#define USE_DIGITAL_VTX
1414
#define USE_MAX7456
15+
#define USE_RGB_LED
1516

1617
#define USE_MOTOR_DSHOT
1718
#define USE_MOTOR_PWM

src/core/failloop.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ typedef enum {
1010
FAILLOOP_GYRO = 4, // gyro not found
1111
FAILLOOP_FAULT = 5, // clock, intterrupts, systick, gcc bad code, bad memory access (code issues like bad pointers) - this should not come up
1212
FAILLOOP_LOOPTIME = 6, // loop time issue - if loop time exceeds 20mS
13-
FAILLOOP_DMA = 7, // dma error - triggered by dma pool
14-
FAILLOOP_SPI = 8, // spi error - triggered by hardware spi driver only
13+
FAILLOOP_DMA = 7, // dma error
14+
FAILLOOP_SPI = 8, // spi error
1515
} __attribute__((__packed__)) failloop_t;
1616

1717
void failloop(failloop_t val);

src/core/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ __attribute__((__used__)) int main() {
123123

124124
rx_init();
125125
vtx_init();
126-
rgb_init();
126+
rgb_led_init();
127127

128128
blackbox_init();
129129
imu_init();

src/core/target.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ target_info_t target_info = {
4141
#define INDEX_ARRAY_MEMBER CBOR_ENCODE_INDEX_ARRAY_MEMBER
4242
#define STR_ARRAY_MEMBER CBOR_ENCODE_STR_ARRAY_MEMBER
4343

44+
TARGET_DMA_MEMBERS
4445
TARGET_LED_MEMBERS
4546
TARGET_BUZZER_MEMBERS
4647
TARGET_SERIAL_MEMBERS
@@ -69,6 +70,7 @@ TARGET_INFO_MEMBERS
6970
#define INDEX_ARRAY_MEMBER CBOR_DECODE_INDEX_ARRAY_MEMBER
7071
#define STR_ARRAY_MEMBER CBOR_DECODE_STR_ARRAY_MEMBER
7172

73+
TARGET_DMA_MEMBERS
7274
TARGET_LED_MEMBERS
7375
TARGET_BUZZER_MEMBERS
7476
TARGET_SERIAL_MEMBERS

src/core/target.h

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <cbor.h>
44
#include <stdbool.h>
55

6+
#include "driver/dma.h"
67
#include "rx/rx.h"
78

89
#define LED_MAX 4
@@ -64,6 +65,32 @@ typedef enum {
6465
SERIAL_SOFT_COUNT = SERIAL_SOFT_MAX - SERIAL_SOFT_START,
6566
} __attribute__((__packed__)) serial_ports_t;
6667

68+
typedef struct {
69+
#if defined(STM32H7) || defined(STM32G4) || defined(AT32)
70+
uint32_t request;
71+
#else
72+
uint32_t channel;
73+
#endif
74+
resource_tag_t tag;
75+
dma_stream_t dma;
76+
} target_dma_t;
77+
78+
#if defined(STM32H7) || defined(STM32G4) || defined(AT32)
79+
#define TARGET_DMA_MEMBERS \
80+
START_STRUCT(target_dma_t) \
81+
MEMBER(request, uint32_t) \
82+
MEMBER(tag, resource_tag_t) \
83+
MEMBER(dma, dma_stream_t) \
84+
END_STRUCT()
85+
#else
86+
#define TARGET_DMA_MEMBERS \
87+
START_STRUCT(target_dma_t) \
88+
MEMBER(channel, uint32_t) \
89+
MEMBER(tag, resource_tag_t) \
90+
MEMBER(dma, dma_stream_t) \
91+
END_STRUCT()
92+
#endif
93+
6794
typedef struct {
6895
gpio_pins_t pin;
6996
bool invert;
@@ -186,13 +213,16 @@ typedef struct {
186213
gpio_pins_t fpv;
187214
gpio_pins_t vbat;
188215
gpio_pins_t ibat;
216+
gpio_pins_t rgb_led;
189217

190218
target_invert_pin_t sdcard_detect;
191219
target_invert_pin_t buzzer;
192220
gpio_pins_t motor_pins[MOTOR_PIN_MAX];
193221

194222
uint16_t vbat_scale;
195223
uint16_t ibat_scale;
224+
225+
target_dma_t dma[DMA_DEVICE_MAX];
196226
} target_t;
197227

198228
#define TARGET_MEMBERS \
@@ -213,11 +243,13 @@ typedef struct {
213243
MEMBER(fpv, gpio_pins_t) \
214244
MEMBER(vbat, gpio_pins_t) \
215245
MEMBER(ibat, gpio_pins_t) \
246+
MEMBER(rgb_led, gpio_pins_t) \
216247
MEMBER(sdcard_detect, target_invert_pin_t) \
217248
MEMBER(buzzer, target_invert_pin_t) \
218249
ARRAY_MEMBER(motor_pins, MOTOR_PIN_MAX, gpio_pins_t) \
219250
MEMBER(vbat_scale, uint16_t) \
220251
MEMBER(ibat_scale, uint16_t) \
252+
MEMBER(dma, target_dma_array) \
221253
END_STRUCT()
222254

223255
typedef enum {
@@ -268,4 +300,10 @@ cbor_result_t cbor_decode_gpio_pins_t(cbor_value_t *dec, gpio_pins_t *t);
268300
cbor_result_t cbor_encode_target_t(cbor_value_t *enc, const target_t *t);
269301
cbor_result_t cbor_decode_target_t(cbor_value_t *dec, target_t *t);
270302

271-
cbor_result_t cbor_encode_target_info_t(cbor_value_t *enc, const target_info_t *i);
303+
cbor_result_t cbor_encode_target_dma_t(cbor_value_t *enc, const target_dma_t *dma);
304+
cbor_result_t cbor_decode_target_dma_t(cbor_value_t *dec, target_dma_t *dma);
305+
306+
cbor_result_t cbor_encode_target_info_t(cbor_value_t *enc, const target_info_t *i);
307+
308+
cbor_result_t cbor_encode_target_dma_array(cbor_value_t *dec, const target_dma_t (*dma)[DMA_DEVICE_MAX]);
309+
cbor_result_t cbor_decode_target_dma_array(cbor_value_t *dec, target_dma_t (*dma)[DMA_DEVICE_MAX]);

src/core/tasks.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "io/blackbox.h"
1212
#include "io/buzzer.h"
1313
#include "io/led.h"
14+
#include "io/rgb_led.h"
1415
#include "io/usb_configurator.h"
1516
#include "io/vbat.h"
1617
#include "io/vtx.h"
@@ -22,14 +23,7 @@
2223
void util_task() {
2324
// handle led commands
2425
led_update();
25-
26-
#if (RGB_LED_NUMBER > 0)
27-
// RGB led control
28-
rgb_led_lvc();
29-
#ifdef RGB_LED_DMA
30-
rgb_dma_start();
31-
#endif
32-
#endif
26+
rgb_led_update();
3327

3428
buzzer_update();
3529
}

0 commit comments

Comments
 (0)