Skip to content

Commit

Permalink
add script to compute dma assigments
Browse files Browse the repository at this point in the history
  • Loading branch information
bkleiner committed Nov 26, 2024
1 parent f825540 commit 2d6d83d
Show file tree
Hide file tree
Showing 622 changed files with 21,052 additions and 139 deletions.
2 changes: 1 addition & 1 deletion betaflight
164 changes: 164 additions & 0 deletions src/dma.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
import fs from "fs";
import path from "path";
import YAML from "yaml";
import { walk } from "./util";
import { stringifyTarget, target_t } from "./types";

interface device_tag {
type: string;
index: number;
func?: string;
}

const mcus = await fs.promises.readdir("mcu");
const gpios = await mcus.reduce(async (prev, m) => ({ ...(await prev), [m]: YAML.parse(await fs.promises.readFile(path.join("mcu", m, "gpio.yaml"), "utf8")) }), {});
const dmas = await mcus.reduce(async (prev, m) => ({ ...(await prev), [m]: YAML.parse(await fs.promises.readFile(path.join("mcu", m, "dma.yaml"), "utf8")) }), {});

const MCU_MAP = {
at32f435m: "at32f435",
};

function mapMCU(mcu: string) {
if (MCU_MAP[mcu]) {
return MCU_MAP[mcu];
} else {
return mcu;
}
}

function assEqual(lhs: any, rhs: any): boolean {
const ignore = ["tag", "dev"]
return Object.keys(lhs).every(key => ignore.includes(key) || lhs[key] == rhs[key])
}
function assIncludes(array: any[], ass: device_tag) {
return array.find((e) => assEqual(e, ass))
}

function tagEqual(lhs: device_tag, rhs: device_tag): boolean {
if (lhs.func && rhs.func && lhs.func != rhs.func)
return false;
return lhs.type == rhs.type && lhs.index == rhs.index;
}
function tagIncludes(array: device_tag[], tag: device_tag) {
return array.find((e) => tagEqual(e, tag))
}

export function findDmaAssigments(target: target_t): target_t {
const mcu = mapMCU(target.mcu);
const dma = dmas[mcu];
const gpio = gpios[mcu];

if (!dma || !gpio) {
return target;
}

const dma_assigments = [] as any[];
const timer_assigments = [] as device_tag[];

let motor_timers = [{ type: "timer", index: 4 }, { type: "timer", index: 1 }]
if (mcu != "stm32f411") {
motor_timers.push({ type: "timer", index: 8 })
}

const stream_max = mcu == 'at32f435' ? 7 : 8;

let dma_count = 0;

function addTimer(dev: string, tag: device_tag) {
motor_timers = motor_timers.filter(t => !tagEqual(t, tag))
timer_assigments.push({ dev, ...tag } as any);
}

function addDmaAssigment(dev: string, tag: device_tag) {
const ass = dma.find(d => tagEqual(d.tag, tag) && !assIncludes(dma_assigments, d));
if (!ass) {
return false;
}

const port = ass.dma ? ass.dma.port : 1 + Math.floor(dma_count / stream_max);
const stream = ass.dma ? ass.dma.stream : dma_count % stream_max;
dma_count++;

dma_assigments.push({
dev,
...ass,
tag: `${tag.type}${tag.index}${tag.func ? '_' + tag.func : ''}`.toUpperCase(),
dma: `DMA${port}_STREAM${stream}`
});
return true;
}

function findTimers(dev: string, gpios: any[]) {
const entries = gpios.filter(g => g.tag.type == 'timer' && !tagIncludes(timer_assigments, g.tag))
// try to find a timer that is _not_ a motor timer
const timers = entries.filter(g => !tagIncludes(motor_timers, g.tag))
if (timers.length) {
return timers;
}
if (motor_timers.length == 1) {
console.warn("no non-motor timers found for", dev)
return [];
}
return entries;
}

if (target.rgb_led) {
const timers = findTimers("RGB", gpio[target.rgb_led]);
for (const timer of timers) {
if (addDmaAssigment("RGB", timer.tag)) {
addTimer("RGB", timer.tag);
break;
}
}
}

const motor_ports = target.motor_pins.map(p => p.slice(0, 2)).filter((v, i, a) => a.indexOf(v) === i);
const motor_timer = motor_timers[0];
if (!motor_timer) {
console.log(timer_assigments, dma_assigments);
throw new Error("no motor timer found!");
}
for (let i = 0; i < motor_ports.length; i++) {
const tag = { ...motor_timer, func: "ch" + (i + 1) };
addTimer("DSHOT", tag);
if (!addDmaAssigment("DSHOT_CH" + (i + 1), tag)) {
console.log(motor_timer, dma_assigments);
throw new Error("no motor dma found!");
}
}

for (const spi of target.spi_ports) {
const miso = gpio[spi.miso].filter(g => g.tag.type == 'spi' && g.tag.index == spi.index && g.tag.func == 'miso');
for (const m of miso) {
if (addDmaAssigment(`SPI${spi.index}_RX`, m.tag))
break;
}

const mosi = gpio[spi.mosi].filter(g => g.tag.type == 'spi' && g.tag.index == spi.index && g.tag.func == 'mosi');
for (const m of mosi) {
if (addDmaAssigment(`SPI${spi.index}_TX`, m.tag))
break;
}
}

const entries = {}
for (const ass of dma_assigments) {
const ignore = ["dev"]
entries[ass.dev] = Object.keys(ass).reduce((prev, curr) => {
if (!ignore.includes(curr))
prev[curr] = ass[curr];
return prev;
}, {});
}

return { ...target, dma: entries, timers: [] };
}

