1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-14 20:10:18 +03:00

Added DMA mapping (readonly for now), and enabled timer management for all F4 boards.

Converting the universal target as well.

Simplified timer management some.

Added F722 support for good measuer.

Fixed SITL, tests.

Cleanup after rebase.

Added support for all timer consumers and F7.

Fixed 'USE_DMA_SPEC' for F3, some cleanups.
This commit is contained in:
mikeller 2019-02-18 02:09:06 +13:00
parent 9f8ad1aa44
commit f8103b8c86
37 changed files with 904 additions and 484 deletions

View file

@ -4735,7 +4735,7 @@ static void printPeripheralDmaopt(dmaoptEntry_t *entry, int index, uint8_t dumpM
if (defaultConfig) {
if (defaultOpt != DMA_OPT_UNUSED) {
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpec(entry->peripheral, index, defaultOpt);
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(entry->peripheral, index, defaultOpt);
dmaCode_t dmaCode = 0;
if (dmaChannelSpec) {
dmaCode = dmaChannelSpec->code;
@ -4751,7 +4751,7 @@ static void printPeripheralDmaopt(dmaoptEntry_t *entry, int index, uint8_t dumpM
}
if (currentOpt != DMA_OPT_UNUSED) {
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpec(entry->peripheral, index, currentOpt);
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(entry->peripheral, index, currentOpt);
dmaCode_t dmaCode = 0;
if (dmaChannelSpec) {
dmaCode = dmaChannelSpec->code;
@ -4768,16 +4768,60 @@ static void printPeripheralDmaopt(dmaoptEntry_t *entry, int index, uint8_t dumpM
}
}
#if defined(USE_TIMER_MGMT)
static void printTimerDmaopt(const timerIOConfig_t *timerIoConfig, uint8_t dumpMask)
{
const char *format = "dmaopt %c%02d %d";
const ioTag_t ioTag = timerIoConfig->ioTag;
if (!ioTag) {
return;
}
const dmaoptValue_t dmaopt = timerIoConfig->dmaopt;
const timerHardware_t *timer = timerGetByTag(ioTag);
if (dmaopt != DMA_OPT_UNUSED && !(dumpMask & HIDE_UNUSED)) {
cliDumpPrintLinef(dumpMask, false, format,
IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag),
dmaopt
);
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByTimer(timer);
dmaCode_t dmaCode = 0;
if (dmaChannelSpec) {
dmaCode = dmaChannelSpec->code;
}
cliDumpPrintLinef(dumpMask, false,
"# %c%02d: DMA%d Stream %d Channel %d",
IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag),
DMA_CODE_CONTROLLER(dmaCode), DMA_CODE_STREAM(dmaCode), DMA_CODE_CHANNEL(dmaCode)
);
} else {
if (!(dumpMask & HIDE_UNUSED)) {
cliDumpPrintLinef(dumpMask, false,
"dmaopt %c%02d NONE",
IO_GPIOPortIdxByTag(ioTag) + 'A', IO_GPIOPinIdxByTag(ioTag)
);
}
}
}
#endif
static void printDmaopt(uint8_t dumpMask)
{
UNUSED(dumpMask); // XXX For now
for (size_t i = 0; i < ARRAYLEN(dmaoptEntryTable); i++) {
dmaoptEntry_t *entry = &dmaoptEntryTable[i];
for (int index = 0; index < entry->maxIndex; index++) {
printPeripheralDmaopt(entry, index, dumpMask);
}
}
#if defined(USE_TIMER_MGMT)
for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
printTimerDmaopt(timerIOConfig(i), dumpMask);
}
#endif
}
static void cliDmaopt(char *cmdline)
@ -4839,7 +4883,7 @@ static void cliDmaopt(char *cmdline)
} else if (strcasecmp(pch, "list") == 0) {
// Show possible opts
const dmaChannelSpec_t *dmaChannelSpec;
for (int opt = 0; (dmaChannelSpec = dmaGetChannelSpec(entry->peripheral, index, opt)); opt++) {
for (int opt = 0; (dmaChannelSpec = dmaGetChannelSpecByPeripheral(entry->peripheral, index, opt)); opt++) {
cliPrintLinef("# %d: DMA%d Stream %d channel %d", opt, DMA_CODE_CONTROLLER(dmaChannelSpec->code), DMA_CODE_STREAM(dmaChannelSpec->code), DMA_CODE_CHANNEL(dmaChannelSpec->code));
}
return;
@ -4899,7 +4943,7 @@ static void printTimer(uint8_t dumpMask)
}
if (timerIndex != 0 && !(dumpMask & HIDE_UNUSED)) {
cliDumpPrintLinef(dumpMask, false, format,
cliDumpPrintLinef(dumpMask, false, format,
IO_GPIOPortIdxByTag(ioTag) + 'A',
IO_GPIOPinIdxByTag(ioTag),
timerIndex - 1
@ -4954,12 +4998,12 @@ static void cliTimer(char *cmdline)
if (strcasecmp(pch, "list") == 0) {
/* output the list of available options */
uint8_t index = 0;
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
if (timerHardware[i].tag == ioTag) {
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
if (TIMER_HARDWARE[i].tag == ioTag) {
cliPrintLinef("# %d. TIM%d CH%d",
index,
timerGetTIMNumber(timerHardware[i].tim),
CC_INDEX_FROM_CHANNEL(timerHardware[i].channel) + 1
timerGetTIMNumber(TIMER_HARDWARE[i].tim),
CC_INDEX_FROM_CHANNEL(TIMER_HARDWARE[i].channel) + 1
);
index++;
}

View file

@ -26,29 +26,45 @@
#ifdef USE_ADC
#include "common/utils.h"
#include "drivers/accgyro/accgyro.h"
#include "drivers/adc_impl.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "drivers/rcc.h"
#include "drivers/sensor.h"
#include "drivers/time.h"
#include "adc.h"
#include "adc_impl.h"
#include "rcc.h"
#include "dma.h"
#include "common/utils.h"
#include "pg/adc.h"
#include "adc.h"
const adcDevice_t adcHardware[] = {
{ .ADCx = ADC1, .rccADC = RCC_AHB(ADC12), .DMAy_Channelx = DMA1_Channel1 },
#ifdef ADC24_DMA_REMAP
{ .ADCx = ADC2, .rccADC = RCC_AHB(ADC12), .DMAy_Channelx = DMA2_Channel3 },
#else
{ .ADCx = ADC2, .rccADC = RCC_AHB(ADC12), .DMAy_Channelx = DMA2_Channel1 },
{ .ADCx = ADC1, .rccADC = RCC_AHB(ADC12),
#if !defined(USE_DMA_SPEC)
.DMAy_Channelx = DMA1_Channel1,
#endif
{ .ADCx = ADC3, .rccADC = RCC_AHB(ADC34), .DMAy_Channelx = DMA2_Channel5 }
},
#ifdef ADC24_DMA_REMAP
{ .ADCx = ADC2, .rccADC = RCC_AHB(ADC12),
#if !defined(USE_DMA_SPEC)
.DMAy_Channelx = DMA2_Channel3,
#endif
},
#else
{ .ADCx = ADC2, .rccADC = RCC_AHB(ADC12),
#if !defined(USE_DMA_SPEC)
.DMAy_Channelx = DMA2_Channel1,
#endif
},
#endif
{ .ADCx = ADC3, .rccADC = RCC_AHB(ADC34),
#if !defined(USE_DMA_SPEC)
.DMAy_Channelx = DMA2_Channel5,
#endif
}
};
const adcTagMap_t adcTagMap[] = {
@ -158,9 +174,21 @@ void adcInit(const adcConfig_t *config)
RCC_ClockCmd(adc.rccADC, ENABLE);
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_ADC, device, config->dmaopt[device]);
if (!dmaSpec) {
return;
}
dmaInit(dmaGetIdentifier(dmaSpec->ref), OWNER_ADC, RESOURCE_INDEX(device));
DMA_DeInit(dmaSpec->ref);
#else
dmaInit(dmaGetIdentifier(adc.DMAy_Channelx), OWNER_ADC, 0);
DMA_DeInit(adc.DMAy_Channelx);
#endif
DMA_StructInit(&DMA_InitStructure);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&adc.ADCx->DR;
@ -175,9 +203,13 @@ void adcInit(const adcConfig_t *config)
DMA_InitStructure.DMA_Priority = DMA_Priority_High;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
#if defined(USE_DMA_SPEC)
DMA_Init(dmaSpec->ref, &DMA_InitStructure);
DMA_Cmd(dmaSpec->ref, ENABLE);
#else
DMA_Init(adc.DMAy_Channelx, &DMA_InitStructure);
DMA_Cmd(adc.DMAy_Channelx, ENABLE);
#endif
// calibrate

View file

@ -304,7 +304,7 @@ void adcInit(const adcConfig_t *config)
ADC_Cmd(adc.ADCx, ENABLE);
#ifdef USE_DMA_SPEC
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpec(DMA_PERIPH_ADC, device, config->dmaopt[device]);
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_ADC, device, config->dmaopt[device]);
if (!dmaSpec) {
return;

View file

@ -308,7 +308,7 @@ void adcInit(const adcConfig_t *config)
}
#ifdef USE_DMA_SPEC
const dmaChannelSpec_t *dmaspec = dmaGetChannelSpec(DMA_PERIPH_ADC, device, config->dmaopt[device]);
const dmaChannelSpec_t *dmaspec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_ADC, device, config->dmaopt[device]);
if (!dmaspec) {
return;

View file

@ -28,122 +28,215 @@
#include "drivers/bus_spi.h"
#include "drivers/serial.h"
#include "drivers/serial_uart.h"
#include "drivers/timer_def.h"
#include "drivers/dma_reqmap.h"
#include "pg/timerio.h"
typedef struct dmaRequestMapping_s {
#include "dma_reqmap.h"
#define MAX_PERIPHERAL_DMA_OPTIONS 2
typedef struct dmaPeripheralMapping_s {
dmaPeripheral_e device;
uint8_t index;
dmaChannelSpec_t channelSpec[2];
} dmaRequestMapping_t;
dmaChannelSpec_t channelSpec[MAX_PERIPHERAL_DMA_OPTIONS];
} dmaPeripheralMapping_t;
#define MAX_TIMER_DMA_OPTIONS 3
typedef struct dmaTimerMapping_s {
TIM_TypeDef *tim;
uint8_t channel;
dmaChannelSpec_t channelSpec[MAX_TIMER_DMA_OPTIONS];
} dmaTimerMapping_t;
#if defined(STM32F4) || defined(STM32F7)
#if defined(STM32F4)
#define D(d, s, c) { DMA_CODE(d, s, c), DMA ## d ## _Stream ## s, DMA_Channel_ ## c }
#define DMA(d, s, c) { DMA_CODE(d, s, c), DMA ## d ## _Stream ## s, DMA_Channel_ ## c }
#elif defined(STM32F7)
#define D(d, s, c) { DMA_CODE(d, s, c), DMA ## d ## _Stream ## s, DMA_CHANNEL_ ## c }
#define DMA(d, s, c) { DMA_CODE(d, s, c), DMA ## d ## _Stream ## s, DMA_CHANNEL_ ## c }
#endif
static const dmaRequestMapping_t dmaRequestMapping[] = {
static const dmaPeripheralMapping_t dmaPeripheralMapping[] = {
#ifdef USE_SPI
// Everything including F405 and F446
{ DMA_PERIPH_SPI_TX, SPIDEV_1, { D(2, 3, 3), D(2, 5, 3) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_1, { D(2, 0, 3), D(2, 2, 3) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_2, { D(1, 4, 0) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_2, { D(1, 3, 0) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_3, { D(1, 5, 0), D(1, 7, 0) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_3, { D(1, 0, 0), D(1, 2, 0) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_1, { DMA(2, 3, 3), DMA(2, 5, 3) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_1, { DMA(2, 0, 3), DMA(2, 2, 3) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_2, { DMA(1, 4, 0) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_2, { DMA(1, 3, 0) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_3, { DMA(1, 5, 0), DMA(1, 7, 0) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_3, { DMA(1, 0, 0), DMA(1, 2, 0) } },
#if defined(STM32F411xE) || defined(STM32F745xx) || defined(STM32F746xx) || defined(STM32F765xx) || defined(STM32F722xx)
{ DMA_PERIPH_SPI_TX, SPIDEV_4, { D(2, 1, 4) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_4, { D(2, 0, 4) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_4, { DMA(2, 1, 4) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_4, { DMA(2, 0, 4) } },
#ifdef USE_EXTENDED_SPI_DEVICE
{ DMA_PERIPH_SPI_TX, SPIDEV_5, { D(2, 6, 7) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_5, { D(2, 5, 7) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_5, { DMA(2, 6, 7) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_5, { DMA(2, 5, 7) } },
#if !defined(STM32F722xx)
{ DMA_PERIPH_SPI_TX, SPIDEV_6, { D(2, 5, 1) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_6, { D(2, 6, 1) } },
{ DMA_PERIPH_SPI_TX, SPIDEV_6, { DMA(2, 5, 1) } },
{ DMA_PERIPH_SPI_RX, SPIDEV_6, { DMA(2, 6, 1) } },
#endif
#endif // USE_EXTENDED_SPI_DEVICE
#endif
#endif // USE_SPI
#ifdef USE_ADC
{ DMA_PERIPH_ADC, ADCDEV_1, { D(2, 0, 0), D(2, 4, 0) } },
{ DMA_PERIPH_ADC, ADCDEV_2, { D(2, 2, 1), D(2, 3, 1) } },
{ DMA_PERIPH_ADC, ADCDEV_3, { D(2, 0, 2), D(2, 1, 2) } },
{ DMA_PERIPH_ADC, ADCDEV_1, { DMA(2, 0, 0), DMA(2, 4, 0) } },
{ DMA_PERIPH_ADC, ADCDEV_2, { DMA(2, 2, 1), DMA(2, 3, 1) } },
{ DMA_PERIPH_ADC, ADCDEV_3, { DMA(2, 0, 2), DMA(2, 1, 2) } },
#endif
#ifdef USE_SDCARD_SDIO
{ DMA_PERIPH_SDIO, 0, { D(2, 3, 4), D(2, 6, 4) } },
{ DMA_PERIPH_SDIO, 0, { DMA(2, 3, 4), DMA(2, 6, 4) } },
#endif
#ifdef USE_UART
{ DMA_PERIPH_UART_TX, UARTDEV_1, { D(2, 7, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_1, { D(2, 5, 4), D(2, 2, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_2, { D(1, 6, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_2, { D(1, 5, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_3, { D(1, 3, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_3, { D(1, 1, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_4, { D(1, 4, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_4, { D(1, 2, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_5, { D(1, 7, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_5, { D(1, 0, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_6, { D(2, 6, 5), D(2, 7, 5) } },
{ DMA_PERIPH_UART_RX, UARTDEV_6, { D(2, 1, 5), D(2, 2, 5) } },
{ DMA_PERIPH_UART_TX, UARTDEV_1, { DMA(2, 7, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_1, { DMA(2, 5, 4), DMA(2, 2, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_2, { DMA(1, 6, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_2, { DMA(1, 5, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_3, { DMA(1, 3, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_3, { DMA(1, 1, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_4, { DMA(1, 4, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_4, { DMA(1, 2, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_5, { DMA(1, 7, 4) } },
{ DMA_PERIPH_UART_RX, UARTDEV_5, { DMA(1, 0, 4) } },
{ DMA_PERIPH_UART_TX, UARTDEV_6, { DMA(2, 6, 5), DMA(2, 7, 5) } },
{ DMA_PERIPH_UART_RX, UARTDEV_6, { DMA(2, 1, 5), DMA(2, 2, 5) } },
#endif
};
#undef D
#define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
static const dmaTimerMapping_t dmaTimerMapping[] = {
// Generated from 'timer_def.h'
{ TIM1, TC(CH1), { DMA(2, 6, 0), DMA(2, 1, 6), DMA(2, 3, 6) } },
{ TIM1, TC(CH2), { DMA(2, 6, 0), DMA(2, 2, 6) } },
{ TIM1, TC(CH3), { DMA(2, 6, 0), DMA(2, 6, 6) } },
{ TIM1, TC(CH4), { DMA(2, 4, 6) } },
{ TIM2, TC(CH1), { DMA(1, 5, 3) } },
{ TIM2, TC(CH2), { DMA(1, 6, 3) } },
{ TIM2, TC(CH3), { DMA(1, 1, 3) } },
{ TIM2, TC(CH4), { DMA(1, 7, 3), DMA(1, 6, 3) } },
{ TIM3, TC(CH1), { DMA(1, 4, 5) } },
{ TIM3, TC(CH2), { DMA(1, 5, 5) } },
{ TIM3, TC(CH3), { DMA(1, 7, 5) } },
{ TIM3, TC(CH4), { DMA(1, 2, 5) } },
{ TIM4, TC(CH1), { DMA(1, 0, 2) } },
{ TIM4, TC(CH2), { DMA(1, 3, 2) } },
{ TIM4, TC(CH3), { DMA(1, 7, 2) } },
{ TIM5, TC(CH1), { DMA(1, 2, 6) } },
{ TIM5, TC(CH2), { DMA(1, 4, 6) } },
{ TIM5, TC(CH3), { DMA(1, 0, 6) } },
{ TIM5, TC(CH4), { DMA(1, 1, 6), DMA(1, 3, 6) } },
{ TIM8, TC(CH1), { DMA(2, 2, 0), DMA(2, 2, 7) } },
{ TIM8, TC(CH2), { DMA(2, 2, 0), DMA(2, 3, 7) } },
{ TIM8, TC(CH3), { DMA(2, 2, 0), DMA(2, 4, 7) } },
{ TIM8, TC(CH4), { DMA(2, 7, 7) } },
};
#undef TC
#undef DMA
#else // STM32F3
// The embedded ADC24_DMA_REMAP conditional should be removed
// when (and if) F3 is going generic.
#define D(d, c) { DMA_CODE(d, 0, c), DMA ## d ## _Channel ## c }
static const dmaRequestMapping_t dmaRequestMapping[17] = {
#define DMA(d, c) { DMA_CODE(d, 0, c), DMA ## d ## _Channel ## c }
static const dmaPeripheralMapping_t dmaPeripheralMapping[17] = {
#ifdef USE_SPI
{ DMA_PERIPH_SPI_TX, 1, { D(1, 3) } },
{ DMA_PERIPH_SPI_RX, 1, { D(1, 2) } },
{ DMA_PERIPH_SPI_TX, 2, { D(1, 5) } },
{ DMA_PERIPH_SPI_RX, 2, { D(1, 4) } },
{ DMA_PERIPH_SPI_TX, 3, { D(2, 2) } },
{ DMA_PERIPH_SPI_RX, 3, { D(2, 1) } },
{ DMA_PERIPH_SPI_TX, 1, { DMA(1, 3) } },
{ DMA_PERIPH_SPI_RX, 1, { DMA(1, 2) } },
{ DMA_PERIPH_SPI_TX, 2, { DMA(1, 5) } },
{ DMA_PERIPH_SPI_RX, 2, { DMA(1, 4) } },
{ DMA_PERIPH_SPI_TX, 3, { DMA(2, 2) } },
{ DMA_PERIPH_SPI_RX, 3, { DMA(2, 1) } },
#endif
#ifdef USE_ADC
{ DMA_PERIPH_ADC, 1, { D(1, 1) } },
{ DMA_PERIPH_ADC, 1, { DMA(1, 1) } },
#ifdef ADC24_DMA_REMAP
{ DMA_PERIPH_ADC, 2, { D(2, 3) } },
{ DMA_PERIPH_ADC, 2, { DMA(2, 3) } },
#else
{ DMA_PERIPH_ADC, 2, { D(2, 1) } },
{ DMA_PERIPH_ADC, 2, { DMA(2, 1) } },
#endif
{ DMA_PERIPH_ADC, 3, { D(2, 5) } },
{ DMA_PERIPH_ADC, 3, { DMA(2, 5) } },
#endif
#ifdef USE_UART
{ DMA_PERIPH_UART_TX, 1, { D(1, 4) } },
{ DMA_PERIPH_UART_RX, 1, { D(1, 5) } },
{ DMA_PERIPH_UART_TX, 1, { DMA(1, 4) } },
{ DMA_PERIPH_UART_RX, 1, { DMA(1, 5) } },
{ DMA_PERIPH_UART_TX, 2, { D(1, 7) } },
{ DMA_PERIPH_UART_RX, 2, { D(1, 6) } },
{ DMA_PERIPH_UART_TX, 3, { D(1, 2) } },
{ DMA_PERIPH_UART_RX, 3, { D(1, 3) } },
{ DMA_PERIPH_UART_TX, 4, { D(2, 5) } },
{ DMA_PERIPH_UART_RX, 4, { D(2, 3) } },
{ DMA_PERIPH_UART_TX, 2, { DMA(1, 7) } },
{ DMA_PERIPH_UART_RX, 2, { DMA(1, 6) } },
{ DMA_PERIPH_UART_TX, 3, { DMA(1, 2) } },
{ DMA_PERIPH_UART_RX, 3, { DMA(1, 3) } },
{ DMA_PERIPH_UART_TX, 4, { DMA(2, 5) } },
{ DMA_PERIPH_UART_RX, 4, { DMA(2, 3) } },
};
#endif
#undef D
#define TC(chan) DEF_TIM_CHANNEL(CH_ ## chan)
static const dmaTimerMapping_t dmaTimerMapping[] = {
// Generated from 'timer_def.h'
{ TIM1, TC(CH1), { DMA(1, 2) } },
{ TIM1, TC(CH2), { DMA(1, 3) } },
{ TIM1, TC(CH3), { DMA(1, 6) } },
{ TIM1, TC(CH4), { DMA(1, 4) } },
{ TIM2, TC(CH1), { DMA(1, 5) } },
{ TIM2, TC(CH2), { DMA(1, 7) } },
{ TIM2, TC(CH3), { DMA(1, 1) } },
{ TIM2, TC(CH4), { DMA(1, 7) } },
{ TIM3, TC(CH1), { DMA(1, 6) } },
{ TIM3, TC(CH3), { DMA(1, 2) } },
{ TIM3, TC(CH4), { DMA(1, 3) } },
{ TIM4, TC(CH1), { DMA(1, 1) } },
{ TIM4, TC(CH2), { DMA(1, 4) } },
{ TIM4, TC(CH3), { DMA(1, 5) } },
{ TIM8, TC(CH1), { DMA(2, 3) } },
{ TIM8, TC(CH2), { DMA(2, 5) } },
{ TIM8, TC(CH3), { DMA(2, 1) } },
{ TIM8, TC(CH4), { DMA(2, 2) } },
{ TIM15, TC(CH1), { DMA(1, 5) } },
#ifdef REMAP_TIM16_DMA
{ TIM16, TC(CH1), { DMA(1, 6) } },
#else
{ TIM16, TC(CH1), { DMA(1, 3) } },
#endif
const dmaChannelSpec_t *dmaGetChannelSpec(dmaPeripheral_e device, uint8_t index, int8_t opt)
#ifdef REMAP_TIM17_DMA
{ TIM17, TC(CH1), { DMA(1, 7) } },
#else
{ TIM17, TC(CH1), { DMA(1, 1) } },
#endif
};
#undef TC
#undef DMA
#endif
const dmaChannelSpec_t *dmaGetChannelSpecByPeripheral(dmaPeripheral_e device, uint8_t index, int8_t opt)
{
if (opt < 0 || opt >= 2) {
if (opt < 0 || opt >= MAX_PERIPHERAL_DMA_OPTIONS) {
return NULL;
}
for (unsigned i = 0 ; i < ARRAYLEN(dmaRequestMapping) ; i++) {
const dmaRequestMapping_t *periph = &dmaRequestMapping[i];
for (unsigned i = 0 ; i < ARRAYLEN(dmaPeripheralMapping) ; i++) {
const dmaPeripheralMapping_t *periph = &dmaPeripheralMapping[i];
if (periph->device == device && periph->index == index && periph->channelSpec[opt].ref) {
return &periph->channelSpec[opt];
}
@ -151,4 +244,61 @@ const dmaChannelSpec_t *dmaGetChannelSpec(dmaPeripheral_e device, uint8_t index,
return NULL;
}
static int8_t dmaoptByTag(ioTag_t ioTag)
{
#ifdef USE_TIMER_MGMT
for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
if (timerIOConfig(i)->ioTag == ioTag) {
return timerIOConfig(i)->dmaopt;
}
}
#else
UNUSED(ioTag);
#endif
return -1;
}
const dmaChannelSpec_t *dmaGetChannelSpecByTimer(const timerHardware_t *timer)
{
if (!timer) {
return NULL;
}
int8_t dmaopt = dmaoptByTag(timer->tag);
if (dmaopt < 0 || dmaopt >= MAX_TIMER_DMA_OPTIONS) {
return NULL;
}
for (unsigned i = 0 ; i < ARRAYLEN(dmaTimerMapping) ; i++) {
const dmaTimerMapping_t *timerMapping = &dmaTimerMapping[i];
if (timerMapping->tim == timer->tim && timerMapping->channel == timer->channel && timerMapping->channelSpec[dmaopt].ref) {
return &timerMapping->channelSpec[dmaopt];
}
}
return NULL;
}
int8_t dmaGetOptionByTimer(const timerHardware_t *timer)
{
for (unsigned i = 0 ; i < ARRAYLEN(dmaTimerMapping); i++) {
const dmaTimerMapping_t *timerMapping = &dmaTimerMapping[i];
if (timerMapping->tim == timer->tim && timerMapping->channel == timer->channel) {
for (unsigned j = 0; j < MAX_TIMER_DMA_OPTIONS; j++) {
const dmaChannelSpec_t *dma = &timerMapping->channelSpec[j];
if (dma->ref == timer->dmaRefConfigured
#if defined(STM32F4) || defined(STM32F7)
&& dma->channel == timer->dmaChannelConfigured
#endif
) {
return j;
}
}
}
}
return -1;
}
#endif // USE_DMA_SPEC

View file

@ -22,6 +22,8 @@
#include "platform.h"
#include "drivers/timer.h"
typedef uint16_t dmaCode_t;
typedef struct dmaChannelSpec_s {
@ -52,4 +54,6 @@ typedef enum {
typedef int8_t dmaoptValue_t;
#define DMA_OPT_UNUSED (-1)
const dmaChannelSpec_t *dmaGetChannelSpec(dmaPeripheral_e device, uint8_t index, int8_t opt);
const dmaChannelSpec_t *dmaGetChannelSpecByPeripheral(dmaPeripheral_e device, uint8_t index, int8_t opt);
const dmaChannelSpec_t *dmaGetChannelSpecByTimer(const timerHardware_t *timer);
int8_t dmaGetOptionByTimer(const timerHardware_t *timer);

View file

@ -28,6 +28,7 @@
#include "common/color.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
@ -36,6 +37,8 @@
#include "light_ws2811strip.h"
typedef DMA_Stream_TypeDef dmaStream_t;
static IO_t ws2811IO = IO_NONE;
static TIM_HandleTypeDef TimHandle;
@ -58,7 +61,22 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
TIM_TypeDef *timer = timerHardware->tim;
timerChannel = timerHardware->channel;
if (timerHardware->dmaRef == NULL) {
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByTimer(timerHardware);
if (dmaSpec == NULL) {
return false;
}
dmaStream_t *dmaRef = dmaSpec->ref;
uint32_t dmaChannel = dmaSpec->channel;
#else
dmaStream_t *dmaRef = timerHardware->dmaRef;
uint32_t dmaChannel = timerHardware->dmaChannel;
#endif
if (dmaRef == NULL) {
return false;
}
TimHandle.Instance = timer;
@ -88,7 +106,7 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
__DMA1_CLK_ENABLE();
/* Set the parameters to be configured */
hdma_tim.Init.Channel = timerHardware->dmaChannel;
hdma_tim.Init.Channel = dmaChannel;
hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
@ -102,15 +120,15 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
/* Set hdma_tim instance */
hdma_tim.Instance = timerHardware->dmaRef;
hdma_tim.Instance = dmaRef;
uint16_t dmaIndex = timerDmaIndex(timerChannel);
/* Link hdma_tim to hdma[x] (channelx) */
__HAL_LINKDMA(&TimHandle, hdma[dmaIndex], hdma_tim);
dmaInit(timerHardware->dmaIrqHandler, OWNER_LED_STRIP, 0);
dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, dmaIndex);
dmaInit(dmaGetIdentifier(dmaRef), OWNER_LED_STRIP, 0);
dmaSetHandler(dmaGetIdentifier(dmaRef), WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, dmaIndex);
/* Initialize TIMx DMA handle */
if (HAL_DMA_Init(TimHandle.hdma[dmaIndex]) != HAL_OK) {

View file

@ -31,6 +31,7 @@
#include "common/color.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
@ -38,6 +39,12 @@
#include "light_ws2811strip.h"
#if defined(STM32F4) || defined(STM32F7)
typedef DMA_Stream_TypeDef dmaStream_t;
#else
typedef DMA_Channel_TypeDef dmaStream_t;
#endif
static IO_t ws2811IO = IO_NONE;
#if defined(STM32F4)
static DMA_Stream_TypeDef *dmaRef = NULL;
@ -87,7 +94,25 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
const timerHardware_t *timerHardware = timerGetByTag(ioTag);
timer = timerHardware->tim;
if (timerHardware->dmaRef == NULL) {
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByTimer(timerHardware);
if (dmaSpec == NULL) {
return false;
}
dmaStream_t *dmaRef = dmaSpec->ref;
#if defined(STM32F4)
uint32_t dmaChannel = dmaSpec->channel;
#endif
#else
dmaStream_t *dmaRef = timerHardware->dmaRef;
#if defined(STM32F4)
uint32_t dmaChannel = timerHardware->dmaChannel;
#endif
#endif
if (dmaRef == NULL) {
return false;
}
@ -149,10 +174,9 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
TIM_Cmd(timer, ENABLE);
dmaInit(timerHardware->dmaIrqHandler, OWNER_LED_STRIP, 0);
dmaSetHandler(timerHardware->dmaIrqHandler, WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
dmaInit(dmaGetIdentifier(dmaRef), OWNER_LED_STRIP, 0);
dmaSetHandler(dmaGetIdentifier(dmaRef), WS2811_DMA_IRQHandler, NVIC_PRIO_WS2811_DMA, 0);
dmaRef = timerHardware->dmaRef;
DMA_DeInit(dmaRef);
/* configure DMA */
@ -165,7 +189,7 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
#if defined(STM32F4)
DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel;
DMA_InitStructure.DMA_Channel = dmaChannel;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ledStripDMABuffer;
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;

View file

@ -37,11 +37,10 @@ uint8_t hardwareMotorType = MOTOR_UNKNOWN;
void detectBrushedESC(void)
{
int i = 0;
while (!(timerHardware[i].usageFlags & TIM_USE_MOTOR) && (i < USABLE_TIMER_CHANNEL_COUNT)) {
while (!(TIMER_HARDWARE[i].usageFlags & TIM_USE_MOTOR) && (i < TIMER_CHANNEL_COUNT)) {
i++;
}
IO_t MotorDetectPin = IOGetByTag(timerHardware[i].tag);
IO_t MotorDetectPin = IOGetByTag(TIMER_HARDWARE[i].tag);
IOInit(MotorDetectPin, OWNER_SYSTEM, 0);
IOConfigGPIO(MotorDetectPin, IOCFG_IPU);

View file

@ -150,12 +150,12 @@ typedef struct {
TIM_ICInitTypeDef icInitStruct;
DMA_InitTypeDef dmaInitStruct;
uint8_t dmaInputLen;
#endif
#ifdef STM32F3
DMA_Channel_TypeDef *dmaRef;
#else
DMA_Stream_TypeDef *dmaRef;
#endif
#endif
#endif
motorDmaTimer_t *timer;
volatile bool requestTelemetry;

View file

@ -28,24 +28,32 @@
#include "build/debug.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "timer.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
#include "drivers/time.h"
#include "drivers/timer.h"
#if defined(STM32F4)
#include "stm32f4xx.h"
#elif defined(STM32F3)
#include "stm32f30x.h"
#endif
#include "pwm_output.h"
#include "drivers/nvic.h"
#include "drivers/time.h"
#include "dma.h"
#include "rcc.h"
// TODO remove once debugging no longer needed
#ifdef USE_DSHOT_TELEMETRY
#include <string.h>
#endif
#if defined(STM32F4) || defined(STM32F7)
typedef DMA_Stream_TypeDef dmaStream_t;
#else
typedef DMA_Channel_TypeDef dmaStream_t;
#endif
static uint8_t dmaMotorTimerCount = 0;
static motorDmaTimer_t dmaMotorTimers[MAX_DMA_TIMERS];
static motorDmaOutput_t dmaMotors[MAX_SUPPORTED_MOTORS];
@ -105,8 +113,8 @@ void pwmWriteDshotInt(uint8_t index, uint16_t value)
{
bufferSize = loadDmaBuffer(motor->dmaBuffer, 1, packet);
motor->timer->timerDmaSources |= motor->timerDmaSource;
DMA_SetCurrDataCounter(motor->timerHardware->dmaRef, bufferSize);
DMA_Cmd(motor->timerHardware->dmaRef, ENABLE);
DMA_SetCurrDataCounter(motor->dmaRef, bufferSize);
DMA_Cmd(motor->dmaRef, ENABLE);
}
}
@ -115,7 +123,7 @@ void pwmWriteDshotInt(uint8_t index, uint16_t value)
static void processInputIrq(motorDmaOutput_t * const motor)
{
motor->hasTelemetry = true;
DMA_Cmd(motor->timerHardware->dmaRef, DISABLE);
DMA_Cmd(motor->dmaRef, DISABLE);
TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE);
readDoneCount++;
}
@ -180,12 +188,6 @@ inline FAST_CODE static void pwmDshotSetDirectionOutput(
#endif
)
{
#if defined(STM32F4) || defined(STM32F7)
typedef DMA_Stream_TypeDef dmaStream_t;
#else
typedef DMA_Channel_TypeDef dmaStream_t;
#endif
#ifdef USE_DSHOT_TELEMETRY
TIM_OCInitTypeDef* pOcInit = &motor->ocInitStruct;
DMA_InitTypeDef* pDmaInit = &motor->dmaInitStruct;
@ -194,19 +196,12 @@ inline FAST_CODE static void pwmDshotSetDirectionOutput(
const timerHardware_t * const timerHardware = motor->timerHardware;
TIM_TypeDef *timer = timerHardware->tim;
#ifndef USE_DSHOT_TELEMETRY
dmaStream_t *dmaRef;
dmaStream_t *dmaRef = motor->dmaRef;
#ifdef USE_DSHOT_DMAR
#if defined(USE_DSHOT_DMAR) && !defined(USE_DSHOT_TELEMETRY)
if (useBurstDshot) {
dmaRef = timerHardware->dmaTimUPRef;
} else
#endif
{
dmaRef = timerHardware->dmaRef;
}
#else
dmaStream_t *dmaRef = motor->dmaRef;
#endif
DMA_DeInit(dmaRef);
@ -345,7 +340,7 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
} else
#endif
{
DMA_Cmd(motor->timerHardware->dmaRef, DISABLE);
DMA_Cmd(motor->dmaRef, DISABLE);
TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, DISABLE);
}
@ -353,7 +348,7 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
if (useDshotTelemetry) {
pwmDshotSetDirectionOutput(motor, false);
DMA_SetCurrDataCounter(motor->dmaRef, motor->dmaInputLen);
DMA_Cmd(motor->timerHardware->dmaRef, ENABLE);
DMA_Cmd(motor->dmaRef, ENABLE);
TIM_DMACmd(motor->timerHardware->tim, motor->timerDmaSource, ENABLE);
setDirectionMicros = micros() - irqStart;
}
@ -365,12 +360,6 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t *descriptor)
void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output)
{
#if defined(STM32F4) || defined(STM32F7)
typedef DMA_Stream_TypeDef dmaStream_t;
#else
typedef DMA_Channel_TypeDef dmaStream_t;
#endif
#ifdef USE_DSHOT_TELEMETRY
#define OCINIT motor->ocInitStruct
#define DMAINIT motor->dmaInitStruct
@ -381,16 +370,29 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
#define DMAINIT dmaInitStruct
#endif
dmaStream_t *dmaRef;
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByTimer(timerHardware);
if (dmaSpec == NULL) {
return;
}
dmaStream_t *dmaRef = dmaSpec->ref;
#if defined(STM32F4)
uint32_t dmaChannel = dmaSpec->channel;
#endif
#else
dmaStream_t *dmaRef = timerHardware->dmaRef;
#if defined(STM32F4)
uint32_t dmaChannel = timerHardware->dmaChannel;
#endif
#endif
#ifdef USE_DSHOT_DMAR
if (useBurstDshot) {
dmaRef = timerHardware->dmaTimUPRef;
} else
#endif
{
dmaRef = timerHardware->dmaRef;
}
#endif
if (dmaRef == NULL) {
return;
@ -467,9 +469,6 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
#ifdef USE_DSHOT_DMAR
if (useBurstDshot) {
motor->timer->dmaBurstRef = dmaRef;
#ifdef USE_DSHOT_TELEMETRY
motor->dmaRef = dmaRef;
#endif
} else
#endif
{
@ -508,14 +507,14 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
} else
#endif
{
dmaInit(timerHardware->dmaIrqHandler, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
dmaInit(dmaGetIdentifier(dmaRef), OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
#if defined(STM32F3)
DMAINIT.DMA_MemoryBaseAddr = (uint32_t)motor->dmaBuffer;
DMAINIT.DMA_DIR = DMA_DIR_PeripheralDST;
DMAINIT.DMA_M2M = DMA_M2M_Disable;
#elif defined(STM32F4)
DMAINIT.DMA_Channel = timerHardware->dmaChannel;
DMAINIT.DMA_Channel = dmaChannel;
DMAINIT.DMA_Memory0BaseAddr = (uint32_t)motor->dmaBuffer;
DMAINIT.DMA_DIR = DMA_DIR_MemoryToPeripheral;
DMAINIT.DMA_FIFOMode = DMA_FIFOMode_Enable;
@ -534,8 +533,9 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
// XXX Consolidate common settings in the next refactor
#ifdef USE_DSHOT_TELEMETRY
motor->dmaRef = dmaRef;
#ifdef USE_DSHOT_TELEMETRY
motor->dmaInputLen = motor->useProshot ? PROSHOT_TELEMETRY_INPUT_LEN : DSHOT_TELEMETRY_INPUT_LEN;
pwmDshotSetDirectionOutput(motor, true);
#else
@ -547,7 +547,7 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
} else
#endif
{
dmaSetHandler(timerHardware->dmaIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(2, 1), motor->index);
dmaSetHandler(dmaGetIdentifier(dmaRef), motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(2, 1), motor->index);
}
TIM_Cmd(timer, ENABLE);

View file

@ -26,13 +26,17 @@
#ifdef USE_DSHOT
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "timer.h"
#include "pwm_output.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
#include "drivers/time.h"
#include "dma.h"
#include "rcc.h"
#include "drivers/timer.h"
#include "pwm_output.h"
typedef DMA_Stream_TypeDef dmaStream_t;
static FAST_RAM_ZERO_INIT uint8_t dmaMotorTimerCount = 0;
static FAST_RAM_ZERO_INIT motorDmaTimer_t dmaMotorTimers[MAX_DMA_TIMERS];
@ -84,8 +88,8 @@ FAST_CODE void pwmWriteDshotInt(uint8_t index, uint16_t value)
{
bufferSize = loadDmaBuffer(motor->dmaBuffer, 1, packet);
motor->timer->timerDmaSources |= motor->timerDmaSource;
LL_EX_DMA_SetDataLength(motor->timerHardware->dmaRef, bufferSize);
LL_EX_DMA_EnableStream(motor->timerHardware->dmaRef);
LL_EX_DMA_SetDataLength(motor->dmaRef, bufferSize);
LL_EX_DMA_EnableStream(motor->dmaRef);
}
}
@ -135,7 +139,7 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
} else
#endif
{
LL_EX_DMA_DisableStream(motor->timerHardware->dmaRef);
LL_EX_DMA_DisableStream(motor->dmaRef);
LL_EX_TIM_DisableIT(motor->timerHardware->tim, motor->timerDmaSource);
}
@ -145,16 +149,25 @@ static void motor_DMA_IRQHandler(dmaChannelDescriptor_t* descriptor)
void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t motorIndex, motorPwmProtocolTypes_e pwmProtocolType, uint8_t output)
{
DMA_Stream_TypeDef *dmaRef;
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByTimer(timerHardware);
if (dmaSpec == NULL) {
return;
}
DMA_Stream_TypeDef *dmaRef = dmaSpec->ref;
uint32_t dmaChannel = dmaSpec->channel;
#else
DMA_Stream_TypeDef *dmaRef = timerHardware->dmaRef;
uint32_t dmaChannel = timerHardware->dmaChannel;
#endif
#ifdef USE_DSHOT_DMAR
if (useBurstDshot) {
dmaRef = timerHardware->dmaTimUPRef;
} else
#endif
{
dmaRef = timerHardware->dmaRef;
}
#endif
if (dmaRef == NULL) {
return;
@ -257,10 +270,10 @@ void pwmDshotMotorHardwareConfig(const timerHardware_t *timerHardware, uint8_t m
} else
#endif
{
dmaInit(timerHardware->dmaIrqHandler, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
dmaSetHandler(timerHardware->dmaIrqHandler, motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex);
dmaInit(dmaGetIdentifier(dmaRef), OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
dmaSetHandler(dmaGetIdentifier(dmaRef), motor_DMA_IRQHandler, NVIC_BUILD_PRIORITY(1, 2), motorIndex);
dma_init.Channel = timerHardware->dmaChannel;
dma_init.Channel = dmaChannel;
dma_init.MemoryOrM2MDstAddress = (uint32_t)motor->dmaBuffer;
dma_init.FIFOThreshold = LL_DMA_FIFOTHRESHOLD_1_4;
dma_init.PeriphOrM2MSrcAddress = (uint32_t)timerChCCR(timerHardware);

View file

@ -198,7 +198,7 @@ static void sdcardSdio_init(const sdcardConfig_t *config, const spiPinConfig_t *
return;
}
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpec(DMA_PERIPH_SDIO, 0, sdioConfig()->dmaopt);
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SDIO, 0, sdioConfig()->dmaopt);
if (!dmaChannelSpec) {
sdcard.state = SDCARD_STATE_NOT_PRESENT;

View file

@ -513,7 +513,7 @@ static void sdcardSpi_init(const sdcardConfig_t *config, const spiPinConfig_t *s
dmaIdentifier_e dmaIdentifier = DMA_NONE;
#ifdef USE_DMA_SPEC
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpec(DMA_PERIPH_SPI_TX, config->device, spiConfig[spiDevice].txDmaopt);
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SPI_TX, config->device, spiConfig[spiDevice].txDmaopt);
if (dmaChannelSpec) {
dmaIdentifier = dmaGetIdentifier(dmaChannelSpec->ref);

View file

@ -665,7 +665,7 @@ static serialPort_t *openEscSerial(escSerialPortIndex_e portIndex, serialReceive
escSerial_t *escSerial = &(escSerialPorts[portIndex]);
if (mode != PROTOCOL_KISSALL) {
escSerial->rxTimerHardware = &(timerHardware[output]);
escSerial->rxTimerHardware = &(TIMER_HARDWARE[output]);
// N-Channels can't be used as RX.
if (escSerial->rxTimerHardware->output & TIMER_OUTPUT_N_CHANNEL) {
return NULL;
@ -731,11 +731,11 @@ static serialPort_t *openEscSerial(escSerialPortIndex_e portIndex, serialReceive
for (volatile uint8_t i = 0; i < MAX_SUPPORTED_MOTORS; i++) {
if (pwmMotors[i].enabled) {
if (pwmMotors[i].io != IO_NONE) {
for (volatile uint8_t j = 0; j < USABLE_TIMER_CHANNEL_COUNT; j++) {
if (pwmMotors[i].io == IOGetByTag(timerHardware[j].tag))
for (volatile uint8_t j = 0; j < TIMER_CHANNEL_COUNT; j++) {
if (pwmMotors[i].io == IOGetByTag(TIMER_HARDWARE[j].tag))
{
escSerialOutputPortConfig(&timerHardware[j]);
if (timerHardware[j].output & TIMER_OUTPUT_INVERTED) {
escSerialOutputPortConfig(&TIMER_HARDWARE[j]);
if (TIMER_HARDWARE[j].output & TIMER_OUTPUT_INVERTED) {
escOutputs[escSerial->outputCount].inverted = 1;
}
break;
@ -958,8 +958,8 @@ void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uin
}
else {
uint8_t first_output = 0;
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
if (timerHardware[i].usageFlags & TIM_USE_MOTOR) {
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
if (TIMER_HARDWARE[i].usageFlags & TIM_USE_MOTOR) {
first_output = i;
break;
}
@ -967,7 +967,7 @@ void escEnablePassthrough(serialPort_t *escPassthroughPort, uint16_t output, uin
//doesn't work with messy timertable
motor_output = first_output + output;
if (motor_output >= USABLE_TIMER_CHANNEL_COUNT) {
if (motor_output >= TIMER_CHANNEL_COUNT) {
return;
}
}

View file

@ -64,7 +64,8 @@ timerConfig_t timerConfig[USED_TIMER_COUNT];
typedef struct {
channelType_t type;
} timerChannelInfo_t;
timerChannelInfo_t timerChannelInfo[USABLE_TIMER_CHANNEL_COUNT];
timerChannelInfo_t timerChannelInfo[TIMER_CHANNEL_COUNT];
typedef struct {
uint8_t priority;
@ -363,9 +364,10 @@ void timerConfigure(const timerHardware_t *timerHardwarePtr, uint16_t period, ui
// allocate and configure timer channel. Timer priority is set to highest priority of its channels
void timerChInit(const timerHardware_t *timHw, channelType_t type, int irqPriority, uint8_t irq)
{
unsigned channel = timHw - timerHardware;
if (channel >= USABLE_TIMER_CHANNEL_COUNT)
unsigned channel = timHw - TIMER_HARDWARE;
if (channel >= TIMER_CHANNEL_COUNT) {
return;
}
timerChannelInfo[channel].type = type;
unsigned timer = lookupTimerIndex(timHw->tim);
@ -779,12 +781,12 @@ void timerInit(void)
#endif
/* enable the timer peripherals */
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
RCC_ClockCmd(timerRCC(timerHardware[i].tim), ENABLE);
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
RCC_ClockCmd(timerRCC(TIMER_HARDWARE[i].tim), ENABLE);
}
// initialize timer channel structures
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
timerChannelInfo[i].type = TYPE_FREE;
}
@ -802,10 +804,10 @@ void timerStart(void)
for (unsigned timer = 0; timer < USED_TIMER_COUNT; timer++) {
int priority = -1;
int irq = -1;
for (unsigned hwc = 0; hwc < USABLE_TIMER_CHANNEL_COUNT; hwc++)
if ((timerChannelInfo[hwc].type != TYPE_FREE) && (timerHardware[hwc].tim == usedTimers[timer])) {
for (unsigned hwc = 0; hwc < TIMER_CHANNEL_COUNT; hwc++)
if ((timerChannelInfo[hwc].type != TYPE_FREE) && (TIMER_HARDWARE[hwc].tim == usedTimers[timer])) {
// TODO - move IRQ to timer info
irq = timerHardware[hwc].irq;
irq = TIMER_HARDWARE[hwc].irq;
}
// TODO - aggregate required timer paramaters
configTimeBase(usedTimers[timer], 0, 1);

View file

@ -106,13 +106,21 @@ typedef struct timerHardware_s {
uint8_t alternateFunction;
#endif
#if defined(USE_DSHOT) || defined(USE_LED_STRIP) || defined(USE_TRANSPONDER)
#if defined(USE_DMA_SPEC)
#if defined(STM32F4) || defined(STM32F7)
DMA_Stream_TypeDef *dmaRefConfigured;
uint32_t dmaChannelConfigured;
#else
DMA_Channel_TypeDef *dmaRefConfigured;
#endif
#else
#if defined(STM32F4) || defined(STM32F7)
DMA_Stream_TypeDef *dmaRef;
uint32_t dmaChannel;
#else
DMA_Channel_TypeDef *dmaRef;
#endif
uint8_t dmaIrqHandler;
#endif
#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
// TIMUP
#ifdef STM32F3
@ -152,7 +160,49 @@ typedef enum {
#define MHZ_TO_HZ(x) ((x) * 1000000)
#if !defined(USE_UNIFIED_TARGET)
extern const timerHardware_t timerHardware[];
#endif
#if defined(USE_TIMER_MGMT)
#if defined(STM32F40_41xxx)
#define FULL_TIMER_CHANNEL_COUNT 70
#elif defined(STM32F722xx)
#define FULL_TIMER_CHANNEL_COUNT 70
#endif
extern const timerHardware_t fullTimerHardware[];
#define TIMER_CHANNEL_COUNT FULL_TIMER_CHANNEL_COUNT
#define TIMER_HARDWARE fullTimerHardware
#if defined(STM32F7) || defined(STM32F4)
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) )
#elif defined(STM32F3)
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
#elif defined(STM32F1)
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) )
#else
#error "No timer / channel tag definition found for CPU"
#endif
#else
#define TIMER_CHANNEL_COUNT USABLE_TIMER_CHANNEL_COUNT
#define TIMER_HARDWARE timerHardware
#endif // USE_TIMER_MGMT
extern const timerDef_t timerDefinitions[];
typedef enum {

View file

@ -27,7 +27,7 @@
#include "pg/timerio.h"
#endif
uint8_t timerIndexByTag(ioTag_t ioTag)
static uint8_t timerIndexByTag(ioTag_t ioTag)
{
#ifdef USE_TIMER_MGMT
for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
@ -47,24 +47,28 @@ const timerHardware_t *timerGetByTag(ioTag_t ioTag)
return NULL;
}
#if TIMER_CHANNEL_COUNT > 0
uint8_t timerIndex = timerIndexByTag(ioTag);
uint8_t index = 1;
for (int i = 0; i < (int)USABLE_TIMER_CHANNEL_COUNT; i++) {
if (timerHardware[i].tag == ioTag) {
if (index == timerIndex || timerIndex == 0) {
return &timerHardware[i];
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
if (TIMER_HARDWARE[i].tag == ioTag) {
if (index == timerIndex || timerIndex == 0) {
return &TIMER_HARDWARE[i];
}
index++;
}
}
#else
UNUSED(timerIndexByTag);
#endif
return NULL;
}
ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index)
{
#if !defined(USE_UNIFIED_TARGET) && USABLE_TIMER_CHANNEL_COUNT > 0
uint8_t currentIndex = 0;
for (int i = 0; i < (int)USABLE_TIMER_CHANNEL_COUNT; i++) {
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
if ((timerHardware[i].usageFlags & usageFlag) == usageFlag) {
if (currentIndex == index) {
return timerHardware[i].tag;
@ -72,5 +76,9 @@ ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index)
currentIndex++;
}
}
#else
UNUSED(usageFlag);
UNUSED(index);
#endif
return IO_TAG_NONE;
}

View file

@ -30,6 +30,11 @@
# define DEF_TIM_DMA_COND(...)
#endif
#if defined(USE_TIMER_MGMT)
#define TIMER_GET_IO_TAG(pin) DEFIO_TAG_E(pin)
#else
#define TIMER_GET_IO_TAG(pin) DEFIO_TAG(pin)
#endif
// map to base channel (strip N from channel); works only when channel N exists
#define DEF_TIM_TCH2BTCH(timch) CONCAT(B, timch)
@ -117,13 +122,12 @@
#define DEF_TIM(tim, chan, pin, flags, out) { \
tim, \
IO_TAG(pin), \
TIMER_GET_IO_TAG(pin), \
DEF_TIM_CHANNEL(CH_ ## chan), \
flags, \
(DEF_TIM_OUTPUT(CH_ ## chan) | out) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_CHANNEL(TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_HANDLER(TCH_## tim ## _ ## chan) \
DEF_TIM_DMA_CHANNEL(TCH_## tim ## _ ## chan) \
) \
} \
/**/
@ -135,10 +139,6 @@
#define DEF_TIM_DMA_CHANNEL__D(dma_n, chan_n) DMA ## dma_n ## _Channel ## chan_n
#define DEF_TIM_DMA_CHANNEL__NONE NULL
#define DEF_TIM_DMA_HANDLER(timch) CONCAT(DEF_TIM_DMA_HANDLER__, DEF_TIM_DMA_GET(0, timch))
#define DEF_TIM_DMA_HANDLER__D(dma_n, chan_n) DMA ## dma_n ## _CH ## chan_n ## _HANDLER
#define DEF_TIM_DMA_HANDLER__NONE 0
/* add F1 DMA mappings here */
// D(dma_n, channel_n)
#define DEF_TIM_DMA__BTCH_TIM1_CH1 D(1, 2)
@ -165,14 +165,13 @@
#define DEF_TIM(tim, chan, pin, flags, out) { \
tim, \
IO_TAG(pin), \
TIMER_GET_IO_TAG(pin), \
DEF_TIM_CHANNEL(CH_ ## chan), \
flags, \
(DEF_TIM_OUTPUT(CH_ ## chan) | out), \
DEF_TIM_AF(TCH_## tim ## _ ## chan, pin) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_CHANNEL(TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_HANDLER(TCH_## tim ## _ ## chan) \
DEF_TIM_DMA_CHANNEL(TCH_## tim ## _ ## chan) \
) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_CHANNEL(TCH_## tim ## _UP), \
@ -382,15 +381,14 @@
#define DEF_TIM(tim, chan, pin, flags, out, dmaopt) { \
tim, \
IO_TAG(pin), \
TIMER_GET_IO_TAG(pin), \
DEF_TIM_CHANNEL(CH_ ## chan), \
flags, \
(DEF_TIM_OUTPUT(CH_ ## chan) | out), \
DEF_TIM_AF(TIM_ ## tim) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_STREAM(dmaopt, TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_CHANNEL(dmaopt, TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_HANDLER(dmaopt, TCH_## tim ## _ ## chan) \
DEF_TIM_DMA_CHANNEL(dmaopt, TCH_## tim ## _ ## chan) \
) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_STREAM(0, TCH_## tim ## _UP), \
@ -488,15 +486,14 @@
#elif defined(STM32F7)
#define DEF_TIM(tim, chan, pin, flags, out, dmaopt) { \
tim, \
IO_TAG(pin), \
TIMER_GET_IO_TAG(pin), \
DEF_TIM_CHANNEL(CH_ ## chan), \
flags, \
(DEF_TIM_OUTPUT(CH_ ## chan) | out), \
DEF_TIM_AF(TCH_## tim ## _ ## chan, pin) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_STREAM(dmaopt, TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_CHANNEL(dmaopt, TCH_## tim ## _ ## chan), \
DEF_TIM_DMA_HANDLER(dmaopt, TCH_## tim ## _ ## chan) \
DEF_TIM_DMA_CHANNEL(dmaopt, TCH_## tim ## _ ## chan) \
) \
DEF_TIM_DMA_COND(/* add comma */ , \
DEF_TIM_DMA_STREAM(0, TCH_## tim ## _UP), \
@ -703,25 +700,3 @@
#define DEF_TIM_AF__PI7__TCH_TIM8_CH3 D(3, 8)
#endif
#ifdef USE_TIMER_MGMT
#if defined(STM32F7) || defined(STM32F4)
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(9) | TIM_N(10) | TIM_N(11) | TIM_N(12) | TIM_N(13) | TIM_N(14) )
#elif defined(STM32F3)
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) | TIM_N(5) | TIM_N(6) | TIM_N(7) | TIM_N(8) | TIM_N(15) | TIM_N(16) | TIM_N(17) )
#elif defined(STM32F1)
#define USED_TIMERS ( TIM_N(1) | TIM_N(2) | TIM_N(3) | TIM_N(4) )
#else
#error "No timer / channel tag definition found for CPU"
#endif
#define TIMER_COUNT BITCOUNT(USED_TIMERS)
#endif

View file

@ -65,7 +65,7 @@ timerConfig_t timerConfig[USED_TIMER_COUNT + 1];
typedef struct {
channelType_t type;
} timerChannelInfo_t;
timerChannelInfo_t timerChannelInfo[USABLE_TIMER_CHANNEL_COUNT];
timerChannelInfo_t timerChannelInfo[TIMER_CHANNEL_COUNT];
typedef struct {
uint8_t priority;
@ -389,8 +389,8 @@ void timerChInit(const timerHardware_t *timHw, channelType_t type, int irqPriori
if (timerIndex >= USED_TIMER_COUNT) {
return;
}
unsigned channel = timHw - timerHardware;
if (channel >= USABLE_TIMER_CHANNEL_COUNT)
unsigned channel = timHw - TIMER_HARDWARE;
if (channel >= TIMER_CHANNEL_COUNT)
return;
timerChannelInfo[channel].type = type;
@ -868,13 +868,13 @@ void timerInit(void)
#endif
/* enable the timer peripherals */
for (int i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
RCC_ClockCmd(timerRCC(timerHardware[i].tim), ENABLE);
for (int i = 0; i < TIMER_CHANNEL_COUNT; i++) {
RCC_ClockCmd(timerRCC(TIMER_HARDWARE[i].tim), ENABLE);
}
#if defined(STM32F3) || defined(STM32F4) || defined(STM32F7)
for (unsigned timerIndex = 0; timerIndex < USABLE_TIMER_CHANNEL_COUNT; timerIndex++) {
const timerHardware_t *timerHardwarePtr = &timerHardware[timerIndex];
for (unsigned timerIndex = 0; timerIndex < TIMER_CHANNEL_COUNT; timerIndex++) {
const timerHardware_t *timerHardwarePtr = &TIMER_HARDWARE[timerIndex];
if (timerHardwarePtr->usageFlags == TIM_USE_NONE) {
continue;
}
@ -884,12 +884,12 @@ void timerInit(void)
#endif
/* enable the timer peripherals */
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
RCC_ClockCmd(timerRCC(timerHardware[i].tim), ENABLE);
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
RCC_ClockCmd(timerRCC(TIMER_HARDWARE[i].tim), ENABLE);
}
// initialize timer channel structures
for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
timerChannelInfo[i].type = TYPE_FREE;
}
@ -907,10 +907,10 @@ void timerStart(void)
for (unsigned timer = 0; timer < USED_TIMER_COUNT; timer++) {
int priority = -1;
int irq = -1;
for (unsigned hwc = 0; hwc < USABLE_TIMER_CHANNEL_COUNT; hwc++) {
if ((timerChannelInfo[hwc].type != TYPE_FREE) && (timerHardware[hwc].tim == usedTimers[timer])) {
for (unsigned hwc = 0; hwc < TIMER_CHANNEL_COUNT; hwc++) {
if ((timerChannelInfo[hwc].type != TYPE_FREE) && (TIMER_HARDWARE[hwc].tim == usedTimers[timer])) {
// TODO - move IRQ to timer info
irq = timerHardware[hwc].irq;
irq = TIMER_HARDWARE[hwc].irq;
}
}
// TODO - aggregate required timer paramaters

View file

@ -22,10 +22,15 @@
#include "common/utils.h"
#include "drivers/dma.h"
#include "drivers/io.h"
#include "drivers/timer_def.h"
#include "stm32f4xx.h"
#include "rcc.h"
#include "timer.h"
const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
{ .TIMx = TIM1, .rcc = RCC_APB2(TIM1), .inputIrq = TIM1_CC_IRQn},
{ .TIMx = TIM2, .rcc = RCC_APB1(TIM2), .inputIrq = TIM2_IRQn},
@ -47,6 +52,104 @@ const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
#endif
};
#if defined(USE_TIMER_MGMT)
#if defined(STM32F40_41xxx)
const timerHardware_t fullTimerHardware[FULL_TIMER_CHANNEL_COUNT] = {
// Auto-generated from 'timer_def.h'
//PORTA
DEF_TIM(TIM2, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PA9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PA10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM13, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM14, CH1, PA7, TIM_USE_ANY, 0, 0),
//PORTB
DEF_TIM(TIM1, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PB3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PB10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PB11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PB13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PB4, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PB5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH1, PB6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PB7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM10, CH1, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH1, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0),
//PORTC
DEF_TIM(TIM3, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PC9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0),
//PORTD
DEF_TIM(TIM4, CH1, PD12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PD13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PD14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PD15, TIM_USE_ANY, 0, 0),
//PORTE
DEF_TIM(TIM1, CH1N, PE8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PE9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PE10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PE11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PE12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PE13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH4, PE14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PE5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PE6, TIM_USE_ANY, 0, 0),
//PORTF
DEF_TIM(TIM10, CH1, PF6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PF7, TIM_USE_ANY, 0, 0),
};
#endif
#endif // USE_TIMER_MGMT
/*
need a mapping from dma and timers to pins, and the values should all be set here to the dmaMotors array.
this mapping could be used for both these motors and for led strip.

View file

@ -22,6 +22,10 @@
#include "common/utils.h"
#include "drivers/dma.h"
#include "drivers/io.h"
#include "drivers/timer_def.h"
#include "stm32f7xx.h"
#include "rcc.h"
#include "timer.h"
@ -43,6 +47,104 @@ const timerDef_t timerDefinitions[HARDWARE_TIMER_DEFINITION_COUNT] = {
{ .TIMx = TIM14, .rcc = RCC_APB1(TIM14), .inputIrq = TIM8_TRG_COM_TIM14_IRQn},
};
#if defined(USE_TIMER_MGMT)
#if defined(STM32F722xx)
const timerHardware_t fullTimerHardware[FULL_TIMER_CHANNEL_COUNT] = {
// Auto-generated from 'timer_def.h'
//PORTA
DEF_TIM(TIM2, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PA9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PA10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM13, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM14, CH1, PA7, TIM_USE_ANY, 0, 0),
//PORTB
DEF_TIM(TIM1, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PB3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PB10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PB11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PB13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PB4, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PB5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH1, PB6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PB7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM10, CH1, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH1, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0),
//PORTC
DEF_TIM(TIM3, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PC9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0),
//PORTD
DEF_TIM(TIM4, CH1, PD12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PD13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PD14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PD15, TIM_USE_ANY, 0, 0),
//PORTE
DEF_TIM(TIM1, CH1N, PE8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PE9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PE10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PE11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PE12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PE13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH4, PE14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PE5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PE6, TIM_USE_ANY, 0, 0),
//PORTF
DEF_TIM(TIM10, CH1, PF6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PF7, TIM_USE_ANY, 0, 0),
};
#endif
#endif // USE_TIMER_MGMT
/*
need a mapping from dma and timers to pins, and the values should all be set here to the dmaMotors array.
this mapping could be used for both these motors and for led strip.

View file

@ -21,6 +21,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include "platform.h"
#ifdef USE_TRANSPONDER

View file

@ -20,6 +20,8 @@
#pragma once
#include "drivers/transponder_ir.h"
// aRCiTimer transponder codes:
//
// ID1 0x1F, 0xFC, 0x8F, 0x3, 0xF0, 0x1, 0xF8, 0x1F, 0x0 // E00370FC0FFE07E0FF

View file

@ -26,20 +26,22 @@
#ifdef USE_TRANSPONDER
#include "dma.h"
#include "drivers/nvic.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "rcc.h"
#include "timer.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
#include "drivers/timer.h"
#include "drivers/transponder_ir_arcitimer.h"
#include "drivers/transponder_ir_erlt.h"
#include "drivers/transponder_ir_ilap.h"
#include "transponder_ir.h"
#include "drivers/transponder_ir_arcitimer.h"
#include "drivers/transponder_ir_ilap.h"
#include "drivers/transponder_ir_erlt.h"
typedef DMA_Stream_TypeDef dmaStream_t;
volatile uint8_t transponderIrDataTransferInProgress = 0;
static IO_t transponderIO = IO_NONE;
static TIM_HandleTypeDef TimHandle;
static uint16_t timerChannel = 0;
@ -68,7 +70,21 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
TIM_TypeDef *timer = timerHardware->tim;
timerChannel = timerHardware->channel;
if (timerHardware->dmaRef == NULL) {
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByTimer(timerHardware);
if (dmaSpec == NULL) {
return;
}
dmaStream_t *dmaRef = dmaSpec->ref;
uint32_t dmaChannel = dmaSpec->channel;
#else
dmaStream_t *dmaRef = timerHardware->dmaRef;
uint32_t dmaChannel = timerHardware->dmaChannel;
#endif
if (dmaRef == NULL) {
return;
}
@ -101,7 +117,7 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
__DMA1_CLK_ENABLE();
/* Set the parameters to be configured */
hdma_tim.Init.Channel = timerHardware->dmaChannel;
hdma_tim.Init.Channel = dmaChannel;
hdma_tim.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tim.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tim.Init.MemInc = DMA_MINC_ENABLE;
@ -115,15 +131,15 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
hdma_tim.Init.PeriphBurst = DMA_PBURST_SINGLE;
/* Set hdma_tim instance */
hdma_tim.Instance = timerHardware->dmaRef;
hdma_tim.Instance = dmaRef;
uint16_t dmaIndex = timerDmaIndex(timerChannel);
/* Link hdma_tim to hdma[x] (channelx) */
__HAL_LINKDMA(&TimHandle, hdma[dmaIndex], hdma_tim);
dmaInit(timerHardware->dmaIrqHandler, OWNER_TRANSPONDER, 0);
dmaSetHandler(timerHardware->dmaIrqHandler, TRANSPONDER_DMA_IRQHandler, NVIC_PRIO_TRANSPONDER_DMA, dmaIndex);
dmaInit(dmaGetIdentifier(dmaRef), OWNER_TRANSPONDER, 0);
dmaSetHandler(dmaGetIdentifier(dmaRef), TRANSPONDER_DMA_IRQHandler, NVIC_PRIO_TRANSPONDER_DMA, dmaIndex);
/* Initialize TIMx DMA handle */
if (HAL_DMA_Init(TimHandle.hdma[dmaIndex]) != HAL_OK) {

View file

@ -26,20 +26,26 @@
#ifdef USE_TRANSPONDER
#include "dma.h"
#include "drivers/nvic.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h"
#include "drivers/io.h"
#include "rcc.h"
#include "timer.h"
#include "drivers/nvic.h"
#include "drivers/rcc.h"
#include "drivers/timer.h"
#include "drivers/transponder_ir_arcitimer.h"
#include "drivers/transponder_ir_erlt.h"
#include "drivers/transponder_ir_ilap.h"
#include "transponder_ir.h"
#include "drivers/transponder_ir_arcitimer.h"
#include "drivers/transponder_ir_ilap.h"
#include "drivers/transponder_ir_erlt.h"
#if defined(STM32F4) || defined(STM32F7)
typedef DMA_Stream_TypeDef dmaStream_t;
#else
typedef DMA_Channel_TypeDef dmaStream_t;
#endif
volatile uint8_t transponderIrDataTransferInProgress = 0;
static IO_t transponderIO = IO_NONE;
static TIM_TypeDef *timer = NULL;
#if defined(STM32F3)
@ -75,7 +81,25 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
const timerHardware_t *timerHardware = timerGetByTag(ioTag);
timer = timerHardware->tim;
if (timerHardware->dmaRef == NULL) {
#if defined(USE_DMA_SPEC)
const dmaChannelSpec_t *dmaSpec = dmaGetChannelSpecByTimer(timerHardware);
if (dmaSpec == NULL) {
return;
}
dmaStream_t *dmaRef = dmaSpec->ref;
#if defined(STM32F4)
uint32_t dmaChannel = dmaSpec->channel;
#endif
#else
dmaStream_t *dmaRef = timerHardware->dmaRef;
#if defined(STM32F4)
uint32_t dmaChannel = timerHardware->dmaChannel;
#endif
#endif
if (dmaRef == NULL) {
return;
}
@ -83,8 +107,8 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
IOInit(transponderIO, OWNER_TRANSPONDER, 0);
IOConfigGPIOAF(transponderIO, IO_CONFIG(GPIO_Mode_AF, GPIO_Speed_50MHz, GPIO_OType_PP, GPIO_PuPd_DOWN), timerHardware->alternateFunction);
dmaInit(timerHardware->dmaIrqHandler, OWNER_TRANSPONDER, 0);
dmaSetHandler(timerHardware->dmaIrqHandler, TRANSPONDER_DMA_IRQHandler, NVIC_PRIO_TRANSPONDER_DMA, 0);
dmaInit(dmaGetIdentifier(dmaRef), OWNER_TRANSPONDER, 0);
dmaSetHandler(dmaGetIdentifier(dmaRef), TRANSPONDER_DMA_IRQHandler, NVIC_PRIO_TRANSPONDER_DMA, 0);
RCC_ClockCmd(timerRCC(timer), ENABLE);
@ -119,7 +143,6 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
TIM_CtrlPWMOutputs(timer, ENABLE);
/* configure DMA */
dmaRef = timerHardware->dmaRef;
DMA_Cmd(dmaRef, DISABLE);
DMA_DeInit(dmaRef);
@ -130,7 +153,7 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
#elif defined(STM32F4)
DMA_InitStructure.DMA_Channel = timerHardware->dmaChannel;
DMA_InitStructure.DMA_Channel = dmaChannel;
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&(transponder->transponderIrDMABuffer);
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;
#endif

View file

@ -52,10 +52,9 @@ void pgResetFn_transponderConfig(transponderConfig_t *transponderConfig)
.data = { 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0x0, 0x0, 0x0 }, // Note, this is NOT a valid transponder code, it's just for testing production hardware
.ioTag = IO_TAG_NONE
);
for (int i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
if (timerHardware[i].usageFlags & TIM_USE_TRANSPONDER) {
transponderConfig->ioTag = timerHardware[i].tag;
for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
if (TIMER_HARDWARE[i].usageFlags & TIM_USE_TRANSPONDER) {
transponderConfig->ioTag = TIMER_HARDWARE[i].tag;
break;
}
}

View file

@ -162,7 +162,7 @@ static int8_t STORAGE_Init (uint8_t lun)
LED0_OFF;
#ifdef USE_DMA_SPEC
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpec(DMA_PERIPH_SDIO, 0, sdioConfig()->dmaopt);
const dmaChannelSpec_t *dmaChannelSpec = dmaGetChannelSpecByPeripheral(DMA_PERIPH_SDIO, 0, sdioConfig()->dmaopt);
if (!dmaChannelSpec) {
return 1;

View file

@ -18,10 +18,46 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "timerio.h"
#include <string.h>
#include "platform.h"
#ifdef USE_TIMER_MGMT
PG_REGISTER_ARRAY(timerIOConfig_t, MAX_TIMER_PINMAP_COUNT, timerIOConfig, PG_TIMER_IO_CONFIG, 0);
#include "drivers/dma_reqmap.h"
#include "drivers/timer.h"
#endif
#include "timerio.h"
PG_REGISTER_ARRAY_WITH_RESET_FN(timerIOConfig_t, MAX_TIMER_PINMAP_COUNT, timerIOConfig, PG_TIMER_IO_CONFIG, 0);
void pgResetFn_timerIOConfig(timerIOConfig_t *config)
{
#if defined(USE_TIMER_MGMT) && !defined(USE_UNIFIED_TARGET)
unsigned configIndex = 0;
for (unsigned timerIndex = 0; timerIndex < USABLE_TIMER_CHANNEL_COUNT; timerIndex++) {
const timerHardware_t *configuredTimer = &timerHardware[timerIndex];
unsigned positionIndex = 1;
for (unsigned fullTimerIndex = 0; fullTimerIndex < FULL_TIMER_CHANNEL_COUNT; fullTimerIndex++) {
const timerHardware_t *timer = &fullTimerHardware[fullTimerIndex];
if (timer->tag == configuredTimer->tag) {
if (timer->tim == configuredTimer->tim && timer->channel == configuredTimer->channel) {
config[configIndex].ioTag = timer->tag;
config[configIndex].index = positionIndex;
config[configIndex].dmaopt = dmaGetOptionByTimer(configuredTimer);
configIndex++;
break;
} else {
positionIndex++;
}
}
}
}
#else
UNUSED(config);
#endif
}
#endif

View file

@ -30,6 +30,7 @@
typedef struct timerIOConfig_s {
ioTag_t ioTag;
uint8_t index;
int8_t dmaopt;
} timerIOConfig_t;
PG_DECLARE_ARRAY(timerIOConfig_t, MAX_TIMER_PINMAP_COUNT, timerIOConfig);

View file

@ -18,104 +18,5 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include "platform.h"
#include "drivers/io.h"
#include "drivers/dma.h"
#include "drivers/timer.h"
#include "drivers/timer_def.h"
const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
// Auto-generated from 'timer_def.h'
//PORTA
DEF_TIM(TIM2, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PA9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PA10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM13, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM14, CH1, PA7, TIM_USE_ANY, 0, 0),
//PORTB
DEF_TIM(TIM1, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PB3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PB10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PB11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PB13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PB4, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PB5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH1, PB6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PB7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM10, CH1, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH1, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0),
//PORTC
DEF_TIM(TIM3, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PC9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0),
//PORTD
DEF_TIM(TIM4, CH1, PD12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PD13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PD14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PD15, TIM_USE_ANY, 0, 0),
//PORTE
DEF_TIM(TIM1, CH1N, PE8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PE9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PE10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PE11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PE12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PE13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH4, PE14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PE5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PE6, TIM_USE_ANY, 0, 0),
//PORTF
DEF_TIM(TIM10, CH1, PF6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PF7, TIM_USE_ANY, 0, 0),
};
// Needed to suppress the pedantic warning about an empty file
#include <stddef.h>

View file

@ -110,7 +110,3 @@
#define TARGET_IO_PORTD 0xffff
#define TARGET_IO_PORTE 0xffff
#define TARGET_IO_PORTF 0xffff
#define USABLE_TIMER_CHANNEL_COUNT 70
#define USE_TIMER_MGMT

View file

@ -18,104 +18,5 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include "platform.h"
#include "drivers/io.h"
#include "drivers/dma.h"
#include "drivers/timer.h"
#include "drivers/timer_def.h"
const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT] = {
// Auto-generated from 'timer_def.h'
//PORTA
DEF_TIM(TIM2, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PA8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PA9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PA10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PA11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH1, PA15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH1, PA0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH2, PA1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH3, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM5, CH4, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PA2, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PA3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1N, PA7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM13, CH1, PA6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM14, CH1, PA7, TIM_USE_ANY, 0, 0),
//PORTB
DEF_TIM(TIM1, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH2, PB3, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH3, PB10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM2, CH4, PB11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1N, PB13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH1, PB4, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PB5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH1, PB6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PB7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB0, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB1, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM10, CH1, PB8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PB9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2N, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3N, PB15, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH1, PB14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM12, CH2, PB15, TIM_USE_ANY, 0, 0),
//PORTC
DEF_TIM(TIM3, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM3, CH4, PC9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH1, PC6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH2, PC7, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH3, PC8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM8, CH4, PC9, TIM_USE_ANY, 0, 0),
//PORTD
DEF_TIM(TIM4, CH1, PD12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH2, PD13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH3, PD14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM4, CH4, PD15, TIM_USE_ANY, 0, 0),
//PORTE
DEF_TIM(TIM1, CH1N, PE8, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH1, PE9, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2N, PE10, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH2, PE11, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3N, PE12, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH3, PE13, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM1, CH4, PE14, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH1, PE5, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM9, CH2, PE6, TIM_USE_ANY, 0, 0),
//PORTF
DEF_TIM(TIM10, CH1, PF6, TIM_USE_ANY, 0, 0),
DEF_TIM(TIM11, CH1, PF7, TIM_USE_ANY, 0, 0),
};
// Needed to suppress the pedantic warning about an empty file
#include <stddef.h>

View file

@ -110,7 +110,3 @@
#define TARGET_IO_PORTD 0xffff
#define TARGET_IO_PORTE 0xffff
#define TARGET_IO_PORTF 0xffff
#define USABLE_TIMER_CHANNEL_COUNT 70
#define USE_TIMER_MGMT

View file

@ -276,3 +276,13 @@
#undef BEEPER_PIN
#undef BEEPER_PWM_HZ
#endif
#if !defined(USE_DMA_SPEC)
#undef USE_TIMER_MGMT
#endif
#if defined(USE_TIMER_MGMT)
#undef USED_TIMERS
#else
#undef USE_UNIFIED_TARGET
#endif

View file

@ -70,6 +70,10 @@
#define USE_OVERCLOCK
#endif
#if defined(STM32F40_41xxx)
#define USE_TIMER_MGMT
#endif
#endif // STM32F4
#ifdef STM32F7
@ -89,6 +93,11 @@
#define USE_DMA_SPEC
// Re-enable this after 4.0 has been released, and remove the define from STM32F4DISCOVERY
//#define USE_SPI_TRANSACTION
#if defined(STM32F722xx)
#define USE_TIMER_MGMT
#endif
#endif // STM32F7
#if defined(STM32F4) || defined(STM32F7)

View file

@ -18,7 +18,6 @@
extern "C" {
#include <target.h>
#include <drivers/timer.h>
extern const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT];
}
#include <bitset>
@ -28,6 +27,11 @@ extern "C" {
#include <string>
#include "gtest/gtest.h"
#if !defined(USE_UNIFIED_TARGET)
extern "C" {
extern const timerHardware_t timerHardware[USABLE_TIMER_CHANNEL_COUNT];
}
TEST(TimerDefinitionTest, Test_counterMismatch) {
for (const timerHardware_t &t : timerHardware)
ASSERT_EQ(&t - timerHardware, t.def_tim_counter)
@ -39,7 +43,6 @@ TEST(TimerDefinitionTest, Test_counterMismatch) {
<< " array element appears to be " << &t - timerHardware - 1 << '.';
}
#if !defined(USE_TIMER_MGMT)
TEST(TimerDefinitionTest, Test_duplicatePin) {
std::set<TestPinEnum> usedPins;
for (const timerHardware_t &t : timerHardware)
@ -51,6 +54,7 @@ TEST(TimerDefinitionTest, Test_duplicatePin) {
EXPECT_EQ(USABLE_TIMER_CHANNEL_COUNT, usedPins.size());
}
#if !defined(USE_TIMER_MGMT)
namespace {
std::string writeUsedTimers(const std::bitset<TEST_TIMER_SIZE> &tset) {
std::stringstream used_timers;
@ -103,3 +107,4 @@ extern "C" {
void bstInit(int) {}
}
#endif // USE_UNIFIED_TARGET