Skip to content

Commit

Permalink
dma: dynamically assign streams/channels
Browse files Browse the repository at this point in the history
  • Loading branch information
bkleiner committed Dec 12, 2024
1 parent 689ec84 commit 8c910d9
Show file tree
Hide file tree
Showing 35 changed files with 1,323 additions and 1,044 deletions.
207 changes: 112 additions & 95 deletions script/device_gen.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import glob
import hashlib
import yaml
import os
import re

import modm_devices

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


def map_signal(s):
if s is None:
return None

if s["driver"] == "tim" and s["name"].startswith("ch"):
return {
"func": "timer",
"af": int(s.get("af", "-1")),
"instance": int(s["instance"]),
"name": s["name"],
}
elif s["driver"] == "spi" and (
s["name"] == "sck"
or s["name"] == "mosi"
or s["name"] == "miso"
or s["name"] == "tx"
or s["name"] == "rx"
):
return {
"func": "spi",
"af": int(s.get("af", "-1")),
"instance": int(s["instance"]),
"name": {"tx": "mosi", "rx": "miso"}.get(s["name"], s["name"]),
}
elif (s["driver"] == "uart" or s["driver"] == "usart") and (
s["name"] == "rx" or s["name"] == "tx"
):
return {
"func": "serial",
"af": int(s.get("af", "-1")),
"instance": int(s["instance"]),
"name": s["name"],
}
elif s["driver"] == "adc" and re.match(r"in\d+", s.get("name", "in0")):
return {
"func": "adc",
"af": -1,
"instance": int(s["instance"]),
"name": s.get("name", "in0xff")[2:],
}
else:
return None


def map_tag(f):
if f is None:
return None

if f["func"] == "timer":
return f"TIMER_TAG(TIMER{f['instance']}, TIMER_{f['name']})".upper()
elif f["func"] == "spi":
return f"SPI_TAG(SPI_PORT{f['instance']}, RES_SPI_{f['name']})".upper()
elif f["func"] == "serial":
return f"SERIAL_TAG(SERIAL_PORT{f['instance']}, RES_SERIAL_{f['name']})".upper()
elif f["func"] == "adc":
return f"ADC_TAG(ADC_DEVICE{f['instance']}, {f['name']})".upper()
else:
return None


