diff --git a/script/device_gen.py b/script/device_gen.py index 16edee41d..069286654 100644 --- a/script/device_gen.py +++ b/script/device_gen.py @@ -1,7 +1,6 @@ import glob import hashlib -import yaml -import os +import re import modm_devices @@ -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", @@ -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") diff --git a/src/config/feature.h b/src/config/feature.h index 2df2bb06b..a7fb04ba9 100644 --- a/src/config/feature.h +++ b/src/config/feature.h @@ -6,6 +6,7 @@ #define USE_BLACKBOX #define USE_MAX7456 +#define USE_RGB_LED #define USE_MOTOR_DSHOT #define USE_MOTOR_PWM diff --git a/src/core/main.c b/src/core/main.c index 083ed6e6b..2d7fbaf0a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -79,7 +79,6 @@ __attribute__((__used__)) int main() { // setup filters early filter_global_init(); - timer_alloc_init(); pid_init(); // init some hardware things @@ -124,7 +123,7 @@ __attribute__((__used__)) int main() { rx_init(); vtx_init(); - rgb_init(); + rgb_led_init(); blackbox_init(); imu_init(); diff --git a/src/core/target.h b/src/core/target.h index a191d3c26..798087d94 100644 --- a/src/core/target.h +++ b/src/core/target.h @@ -186,6 +186,7 @@ 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; @@ -213,6 +214,7 @@ 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) \ diff --git a/src/core/tasks.c b/src/core/tasks.c index 8e12b8c98..784db0c03 100644 --- a/src/core/tasks.c +++ b/src/core/tasks.c @@ -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" @@ -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(); } diff --git a/src/driver/at32/dma.c b/src/driver/at32/dma.c index 5c8f71808..64e96aa11 100644 --- a/src/driver/at32/dma.c +++ b/src/driver/at32/dma.c @@ -1,50 +1,73 @@ #include "driver/dma.h" +#include "driver/adc.h" #include "driver/rcc.h" +#include "driver/resource.h" +#include "driver/timer.h" -#define DMAMUX_DMAREQ_ID_TIM1_CH1 DMAMUX_DMAREQ_ID_TMR1_CH1 -#define DMAMUX_DMAREQ_ID_TIM1_CH2 DMAMUX_DMAREQ_ID_TMR1_CH2 -#define DMAMUX_DMAREQ_ID_TIM1_CH3 DMAMUX_DMAREQ_ID_TMR1_CH3 -#define DMAMUX_DMAREQ_ID_TIM1_CH4 DMAMUX_DMAREQ_ID_TMR1_CH3 - -#define DMA_STREAMS \ - DMA_STREAM(1, 1, SPI1_RX) \ - DMA_STREAM(1, 2, SPI1_TX) \ - DMA_STREAM(1, 3, SPI2_RX) \ - DMA_STREAM(1, 4, SPI2_TX) \ - DMA_STREAM(1, 5, SPI3_RX) \ - DMA_STREAM(1, 6, SPI3_TX) \ - DMA_STREAM(2, 1, SPI4_RX) \ - DMA_STREAM(2, 2, SPI4_TX) \ - DMA_STREAM(2, 3, TIM1_CH1) \ - DMA_STREAM(2, 4, TIM1_CH3) \ - DMA_STREAM(2, 5, TIM1_CH4) - -#define DMA_STREAM(_port, _chan, _dev) \ - [DMA_DEVICE_##_dev] = { \ - .device = DMA_DEVICE_##_dev, \ +#define DMA_STREAM_MAX 14 + +#define DMA_STREAMS \ + DMA_STREAM(1, 1) \ + DMA_STREAM(1, 2) \ + DMA_STREAM(1, 3) \ + DMA_STREAM(1, 4) \ + DMA_STREAM(1, 5) \ + DMA_STREAM(1, 6) \ + DMA_STREAM(1, 7) \ + DMA_STREAM(2, 1) \ + DMA_STREAM(2, 2) \ + DMA_STREAM(2, 3) \ + DMA_STREAM(2, 4) \ + DMA_STREAM(2, 5) \ + DMA_STREAM(2, 6) \ + DMA_STREAM(2, 7) + +#define DMA_STREAM_INDEX(_port, _stream) ((_port - 1) * 7 + (_stream - 1)) +#define DMA_STREAM(_port, _chan) \ + { \ .port = DMA##_port, \ .port_index = _port, \ - .channel = DMA##_port##_CHANNEL##_chan, \ - .channel_index = _chan, \ - .request = DMAMUX_DMAREQ_ID_##_dev, \ + .stream = DMA##_port##_CHANNEL##_chan, \ + .stream_index = _chan, \ .mux = DMA##_port##MUX_CHANNEL##_chan, \ .irq = DMA##_port##_Channel##_chan##_IRQn, \ }, +static const dma_stream_def_t dma_stream_defs[DMA_STREAM_MAX] = {DMA_STREAMS}; +#undef DMA_STREAM -const dma_stream_def_t dma_stream_defs[DMA_DEVICE_MAX] = {DMA_STREAMS}; +static const dma_channel_t dma_channels[] = { +#include "dma.in" +}; +#define DMA_CHANNEL_MAX (sizeof(dma_channels) / sizeof(dma_channel_t)) -#undef DMA_STREAM +static dma_assigment_t dma_assigments[DMA_STREAM_MAX] = {}; -void dma_prepare_tx_memory(void *addr, uint32_t size) { -} +const dma_assigment_t *dma_alloc(dma_device_t dev, resource_tag_t tag) { + for (uint32_t i = 0; i < DMA_CHANNEL_MAX; i++) { + const dma_channel_t *chan = &dma_channels[i]; + if (chan->tag != tag) { + continue; + } -void dma_prepare_rx_memory(void *addr, uint32_t size) { + for (uint32_t j = 0; j < DMA_STREAM_MAX; j++) { + dma_assigment_t *ass = &dma_assigments[j]; + if (ass->dev != DMA_DEVICE_INVALID) { + continue; + } + + ass->dev = dev; + ass->chan = chan; + ass->def = &dma_stream_defs[j]; + return ass; + } + } + + return NULL; } -void dma_enable_rcc(dma_device_t dev) { - const dma_stream_def_t *dma = &dma_stream_defs[dev]; - switch (dma->port_index) { +void dma_enable_rcc(const dma_assigment_t *ass) { + switch (ass->def->port_index) { case 1: rcc_enable(RCC_ENCODE(DMA1)); dmamux_enable(DMA1, TRUE); @@ -56,37 +79,45 @@ void dma_enable_rcc(dma_device_t dev) { } } -extern void dshot_dma_isr(dma_device_t dev); -extern void spi_dma_isr(dma_device_t dev); +void dma_prepare_tx_memory(void *addr, uint32_t size) {} +void dma_prepare_rx_memory(void *addr, uint32_t size) {} + +extern void dshot_dma_isr(const dma_assigment_t *); +extern void spi_dma_isr(const dma_assigment_t *); +extern void rgb_dma_isr(const dma_assigment_t *); -static void handle_dma_stream_isr(dma_device_t dev) { - switch (dev) { +static void handle_dma_stream_isr(const dma_assigment_t *ass) { + switch (ass->dev) { case DMA_DEVICE_SPI1_RX: - case DMA_DEVICE_SPI2_RX: - case DMA_DEVICE_SPI3_RX: - case DMA_DEVICE_SPI4_RX: case DMA_DEVICE_SPI1_TX: + case DMA_DEVICE_SPI2_RX: case DMA_DEVICE_SPI2_TX: + case DMA_DEVICE_SPI3_RX: case DMA_DEVICE_SPI3_TX: + case DMA_DEVICE_SPI4_RX: case DMA_DEVICE_SPI4_TX: - spi_dma_isr(dev); + spi_dma_isr(ass); break; - case DMA_DEVICE_TIM1_CH1: - case DMA_DEVICE_TIM1_CH3: - case DMA_DEVICE_TIM1_CH4: + case DMA_DEVICE_DSHOT_CH1: + case DMA_DEVICE_DSHOT_CH2: + case DMA_DEVICE_DSHOT_CH3: #ifdef USE_MOTOR_DSHOT - dshot_dma_isr(dev); + dshot_dma_isr(ass); +#endif + break; + case DMA_DEVICE_RGB: +#ifdef USE_RGB_LED + rgb_dma_isr(ass); #endif break; + case DMA_DEVICE_INVALID: case DMA_DEVICE_MAX: break; } } -#define DMA_STREAM(_port, _chan, _dev) \ - void DMA##_port##_Channel##_chan##_IRQHandler() { \ - handle_dma_stream_isr(DMA_DEVICE_##_dev); \ - } +#define DMA_STREAM(_port, _stream) \ + void DMA##_port##_Channel##_stream##_IRQHandler() { handle_dma_stream_isr(&dma_assigments[DMA_STREAM_INDEX(_port, _stream)]); } DMA_STREAMS diff --git a/src/driver/at32/dma.h b/src/driver/at32/dma.h index 94e6b3c1c..295a6878f 100644 --- a/src/driver/at32/dma.h +++ b/src/driver/at32/dma.h @@ -5,8 +5,13 @@ #define DMA_HDT_FLAG ((uint32_t)0x00000004) #define DMA_DTERR_FLAG ((uint32_t)0x00000008) -// 4bits per channel -#define dma_flag_for_channel(dev, flags) ((dev->port_index == 2 ? 0x10000000 : 0x0) | ((flags) << ((dev->channel_index - 1) * 4))) +// 4bits per stream +#define dma_flag_for_stream(dev, flags) ((dev->port_index == 2 ? 0x10000000 : 0x0) | ((flags) << ((dev->stream_index - 1) * 4))) -#define dma_is_flag_active_tc(dev) (dma_flag_get(dma_flag_for_channel(dev, DMA_FDT_FLAG))) -#define dma_clear_flag_tc(dev) dma_flag_clear(dma_flag_for_channel(dev, DMA_FDT_FLAG | DMA_HDT_FLAG | DMA_DTERR_FLAG)) +#define dma_is_flag_active_tc(dev) (dma_flag_get(dma_flag_for_stream(dev, DMA_FDT_FLAG))) +#define dma_clear_flag_tc(dev) dma_flag_clear(dma_flag_for_stream(dev, DMA_FDT_FLAG | DMA_HDT_FLAG | DMA_DTERR_FLAG)) + +typedef struct { + uint32_t tag; + uint32_t request; +} dma_channel_t; \ No newline at end of file diff --git a/src/driver/at32/motor_dshot.c b/src/driver/at32/motor_dshot.c index 815ad3539..c2add49dd 100644 --- a/src/driver/at32/motor_dshot.c +++ b/src/driver/at32/motor_dshot.c @@ -2,6 +2,7 @@ #include +#include "core/failloop.h" #include "core/profile.h" #include "core/project.h" #include "driver/dma.h" @@ -11,22 +12,57 @@ #ifdef USE_MOTOR_DSHOT -extern volatile uint32_t dshot_dma_phase; extern uint16_t dshot_packet[MOTOR_PIN_MAX]; extern dshot_pin_t dshot_pins[MOTOR_PIN_MAX]; - -extern motor_direction_t motor_dir; +extern volatile uint32_t dshot_dma_phase; extern uint8_t dshot_gpio_port_count; extern dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT]; extern volatile DMA_RAM uint32_t port_dma_buffer[DSHOT_MAX_PORT_COUNT][DSHOT_DMA_BUFFER_SIZE]; -extern void dshot_init_motor_pin(uint32_t index); +static const resource_tag_t timers[] = { + TIMER_TAG(TIMER8, TIMER_CH1), + TIMER_TAG(TIMER8, TIMER_CH2), + TIMER_TAG(TIMER8, TIMER_CH3), + TIMER_TAG(TIMER8, TIMER_CH4), + TIMER_TAG(TIMER1, TIMER_CH1), + TIMER_TAG(TIMER1, TIMER_CH2), + TIMER_TAG(TIMER1, TIMER_CH3), + TIMER_TAG(TIMER1, TIMER_CH4), +}; +static const uint32_t timer_count = sizeof(timers) / sizeof(resource_tag_t); + extern const dshot_gpio_port_t *dshot_gpio_for_device(const dma_device_t dev); -static void dshot_init_gpio_port(dshot_gpio_port_t *port) { - dma_enable_rcc(port->dma_device); +void dshot_init_gpio_port(dshot_gpio_port_t *port) { + for (uint8_t i = 0; i < timer_count; i++) { + const resource_tag_t tag = timers[i]; + if (timer_alloc_tag(TIMER_USE_MOTOR_DSHOT, tag)) { + port->timer_tag = tag; + break; + } + } + if (port->timer_tag == 0) { + failloop(FAILLOOP_DMA); + } + + const dma_assigment_t *dma = port->dma_ass = dma_alloc(port->dma_device, port->timer_tag); + if (dma == NULL) { + failloop(FAILLOOP_DMA); + } + + const timer_channel_t ch = TIMER_TAG_CH(port->timer_tag); + const timer_index_t tim = TIMER_TAG_TIM(port->timer_tag); + const timer_def_t *def = &timer_defs[tim]; + + rcc_enable(def->rcc); + + // setup timer to 1/3 of the full bit time + tmr_base_init(def->instance, DSHOT_SYMBOL_TIME, 0); + tmr_clock_source_div_set(def->instance, TMR_CLOCK_DIV1); + tmr_cnt_dir_set(def->instance, TMR_COUNT_UP); + tmr_period_buffer_enable(def->instance, TRUE); tmr_output_config_type tim_oc_init; tmr_output_default_para_init(&tim_oc_init); @@ -34,13 +70,13 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { tim_oc_init.oc_idle_state = TRUE; tim_oc_init.oc_polarity = TMR_OUTPUT_ACTIVE_LOW; tim_oc_init.oc_output_state = TRUE; - tmr_output_channel_config(TMR1, timer_channel_val(port->timer_channel), &tim_oc_init); - tmr_output_channel_buffer_enable(TMR1, timer_channel_val(port->timer_channel), TRUE); + tmr_output_channel_config(def->instance, timer_channel_val(ch), &tim_oc_init); + tmr_output_channel_buffer_enable(def->instance, timer_channel_val(ch), TRUE); - const dma_stream_def_t *dma = &dma_stream_defs[port->dma_device]; + dma_enable_rcc(dma); - dma_reset(dma->channel); - dmamux_init(dma->mux, dma->request); + dma_reset(dma->def->stream); + dmamux_init(dma->def->mux, dma->chan->request); dma_init_type init; init.peripheral_base_addr = (uint32_t)(&port->gpio->scr); @@ -53,53 +89,26 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { init.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD; init.loop_mode_enable = FALSE; init.priority = DMA_PRIORITY_VERY_HIGH; - dma_init(dma->channel, &init); - dma_interrupt_enable(dma->channel, DMA_FDT_INT, TRUE); - - interrupt_enable(dma->irq, DMA_PRIORITY); -} - -void motor_dshot_init() { - dshot_gpio_port_count = 0; - - rcc_enable(RCC_ENCODE(TMR1)); - - // setup timer to 1/3 of the full bit time - tmr_base_init(TMR1, DSHOT_SYMBOL_TIME, 0); - tmr_clock_source_div_set(TMR1, TMR_CLOCK_DIV1); - tmr_cnt_dir_set(TMR1, TMR_COUNT_UP); - tmr_period_buffer_enable(TMR1, TRUE); - - for (uint32_t i = 0; i < MOTOR_PIN_MAX; i++) { - dshot_init_motor_pin(i); - } + dma_init(dma->def->stream, &init); + dma_interrupt_enable(dma->def->stream, DMA_FDT_INT, TRUE); - for (uint32_t j = 0; j < dshot_gpio_port_count; j++) { - dshot_init_gpio_port(&dshot_gpio_ports[j]); - - for (uint8_t i = 0; i < 16; i++) { - port_dma_buffer[j][i * 3 + 0] = dshot_gpio_ports[j].port_high; // start bit - port_dma_buffer[j][i * 3 + 1] = 0; // actual bit, set below - port_dma_buffer[j][i * 3 + 2] = dshot_gpio_ports[j].port_low; // return line to low - } - } + interrupt_enable(dma->def->irq, DMA_PRIORITY); - tmr_counter_enable(TMR1, TRUE); - motor_dir = MOTOR_FORWARD; + tmr_counter_enable(def->instance, TRUE); } void dshot_dma_setup_port(uint32_t index) { const dshot_gpio_port_t *port = &dshot_gpio_ports[index]; - const dma_stream_def_t *dma = &dma_stream_defs[port->dma_device]; + const dma_assigment_t *dma = port->dma_ass; - dma_clear_flag_tc(dma); + dma_clear_flag_tc(dma->def); - dma->channel->paddr = (uint32_t)(&port->gpio->scr); - dma->channel->maddr = (uint32_t)&port_dma_buffer[index][0]; - dma->channel->dtcnt = DSHOT_DMA_BUFFER_SIZE; + dma->def->stream->paddr = (uint32_t)(&port->gpio->scr); + dma->def->stream->maddr = (uint32_t)&port_dma_buffer[index][0]; + dma->def->stream->dtcnt = DSHOT_DMA_BUFFER_SIZE; - dma_channel_enable(dma->channel, TRUE); - timer_enable_dma_request(TIMER1, port->timer_channel, true); + dma_channel_enable(dma->def->stream, TRUE); + timer_enable_dma_request(TIMER_TAG_TIM(port->timer_tag), TIMER_TAG_CH(port->timer_tag), true); } void motor_dshot_wait_for_ready() { @@ -107,13 +116,12 @@ void motor_dshot_wait_for_ready() { __NOP(); } -void dshot_dma_isr(dma_device_t dev) { - const dma_stream_def_t *dma = &dma_stream_defs[dev]; - dma_clear_flag_tc(dma); - dma_channel_enable(dma->channel, FALSE); +void dshot_dma_isr(const dma_assigment_t *ass) { + dma_clear_flag_tc(ass->def); + dma_channel_enable(ass->def->stream, FALSE); - const dshot_gpio_port_t *port = dshot_gpio_for_device(dev); - timer_enable_dma_request(TIMER1, port->timer_channel, false); + const dshot_gpio_port_t *port = dshot_gpio_for_device(ass->dev); + timer_enable_dma_request(TIMER_TAG_TIM(port->timer_tag), TIMER_TAG_CH(port->timer_tag), false); dshot_dma_phase--; } diff --git a/src/driver/at32/motor_pwm.c b/src/driver/at32/motor_pwm.c index 2f0c45f34..a0d653172 100644 --- a/src/driver/at32/motor_pwm.c +++ b/src/driver/at32/motor_pwm.c @@ -54,6 +54,7 @@ void motor_pwm_init() { tmr_output_channel_config(def->instance, timer_channel_val(ch), &tim_oc_init); tmr_channel_value_set(def->instance, timer_channel_val(ch), 0); tmr_output_channel_buffer_enable(def->instance, timer_channel_val(ch), TRUE); + tmr_channel_enable(def->instance, timer_channel_val(ch), TRUE); tmr_output_enable(def->instance, TRUE); tmr_counter_enable(def->instance, TRUE); diff --git a/src/driver/at32/rgb_led.c b/src/driver/at32/rgb_led.c new file mode 100644 index 000000000..ef2101914 --- /dev/null +++ b/src/driver/at32/rgb_led.c @@ -0,0 +1,188 @@ +#include "driver/rgb_led.h" + +#include +#include + +#include "core/project.h" +#include "driver/dma.h" +#include "driver/gpio.h" +#include "driver/interrupt.h" +#include "driver/timer.h" + +#if defined(USE_RGB_LED) + +#define TIMER_HZ PWM_CLOCK_FREQ_HZ +#define TIMER_DIV ((PWM_CLOCK_FREQ_HZ / TIMER_HZ) - 1) + +#define RGB_BIT_TIME ((TIMER_HZ / 800000) - 1) +#define RGB_T0H_TIME ((RGB_BIT_TIME / 3) + 1) +#define RGB_T1H_TIME ((RGB_BIT_TIME / 3) * 2 + 1) + +#define RGB_BITS_LED 24 +#define RGB_BUFFER_SIZE (RGB_BITS_LED * RGB_LED_MAX + 40) + +static resource_tag_t timer_tag = 0; +static const dma_assigment_t *rgb_dma = NULL; + +static volatile bool rgb_dma_busy = false; +static DMA_RAM uint32_t rgb_timer_buffer[RGB_BUFFER_SIZE]; +static uint32_t rgb_timer_buffer_count = 0; + +static const gpio_af_t *rgb_led_find_af(gpio_pins_t pin) { + for (uint32_t j = 0; j < GPIO_AF_MAX; j++) { + const gpio_af_t *func = &gpio_pin_afs[j]; + if (func->pin != pin || + RESOURCE_TAG_TYPE(func->tag) != RESOURCE_TIM || + TIMER_TAG_CH(func->tag) == TIMER_CH1N || + TIMER_TAG_CH(func->tag) == TIMER_CH2N || + TIMER_TAG_CH(func->tag) == TIMER_CH3N || + TIMER_TAG_CH(func->tag) == TIMER_CH4N) { + continue; + } + + if (timer_alloc_tag(TIMER_USE_RGB_LED, func->tag)) { + return func; + } + } + + return NULL; +} + +void rgb_led_init() { + const gpio_pins_t pin = target.rgb_led; + if (pin == PIN_NONE) { + return; + } + + const gpio_af_t *func = rgb_led_find_af(pin); + if (func == NULL) { + return; + } + + timer_tag = func->tag; + rgb_dma = dma_alloc(DMA_DEVICE_RGB, timer_tag); + if (rgb_dma == NULL) { + return; + } + + gpio_config_t gpio_init; + gpio_init.mode = GPIO_ALTERNATE; + gpio_init.drive = GPIO_DRIVE_HIGH; + gpio_init.output = GPIO_PUSHPULL; + gpio_init.pull = GPIO_DOWN_PULL; + gpio_pin_init_af(pin, gpio_init, func->af); + + const timer_channel_t ch = TIMER_TAG_CH(func->tag); + const timer_index_t tim = TIMER_TAG_TIM(func->tag); + const timer_def_t *def = &timer_defs[tim]; + + rcc_enable(def->rcc); + + tmr_counter_enable(def->instance, FALSE); + + tmr_base_init(def->instance, RGB_BIT_TIME, TIMER_DIV); + tmr_cnt_dir_set(def->instance, TMR_COUNT_UP); + tmr_clock_source_div_set(def->instance, TMR_CLOCK_DIV1); + + tmr_output_config_type tim_oc_init; + tmr_output_default_para_init(&tim_oc_init); + tim_oc_init.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A; + tim_oc_init.oc_idle_state = FALSE; + tim_oc_init.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH; + tim_oc_init.oc_output_state = TRUE; + tmr_output_channel_config(def->instance, timer_channel_val(ch), &tim_oc_init); + + tmr_channel_value_set(def->instance, timer_channel_val(ch), 0); + tmr_output_channel_buffer_enable(def->instance, timer_channel_val(ch), TRUE); + tmr_channel_enable(def->instance, timer_channel_val(ch), TRUE); + + tmr_period_buffer_enable(def->instance, TRUE); + + dma_enable_rcc(rgb_dma); + dma_reset(rgb_dma->def->stream); + + dma_init_type init; + init.peripheral_base_addr = timer_channel_addr(def->instance, ch); + init.memory_base_addr = (uint32_t)rgb_timer_buffer; + init.direction = DMA_DIR_MEMORY_TO_PERIPHERAL; + init.buffer_size = RGB_BUFFER_SIZE; + init.peripheral_inc_enable = FALSE; + init.memory_inc_enable = TRUE; + init.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_WORD; + init.memory_data_width = DMA_MEMORY_DATA_WIDTH_WORD; + init.loop_mode_enable = FALSE; + init.priority = DMA_PRIORITY_MEDIUM; + dma_init(rgb_dma->def->stream, &init); + dmamux_init(rgb_dma->def->mux, rgb_dma->chan->request); + + interrupt_enable(rgb_dma->def->irq, DMA_PRIORITY); + + tmr_output_enable(def->instance, TRUE); +} + +bool rgb_led_busy() { + return rgb_dma == NULL || rgb_dma_busy; +} + +void rgb_led_set_value(uint32_t value, uint32_t count) { + if (rgb_led_busy()) { + return; + } + + uint32_t offset = 0; + for (uint32_t i = 0; i < 20; i++) { + rgb_timer_buffer[offset++] = 0; + } + for (uint32_t i = 0; i < count; i++) { + // rgb_led_value contains a (32bit) int that contains the RGB values in G R B format already + // Test each bit and assign the T1H or T0H depending on whether it is 1 or 0. + for (int32_t j = RGB_BITS_LED - 1; j >= 0; j--) { + rgb_timer_buffer[offset++] = ((value >> j) & 0x1) ? RGB_T1H_TIME : RGB_T0H_TIME; + } + } + for (uint32_t i = 0; i < 20; i++) { + rgb_timer_buffer[offset++] = 0; + } + rgb_timer_buffer_count = offset; +} + +void rgb_led_send() { + if (rgb_led_busy()) { + return; + } + + rgb_dma_busy = true; + + const timer_channel_t ch = TIMER_TAG_CH(timer_tag); + const timer_index_t tim = TIMER_TAG_TIM(timer_tag); + const timer_def_t *def = &timer_defs[tim]; + + dma_clear_flag_tc(rgb_dma->def); + dma_prepare_tx_memory((void *)rgb_timer_buffer, sizeof(rgb_timer_buffer)); + + rgb_dma->def->stream->paddr = timer_channel_addr(def->instance, ch); + rgb_dma->def->stream->maddr = (uint32_t)rgb_timer_buffer; + rgb_dma->def->stream->dtcnt = rgb_timer_buffer_count; + + dma_interrupt_enable(rgb_dma->def->stream, DMA_FDT_INT, TRUE); + + dma_channel_enable(rgb_dma->def->stream, TRUE); + timer_enable_dma_request(tim, ch, TRUE); + tmr_counter_enable(def->instance, TRUE); +} + +void rgb_dma_isr(const dma_assigment_t *ass) { + dma_clear_flag_tc(ass->def); + dma_channel_enable(ass->def->stream, FALSE); + + const uint8_t ch = TIMER_TAG_CH(timer_tag); + const uint8_t tim = TIMER_TAG_TIM(timer_tag); + const timer_def_t *def = &timer_defs[tim]; + + tmr_counter_enable(def->instance, FALSE); + timer_enable_dma_request(tim, ch, FALSE); + + rgb_dma_busy = false; +} + +#endif \ No newline at end of file diff --git a/src/driver/at32/spi.c b/src/driver/at32/spi.c index ecd2269c6..ba2e6e4d7 100644 --- a/src/driver/at32/spi.c +++ b/src/driver/at32/spi.c @@ -81,10 +81,10 @@ static uint32_t spi_find_divder(uint32_t clk_hz) { } static void spi_dma_init_rx(spi_ports_t port) { - const dma_stream_def_t *dma = &dma_stream_defs[PORT.dma_rx]; + const dma_assigment_t *dma = spi_dev[port].dma_rx; - dma_reset(dma->channel); - dmamux_init(dma->mux, dma->request); + dma_reset(dma->def->stream); + dmamux_init(dma->def->mux, dma->chan->request); dma_init_type init; init.peripheral_base_addr = (uint32_t)(&PORT.channel->dt); @@ -97,22 +97,14 @@ static void spi_dma_init_rx(spi_ports_t port) { init.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; init.loop_mode_enable = FALSE; init.priority = DMA_PRIORITY_HIGH; - dma_init(dma->channel, &init); -} - -static void spi_dma_reset_rx(spi_ports_t port, uint8_t *rx_data, uint32_t rx_size) { - dma_prepare_rx_memory(rx_data, rx_size); - - const dma_stream_def_t *dma = &dma_stream_defs[PORT.dma_rx]; - dma->channel->maddr = (uint32_t)rx_data; - dma_data_number_set(dma->channel, rx_size); + dma_init(dma->def->stream, &init); } static void spi_dma_init_tx(spi_ports_t port) { - const dma_stream_def_t *dma = &dma_stream_defs[PORT.dma_tx]; + const dma_assigment_t *dma = spi_dev[port].dma_tx; - dma_reset(dma->channel); - dmamux_init(dma->mux, dma->request); + dma_reset(dma->def->stream); + dmamux_init(dma->def->mux, dma->chan->request); dma_init_type init; init.peripheral_base_addr = (uint32_t)(&PORT.channel->dt); @@ -125,15 +117,7 @@ static void spi_dma_init_tx(spi_ports_t port) { init.memory_data_width = DMA_MEMORY_DATA_WIDTH_BYTE; init.loop_mode_enable = FALSE; init.priority = DMA_PRIORITY_HIGH; - dma_init(dma->channel, &init); -} - -static void spi_dma_reset_tx(spi_ports_t port, uint8_t *tx_data, uint32_t tx_size) { - dma_prepare_tx_memory(tx_data, tx_size); - - const dma_stream_def_t *dma = &dma_stream_defs[PORT.dma_tx]; - dma->channel->maddr = (uint32_t)tx_data; - dma_data_number_set(dma->channel, tx_size); + dma_init(dma->def->stream, &init); } static void spi_set_divider(spi_type *channel, spi_mclk_freq_div_type div) { @@ -186,20 +170,26 @@ void spi_reconfigure(spi_bus_device_t *bus) { } void spi_dma_transfer_begin(spi_ports_t port, uint8_t *buffer, uint32_t length) { - const dma_stream_def_t *dma_tx = &dma_stream_defs[PORT.dma_tx]; - const dma_stream_def_t *dma_rx = &dma_stream_defs[PORT.dma_rx]; + const dma_assigment_t *dma_tx = spi_dev[port].dma_tx; + const dma_assigment_t *dma_rx = spi_dev[port].dma_rx; + + dma_clear_flag_tc(dma_rx->def); + dma_clear_flag_tc(dma_tx->def); - dma_clear_flag_tc(dma_rx); - dma_clear_flag_tc(dma_tx); + dma_prepare_rx_memory(buffer, length); + dma_prepare_tx_memory(buffer, length); - spi_dma_reset_rx(port, buffer, length); - spi_dma_reset_tx(port, buffer, length); + dma_rx->def->stream->maddr = (uint32_t)buffer; + dma_data_number_set(dma_rx->def->stream, length); - dma_interrupt_enable(dma_rx->channel, DMA_FDT_INT, TRUE); - dma_interrupt_enable(dma_rx->channel, DMA_DTERR_INT, TRUE); + dma_tx->def->stream->maddr = (uint32_t)buffer; + dma_data_number_set(dma_tx->def->stream, length); - dma_channel_enable(dma_rx->channel, TRUE); - dma_channel_enable(dma_tx->channel, TRUE); + dma_interrupt_enable(dma_rx->def->stream, DMA_FDT_INT, TRUE); + dma_interrupt_enable(dma_rx->def->stream, DMA_DTERR_INT, TRUE); + + dma_channel_enable(dma_rx->def->stream, TRUE); + dma_channel_enable(dma_tx->def->stream, TRUE); spi_i2s_dma_transmitter_enable(PORT.channel, TRUE); spi_i2s_dma_receiver_enable(PORT.channel, TRUE); @@ -210,8 +200,9 @@ void spi_dma_transfer_begin(spi_ports_t port, uint8_t *buffer, uint32_t length) void spi_device_init(spi_ports_t port) { const spi_port_def_t *def = &spi_port_defs[port]; rcc_enable(def->rcc); - dma_enable_rcc(def->dma_rx); - dma_enable_rcc(def->dma_tx); + + dma_enable_rcc(spi_dev[port].dma_rx); + dma_enable_rcc(spi_dev[port].dma_tx); spi_i2s_reset(def->channel); @@ -233,8 +224,8 @@ void spi_device_init(spi_ports_t port) { spi_dma_init_rx(port); spi_dma_init_tx(port); - const dma_stream_def_t *dma_rx = &dma_stream_defs[def->dma_rx]; - interrupt_enable(dma_rx->irq, DMA_PRIORITY); + const dma_assigment_t *dma_rx = spi_dev[port].dma_rx; + interrupt_enable(dma_rx->def->irq, DMA_PRIORITY); } void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs, const uint32_t count) { @@ -289,32 +280,32 @@ void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs } static void handle_dma_rx_isr(spi_ports_t port) { - const dma_stream_def_t *dma_rx = &dma_stream_defs[PORT.dma_rx]; - const dma_stream_def_t *dma_tx = &dma_stream_defs[PORT.dma_tx]; + const dma_assigment_t *dma_tx = spi_dev[port].dma_tx; + const dma_assigment_t *dma_rx = spi_dev[port].dma_rx; - if (!dma_is_flag_active_tc(dma_rx)) { + if (!dma_is_flag_active_tc(dma_rx->def)) { return; } - dma_clear_flag_tc(dma_rx); - dma_clear_flag_tc(dma_tx); + dma_clear_flag_tc(dma_rx->def); + dma_clear_flag_tc(dma_tx->def); - dma_interrupt_enable(dma_rx->channel, DMA_FDT_INT, FALSE); - dma_interrupt_enable(dma_rx->channel, DMA_DTERR_INT, FALSE); + dma_interrupt_enable(dma_rx->def->stream, DMA_FDT_INT, FALSE); + dma_interrupt_enable(dma_rx->def->stream, DMA_DTERR_INT, FALSE); spi_i2s_dma_transmitter_enable(PORT.channel, FALSE); spi_i2s_dma_receiver_enable(PORT.channel, FALSE); - dma_channel_enable(dma_rx->channel, FALSE); - dma_channel_enable(dma_tx->channel, FALSE); + dma_channel_enable(dma_rx->def->stream, FALSE); + dma_channel_enable(dma_tx->def->stream, FALSE); spi_enable(PORT.channel, FALSE); spi_txn_finish(port); } -void spi_dma_isr(dma_device_t dev) { - switch (dev) { +void spi_dma_isr(const dma_assigment_t *ass) { + switch (ass->dev) { case DMA_DEVICE_SPI1_RX: handle_dma_rx_isr(SPI_PORT1); break; diff --git a/src/driver/at32/system.h b/src/driver/at32/system.h index 8e9a65176..df760fa2a 100644 --- a/src/driver/at32/system.h +++ b/src/driver/at32/system.h @@ -20,17 +20,13 @@ typedef tmr_type timer_dev_t; typedef usart_type usart_dev_t; typedef struct { - uint32_t device; - dma_type *port; uint8_t port_index; - dma_channel_type *channel; - uint8_t channel_index; + dma_channel_type *stream; + uint8_t stream_index; - uint32_t request; dmamux_channel_type *mux; - IRQn_Type irq; } dma_stream_def_t; diff --git a/src/driver/at32/timer.c b/src/driver/at32/timer.c index fd7ab6004..c29a96e6e 100644 --- a/src/driver/at32/timer.c +++ b/src/driver/at32/timer.c @@ -108,6 +108,24 @@ uint32_t timer_channel_val(timer_channel_t chan) { } } +uint32_t timer_channel_addr(timer_dev_t *timer, timer_channel_t chan) { + switch (chan) { + case TIMER_CH1: + case TIMER_CH1N: + return (uint32_t)(&timer->c1dt); + case TIMER_CH2: + case TIMER_CH2N: + return (uint32_t)(&timer->c2dt); + case TIMER_CH3: + case TIMER_CH3N: + return (uint32_t)(&timer->c3dt); + case TIMER_CH4: + return (uint32_t)(&timer->c4dt); + default: + return 0; + } +} + void timer_enable_dma_request(timer_index_t tim, timer_channel_t chan, bool state) { const timer_def_t *def = &timer_defs[tim]; diff --git a/src/driver/dma.h b/src/driver/dma.h index bb3b23c1c..31e429cff 100644 --- a/src/driver/dma.h +++ b/src/driver/dma.h @@ -3,11 +3,18 @@ #include #include "core/project.h" +#include "driver/resource.h" #define DMA_ALIGN_SIZE 32 #define DMA_ALIGN(offset) MEMORY_ALIGN(offset, DMA_ALIGN_SIZE) typedef enum { + DMA_DEVICE_INVALID, + + DMA_DEVICE_DSHOT_CH1, + DMA_DEVICE_DSHOT_CH2, + DMA_DEVICE_DSHOT_CH3, + DMA_DEVICE_SPI1_RX, DMA_DEVICE_SPI1_TX, DMA_DEVICE_SPI2_RX, @@ -16,16 +23,21 @@ typedef enum { DMA_DEVICE_SPI3_TX, DMA_DEVICE_SPI4_RX, DMA_DEVICE_SPI4_TX, - DMA_DEVICE_TIM1_CH1, - DMA_DEVICE_TIM1_CH3, - DMA_DEVICE_TIM1_CH4, + + DMA_DEVICE_RGB, DMA_DEVICE_MAX, } dma_device_t; -extern const dma_stream_def_t dma_stream_defs[DMA_DEVICE_MAX]; +typedef struct { + dma_device_t dev; + const dma_stream_def_t *def; + const dma_channel_t *chan; +} dma_assigment_t; + +const dma_assigment_t *dma_alloc(dma_device_t dev, resource_tag_t tag); void dma_prepare_tx_memory(void *addr, uint32_t size); void dma_prepare_rx_memory(void *addr, uint32_t size); -void dma_enable_rcc(dma_device_t dev); +void dma_enable_rcc(const dma_assigment_t *ass); diff --git a/src/driver/motor_dshot.c b/src/driver/motor_dshot.c index 8f1df301f..f8325e709 100644 --- a/src/driver/motor_dshot.c +++ b/src/driver/motor_dshot.c @@ -24,18 +24,9 @@ dshot_pin_t dshot_pins[MOTOR_PIN_MAX]; uint8_t dshot_gpio_port_count = 0; dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT] = { - { - .timer_channel = TIMER_CH1, - .dma_device = DMA_DEVICE_TIM1_CH1, - }, - { - .timer_channel = TIMER_CH3, - .dma_device = DMA_DEVICE_TIM1_CH3, - }, - { - .timer_channel = TIMER_CH4, - .dma_device = DMA_DEVICE_TIM1_CH4, - }, + {.dma_device = DMA_DEVICE_DSHOT_CH1}, + {.dma_device = DMA_DEVICE_DSHOT_CH2}, + {.dma_device = DMA_DEVICE_DSHOT_CH3}, }; motor_direction_t motor_dir = MOTOR_FORWARD; @@ -44,9 +35,10 @@ static bool dir_change_done = true; volatile DMA_RAM uint32_t port_dma_buffer[DSHOT_MAX_PORT_COUNT][DSHOT_DMA_BUFFER_SIZE]; extern void dshot_dma_setup_port(uint32_t index); +extern void dshot_init_gpio_port(dshot_gpio_port_t *port); const dshot_gpio_port_t *dshot_gpio_for_device(const dma_device_t dev) { - return &dshot_gpio_ports[dev - DMA_DEVICE_TIM1_CH1]; + return &dshot_gpio_ports[dev - DMA_DEVICE_DSHOT_CH1]; } void dshot_init_motor_pin(uint32_t index) { @@ -134,6 +126,26 @@ void dshot_dma_start() { } } +void motor_dshot_init() { + dshot_gpio_port_count = 0; + + for (uint32_t i = 0; i < MOTOR_PIN_MAX; i++) { + dshot_init_motor_pin(i); + } + + for (uint32_t j = 0; j < dshot_gpio_port_count; j++) { + dshot_init_gpio_port(&dshot_gpio_ports[j]); + + for (uint8_t i = 0; i < 16; i++) { + port_dma_buffer[j][i * 3 + 0] = dshot_gpio_ports[j].port_high; // start bit + port_dma_buffer[j][i * 3 + 1] = 0; // actual bit, set below + port_dma_buffer[j][i * 3 + 2] = dshot_gpio_ports[j].port_low; // return line to low + } + } + + motor_dir = MOTOR_FORWARD; +} + void motor_dshot_write(float *values) { if (dir_change_done) { for (uint32_t i = 0; i < MOTOR_PIN_MAX; i++) { diff --git a/src/driver/motor_dshot.h b/src/driver/motor_dshot.h index a034ad621..b9106067d 100644 --- a/src/driver/motor_dshot.h +++ b/src/driver/motor_dshot.h @@ -1,5 +1,6 @@ #pragma once +#include "core/project.h" #include "driver/dma.h" #include "driver/gpio.h" #include "driver/motor.h" @@ -17,8 +18,10 @@ typedef struct { uint32_t port_low; // motor pins for BSRRL, for setting pins low uint32_t port_high; // motor pins for BSRRH, for setting pins high - timer_channel_t timer_channel; + resource_tag_t timer_tag; + dma_device_t dma_device; + const dma_assigment_t *dma_ass; } dshot_gpio_port_t; #define DSHOT_CMD_BEEP1 1 @@ -37,4 +40,4 @@ typedef struct { #define DSHOT_SYMBOL_TIME (PWM_CLOCK_FREQ_HZ / (3 * DSHOT_TIME * 1000) - 1) #define DSHOT_MAX_PORT_COUNT 3 -#define DSHOT_DMA_BUFFER_SIZE (3 * 16) \ No newline at end of file +#define DSHOT_DMA_BUFFER_SIZE (3 * 16) diff --git a/src/driver/rgb_led.c b/src/driver/rgb_led.c deleted file mode 100644 index 2456e1d03..000000000 --- a/src/driver/rgb_led.c +++ /dev/null @@ -1,347 +0,0 @@ -//**********************************************WARNING - THIS FILE NOT YET PORTED FROM F0 SILVERWARE*********************************** - -#include "driver/rgb_led.h" - -#include "core/project.h" -#include "driver/spi.h" -#include "driver/time.h" -#include "util/util.h" - -#if (RGB_LED_NUMBER > 0) -void rgb_send(int data); - -#ifdef RGB_LED_DMA - -#define RGB_BIT_TIME ((SYS_CLOCK_FREQ_HZ / 1000 / 800) - 1) -#define RGB_T0H_TIME (RGB_BIT_TIME * 0.30 + 0.05) -#define RGB_T1H_TIME (RGB_BIT_TIME * 0.60 + 0.05) - -extern int rgb_led_value[]; - -volatile int rgb_dma_phase = 0; // 3:rgb data ready - // 2:rgb dma buffer ready - -// wait to be cascaded after dshot, or fired at next frame if no dshot activity -// 1:rgb dma busy -// 0:idle - -const int offset = RGB_PIN > LL_GPIO_PIN_7; - -volatile uint32_t rgb_data_portA[RGB_LED_NUMBER * 24 / 4] = {0}; // DMA buffer: reset output when bit data=0 at TOH timing -volatile uint16_t rgb_portX[1] = {RGB_PIN}; // sum of all rgb pins at port -volatile uint32_t RGB_DATA16[16]; // 4-bit look-up table for dma buffer making - -void rgb_init() { - if ((RGB_PIN == LL_GPIO_PIN_13 || RGB_PIN == LL_GPIO_PIN_14) && RGB_PORT == GPIOA) { - // programming port used - // wait until 2 seconds from powerup passed - while (time_micros() < 2e6) - ; - } - - gpio_config_t GPIO_InitStructure; - - GPIO_InitStructure.mode = GPIO_OUTPUT; - GPIO_InitStructure.output = GPIO_PUSHPULL; - GPIO_InitStructure.pull = GPIO_NO_PULL; - GPIO_InitStructure.drive =GPIO_DRIVE_HIGH; - - GPIO_InitStructure.Pin = RGB_PIN; - LL_GPIO_Init(RGB_PORT, &GPIO_InitStructure); - -#ifndef USE_DSHOT_DMA_DRIVER - // RGB timer/DMA init - // TIM1_UP DMA_CH5: set all output to HIGH at TIM1 update - // TIM1_CH1 DMA_CH2: reset output if data=0 at T0H timing - // TIM1_CH4 DMA_CH4: reset all output at T1H timing - - TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; - TIM_OCInitTypeDef TIM_OCInitStructure; - - TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); - TIM_OCStructInit(&TIM_OCInitStructure); - // TIM1 Periph clock enable - RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); - - /* Time base configuration */ - TIM_TimeBaseStructure.TIM_Period = RGB_BIT_TIME; - TIM_TimeBaseStructure.TIM_Prescaler = 0; - TIM_TimeBaseStructure.TIM_ClockDivision = 0; - TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; - TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure); - TIM_ARRPreloadConfig(TIM1, DISABLE); - - /* Timing Mode configuration: Channel 1 */ - TIM_OCInitStructure.OCMode = LL_TIM_OCMODE_FROZEN; - TIM_OCInitStructure.OCState = LL_TIM_OCSTATE_DISABLE; - TIM_OCInitStructure.CompareValue = RGB_T0H_TIME; - LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH1, &TIM_OCInitStructure); - LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH1); - - /* Timing Mode configuration: Channel 4 */ - TIM_OCInitStructure.OCMode = LL_TIM_OCMODE_FROZEN; - TIM_OCInitStructure.OCState = LL_TIM_OCSTATE_DISABLE; - TIM_OCInitStructure.CompareValue = RGB_T1H_TIME; - LL_TIM_OC_Init(TIM1, LL_TIM_CHANNEL_CH4, &TIM_OCInitStructure); - LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH4); - - LL_LL_DMA_InitTypeDef DMA_InitStructure; - - LL_DMA_StructInit(&DMA_InitStructure); - RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); - - /* DMA1 Channe5 configuration ----------------------------------------------*/ - LL_DMA_DeInit(DMA1_Channel3); - DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&RGB_PORT->BSRR; - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rgb_portX; - DMA_InitStructure.Direction = DMA_DIR_PeripheralDST; - DMA_InitStructure.NbData = RGB_LED_NUMBER * 24; - DMA_InitStructure.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - DMA_InitStructure.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT; - DMA_InitStructure.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD; - DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD; - DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; - DMA_InitStructure.Priority = LL_DMA_PRIORITY_HIGH; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(DMA1_Channel5, &DMA_InitStructure); - - /* DMA1 Channel2 configuration ----------------------------------------------*/ - LL_DMA_DeInit(DMA1_Channel2); - DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&RGB_PORT->BRR + offset; - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rgb_data_portA; - DMA_InitStructure.Direction = DMA_DIR_PeripheralDST; - DMA_InitStructure.NbData = RGB_LED_NUMBER * 24; - DMA_InitStructure.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - DMA_InitStructure.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; - DMA_InitStructure.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_BYTE; - DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_BYTE; - DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; - DMA_InitStructure.Priority = LL_DMA_PRIORITY_HIGH; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(DMA1_Channel2, &DMA_InitStructure); - - /* DMA1 Channel4 configuration ----------------------------------------------*/ - LL_DMA_DeInit(DMA1_Channel4); - DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&RGB_PORT->BRR; - DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)rgb_portX; - DMA_InitStructure.Direction = DMA_DIR_PeripheralDST; - DMA_InitStructure.NbData = RGB_LED_NUMBER * 24; - DMA_InitStructure.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; - DMA_InitStructure.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_NOINCREMENT; - DMA_InitStructure.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_HALFWORD; - DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_HALFWORD; - DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; - DMA_InitStructure.Priority = LL_DMA_PRIORITY_HIGH; - DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; - DMA_Init(DMA1_Channel4, &DMA_InitStructure); - - TIM_DMACmd(TIM1, TIM_DMA_Update | TIM_DMA_CC4 | TIM_DMA_CC1, ENABLE); - - NVIC_InitTypeDef NVIC_InitStructure; - /* configure DMA1 Channel4 interrupt */ - NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel4_5_IRQn; - NVIC_InitStructure.NVIC_IRQChannelPriority = (uint8_t)LL_DMA_PRIORITY_HIGH; - NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - NVIC_Init(&NVIC_InitStructure); - /* enable DMA1 Channel4 transfer complete interrupt */ - DMA_ITConfig(DMA1_Channel4, DMA_IT_TC, ENABLE); -#endif - - for (int i = 0; i < RGB_LED_NUMBER; i++) { - rgb_led_value[i] = 0; - } - if (!rgb_dma_phase) - rgb_dma_phase = 3; - - int pin = rgb_portX[0]; - - if (offset) { - pin >>= 8; - } - - for (int i = 0; i < 16; i++) { - RGB_DATA16[i] = (i & 0x01) ? 0 : pin; - RGB_DATA16[i] <<= 8; - RGB_DATA16[i] |= (i & 0x02) ? 0 : pin; - RGB_DATA16[i] <<= 8; - RGB_DATA16[i] |= (i & 0x04) ? 0 : pin; - RGB_DATA16[i] <<= 8; - RGB_DATA16[i] |= (i & 0x08) ? 0 : pin; - } -} - -void rgb_dma_buffer_making() { - // generate rgb dma packet - int j = 0; - for (int n = 0; n < RGB_LED_NUMBER; n++) { - rgb_data_portA[j++] = RGB_DATA16[(rgb_led_value[n] >> 20) & 0x0f]; - rgb_data_portA[j++] = RGB_DATA16[(rgb_led_value[n] >> 16) & 0x0f]; - rgb_data_portA[j++] = RGB_DATA16[(rgb_led_value[n] >> 12) & 0x0f]; - rgb_data_portA[j++] = RGB_DATA16[(rgb_led_value[n] >> 8) & 0x0f]; - rgb_data_portA[j++] = RGB_DATA16[(rgb_led_value[n] >> 4) & 0x0f]; - rgb_data_portA[j++] = RGB_DATA16[(rgb_led_value[n]) & 0x0f]; - } -} - -void rgb_dma_trigger() { - TIM1->ARR = RGB_BIT_TIME; - TIM1->CCR1 = RGB_T0H_TIME; - TIM1->CCR4 = RGB_T1H_TIME; - - DMA1_Channel5->CPAR = (uint32_t)&RGB_PORT->BSRR; - DMA1_Channel5->CMAR = (uint32_t)rgb_portX; - DMA1_Channel2->CPAR = (uint32_t)&RGB_PORT->BRR + offset; - DMA1_Channel2->CMAR = (uint32_t)rgb_data_portA; - DMA1_Channel4->CPAR = (uint32_t)&RGB_PORT->BRR; - DMA1_Channel4->CMAR = (uint32_t)rgb_portX; - - DMA1_Channel2->CCR &= ~(DMA_CCR_MSIZE_0 | DMA_CCR_MSIZE_1 | DMA_CCR_PSIZE_0 | DMA_CCR_PSIZE_1); // switch from halfword to byte - - DMA_ClearFlag(DMA1_FLAG_GL2 | DMA1_FLAG_GL4 | DMA1_FLAG_GL5); - - DMA1_Channel5->CNDTR = RGB_LED_NUMBER * 24; - DMA1_Channel2->CNDTR = RGB_LED_NUMBER * 24; - DMA1_Channel4->CNDTR = RGB_LED_NUMBER * 24; - - TIM1->SR = 0; - - DMA_Cmd(DMA1_Channel2, ENABLE); - DMA_Cmd(DMA1_Channel4, ENABLE); - DMA_Cmd(DMA1_Channel5, ENABLE); - - TIM_DMACmd(TIM1, TIM_DMA_Update | TIM_DMA_CC4 | TIM_DMA_CC1, ENABLE); - - TIM_SetCounter(TIM1, RGB_BIT_TIME); - TIM_Cmd(TIM1, ENABLE); -} - -void rgb_dma_start() { - if (rgb_dma_phase <= 1) - return; - - if (rgb_dma_phase == 3) { - rgb_dma_buffer_making(); - rgb_dma_phase = 2; - return; - } - -#ifdef USE_DSHOT_DMA_DRIVER - extern int dshot_dma_phase; - if (dshot_dma_phase) - return; -#endif - - rgb_dma_phase = 1; - rgb_dma_trigger(); -} - -void rgb_send(int data) { - if (!rgb_dma_phase) - rgb_dma_phase = 3; -} - -// if dshot dma is used the routine is in that file -#if !defined(USE_DSHOT_DMA_DRIVER) && defined(RGB_LED_DMA) && (RGB_LED_NUMBER > 0) - -void DMA1_Channel4_5_IRQHandler() { - DMA_Cmd(DMA1_Channel5, DISABLE); - DMA_Cmd(DMA1_Channel2, DISABLE); - DMA_Cmd(DMA1_Channel4, DISABLE); - - TIM_DMACmd(TIM1, TIM_DMA_Update | TIM_DMA_CC4 | TIM_DMA_CC1, DISABLE); - DMA_ClearITPendingBit(DMA1_IT_TC4); - TIM_Cmd(TIM1, DISABLE); - - rgb_dma_phase = 0; -} -#endif - -#else - -// sets all leds to a brightness -void rgb_init() { - // spi port inits - - if ((RGB_PIN == LL_GPIO_PIN_13 || RGB_PIN == LL_GPIO_PIN_14) && RGB_PORT == GPIOA) { - // programming port used - - // wait until 2 seconds from powerup passed - while (time_micros() < 2e6) - ; - } - - gpio_config_t GPIO_InitStructure; - - GPIO_InitStructure.mode = GPIO_OUTPUT; - GPIO_InitStructure.output = GPIO_PUSHPULL; - GPIO_InitStructure.pull = GPIO_UP_PULL; - GPIO_InitStructure.drive =GPIO_DRIVE_HIGH; - - GPIO_InitStructure.Pin = RGB_PIN; - LL_GPIO_Init(RGB_PORT, &GPIO_InitStructure); - - for (int i = 0; i < RGB_LED_NUMBER; i++) { - rgb_send(0); - } -} - -#define RGBHIGH gpioset(RGB_PORT, RGB_PIN) -#define RGBLOW gpioreset(RGB_PORT, RGB_PIN); - -#pragma push - -#pragma Otime -#pragma O2 - -void delay1a() { - uint8_t count = 2; - while (count--) - ; -} - -void delay1b() { - uint8_t count = 2; - while (count--) - ; -} - -void delay2a() { - uint8_t count = 1; - while (count--) - ; -} - -void delay2b() { - uint8_t count = 3; - while (count--) - ; -} - -void rgb_send(int data) { - for (int i = 23; i >= 0; i--) { - if ((data >> i) & 1) { - RGBHIGH; - delay1a(); - RGBLOW; - delay1b(); - } else { - RGBHIGH; - delay2a(); - RGBLOW; - delay2b(); - } - } -} -#pragma pop - -#endif - -#else -// rgb led not found -// some dummy headers just in case -void rgb_init() { -} - -void rgb_send(int data) { -} -#endif diff --git a/src/driver/rgb_led.h b/src/driver/rgb_led.h index ded3d5ec5..a52dba850 100644 --- a/src/driver/rgb_led.h +++ b/src/driver/rgb_led.h @@ -1,6 +1,11 @@ #pragma once -void rgb_init(); -void rgb_send(int data); +#include +#include -void rgb_dma_start(); \ No newline at end of file +#define RGB_LED_MAX 32 + +void rgb_led_init(); +void rgb_led_set_value(uint32_t value, uint32_t count); +void rgb_led_send(); +bool rgb_led_busy(); \ No newline at end of file diff --git a/src/driver/spi.c b/src/driver/spi.c index 5172bf5c1..fdcec4a9c 100644 --- a/src/driver/spi.c +++ b/src/driver/spi.c @@ -231,6 +231,18 @@ void spi_bus_device_init(const spi_bus_device_t *bus) { return; } + const spi_port_def_t *def = &spi_port_defs[bus->port]; + + spi_dev[bus->port].dma_rx = dma_alloc(def->dma_rx, SPI_TAG(bus->port, RES_SPI_MISO)); + if (spi_dev[bus->port].dma_rx == NULL) { + failloop(FAILLOOP_DMA); + } + + spi_dev[bus->port].dma_tx = dma_alloc(def->dma_tx, SPI_TAG(bus->port, RES_SPI_MOSI)); + if (spi_dev[bus->port].dma_tx == NULL) { + failloop(FAILLOOP_DMA); + } + spi_init_pins(bus->port); spi_device_init(bus->port); spi_dev[bus->port].is_init = true; diff --git a/src/driver/spi.h b/src/driver/spi.h index e93a8f023..7a3247288 100644 --- a/src/driver/spi.h +++ b/src/driver/spi.h @@ -106,6 +106,9 @@ typedef struct { bool is_init; volatile bool dma_done; + const dma_assigment_t *dma_rx; + const dma_assigment_t *dma_tx; + // only modified by the main loop volatile uint8_t txn_head; // only modified by the intterupt or protected code diff --git a/src/driver/stm32/dma.c b/src/driver/stm32/dma.c index 13e7af8fe..92049137e 100644 --- a/src/driver/stm32/dma.c +++ b/src/driver/stm32/dma.c @@ -1,102 +1,111 @@ #include "driver/dma.h" +#include "driver/adc.h" #include "driver/rcc.h" +#include "driver/resource.h" +#include "driver/timer.h" -#if !defined(STM32G4) -// DMA1 Stream0 SPI3_RX -// DMA1 Stream1 -// DMA1 Stream2 -// DMA1 Stream3 SPI2_RX -// DMA1 Stream4 SPI2_TX -// DMA1 Stream5 -// DMA1 Stream6 -// DMA1 Stream7 SPI3_TX - -// DMA2 Stream0 SPI4_RX -// DMA2 Stream1 SPI4_TX -// DMA2 Stream2 SPI1_RX -// DMA2 Stream3 TIM1_CH1 -// DMA2 Stream4 TIM1_CH4 -// DMA2 Stream5 SPI1_TX -// DMA2 Stream6 TIM1_CH3 -// DMA2 Stream7 - -#define DMA_STREAMS \ - DMA_STREAM(2, 3, 2, SPI1_RX) \ - DMA_STREAM(2, 3, 5, SPI1_TX) \ - DMA_STREAM(1, 0, 3, SPI2_RX) \ - DMA_STREAM(1, 0, 4, SPI2_TX) \ - DMA_STREAM(1, 0, 0, SPI3_RX) \ - DMA_STREAM(1, 0, 7, SPI3_TX) \ - DMA_STREAM(2, 4, 0, SPI4_RX) \ - DMA_STREAM(2, 4, 1, SPI4_TX) \ - DMA_STREAM(2, 6, 3, TIM1_CH1) \ - DMA_STREAM(2, 6, 6, TIM1_CH3) \ - DMA_STREAM(2, 6, 4, TIM1_CH4) -#else -#define DMA_STREAMS \ - DMA_STREAM(1, 0, 1, SPI1_RX) \ - DMA_STREAM(1, 0, 2, SPI1_TX) \ - DMA_STREAM(1, 0, 3, SPI2_RX) \ - DMA_STREAM(1, 0, 4, SPI2_TX) \ - DMA_STREAM(1, 0, 5, SPI3_RX) \ - DMA_STREAM(1, 0, 6, SPI3_TX) \ - DMA_STREAM(1, 0, 7, SPI4_RX) \ - DMA_STREAM(1, 0, 8, SPI4_TX) \ - DMA_STREAM(2, 0, 1, TIM1_CH1) \ - DMA_STREAM(2, 0, 2, TIM1_CH3) \ - DMA_STREAM(2, 0, 3, TIM1_CH4) +#define DMA_STREAM_MAX 16 + +#if defined(STM32F7) || defined(STM32H7) +#define CACHE_LINE_SIZE 32 +#define CACHE_LINE_MASK (CACHE_LINE_SIZE - 1) #endif #if defined(STM32G4) -#define DMA_STREAM(_port, _chan, _stream, _dev) \ - [DMA_DEVICE_##_dev] = { \ - .device = DMA_DEVICE_##_dev, \ +#define DMA_STREAMS \ + DMA_STREAM(1, 1) \ + DMA_STREAM(1, 2) \ + DMA_STREAM(1, 3) \ + DMA_STREAM(1, 4) \ + DMA_STREAM(1, 5) \ + DMA_STREAM(1, 6) \ + DMA_STREAM(1, 7) \ + DMA_STREAM(1, 8) \ + DMA_STREAM(2, 1) \ + DMA_STREAM(2, 2) \ + DMA_STREAM(2, 3) \ + DMA_STREAM(2, 4) \ + DMA_STREAM(2, 5) \ + DMA_STREAM(2, 6) \ + DMA_STREAM(2, 7) \ + DMA_STREAM(2, 8) +#define DMA_STREAM_INDEX(_port, _stream) ((_port - 1) * 8 + _stream - 1) +#define DMA_STREAM(_port, _stream) \ + { \ .port = DMA##_port, \ .port_index = _port, \ - .channel = 0, \ - .channel_index = 0, \ - .request = LL_DMAMUX_REQ_##_dev, \ .stream = DMA##_port##_Channel##_stream, \ .stream_index = LL_DMA_CHANNEL_##_stream, \ .irq = DMA##_port##_Channel##_stream##_IRQn, \ }, -#elif defined(STM32H7) -#define DMA_STREAM(_port, _chan, _stream, _dev) \ - [DMA_DEVICE_##_dev] = { \ - .device = DMA_DEVICE_##_dev, \ - .port = DMA##_port, \ - .port_index = _port, \ - .channel = -1, \ - .channel_index = -1, \ - .request = LL_DMAMUX1_REQ_##_dev, \ - .stream = DMA##_port##_Stream##_stream, \ - .stream_index = LL_DMA_STREAM_##_stream, \ - .irq = DMA##_port##_Stream##_stream##_IRQn, \ - }, #else -#define DMA_STREAM(_port, _chan, _stream, _dev) \ - [DMA_DEVICE_##_dev] = { \ - .device = DMA_DEVICE_##_dev, \ +#define DMA_STREAMS \ + DMA_STREAM(1, 0) \ + DMA_STREAM(1, 1) \ + DMA_STREAM(1, 2) \ + DMA_STREAM(1, 3) \ + DMA_STREAM(1, 4) \ + DMA_STREAM(1, 5) \ + DMA_STREAM(1, 6) \ + DMA_STREAM(1, 7) \ + DMA_STREAM(2, 0) \ + DMA_STREAM(2, 1) \ + DMA_STREAM(2, 2) \ + DMA_STREAM(2, 3) \ + DMA_STREAM(2, 4) \ + DMA_STREAM(2, 5) \ + DMA_STREAM(2, 6) \ + DMA_STREAM(2, 7) +#define DMA_STREAM_INDEX(_port, _stream) ((_port - 1) * 8 + _stream) +#define DMA_STREAM(_port, _stream) \ + { \ .port = DMA##_port, \ .port_index = _port, \ - .channel = LL_DMA_CHANNEL_##_chan, \ - .channel_index = _chan, \ - .request = -1, \ .stream = DMA##_port##_Stream##_stream, \ .stream_index = LL_DMA_STREAM_##_stream, \ .irq = DMA##_port##_Stream##_stream##_IRQn, \ }, #endif +static const dma_stream_def_t dma_stream_defs[DMA_STREAM_MAX] = {DMA_STREAMS}; +#undef DMA_STREAM -const dma_stream_def_t dma_stream_defs[DMA_DEVICE_MAX] = {DMA_STREAMS}; +static const dma_channel_t dma_channels[] = { +#include "dma.in" +}; +#define DMA_CHANNEL_MAX (sizeof(dma_channels) / sizeof(dma_channel_t)) -#undef DMA_STREAM +static dma_assigment_t dma_assigments[DMA_STREAM_MAX] = {}; -#if defined(STM32F7) || defined(STM32H7) -#define CACHE_LINE_SIZE 32 -#define CACHE_LINE_MASK (CACHE_LINE_SIZE - 1) +const dma_assigment_t *dma_alloc(dma_device_t dev, resource_tag_t tag) { + for (uint32_t i = 0; i < DMA_CHANNEL_MAX; i++) { + const dma_channel_t *chan = &dma_channels[i]; + if (chan->tag != tag) { + continue; + } + +#if defined(STM32H7) || defined(STM32G4) + const uint32_t start = 0; + const uint32_t max = DMA_STREAM_MAX; +#else + const uint32_t start = chan->port_index == -1 ? 0 : ((chan->port_index - 1) * 8 + chan->stream_index); + const uint32_t max = chan->port_index == -1 ? DMA_STREAM_MAX : start + 1; #endif + for (uint32_t j = start; j < max; j++) { + dma_assigment_t *ass = &dma_assigments[j]; + if (ass->dev != DMA_DEVICE_INVALID) { + continue; + } + + ass->dev = dev; + ass->chan = chan; + ass->def = &dma_stream_defs[j]; + return ass; + } + } + + return NULL; +} void dma_prepare_tx_memory(void *addr, uint32_t size) { #if defined(STM32F7) || defined(STM32H7) @@ -114,13 +123,12 @@ void dma_prepare_rx_memory(void *addr, uint32_t size) { #endif } -void dma_enable_rcc(dma_device_t dev) { +void dma_enable_rcc(const dma_assigment_t *ass) { #ifdef STM32G4 rcc_enable(RCC_AHB1_GRP1(DMAMUX1)); #endif - const dma_stream_def_t *dma = &dma_stream_defs[dev]; - switch (dma->port_index) { + switch (ass->def->port_index) { case 1: rcc_enable(RCC_AHB1_GRP1(DMA1)); break; @@ -130,11 +138,12 @@ void dma_enable_rcc(dma_device_t dev) { } } -extern void dshot_dma_isr(dma_device_t dev); -extern void spi_dma_isr(dma_device_t dev); +extern void dshot_dma_isr(const dma_assigment_t *ass); +extern void spi_dma_isr(const dma_assigment_t *ass); +extern void rgb_dma_isr(const dma_assigment_t *ass); -static void handle_dma_stream_isr(dma_device_t dev) { - switch (dev) { +static void handle_dma_stream_isr(const dma_assigment_t *ass) { + switch (ass->dev) { case DMA_DEVICE_SPI1_RX: case DMA_DEVICE_SPI2_RX: case DMA_DEVICE_SPI3_RX: @@ -143,23 +152,29 @@ static void handle_dma_stream_isr(dma_device_t dev) { case DMA_DEVICE_SPI2_TX: case DMA_DEVICE_SPI3_TX: case DMA_DEVICE_SPI4_TX: - spi_dma_isr(dev); + spi_dma_isr(ass); break; - case DMA_DEVICE_TIM1_CH1: - case DMA_DEVICE_TIM1_CH3: - case DMA_DEVICE_TIM1_CH4: + case DMA_DEVICE_DSHOT_CH1: + case DMA_DEVICE_DSHOT_CH2: + case DMA_DEVICE_DSHOT_CH3: #ifdef USE_MOTOR_DSHOT - dshot_dma_isr(dev); + dshot_dma_isr(ass); +#endif + break; + case DMA_DEVICE_RGB: +#ifdef USE_RGB_LED + rgb_dma_isr(ass); #endif break; + case DMA_DEVICE_INVALID: case DMA_DEVICE_MAX: break; } } -#define DMA_STREAM(_port, _chan, _stream, _dev) \ - void DMA##_port##_Stream##_stream##_IRQHandler() { handle_dma_stream_isr(DMA_DEVICE_##_dev); } \ - void DMA##_port##_Channel##_stream##_IRQHandler() { handle_dma_stream_isr(DMA_DEVICE_##_dev); } +#define DMA_STREAM(_port, _stream) \ + void DMA##_port##_Stream##_stream##_IRQHandler() { handle_dma_stream_isr(&dma_assigments[DMA_STREAM_INDEX(_port, _stream)]); } \ + void DMA##_port##_Channel##_stream##_IRQHandler() { handle_dma_stream_isr(&dma_assigments[DMA_STREAM_INDEX(_port, _stream)]); } DMA_STREAMS diff --git a/src/driver/stm32/dma.h b/src/driver/stm32/dma.h index 4f6269627..66ae301c1 100644 --- a/src/driver/stm32/dma.h +++ b/src/driver/stm32/dma.h @@ -14,6 +14,11 @@ #define LL_DMA_DisableStream LL_DMA_DisableChannel #define LL_DMA_IsEnabledStream LL_DMA_IsEnabledChannel +typedef struct { + uint32_t tag; + uint32_t request; +} dma_channel_t; + #else #define DMA_FLAG_TC (0x1 << 5) #define DMA_FLAG_HT (0x1 << 4) @@ -35,4 +40,15 @@ static const uint32_t _dma_flag_shift[] = {0, 6, 16, 22, 0, 6, 16, 22}; WRITE_REG(dev->port->HIFCR, dma_flag_for_channel(dev, DMA_FLAG_TC | DMA_FLAG_TE | DMA_FLAG_HT | DMA_FLAG_FE)); \ } +typedef struct { + uint32_t tag; +#ifdef STM32H7 + uint32_t request; +#else + int8_t port_index; + int8_t stream_index; + uint32_t channel; +#endif +} dma_channel_t; + #endif \ No newline at end of file diff --git a/src/driver/stm32/motor_dshot.c b/src/driver/stm32/motor_dshot.c index 4c0db36e8..541960933 100644 --- a/src/driver/stm32/motor_dshot.c +++ b/src/driver/stm32/motor_dshot.c @@ -2,6 +2,7 @@ #include +#include "core/failloop.h" #include "core/profile.h" #include "core/project.h" #include "driver/dma.h" @@ -11,21 +12,65 @@ #ifdef USE_MOTOR_DSHOT -extern volatile uint32_t dshot_dma_phase; extern uint16_t dshot_packet[MOTOR_PIN_MAX]; extern dshot_pin_t dshot_pins[MOTOR_PIN_MAX]; - -extern motor_direction_t motor_dir; +extern volatile uint32_t dshot_dma_phase; extern uint8_t dshot_gpio_port_count; extern dshot_gpio_port_t dshot_gpio_ports[DSHOT_MAX_PORT_COUNT]; -static volatile DMA_RAM uint32_t port_dma_buffer[DSHOT_MAX_PORT_COUNT][DSHOT_DMA_BUFFER_SIZE]; +extern volatile DMA_RAM uint32_t port_dma_buffer[DSHOT_MAX_PORT_COUNT][DSHOT_DMA_BUFFER_SIZE]; + +static const resource_tag_t timers[] = { +#ifndef STM32F411 + TIMER_TAG(TIMER8, TIMER_CH1), + TIMER_TAG(TIMER8, TIMER_CH2), + TIMER_TAG(TIMER8, TIMER_CH3), + TIMER_TAG(TIMER8, TIMER_CH4), +#endif + TIMER_TAG(TIMER1, TIMER_CH1), + TIMER_TAG(TIMER1, TIMER_CH2), + TIMER_TAG(TIMER1, TIMER_CH3), + TIMER_TAG(TIMER1, TIMER_CH4), +}; +static const uint32_t timer_count = sizeof(timers) / sizeof(resource_tag_t); -extern void dshot_init_motor_pin(uint32_t index); extern const dshot_gpio_port_t *dshot_gpio_for_device(const dma_device_t dev); -static void dshot_init_gpio_port(dshot_gpio_port_t *port) { +void dshot_init_gpio_port(dshot_gpio_port_t *port) { + for (uint8_t i = 0; i < timer_count; i++) { + const resource_tag_t tag = timers[i]; + if (timer_alloc_tag(TIMER_USE_MOTOR_DSHOT, tag)) { + port->timer_tag = tag; + break; + } + } + if (port->timer_tag == 0) { + failloop(FAILLOOP_DMA); + } + + const dma_assigment_t *dma = port->dma_ass = dma_alloc(port->dma_device, port->timer_tag); + if (dma == NULL) { + failloop(FAILLOOP_DMA); + } + + const timer_channel_t ch = TIMER_TAG_CH(port->timer_tag); + const timer_index_t tim = TIMER_TAG_TIM(port->timer_tag); + const timer_def_t *def = &timer_defs[tim]; + + rcc_enable(def->rcc); + + // setup timer to 1/3 of the full bit time + LL_TIM_InitTypeDef tim_init; + LL_TIM_StructInit(&tim_init); + tim_init.Autoreload = DSHOT_SYMBOL_TIME; + tim_init.Prescaler = 0; + tim_init.ClockDivision = 0; + tim_init.CounterMode = LL_TIM_COUNTERMODE_UP; + LL_TIM_Init(def->instance, &tim_init); + LL_TIM_EnableARRPreload(def->instance); + LL_TIM_DisableMasterSlaveMode(def->instance); + LL_TIM_OC_InitTypeDef tim_oc_init; LL_TIM_OC_StructInit(&tim_oc_init); tim_oc_init.OCMode = LL_TIM_OCMODE_PWM1; @@ -33,20 +78,18 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { tim_oc_init.OCState = LL_TIM_OCSTATE_ENABLE; tim_oc_init.OCPolarity = LL_TIM_OCPOLARITY_LOW; tim_oc_init.CompareValue = 10; - LL_TIM_OC_Init(TIM1, timer_channel_val(port->timer_channel), &tim_oc_init); - LL_TIM_OC_EnablePreload(TIM1, timer_channel_val(port->timer_channel)); - - const dma_stream_def_t *dma = &dma_stream_defs[port->dma_device]; + LL_TIM_OC_Init(def->instance, ch, &tim_oc_init); + LL_TIM_OC_EnablePreload(def->instance, ch); - dma_enable_rcc(port->dma_device); - LL_DMA_DeInit(dma->port, dma->stream_index); + dma_enable_rcc(dma); + LL_DMA_DeInit(dma->def->port, dma->def->stream_index); LL_DMA_InitTypeDef DMA_InitStructure; LL_DMA_StructInit(&DMA_InitStructure); #if defined(STM32H7) || defined(STM32G4) - DMA_InitStructure.PeriphRequest = dma->request; + DMA_InitStructure.PeriphRequest = dma->chan->request; #else - DMA_InitStructure.Channel = dma->channel; + DMA_InitStructure.Channel = dma->chan->channel; #endif DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&port->gpio->BSRR; DMA_InitStructure.MemoryOrM2MDstAddress = (uint32_t)port_dma_buffer[0]; @@ -63,59 +106,26 @@ static void dshot_init_gpio_port(dshot_gpio_port_t *port) { DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; #endif - LL_DMA_Init(dma->port, dma->stream_index, &DMA_InitStructure); - - interrupt_enable(dma->irq, DMA_PRIORITY); - - LL_DMA_EnableIT_TC(dma->port, dma->stream_index); -} - -void motor_dshot_init() { - dshot_gpio_port_count = 0; - - rcc_enable(RCC_APB2_GRP1(TIM1)); - - // setup timer to 1/3 of the full bit time - LL_TIM_InitTypeDef tim_init; - LL_TIM_StructInit(&tim_init); - tim_init.Autoreload = DSHOT_SYMBOL_TIME; - tim_init.Prescaler = 0; - tim_init.ClockDivision = 0; - tim_init.CounterMode = LL_TIM_COUNTERMODE_UP; - LL_TIM_Init(TIM1, &tim_init); - LL_TIM_EnableARRPreload(TIM1); - LL_TIM_DisableMasterSlaveMode(TIM1); + LL_DMA_Init(dma->def->port, dma->def->stream_index, &DMA_InitStructure); - for (uint32_t i = 0; i < MOTOR_PIN_MAX; i++) { - dshot_init_motor_pin(i); - } - - for (uint32_t j = 0; j < dshot_gpio_port_count; j++) { - dshot_init_gpio_port(&dshot_gpio_ports[j]); - - for (uint8_t i = 0; i < 16; i++) { - port_dma_buffer[j][i * 3 + 0] = dshot_gpio_ports[j].port_high; // start bit - port_dma_buffer[j][i * 3 + 1] = 0; // actual bit, set below - port_dma_buffer[j][i * 3 + 2] = dshot_gpio_ports[j].port_low; // return line to low - } - } + interrupt_enable(dma->def->irq, DMA_PRIORITY); + LL_DMA_EnableIT_TC(dma->def->port, dma->def->stream_index); - LL_TIM_EnableCounter(TIM1); - motor_dir = MOTOR_FORWARD; + LL_TIM_EnableCounter(def->instance); } void dshot_dma_setup_port(uint32_t index) { const dshot_gpio_port_t *port = &dshot_gpio_ports[index]; - const dma_stream_def_t *dma = &dma_stream_defs[port->dma_device]; + const dma_assigment_t *dma = port->dma_ass; - dma_clear_flag_tc(dma); + dma_clear_flag_tc(dma->def); - LL_DMA_SetPeriphAddress(dma->port, dma->stream_index, (uint32_t)&port->gpio->BSRR); - LL_DMA_SetMemoryAddress(dma->port, dma->stream_index, (uint32_t)&port_dma_buffer[index][0]); - LL_DMA_SetDataLength(dma->port, dma->stream_index, DSHOT_DMA_BUFFER_SIZE); + LL_DMA_SetPeriphAddress(dma->def->port, dma->def->stream_index, (uint32_t)&port->gpio->BSRR); + LL_DMA_SetMemoryAddress(dma->def->port, dma->def->stream_index, (uint32_t)&port_dma_buffer[index][0]); + LL_DMA_SetDataLength(dma->def->port, dma->def->stream_index, DSHOT_DMA_BUFFER_SIZE); - LL_DMA_EnableStream(dma->port, dma->stream_index); - timer_enable_dma_request(TIMER1, port->timer_channel, true); + LL_DMA_EnableStream(dma->def->port, dma->def->stream_index); + timer_enable_dma_request(TIMER_TAG_TIM(port->timer_tag), TIMER_TAG_CH(port->timer_tag), true); } void motor_dshot_wait_for_ready() { @@ -123,13 +133,12 @@ void motor_dshot_wait_for_ready() { __NOP(); } -void dshot_dma_isr(dma_device_t dev) { - const dma_stream_def_t *dma = &dma_stream_defs[dev]; - dma_clear_flag_tc(dma); - LL_DMA_DisableStream(dma->port, dma->stream_index); +void dshot_dma_isr(const dma_assigment_t *ass) { + dma_clear_flag_tc(ass->def); + LL_DMA_DisableStream(ass->def->port, ass->def->stream_index); - const dshot_gpio_port_t *port = dshot_gpio_for_device(dev); - timer_enable_dma_request(TIMER1, port->timer_channel, false); + const dshot_gpio_port_t *port = dshot_gpio_for_device(ass->dev); + timer_enable_dma_request(TIMER_TAG_TIM(port->timer_tag), TIMER_TAG_CH(port->timer_tag), false); dshot_dma_phase--; } diff --git a/src/driver/stm32/rgb_led.c b/src/driver/stm32/rgb_led.c new file mode 100644 index 000000000..667c8b6f6 --- /dev/null +++ b/src/driver/stm32/rgb_led.c @@ -0,0 +1,194 @@ +#include "driver/rgb_led.h" + +#include +#include + +#include "core/project.h" +#include "driver/dma.h" +#include "driver/gpio.h" +#include "driver/interrupt.h" +#include "driver/timer.h" + +#if defined(USE_RGB_LED) + +#define TIMER_HZ PWM_CLOCK_FREQ_HZ +#define TIMER_DIV ((PWM_CLOCK_FREQ_HZ / TIMER_HZ) - 1) + +#define RGB_BIT_TIME ((TIMER_HZ / 800000) - 1) +#define RGB_T0H_TIME ((RGB_BIT_TIME / 3) + 1) +#define RGB_T1H_TIME ((RGB_BIT_TIME / 3) * 2 + 1) + +#define RGB_BITS_LED 24 +#define RGB_BUFFER_SIZE (RGB_BITS_LED * RGB_LED_MAX + 40) + +static resource_tag_t timer_tag = 0; +static const dma_assigment_t *rgb_dma = NULL; + +static volatile bool rgb_dma_busy = false; +static DMA_RAM uint32_t rgb_timer_buffer[RGB_BUFFER_SIZE]; +static uint32_t rgb_timer_buffer_count = 0; + +static const gpio_af_t *rgb_led_find_af(gpio_pins_t pin) { + for (uint32_t j = 0; j < GPIO_AF_MAX; j++) { + const gpio_af_t *func = &gpio_pin_afs[j]; + if (func->pin != pin || + RESOURCE_TAG_TYPE(func->tag) != RESOURCE_TIM || + TIMER_TAG_CH(func->tag) == TIMER_CH1N || + TIMER_TAG_CH(func->tag) == TIMER_CH2N || + TIMER_TAG_CH(func->tag) == TIMER_CH3N || + TIMER_TAG_CH(func->tag) == TIMER_CH4N) { + continue; + } + + if (timer_alloc_tag(TIMER_USE_RGB_LED, func->tag)) { + return func; + } + } + + return NULL; +} + +void rgb_led_init() { + const gpio_pins_t pin = target.rgb_led; + if (pin == PIN_NONE) { + return; + } + + const gpio_af_t *func = rgb_led_find_af(pin); + if (func == NULL) { + return; + } + + timer_tag = func->tag; + rgb_dma = dma_alloc(DMA_DEVICE_RGB, timer_tag); + if (rgb_dma == NULL) { + return; + } + + gpio_config_t gpio_init; + gpio_init.mode = GPIO_ALTERNATE; + gpio_init.drive = GPIO_DRIVE_HIGH; + gpio_init.output = GPIO_PUSHPULL; + gpio_init.pull = GPIO_DOWN_PULL; + gpio_pin_init_af(pin, gpio_init, func->af); + + const timer_channel_t ch = TIMER_TAG_CH(func->tag); + const timer_index_t tim = TIMER_TAG_TIM(func->tag); + const timer_def_t *def = &timer_defs[tim]; + + rcc_enable(def->rcc); + + LL_TIM_InitTypeDef tim_init; + LL_TIM_StructInit(&tim_init); + tim_init.Autoreload = RGB_BIT_TIME; + tim_init.Prescaler = TIMER_DIV; + tim_init.ClockDivision = 0; + tim_init.CounterMode = LL_TIM_COUNTERMODE_UP; + LL_TIM_Init(def->instance, &tim_init); + LL_TIM_EnableARRPreload(def->instance); + LL_TIM_DisableMasterSlaveMode(def->instance); + + LL_TIM_OC_InitTypeDef tim_oc_init; + LL_TIM_OC_StructInit(&tim_oc_init); + tim_oc_init.CompareValue = 0; + tim_oc_init.OCMode = LL_TIM_OCMODE_PWM1; + tim_oc_init.OCState = LL_TIM_OCSTATE_ENABLE; + tim_oc_init.OCPolarity = LL_TIM_OCPOLARITY_HIGH; + tim_oc_init.OCIdleState = LL_TIM_OCIDLESTATE_LOW; + tim_oc_init.OCNState = LL_TIM_OCSTATE_ENABLE; + tim_oc_init.OCNPolarity = LL_TIM_OCPOLARITY_LOW; + tim_oc_init.OCNIdleState = LL_TIM_OCIDLESTATE_LOW; + LL_TIM_OC_Init(def->instance, timer_channel_val(ch), &tim_oc_init); + LL_TIM_OC_EnablePreload(def->instance, timer_channel_val(ch)); + LL_TIM_EnableAllOutputs(def->instance); + + dma_enable_rcc(rgb_dma); + LL_DMA_DeInit(rgb_dma->def->port, rgb_dma->def->stream_index); + + LL_DMA_InitTypeDef DMA_InitStructure; + LL_DMA_StructInit(&DMA_InitStructure); +#if defined(STM32H7) || defined(STM32G4) + DMA_InitStructure.PeriphRequest = rgb_dma->chan->request; +#else + DMA_InitStructure.Channel = rgb_dma->chan->channel; +#endif + DMA_InitStructure.PeriphOrM2MSrcAddress = timer_channel_addr(def->instance, ch); + DMA_InitStructure.MemoryOrM2MDstAddress = (uint32_t)rgb_timer_buffer; + DMA_InitStructure.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH; + DMA_InitStructure.NbData = RGB_BUFFER_SIZE; + DMA_InitStructure.PeriphOrM2MSrcIncMode = LL_DMA_PERIPH_NOINCREMENT; + DMA_InitStructure.MemoryOrM2MDstIncMode = LL_DMA_MEMORY_INCREMENT; + DMA_InitStructure.PeriphOrM2MSrcDataSize = LL_DMA_PDATAALIGN_WORD; + DMA_InitStructure.MemoryOrM2MDstDataSize = LL_DMA_MDATAALIGN_WORD; + DMA_InitStructure.Mode = LL_DMA_MODE_NORMAL; + DMA_InitStructure.Priority = LL_DMA_PRIORITY_VERYHIGH; +#ifndef STM32G4 + DMA_InitStructure.FIFOMode = LL_DMA_FIFOMODE_DISABLE; + DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; + DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; +#endif + LL_DMA_Init(rgb_dma->def->port, rgb_dma->def->stream_index, &DMA_InitStructure); + + LL_DMA_EnableIT_TC(rgb_dma->def->port, rgb_dma->def->stream_index); + interrupt_enable(rgb_dma->def->irq, DMA_PRIORITY); +} + +bool rgb_led_busy() { + return rgb_dma == NULL || rgb_dma_busy; +} + +void rgb_led_set_value(uint32_t value, uint32_t count) { + if (rgb_led_busy()) { + return; + } + + uint32_t offset = 0; + for (uint32_t i = 0; i < 20; i++) { + rgb_timer_buffer[offset++] = 0; + } + for (uint32_t i = 0; i < count; i++) { + // rgb_led_value contains a (32bit) int that contains the RGB values in G R B format already + // Test each bit and assign the T1H or T0H depending on whether it is 1 or 0. + for (int32_t j = RGB_BITS_LED - 1; j >= 0; j--) { + rgb_timer_buffer[offset++] = ((value >> j) & 0x1) ? RGB_T1H_TIME : RGB_T0H_TIME; + } + } + for (uint32_t i = 0; i < 20; i++) { + rgb_timer_buffer[offset++] = 0; + } + rgb_timer_buffer_count = offset; +} + +void rgb_led_send() { + rgb_dma_busy = true; + + const timer_channel_t ch = TIMER_TAG_CH(timer_tag); + const timer_index_t tim = TIMER_TAG_TIM(timer_tag); + const timer_def_t *def = &timer_defs[tim]; + + dma_clear_flag_tc(rgb_dma->def); + dma_prepare_tx_memory((void *)rgb_timer_buffer, sizeof(rgb_timer_buffer)); + + LL_DMA_SetMemoryAddress(rgb_dma->def->port, rgb_dma->def->stream_index, (uint32_t)rgb_timer_buffer); + LL_DMA_SetDataLength(rgb_dma->def->port, rgb_dma->def->stream_index, rgb_timer_buffer_count); + + LL_DMA_EnableStream(rgb_dma->def->port, rgb_dma->def->stream_index); + timer_enable_dma_request(tim, ch, true); + LL_TIM_EnableCounter(def->instance); +} + +void rgb_dma_isr(const dma_assigment_t *ass) { + dma_clear_flag_tc(ass->def); + LL_DMA_DisableStream(ass->def->port, ass->def->stream_index); + + const uint8_t ch = TIMER_TAG_CH(timer_tag); + const uint8_t tim = TIMER_TAG_TIM(timer_tag); + const timer_def_t *def = &timer_defs[tim]; + + LL_TIM_DisableCounter(def->instance); + timer_enable_dma_request(tim, ch, false); + + rgb_dma_busy = false; +} + +#endif \ No newline at end of file diff --git a/src/driver/stm32/spi.c b/src/driver/stm32/spi.c index cb3dd3a22..3ff13d63f 100644 --- a/src/driver/stm32/spi.c +++ b/src/driver/stm32/spi.c @@ -79,15 +79,15 @@ static uint32_t spi_find_divder(uint32_t clk_hz) { } static void spi_dma_init_rx(spi_ports_t port) { - const dma_stream_def_t *dma = &dma_stream_defs[PORT.dma_rx]; + const dma_assigment_t *dma = spi_dev[port].dma_rx; - LL_DMA_DeInit(dma->port, dma->stream_index); + LL_DMA_DeInit(dma->def->port, dma->def->stream_index); LL_DMA_InitTypeDef DMA_InitStructure; #if defined(STM32H7) || defined(STM32G4) - DMA_InitStructure.PeriphRequest = dma->request; + DMA_InitStructure.PeriphRequest = dma->chan->request; #else - DMA_InitStructure.Channel = dma->channel; + DMA_InitStructure.Channel = dma->chan->channel; #endif #if defined(STM32H7) DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&PORT.channel->RXDR; @@ -108,19 +108,19 @@ static void spi_dma_init_rx(spi_ports_t port) { DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; #endif - LL_DMA_Init(dma->port, dma->stream_index, &DMA_InitStructure); + LL_DMA_Init(dma->def->port, dma->def->stream_index, &DMA_InitStructure); } static void spi_dma_init_tx(spi_ports_t port) { - const dma_stream_def_t *dma = &dma_stream_defs[PORT.dma_tx]; + const dma_assigment_t *dma = spi_dev[port].dma_tx; - LL_DMA_DeInit(dma->port, dma->stream_index); + LL_DMA_DeInit(dma->def->port, dma->def->stream_index); LL_DMA_InitTypeDef DMA_InitStructure; #if defined(STM32H7) || defined(STM32G4) - DMA_InitStructure.PeriphRequest = dma->request; + DMA_InitStructure.PeriphRequest = dma->chan->request; #else - DMA_InitStructure.Channel = dma->channel; + DMA_InitStructure.Channel = dma->chan->channel; #endif #if defined(STM32H7) DMA_InitStructure.PeriphOrM2MSrcAddress = (uint32_t)&PORT.channel->TXDR; @@ -141,7 +141,7 @@ static void spi_dma_init_tx(spi_ports_t port) { DMA_InitStructure.MemBurst = LL_DMA_MBURST_SINGLE; DMA_InitStructure.PeriphBurst = LL_DMA_PBURST_SINGLE; #endif - LL_DMA_Init(dma->port, dma->stream_index, &DMA_InitStructure); + LL_DMA_Init(dma->def->port, dma->def->stream_index, &DMA_InitStructure); } void spi_reconfigure(spi_bus_device_t *bus) { @@ -184,29 +184,29 @@ void spi_dma_transfer_begin(spi_ports_t port, uint8_t *buffer, uint32_t length) LL_SPI_ReceiveData8(PORT.channel); #endif - const dma_stream_def_t *dma_tx = &dma_stream_defs[PORT.dma_tx]; - const dma_stream_def_t *dma_rx = &dma_stream_defs[PORT.dma_rx]; + const dma_assigment_t *dma_tx = spi_dev[port].dma_tx; + const dma_assigment_t *dma_rx = spi_dev[port].dma_rx; - dma_clear_flag_tc(dma_rx); - dma_clear_flag_tc(dma_tx); + dma_clear_flag_tc(dma_rx->def); + dma_clear_flag_tc(dma_tx->def); dma_prepare_rx_memory(buffer, length); dma_prepare_tx_memory(buffer, length); - while (LL_DMA_IsEnabledStream(dma_rx->port, dma_rx->stream_index)) + while (LL_DMA_IsEnabledStream(dma_rx->def->port, dma_rx->def->stream_index)) ; - while (LL_DMA_IsEnabledStream(dma_tx->port, dma_tx->stream_index)) + while (LL_DMA_IsEnabledStream(dma_tx->def->port, dma_tx->def->stream_index)) ; - LL_DMA_SetMemoryAddress(dma_rx->port, dma_rx->stream_index, (uint32_t)buffer); - LL_DMA_SetDataLength(dma_rx->port, dma_rx->stream_index, length); + LL_DMA_SetMemoryAddress(dma_rx->def->port, dma_rx->def->stream_index, (uint32_t)buffer); + LL_DMA_SetDataLength(dma_rx->def->port, dma_rx->def->stream_index, length); - LL_DMA_SetMemoryAddress(dma_tx->port, dma_tx->stream_index, (uint32_t)buffer); - LL_DMA_SetDataLength(dma_tx->port, dma_tx->stream_index, length); + LL_DMA_SetMemoryAddress(dma_tx->def->port, dma_tx->def->stream_index, (uint32_t)buffer); + LL_DMA_SetDataLength(dma_tx->def->port, dma_tx->def->stream_index, length); - LL_DMA_EnableStream(dma_rx->port, dma_rx->stream_index); - LL_DMA_EnableStream(dma_tx->port, dma_tx->stream_index); + LL_DMA_EnableStream(dma_rx->def->port, dma_rx->def->stream_index); + LL_DMA_EnableStream(dma_tx->def->port, dma_tx->def->stream_index); LL_SPI_EnableDMAReq_TX(PORT.channel); LL_SPI_EnableDMAReq_RX(PORT.channel); @@ -223,8 +223,9 @@ void spi_dma_transfer_begin(spi_ports_t port, uint8_t *buffer, uint32_t length) void spi_device_init(spi_ports_t port) { const spi_port_def_t *def = &spi_port_defs[port]; rcc_enable(def->rcc); - dma_enable_rcc(def->dma_rx); - dma_enable_rcc(def->dma_tx); + + dma_enable_rcc(spi_dev[port].dma_rx); + dma_enable_rcc(spi_dev[port].dma_tx); LL_SPI_DeInit(def->channel); @@ -258,11 +259,11 @@ void spi_device_init(spi_ports_t port) { spi_dma_init_rx(port); spi_dma_init_tx(port); - const dma_stream_def_t *dma_rx = &dma_stream_defs[def->dma_rx]; - interrupt_enable(dma_rx->irq, DMA_PRIORITY); + const dma_assigment_t *dma_rx = spi_dev[port].dma_rx; + interrupt_enable(dma_rx->def->irq, DMA_PRIORITY); - LL_DMA_EnableIT_TC(dma_rx->port, dma_rx->stream_index); - LL_DMA_EnableIT_TE(dma_rx->port, dma_rx->stream_index); + LL_DMA_EnableIT_TC(dma_rx->def->port, dma_rx->def->stream_index); + LL_DMA_EnableIT_TE(dma_rx->def->port, dma_rx->def->stream_index); } void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs, const uint32_t count) { @@ -342,21 +343,21 @@ void spi_seg_submit_wait_ex(spi_bus_device_t *bus, const spi_txn_segment_t *segs } static void handle_dma_rx_isr(spi_ports_t port) { - const dma_stream_def_t *dma_rx = &dma_stream_defs[PORT.dma_rx]; - const dma_stream_def_t *dma_tx = &dma_stream_defs[PORT.dma_tx]; + const dma_assigment_t *dma_tx = spi_dev[port].dma_tx; + const dma_assigment_t *dma_rx = spi_dev[port].dma_rx; - if (!dma_is_flag_active_tc(dma_rx)) { + if (!dma_is_flag_active_tc(dma_rx->def)) { return; } - dma_clear_flag_tc(dma_rx); - dma_clear_flag_tc(dma_tx); + dma_clear_flag_tc(dma_rx->def); + dma_clear_flag_tc(dma_tx->def); LL_SPI_DisableDMAReq_TX(PORT.channel); LL_SPI_DisableDMAReq_RX(PORT.channel); - LL_DMA_DisableStream(dma_rx->port, dma_rx->stream_index); - LL_DMA_DisableStream(dma_tx->port, dma_tx->stream_index); + LL_DMA_DisableStream(dma_rx->def->port, dma_rx->def->stream_index); + LL_DMA_DisableStream(dma_tx->def->port, dma_tx->def->stream_index); #if defined(STM32H7) // now we can disable the peripheral @@ -368,8 +369,8 @@ static void handle_dma_rx_isr(spi_ports_t port) { spi_txn_finish(port); } -void spi_dma_isr(dma_device_t dev) { - switch (dev) { +void spi_dma_isr(const dma_assigment_t *ass) { + switch (ass->dev) { case DMA_DEVICE_SPI1_RX: handle_dma_rx_isr(SPI_PORT1); break; diff --git a/src/driver/stm32/system.h b/src/driver/stm32/system.h index 7aa7da0d7..0f27cee97 100644 --- a/src/driver/stm32/system.h +++ b/src/driver/stm32/system.h @@ -117,16 +117,9 @@ typedef TIM_TypeDef timer_dev_t; typedef USART_TypeDef usart_dev_t; typedef struct { - uint32_t device; - DMA_TypeDef *port; uint8_t port_index; - uint32_t channel; - uint8_t channel_index; - - uint32_t request; - #ifdef STM32G4 DMA_Channel_TypeDef *stream; #else diff --git a/src/driver/stm32/timer.c b/src/driver/stm32/timer.c index 55596bbb1..73e89b7ab 100644 --- a/src/driver/stm32/timer.c +++ b/src/driver/stm32/timer.c @@ -81,6 +81,24 @@ uint32_t timer_channel_val(timer_channel_t chan) { } } +uint32_t timer_channel_addr(timer_dev_t *timer, timer_channel_t chan) { + switch (chan) { + case TIMER_CH1: + case TIMER_CH1N: + return (uint32_t)(&timer->CCR1); + case TIMER_CH2: + case TIMER_CH2N: + return (uint32_t)(&timer->CCR2); + case TIMER_CH3: + case TIMER_CH3N: + return (uint32_t)(&timer->CCR3); + case TIMER_CH4: + return (uint32_t)(&timer->CCR4); + default: + return 0; + } +} + void timer_enable_dma_request(timer_index_t tim, timer_channel_t chan, bool state) { const timer_def_t *def = &timer_defs[tim]; diff --git a/src/driver/timer.c b/src/driver/timer.c index 6f39b16f6..a5a1750ef 100644 --- a/src/driver/timer.c +++ b/src/driver/timer.c @@ -4,13 +4,6 @@ timer_assigment_t timer_assigments[TIMER_ASSIGMENT_MAX] = {}; -void timer_alloc_init() { - if (target.brushless) { - timer_assigments[0].use = TIMER_USE_MOTOR_DSHOT; - timer_assigments[0].tag = TIMER_TAG(TIMER1, TIMER_CH1 | TIMER_CH3 | TIMER_CH4); - } -} - bool timer_alloc_tag(timer_use_t use, resource_tag_t tag) { for (uint32_t i = 0; i < TIMER_ASSIGMENT_MAX; i++) { timer_assigment_t *ass = &timer_assigments[i]; diff --git a/src/driver/timer.h b/src/driver/timer.h index f5160ab4a..a28db3920 100644 --- a/src/driver/timer.h +++ b/src/driver/timer.h @@ -67,6 +67,7 @@ typedef enum { TIMER_USE_FREE, TIMER_USE_MOTOR_DSHOT, TIMER_USE_MOTOR_PWM, + TIMER_USE_RGB_LED, TIMER_USE_ELRS, TIMER_USE_SOFT_SERIAL, } timer_use_t; @@ -88,6 +89,7 @@ void timer_alloc_init(); bool timer_alloc_tag(timer_use_t use, resource_tag_t tag); resource_tag_t timer_alloc(timer_use_t use); uint32_t timer_channel_val(timer_channel_t chan); +uint32_t timer_channel_addr(timer_dev_t *timer, timer_channel_t chan); void timer_enable_dma_request(timer_index_t tim, timer_channel_t chan, bool state); void timer_up_init(timer_index_t tim, uint16_t divider, uint32_t period); \ No newline at end of file diff --git a/src/io/rgb_led.c b/src/io/rgb_led.c index f02b19202..c1ea4c191 100644 --- a/src/io/rgb_led.c +++ b/src/io/rgb_led.c @@ -1,168 +1,58 @@ -#include +#include "io/rgb_led.h" #include "core/project.h" #include "driver/rgb_led.h" -#include "driver/time.h" #include "flight/control.h" +#include "flight/filter.h" #include "util/util.h" -// normal flight rgb colour - LED switch ON -#define RGB_VALUE_INFLIGHT_ON RGB(255, 255, 255) +#define RGB_LED_COUNT 8 +#define RGB_FILTER_TIME FILTERCALC(100, 1000000) -// normal flight rgb colour - LED switch OFF -#define RGB_VALUE_INFLIGHT_OFF RGB(0, 0, 0) +static void rgb_led_set_all(uint32_t color, float fade_coeff) { + static float g_filt = 0; + const uint32_t g = (color >> 16) & 0xff; + lpf(&g_filt, g, fade_coeff); -// colour before bind -#define RGB_VALUE_BEFORE_BIND RGB(0, 128, 128) + static float r_filt = 0; + const uint32_t r = (color >> 8) & 0xff; + lpf(&r_filt, r, fade_coeff); -// fade from one color to another when changed -#define RGB_FILTER_ENABLE -#define RGB_FILTER_TIME_MICROSECONDS 50e3 + static float b_filt = 0; + const uint32_t b = (color >> 0) & 0xff; + lpf(&b_filt, b, fade_coeff); -// runs the update once every 16 loop times ( 16 mS ) -#define DOWNSAMPLE 16 - -#define RGB_FILTER_TIME lpfcalc(1000 * DOWNSAMPLE, RGB_FILTER_TIME_MICROSECONDS) -#define RGB(r, g, b) ((((int)g & 0xff) << 16) | (((int)r & 0xff) << 8) | ((int)b & 0xff)) - -#if (RGB_LED_NUMBER > 0) - -// array with individual led brightnesses -int rgb_led_value[RGB_LED_NUMBER]; -// loop count for downsampling -int rgb_loopcount = 0; -// rgb low pass filter variables -float r_filt, g_filt, b_filt; - -// sets all leds to a brightness -void rgb_led_set_all(int rgb) { -#ifdef RGB_FILTER_ENABLE - // deconstruct the colour into components - int g = rgb >> 16; - int r = (rgb & 0x0000FF00) >> 8; - int b = rgb & 0xff; - - // filter individual colors - lpf(&r_filt, r, RGB_FILTER_TIME); - lpf(&g_filt, g, RGB_FILTER_TIME); - lpf(&b_filt, b, RGB_FILTER_TIME); - - int temp = RGB(r_filt, g_filt, b_filt); - - for (int i = 0; i < RGB_LED_NUMBER; i++) - rgb_led_value[i] = temp; - -#else - for (int i = 0; i < RGB_LED_NUMBER; i++) - rgb_led_value[i] = rgb; -#endif -} - -// set an individual led brightness -void rgb_led_set_one(int led_number, int rgb) { - rgb_led_value[led_number] = rgb; + rgb_led_set_value(RGB(r_filt, g_filt, b_filt), RGB_LED_COUNT); } -// flashes between 2 colours, duty cycle 1 - 15 -void rgb_ledflash(int color1, int color2, uint32_t period, int duty) { - if (time_micros() % period > (period * duty) >> 4) { - rgb_led_set_all(color1); +// flashes between 2 colours, duty cycle 1 - 16 +static void rgb_ledflash(uint32_t color1, uint32_t color2, uint32_t period_ms, uint8_t duty) { + const uint32_t period = period_ms * 1000; + const uint32_t divider = (period * duty) >> 5; + if (time_micros() % period > divider) { + rgb_led_set_all(color1, lpfcalc(divider, period)); } else { - rgb_led_set_all(color2); + rgb_led_set_all(color2, lpfcalc(divider, period)); } } -// speed of movement -float KR_SPEED = 0.005f * DOWNSAMPLE; - -float kr_position = 0; -int kr_dir = 0; - -// knight rider style led movement -void rgb_knight_rider() { - if (kr_dir) { - kr_position += KR_SPEED; - if (kr_position > RGB_LED_NUMBER - 1) - kr_dir = !kr_dir; - } else { - kr_position -= KR_SPEED; - if (kr_position < 0) - kr_dir = !kr_dir; +void rgb_led_update() { +#if defined(USE_RGB_LED) + if (rgb_led_busy()) { + return; } - - // calculate led value - for (int i = 0; i < RGB_LED_NUMBER; i++) { - float led_bright = fabsf((float)i - kr_position); - if (led_bright > 1.0f) - led_bright = 1.0f; - led_bright = 1.0f - led_bright; - - // set a green background as well, 32 brightness - rgb_led_set_one(i, RGB((led_bright * 255.0f), (32.0f - led_bright * 32.0f), 0)); + if (flags.lowbatt) { + rgb_ledflash(RGB(255, 0, 0), RGB(0, 0, 255), 500, 16); } -} - -// 2 led flasher -void rgb_ledflash_twin(int color1, int color2, uint32_t period) { - if (time_micros() % period > (period / 2)) { - for (int i = 0; i < RGB_LED_NUMBER; i++) { - if ((i / 2) * 2 == i) - rgb_led_set_one(i, color1); - else - rgb_led_set_one(i, color2); - } - } else { - for (int i = 0; i < RGB_LED_NUMBER; i++) { - if ((i / 2) * 2 == i) - rgb_led_set_one(i, color2); - else - rgb_led_set_one(i, color1); - } + if (flags.rx_mode == RXMODE_BIND) { + rgb_ledflash(RGB(255, 0, 0), RGB(0, 0, 255), 100, 24); } -} - -// main function -void rgb_led_lvc() { - rgb_loopcount++; - if (rgb_loopcount > DOWNSAMPLE) { - rgb_loopcount = 0; - // led flash logic - if (flags.lowbatt) { - // rgb_led_set_all( RGB( 255 , 0 , 0 ) ); - rgb_ledflash(RGB(255, 0, 0), RGB(255, 32, 0), 500000, 8); - } else { - if (flags.rx_mode == RXMODE_BIND) { - // bind mode - // rgb_ledflash ( RGB( 0 , 0 , 255 ), RGB( 0 , 128 , 0 ), 1000000, 12); - // rgb_ledflash_twin( RGB( 0 , 0 , 255 ), RGB( 0 , 128 , 0 ), 1000000); - rgb_led_set_all(RGB_VALUE_BEFORE_BIND); - // rgb_knight_rider(); - } else { // non bind - if (flags.failsafe) { - // failsafe flash - rgb_ledflash(RGB(0, 128, 0), RGB(0, 0, 128), 500000, 8); - // rgb_led_set_all( RGB( 0 , 128 , 128 ) ); - } else { - - if (rx_aux_on(AUX_LEDS_ON)) - - rgb_led_set_all(RGB_VALUE_INFLIGHT_ON); - else - rgb_led_set_all(RGB_VALUE_INFLIGHT_OFF); - } - } - } - -#ifdef RGB_LED_DMA - // send dma start signal - rgb_send(0); -#else - // send data to leds - for (int i = 0; i < RGB_LED_NUMBER; i++) { - rgb_send(rgb_led_value[i]); - } -#endif + if (flags.failsafe) { + rgb_ledflash(RGB(255, 0, 0), RGB(0, 0, 255), 500, 30); } -} - + if (flags.arm_switch && (flags.throttle_safety == 1 || flags.arm_safety == 1)) { + rgb_ledflash(RGB(255, 0, 0), RGB(0, 0, 255), 100, 8); + } + rgb_led_send(); #endif +} diff --git a/src/io/rgb_led.h b/src/io/rgb_led.h index 686b389ac..921d3fee2 100644 --- a/src/io/rgb_led.h +++ b/src/io/rgb_led.h @@ -1,3 +1,5 @@ #pragma once -void rgb_led_lvc(); \ No newline at end of file +#define RGB(r, g, b) ((((uint32_t)g & 0xff) << 16) | (((uint32_t)r & 0xff) << 8) | ((uint32_t)b & 0xff)) + +void rgb_led_update(); \ No newline at end of file diff --git a/src/system/at32f435/dma.in b/src/system/at32f435/dma.in new file mode 100644 index 000000000..c2e19483c --- /dev/null +++ b/src/system/at32f435/dma.in @@ -0,0 +1,55 @@ +{ .tag = ADC_TAG(ADC_DEVICE1, 0xFF), .request = 5 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0xFF), .request = 36 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0xFF), .request = 37 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .request = 24 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .request = 25 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .request = 26 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .request = 27 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .request = 28 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .request = 29 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .request = 30 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .request = 31 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_RX), .request = 32 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_TX), .request = 33 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .request = 114 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .request = 115 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_RX), .request = 116 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_TX), .request = 117 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_RX), .request = 118 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_TX), .request = 119 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .request = 10 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .request = 11 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .request = 12 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .request = 13 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .request = 14 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .request = 15 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .request = 106 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .request = 107 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .request = 42 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .request = 43 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .request = 44 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .request = 45 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .request = 56 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .request = 57 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .request = 58 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .request = 59 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH1), .request = 86 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH2), .request = 87 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH3), .request = 88 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH4), .request = 89 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .request = 61 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .request = 62 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .request = 63 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .request = 64 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .request = 67 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .request = 68 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .request = 69 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH4), .request = 70 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .request = 72 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .request = 73 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .request = 74 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .request = 75 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .request = 49 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .request = 50 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .request = 51 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .request = 52 }, \ No newline at end of file diff --git a/src/system/stm32f405/dma.in b/src/system/stm32f405/dma.in new file mode 100644 index 000000000..f4636ad74 --- /dev/null +++ b/src/system/stm32f405/dma.in @@ -0,0 +1,64 @@ +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_RX), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_TX), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_7 }, diff --git a/src/system/stm32f411/dma.in b/src/system/stm32f411/dma.in new file mode 100644 index 000000000..c7cf37d9d --- /dev/null +++ b/src/system/stm32f411/dma.in @@ -0,0 +1,58 @@ +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT5, RES_SPI_MISO), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SPI_TAG(SPI_PORT5, RES_SPI_MOSI), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SPI_TAG(SPI_PORT5, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = SPI_TAG(SPI_PORT5, RES_SPI_MISO), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT5, RES_SPI_MOSI), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, diff --git a/src/system/stm32f722/dma.in b/src/system/stm32f722/dma.in new file mode 100644 index 000000000..f4636ad74 --- /dev/null +++ b/src/system/stm32f722/dma.in @@ -0,0 +1,64 @@ +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_RX), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_TX), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_7 }, diff --git a/src/system/stm32f745/dma.in b/src/system/stm32f745/dma.in new file mode 100644 index 000000000..10e771f7e --- /dev/null +++ b/src/system/stm32f745/dma.in @@ -0,0 +1,72 @@ +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_RX), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_TX), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_TX), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_RX), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_RX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_TX), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_7 }, diff --git a/src/system/stm32f765/dma.in b/src/system/stm32f765/dma.in new file mode 100644 index 000000000..15da7a285 --- /dev/null +++ b/src/system/stm32f765/dma.in @@ -0,0 +1,77 @@ +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_RX), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_TX), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .port_index = 1, .stream_index = 0, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_TX), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .port_index = 1, .stream_index = 1, .channel = LL_DMA_CHANNEL_9 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .port_index = 1, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_RX), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .port_index = 1, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .port_index = 1, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .port_index = 1, .stream_index = 5, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_RX), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .port_index = 1, .stream_index = 6, .channel = LL_DMA_CHANNEL_9 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_TX), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .port_index = 1, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 0, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_2 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 1, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 2, .channel = LL_DMA_CHANNEL_9 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .port_index = 2, .stream_index = 3, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .port_index = 2, .stream_index = 4, .channel = LL_DMA_CHANNEL_7 }, +{ .tag = SPI_TAG(SPI_PORT6, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_3 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .port_index = 2, .stream_index = 5, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_0 }, +{ .tag = SPI_TAG(SPI_PORT6, RES_SPI_MISO), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_1 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .port_index = 2, .stream_index = 6, .channel = LL_DMA_CHANNEL_6 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_4 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_5 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .port_index = 2, .stream_index = 7, .channel = LL_DMA_CHANNEL_7 }, diff --git a/src/system/stm32g473/dma.in b/src/system/stm32g473/dma.in new file mode 100644 index 000000000..594ddcb70 --- /dev/null +++ b/src/system/stm32g473/dma.in @@ -0,0 +1,50 @@ +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .request = 5 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .request = 10 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .request = 11 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .request = 12 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .request = 13 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .request = 14 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .request = 15 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .request = 24 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .request = 25 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .request = 26 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .request = 27 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .request = 28 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .request = 29 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .request = 30 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .request = 31 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .request = 36 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .request = 37 }, +{ .tag = ADC_TAG(ADC_DEVICE4, 0XFF), .request = 38 }, +{ .tag = ADC_TAG(ADC_DEVICE5, 0XFF), .request = 39 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .request = 42 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .request = 43 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .request = 44 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .request = 45 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .request = 49 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .request = 50 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .request = 51 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .request = 52 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .request = 56 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .request = 57 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .request = 58 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .request = 59 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .request = 61 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .request = 62 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .request = 63 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .request = 64 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .request = 67 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .request = 68 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .request = 69 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH4), .request = 70 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .request = 72 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .request = 73 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .request = 74 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .request = 75 }, +{ .tag = TIMER_TAG(TIMER15, TIMER_CH1), .request = 78 }, +{ .tag = TIMER_TAG(TIMER16, TIMER_CH1), .request = 82 }, +{ .tag = TIMER_TAG(TIMER17, TIMER_CH1), .request = 84 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH1), .request = 86 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH2), .request = 87 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH3), .request = 88 }, +{ .tag = TIMER_TAG(TIMER20, TIMER_CH4), .request = 89 }, diff --git a/src/system/stm32h743/dma.in b/src/system/stm32h743/dma.in new file mode 100644 index 000000000..1a53261aa --- /dev/null +++ b/src/system/stm32h743/dma.in @@ -0,0 +1,53 @@ +{ .tag = ADC_TAG(ADC_DEVICE1, 0XFF), .request = 9 }, +{ .tag = ADC_TAG(ADC_DEVICE2, 0XFF), .request = 10 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH1), .request = 11 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH2), .request = 12 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH3), .request = 13 }, +{ .tag = TIMER_TAG(TIMER1, TIMER_CH4), .request = 14 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH1), .request = 18 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH2), .request = 19 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH3), .request = 20 }, +{ .tag = TIMER_TAG(TIMER2, TIMER_CH4), .request = 21 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH1), .request = 23 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH2), .request = 24 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH3), .request = 25 }, +{ .tag = TIMER_TAG(TIMER3, TIMER_CH4), .request = 26 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH1), .request = 29 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH2), .request = 30 }, +{ .tag = TIMER_TAG(TIMER4, TIMER_CH3), .request = 31 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .request = 37 }, +{ .tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .request = 38 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .request = 39 }, +{ .tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .request = 40 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_RX), .request = 41 }, +{ .tag = SERIAL_TAG(SERIAL_PORT1, RES_SERIAL_TX), .request = 42 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_RX), .request = 43 }, +{ .tag = SERIAL_TAG(SERIAL_PORT2, RES_SERIAL_TX), .request = 44 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_RX), .request = 45 }, +{ .tag = SERIAL_TAG(SERIAL_PORT3, RES_SERIAL_TX), .request = 46 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH1), .request = 47 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH2), .request = 48 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH3), .request = 49 }, +{ .tag = TIMER_TAG(TIMER8, TIMER_CH4), .request = 50 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH1), .request = 55 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH2), .request = 56 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH3), .request = 57 }, +{ .tag = TIMER_TAG(TIMER5, TIMER_CH4), .request = 58 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .request = 61 }, +{ .tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .request = 62 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_RX), .request = 63 }, +{ .tag = SERIAL_TAG(SERIAL_PORT4, RES_SERIAL_TX), .request = 64 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_RX), .request = 65 }, +{ .tag = SERIAL_TAG(SERIAL_PORT5, RES_SERIAL_TX), .request = 66 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_RX), .request = 71 }, +{ .tag = SERIAL_TAG(SERIAL_PORT6, RES_SERIAL_TX), .request = 72 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_RX), .request = 79 }, +{ .tag = SERIAL_TAG(SERIAL_PORT7, RES_SERIAL_TX), .request = 80 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_RX), .request = 81 }, +{ .tag = SERIAL_TAG(SERIAL_PORT8, RES_SERIAL_TX), .request = 82 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .request = 83 }, +{ .tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .request = 84 }, +{ .tag = TIMER_TAG(TIMER15, TIMER_CH1), .request = 105 }, +{ .tag = TIMER_TAG(TIMER16, TIMER_CH1), .request = 109 }, +{ .tag = TIMER_TAG(TIMER17, TIMER_CH1), .request = 111 }, +{ .tag = ADC_TAG(ADC_DEVICE3, 0XFF), .request = 115 },