Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
bkleiner committed Oct 8, 2023
1 parent 5b8dccf commit 1c02292
Show file tree
Hide file tree
Showing 24 changed files with 893 additions and 938 deletions.
1 change: 1 addition & 0 deletions src/config/feature.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#define USE_BLACKBOX

#define USE_MAX7456
#define USE_RGB_LED

#define USE_MOTOR_DSHOT
#define USE_MOTOR_PWM
Expand Down
13 changes: 3 additions & 10 deletions src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include "driver/fmc.h"
#include "driver/gpio.h"
#include "driver/motor.h"
#include "driver/reset.h"
#include "driver/rgb_led.h"
#include "driver/serial.h"
#include "driver/spi.h"
Expand Down Expand Up @@ -96,6 +95,8 @@ __attribute__((__used__)) int main() {
led_init();
led_on(LEDALL);

rgb_led_init();

debug_pin_init();
buzzer_init();

Expand Down Expand Up @@ -133,7 +134,6 @@ __attribute__((__used__)) int main() {

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

blackbox_init();
imu_init();
Expand Down Expand Up @@ -174,14 +174,7 @@ __attribute__((__used__)) int main() {

// 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();
vtx_update();
Expand Down
2 changes: 2 additions & 0 deletions src/core/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,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;
Expand All @@ -185,6 +186,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) \
Expand Down
255 changes: 182 additions & 73 deletions src/driver/at32/dma.c
Original file line number Diff line number Diff line change
@@ -1,55 +1,119 @@
#include "driver/dma.h"

#include "driver/rcc.h"
#include "driver/resource.h"
#include "driver/timer.h"

#define DMA_CHANNEL_MAX 14

#define DMA_GL_FLAG ((uint32_t)0x00000001)
#define DMA_FDT_FLAG ((uint32_t)0x00000002)
#define DMA_HDT_FLAG ((uint32_t)0x00000004)
#define DMA_DTERR_FLAG ((uint32_t)0x00000008)

#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, \
.port = DMA##_port, \
.port_index = _port, \
.channel = DMA##_port##_CHANNEL##_chan, \
.channel_index = _chan, \
.request = DMAMUX_DMAREQ_ID_##_dev, \
.mux = DMA##_port##MUX_CHANNEL##_chan, \
.irq = DMA##_port##_Channel##_chan##_IRQn, \
},

const dma_stream_def_t dma_stream_defs[DMA_DEVICE_MAX] = {DMA_STREAMS};

#undef DMA_STREAM

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) {
const dma_stream_def_t *dma = &dma_stream_defs[dev];
switch (dma->port_index) {
#define DMA_CHANNEL(_port, _chan) \
{ \
.port = DMA##_port, \
.port_index = _port, \
.channel = DMA##_port##_CHANNEL##_chan, \
.channel_index = _chan, \
.mux = DMA##_port##MUX_CHANNEL##_chan, \
.irq = DMA##_port##_Channel##_chan##_IRQn, \
}

static const dma_channel_def_t dma_channel_defs[DMA_CHANNEL_MAX] = {
DMA_CHANNEL(1, 1),
DMA_CHANNEL(1, 2),
DMA_CHANNEL(1, 3),
DMA_CHANNEL(1, 4),
DMA_CHANNEL(1, 5),
DMA_CHANNEL(1, 6),
DMA_CHANNEL(1, 7),
DMA_CHANNEL(2, 1),
DMA_CHANNEL(2, 2),
DMA_CHANNEL(2, 3),
DMA_CHANNEL(2, 4),
DMA_CHANNEL(2, 5),
DMA_CHANNEL(2, 6),
DMA_CHANNEL(2, 7),
};

#undef DMA_CHANNEL

typedef struct {
resource_tag_t tag;
dmamux_requst_id_sel_type request;
} dma_req_id_t;

static const dma_req_id_t dma_req_ids[] = {
{.tag = SPI_TAG(SPI_PORT1, RES_SPI_MISO), .request = DMAMUX_DMAREQ_ID_SPI1_RX},
{.tag = SPI_TAG(SPI_PORT1, RES_SPI_MOSI), .request = DMAMUX_DMAREQ_ID_SPI1_TX},
{.tag = SPI_TAG(SPI_PORT2, RES_SPI_MISO), .request = DMAMUX_DMAREQ_ID_SPI2_RX},
{.tag = SPI_TAG(SPI_PORT2, RES_SPI_MOSI), .request = DMAMUX_DMAREQ_ID_SPI2_TX},
{.tag = SPI_TAG(SPI_PORT3, RES_SPI_MISO), .request = DMAMUX_DMAREQ_ID_SPI3_RX},
{.tag = SPI_TAG(SPI_PORT3, RES_SPI_MOSI), .request = DMAMUX_DMAREQ_ID_SPI3_TX},
{.tag = SPI_TAG(SPI_PORT4, RES_SPI_MISO), .request = DMAMUX_DMAREQ_ID_SPI4_RX},
{.tag = SPI_TAG(SPI_PORT4, RES_SPI_MOSI), .request = DMAMUX_DMAREQ_ID_SPI4_TX},
{.tag = TIMER_TAG(TIMER1, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR1_CH1},
{.tag = TIMER_TAG(TIMER1, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR1_CH2},
{.tag = TIMER_TAG(TIMER1, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR1_CH3},
{.tag = TIMER_TAG(TIMER1, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR1_CH4},
{.tag = TIMER_TAG(TIMER8, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR8_CH1},
{.tag = TIMER_TAG(TIMER8, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR8_CH2},
{.tag = TIMER_TAG(TIMER8, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR8_CH3},
{.tag = TIMER_TAG(TIMER8, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR8_CH4},
{.tag = TIMER_TAG(TIMER2, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR2_CH1},
{.tag = TIMER_TAG(TIMER2, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR2_CH2},
{.tag = TIMER_TAG(TIMER2, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR2_CH3},
{.tag = TIMER_TAG(TIMER2, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR2_CH4},
{.tag = TIMER_TAG(TIMER3, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR3_CH1},
{.tag = TIMER_TAG(TIMER3, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR3_CH2},
{.tag = TIMER_TAG(TIMER3, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR3_CH3},
{.tag = TIMER_TAG(TIMER3, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR3_CH4},
{.tag = TIMER_TAG(TIMER4, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR4_CH1},
{.tag = TIMER_TAG(TIMER4, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR4_CH2},
{.tag = TIMER_TAG(TIMER4, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR4_CH3},
{.tag = TIMER_TAG(TIMER4, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR4_CH4},
{.tag = TIMER_TAG(TIMER5, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR5_CH1},
{.tag = TIMER_TAG(TIMER5, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR5_CH2},
{.tag = TIMER_TAG(TIMER5, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR5_CH3},
{.tag = TIMER_TAG(TIMER5, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR5_CH4},
{.tag = TIMER_TAG(TIMER20, TIMER_CH1), .request = DMAMUX_DMAREQ_ID_TMR20_CH1},
{.tag = TIMER_TAG(TIMER20, TIMER_CH2), .request = DMAMUX_DMAREQ_ID_TMR20_CH2},
{.tag = TIMER_TAG(TIMER20, TIMER_CH3), .request = DMAMUX_DMAREQ_ID_TMR20_CH3},
{.tag = TIMER_TAG(TIMER20, TIMER_CH4), .request = DMAMUX_DMAREQ_ID_TMR20_CH4},
};

#define DMA_REQ_ID_MAX (sizeof(dma_req_ids) / sizeof(dma_req_id_t))

static dma_assigment_t dma_assigments[DMA_CHANNEL_MAX] = {};

static dmamux_requst_id_sel_type dma_find_req(resource_tag_t tag) {
for (uint32_t i = 0; i < DMA_REQ_ID_MAX; i++) {
const dma_req_id_t *req = &dma_req_ids[i];
if (req->tag == tag) {
return req->request;
}
}
return 0;
}

const dma_assigment_t *dma_alloc(resource_tag_t tag, dma_device_t dev) {
for (uint32_t i = 0; i < DMA_CHANNEL_MAX; i++) {
dma_assigment_t *ass = &dma_assigments[i];
const dma_channel_def_t *def = &dma_channel_defs[i];
if (ass->dev == 0) {
ass->def = def;
ass->request = dma_find_req(tag);
ass->dev = dev;
return ass;
}
}
return NULL;
}

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);
Expand All @@ -61,58 +125,103 @@ void dma_enable_rcc(dma_device_t dev) {
}
}

static uint32_t dma_flag_for_channel(const dma_stream_def_t *dma, uint32_t val) {
static uint32_t dma_flag_for_channel(const dma_channel_def_t *dma, uint32_t val) {
// 4bits per channel
const uint32_t shift = (dma->channel_index - 1) * 4;
const uint32_t port = dma->port_index == 2 ? 0x10000000 : 0x0;
return port | (val << shift);
}

bool dma_is_flag_active_tc(dma_device_t dev) {
const dma_stream_def_t *dma = &dma_stream_defs[dev];
const uint32_t flag = dma_flag_for_channel(dma, DMA_FDT_FLAG);
bool dma_is_flag_active_tc(const dma_assigment_t *ass) {
const uint32_t flag = dma_flag_for_channel(ass->def, DMA_FDT_FLAG);
return dma_flag_get(flag);
}

void dma_clear_flag_tc(dma_device_t dev) {
const dma_stream_def_t *dma = &dma_stream_defs[dev];
dma_flag_clear(dma_flag_for_channel(dma, DMA_FDT_FLAG));
dma_flag_clear(dma_flag_for_channel(dma, DMA_HDT_FLAG));
dma_flag_clear(dma_flag_for_channel(dma, DMA_DTERR_FLAG));
void dma_clear_flag_tc(const dma_assigment_t *ass) {
dma_flag_clear(dma_flag_for_channel(ass->def, DMA_FDT_FLAG));
dma_flag_clear(dma_flag_for_channel(ass->def, DMA_HDT_FLAG));
dma_flag_clear(dma_flag_for_channel(ass->def, DMA_DTERR_FLAG));
}

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(const dma_assigment_t *ass) {
switch (ass->dev) {
case DMA_DEVICE_TIM1_CH1:
case DMA_DEVICE_TIM1_CH3:
case DMA_DEVICE_TIM1_CH4:
#ifdef USE_MOTOR_DSHOT
dshot_dma_isr(ass);
#endif
break;

static void handle_dma_stream_isr(dma_device_t dev) {
switch (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:
#ifdef USE_MOTOR_DSHOT
dshot_dma_isr(dev);

case DMA_DEVICE_RGB:
#ifdef USE_RGB_LED
rgb_dma_isr(ass);
#endif
break;
case DMA_DEVICE_MAX:

default:
break;
}
}

#define DMA_STREAM(_port, _chan, _dev) \
void DMA##_port##_Channel##_chan##_IRQHandler() { \
handle_dma_stream_isr(DMA_DEVICE_##_dev); \
}

DMA_STREAMS
void DMA1_Channel1_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[0]);
}
void DMA1_Channel2_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[1]);
}
void DMA1_Channel3_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[2]);
}
void DMA1_Channel4_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[3]);
}
void DMA1_Channel5_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[4]);
}
void DMA1_Channel6_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[5]);
}
void DMA1_Channel7_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[6]);
}

#undef DMA_STREAM
void DMA2_Channel1_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[7]);
}
void DMA2_Channel2_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[8]);
}
void DMA2_Channel3_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[9]);
}
void DMA2_Channel4_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[10]);
}
void DMA2_Channel5_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[11]);
}
void DMA2_Channel6_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[12]);
}
void DMA2_Channel7_IRQHandler() {
handle_dma_stream_isr(&dma_assigments[13]);
}
Loading

0 comments on commit 1c02292

Please sign in to comment.