if (!module.parent) {
for await (const f of walk("targets")) {
console.log("processing ", f)

const target = YAML.parse(await fs.promises.readFile(f, "utf8")) as target_t;
await fs.promises.writeFile(f, stringifyTarget(findDmaAssigments(target)));
}
}
17 changes: 14 additions & 3 deletions src/translate.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from "fs";
import path from "path";
import { walk } from "./util";
import { GyroRotation, stringifyTarget, target_t } from "./types";
import { GyroRotation, skipEmpty, stringifyTarget, target_t } from "./types";
import { findDmaAssigments } from "./dma";

const OUTPUT_FOLDER = "staging";

Expand All @@ -22,6 +22,13 @@ const MCU_MAP = {
at32f435g: "at32f435",
};

const BLACKLIST = [
"nucleof722",
"nucleof446",
"atstartf435",
"revo_at"
];

function mapMCU(mcu: string) {
if (MCU_MAP[mcu]) {
return MCU_MAP[mcu];
Expand Down Expand Up @@ -286,12 +293,16 @@ async function translate(filename: string, output?: string) {
handle(target, parts);
}

if (BLACKLIST.includes(target.name)) {
return;
}

if (!output) {
output = `${OUTPUT_FOLDER}/${target.manufacturer.toLowerCase()}-${
target.name
}.yaml`;
}
await fs.promises.writeFile(output, stringifyTarget(target));
await fs.promises.writeFile(output, stringifyTarget(findDmaAssigments(skipEmpty(target))));
}

const args = process.argv.slice(2);
Expand Down
2 changes: 1 addition & 1 deletion src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function sortMapEntries(
return aIndex - bIndex;
}

function skipEmpty(val: any) {
export function skipEmpty(val: any) {
if (val === undefined) {
return undefined;
}
Expand Down
33 changes: 33 additions & 0 deletions staging/afng-alienflightf4.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,36 @@ motor_pins:
- PA1
- PB8
- PB9
dma:
DSHOT_CH1:
channel: 2
dma: DMA1_STREAM0
tag: TIMER4_CH1
DSHOT_CH2:
channel: 2
dma: DMA1_STREAM3
tag: TIMER4_CH2
SPI1_RX:
channel: 3
dma: DMA2_STREAM0
tag: SPI1_MISO
SPI1_TX:
channel: 3
dma: DMA2_STREAM3
tag: SPI1_MOSI
SPI2_RX:
channel: 0
dma: DMA1_STREAM3
tag: SPI2_MISO
SPI2_TX:
channel: 0
dma: DMA1_STREAM4
tag: SPI2_MOSI
SPI3_RX:
channel: 0
dma: DMA1_STREAM0
tag: SPI3_MISO
SPI3_TX:
channel: 0
dma: DMA1_STREAM5
tag: SPI3_MOSI
37 changes: 37 additions & 0 deletions staging/afng-alienflightngf7.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,40 @@ motor_pins:
- PB0
- PC6
- PC7
dma:
DSHOT_CH1:
channel: 2
dma: DMA1_STREAM0
tag: TIMER4_CH1
DSHOT_CH2:
channel: 2
dma: DMA1_STREAM3
tag: TIMER4_CH2
RGB:
channel: 6
dma: DMA2_STREAM1
tag: TIMER1_CH1
SPI1_RX:
channel: 3
dma: DMA2_STREAM0
tag: SPI1_MISO
SPI1_TX:
channel: 3
dma: DMA2_STREAM3
tag: SPI1_MOSI
SPI2_RX:
channel: 0
dma: DMA1_STREAM3
tag: SPI2_MISO
SPI2_TX:
channel: 0
dma: DMA1_STREAM4
tag: SPI2_MOSI
SPI3_RX:
channel: 0
dma: DMA1_STREAM0
tag: SPI3_MISO
SPI3_TX:
channel: 0
dma: DMA1_STREAM5
tag: SPI3_MOSI
37 changes: 37 additions & 0 deletions staging/afng-alienflightngf7_dual.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,40 @@ motor_pins:
- PB0
- PC6
- PC7
dma:
DSHOT_CH1:
channel: 2
dma: DMA1_STREAM0
tag: TIMER4_CH1
DSHOT_CH2:
channel: 2
dma: DMA1_STREAM3
tag: TIMER4_CH2
RGB:
channel: 6
dma: DMA2_STREAM1
tag: TIMER1_CH1
SPI1_RX:
channel: 3
dma: DMA2_STREAM0
tag: SPI1_MISO
SPI1_TX:
channel: 3
dma: DMA2_STREAM3
tag: SPI1_MOSI
SPI2_RX:
channel: 0
dma: DMA1_STREAM3
tag: SPI2_MISO
SPI2_TX:
channel: 0
dma: DMA1_STREAM4
tag: SPI2_MOSI
SPI3_RX:
channel: 0
dma: DMA1_STREAM0
tag: SPI3_MISO
SPI3_TX:
channel: 0
dma: DMA1_STREAM5
tag: SPI3_MOSI
37 changes: 37 additions & 0 deletions staging/afng-alienflightngf7_elrs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -55,3 +55,40 @@ motor_pins:
- PB0
- PC6
- PC7
dma:
DSHOT_CH1:
channel: 2
dma: DMA1_STREAM0
tag: TIMER4_CH1
DSHOT_CH2:
channel: 2
dma: DMA1_STREAM3
tag: TIMER4_CH2
RGB:
channel: 6
dma: DMA2_STREAM1
tag: TIMER1_CH1
SPI1_RX:
channel: 3
dma: DMA2_STREAM0
tag: SPI1_MISO
SPI1_TX:
channel: 3
dma: DMA2_STREAM3
tag: SPI1_MOSI
SPI2_RX:
channel: 0
dma: DMA1_STREAM3
tag: SPI2_MISO
SPI2_TX:
channel: 0
dma: DMA1_STREAM4
tag: SPI2_MOSI
SPI3_RX:
channel: 0
dma: DMA1_STREAM0
tag: SPI3_MISO
SPI3_TX:
channel: 0
dma: DMA1_STREAM5
tag: SPI3_MOSI
Loading

0 comments on commit 2d6d83d

Please sign in to comment.