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:
parent
9f8ad1aa44
commit
f8103b8c86
37 changed files with 904 additions and 484 deletions
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "platform.h"
|
||||
|
||||
#ifdef USE_TRANSPONDER
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue