mirror of
https://github.com/betaflight/betaflight.git
synced 2025-07-23 08:15:30 +03:00
Merge pull request #7620 from mikeller/add_timer_management_to_all_f4
Enabled timer management for all F405 / F722 boards.
This commit is contained in:
commit
750e7c30cf
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