devices = [
"stm32f405rg",
"stm32f411re",
Expand All @@ -123,100 +182,58 @@ def __getitem__(self, item) -> modm_devices.device.Device:
pins = {}
key = next((x for x in caches.keys() if x.startswith(device)), None)

for driver in caches[key].get_all_drivers("gpio"):
for pin in driver["gpio"]:
funcs = []
with open(f"src/system/{device[:9]}/gpio_pins.in", "w") as file:
for driver in caches[key].get_all_drivers("gpio"):
for pin in driver["gpio"]:
file.write(f"GPIO_PIN({pin['port']}, {pin['pin']})\n".upper())
if "signal" not in pin:
continue

if "signal" in pin:
for s in pin["signal"]:
if s["driver"] == "tim" and s["name"].startswith("ch"):
funcs.append(
{
"func": "timer",
"af": int(s["af"]),
"instance": int(s["instance"]),
"name": s["name"],
}
)

if s["driver"] == "spi" and (
s["name"] == "sck" or s["name"] == "mosi" or s["name"] == "miso"
):
funcs.append(
{
"func": "spi",
"af": int(s["af"]),
"instance": int(s["instance"]),
"name": s["name"],
}
)

if (s["driver"] == "uart" or s["driver"] == "usart") and (
s["name"] == "rx" or s["name"] == "tx"
):
funcs.append(
{
"func": "serial",
"af": int(s["af"]),
"instance": int(s["instance"]),
"name": s["name"],
}
)

if s["driver"] == "adc" and not (
s["name"].startswith("inp") or s["name"].startswith("inn")
):
funcs.append(
{
"func": "adc",
"af": -1,
"instance": int(s["instance"]),
"name": s["name"][2:],
}
)

pins[f"P{pin['port']}{pin['pin']}".upper()] = funcs

with open(f"src/system/{device[:9]}/gpio_pins.yaml", "w") as file:
documents = yaml.dump(pins, file, sort_keys=False)

for filename in glob.glob("src/system/*/gpio_pins.yaml"):
dir = os.path.dirname(filename)

with open(filename, "r") as f:
pins = yaml.load(f, Loader=yaml.Loader)

with open(f"{dir}/gpio_pins.in", "w") as file:
for k, funcs in pins.items():
port = k[1]
pin = k[2:]
file.write(f"GPIO_PIN({port}, {pin})\n")

for f in funcs:
line = f"GPIO_AF(PIN_{port}{pin}, {f['af']}, "

if f["func"] == "timer":
line = (
line
+ f"TIMER_TAG(TIMER{f['instance']}, TIMER_{f['name'].upper()}))\n"
)

if f["func"] == "spi":
line = (
line
+ f"SPI_TAG(SPI_PORT{f['instance']}, RES_SPI_{f['name'].upper()}))\n"
)

if f["func"] == "serial":
line = (
line
+ f"SERIAL_TAG(SERIAL_PORT{f['instance']}, RES_SERIAL_{f['name'].upper()}))\n"
)

if f["func"] == "adc":
line = (
line
+ f"ADC_TAG(ADC_DEVICE{f['instance']}, {f['name'].upper()}))\n"
f = map_signal(s)
s = map_tag(f)
if s is None:
continue
file.write(
f"GPIO_AF(PIN_{pin['port']}{pin['pin']}, {f['af']}, {s})\n".upper()
)

file.write(line)
with open(f"src/system/{device[:9]}/dma.in", "w") as file:
for driver in caches[key].get_all_drivers("dma"):
if "streams" in driver:
for dma in driver["streams"]:
for stream in dma["stream"]:
for channel in stream["channel"]:
funcs = [
r
for s in channel["signal"]
if (r := map_tag(map_signal(s))) is not None
]
for func in funcs:
entry = ", ".join(
[
f".tag = {func}",
f".port_index = {dma['instance']}",
f".stream_index = {stream['position']}",
f".channel = LL_DMA_CHANNEL_{channel['position']}",
]
)
file.write("{ " + entry + " },\n")
if "requests" in driver:
for dma in driver["requests"]:
for request in dma["request"]:
funcs = [
r
for s in request["signal"]
if (r := map_tag(map_signal(s))) is not None
]
for func in funcs:
entry = ", ".join(
[
f".tag = {func}",
f".port_index = -1",
f".stream_index = -1",
f".request = {request['position']}",
]
)
file.write("{ " + entry + " },\n")
1 change: 1 addition & 0 deletions src/config/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#define USE_VTX
#define USE_DIGITAL_VTX
#define USE_MAX7456
#define USE_RGB_LED

#define USE_MOTOR_DSHOT
#define USE_MOTOR_PWM
Expand Down
4 changes: 2 additions & 2 deletions src/core/failloop.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ typedef enum {
FAILLOOP_GYRO = 4, // gyro not found
FAILLOOP_FAULT = 5, // clock, intterrupts, systick, gcc bad code, bad memory access (code issues like bad pointers) - this should not come up
FAILLOOP_LOOPTIME = 6, // loop time issue - if loop time exceeds 20mS
FAILLOOP_DMA = 7, // dma error - triggered by dma pool
FAILLOOP_SPI = 8, // spi error - triggered by hardware spi driver only
FAILLOOP_DMA = 7, // dma error
FAILLOOP_SPI = 8, // spi error
} __attribute__((__packed__)) failloop_t;

void failloop(failloop_t val);
2 changes: 1 addition & 1 deletion src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ __attribute__((__used__)) int main() {

rx_init();
vtx_init();
rgb_init();
rgb_led_init();

blackbox_init();
imu_init();
Expand Down
2 changes: 2 additions & 0 deletions src/core/target.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ target_info_t target_info = {
#define INDEX_ARRAY_MEMBER CBOR_ENCODE_INDEX_ARRAY_MEMBER
#define STR_ARRAY_MEMBER CBOR_ENCODE_STR_ARRAY_MEMBER

TARGET_DMA_MEMBERS
TARGET_LED_MEMBERS
TARGET_BUZZER_MEMBERS
TARGET_SERIAL_MEMBERS
Expand Down Expand Up @@ -69,6 +70,7 @@ TARGET_INFO_MEMBERS
#define INDEX_ARRAY_MEMBER CBOR_DECODE_INDEX_ARRAY_MEMBER
#define STR_ARRAY_MEMBER CBOR_DECODE_STR_ARRAY_MEMBER

TARGET_DMA_MEMBERS
TARGET_LED_MEMBERS
TARGET_BUZZER_MEMBERS
TARGET_SERIAL_MEMBERS
Expand Down
40 changes: 39 additions & 1 deletion src/core/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <cbor.h>
#include <stdbool.h>

#include "driver/dma.h"
#include "rx/rx.h"

#define LED_MAX 4
Expand Down Expand Up @@ -64,6 +65,32 @@ typedef enum {
SERIAL_SOFT_COUNT = SERIAL_SOFT_MAX - SERIAL_SOFT_START,
} __attribute__((__packed__)) serial_ports_t;

typedef struct {
#if defined(STM32H7) || defined(STM32G4) || defined(AT32)
uint32_t request;
#else
uint32_t channel;
#endif
resource_tag_t tag;
dma_stream_t dma;
} target_dma_t;

#if defined(STM32H7) || defined(STM32G4) || defined(AT32)
#define TARGET_DMA_MEMBERS \
START_STRUCT(target_dma_t) \
MEMBER(request, uint32_t) \
MEMBER(tag, resource_tag_t) \
MEMBER(dma, dma_stream_t) \
END_STRUCT()
#else
#define TARGET_DMA_MEMBERS \
START_STRUCT(target_dma_t) \
MEMBER(channel, uint32_t) \
MEMBER(tag, resource_tag_t) \
MEMBER(dma, dma_stream_t) \
END_STRUCT()
#endif

typedef struct {
gpio_pins_t pin;
bool invert;
Expand Down Expand Up @@ -186,13 +213,16 @@ typedef struct {
gpio_pins_t fpv;
gpio_pins_t vbat;
gpio_pins_t ibat;
gpio_pins_t rgb_led;

target_invert_pin_t sdcard_detect;
target_invert_pin_t buzzer;
gpio_pins_t motor_pins[MOTOR_PIN_MAX];

uint16_t vbat_scale;
uint16_t ibat_scale;

target_dma_t dma[DMA_DEVICE_MAX];
} target_t;

#define TARGET_MEMBERS \
Expand All @@ -213,11 +243,13 @@ typedef struct {
MEMBER(fpv, gpio_pins_t) \
MEMBER(vbat, gpio_pins_t) \
MEMBER(ibat, gpio_pins_t) \
MEMBER(rgb_led, gpio_pins_t) \
MEMBER(sdcard_detect, target_invert_pin_t) \
MEMBER(buzzer, target_invert_pin_t) \
ARRAY_MEMBER(motor_pins, MOTOR_PIN_MAX, gpio_pins_t) \
MEMBER(vbat_scale, uint16_t) \
MEMBER(ibat_scale, uint16_t) \
MEMBER(dma, target_dma_array) \
END_STRUCT()

typedef enum {
Expand Down Expand Up @@ -268,4 +300,10 @@ cbor_result_t cbor_decode_gpio_pins_t(cbor_value_t *dec, gpio_pins_t *t);
cbor_result_t cbor_encode_target_t(cbor_value_t *enc, const target_t *t);
cbor_result_t cbor_decode_target_t(cbor_value_t *dec, target_t *t);

cbor_result_t cbor_encode_target_info_t(cbor_value_t *enc, const target_info_t *i);
cbor_result_t cbor_encode_target_dma_t(cbor_value_t *enc, const target_dma_t *dma);
cbor_result_t cbor_decode_target_dma_t(cbor_value_t *dec, target_dma_t *dma);

cbor_result_t cbor_encode_target_info_t(cbor_value_t *enc, const target_info_t *i);

cbor_result_t cbor_encode_target_dma_array(cbor_value_t *dec, const target_dma_t (*dma)[DMA_DEVICE_MAX]);
cbor_result_t cbor_decode_target_dma_array(cbor_value_t *dec, target_dma_t (*dma)[DMA_DEVICE_MAX]);
10 changes: 2 additions & 8 deletions src/core/tasks.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "io/blackbox.h"
#include "io/buzzer.h"
#include "io/led.h"
#include "io/rgb_led.h"
#include "io/usb_configurator.h"
#include "io/vbat.h"
#include "io/vtx.h"
Expand All @@ -22,14 +23,7 @@
void util_task() {
// handle led commands
led_update();

#if (RGB_LED_NUMBER > 0)
// RGB led control
rgb_led_lvc();
#ifdef RGB_LED_DMA
rgb_dma_start();
#endif
#endif
rgb_led_update();

buzzer_update();
}
Expand Down
Loading

0 comments on commit 8c910d9

Please sign in to comment.