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

Merge pull request #8666 from mikeller/add_timers_show

Added 'timer show' command to CLI.
This commit is contained in:
Michael Keller 2019-08-09 05:49:07 +12:00 committed by GitHub
commit 26bca16d9e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 264 additions and 176 deletions

View file

@ -16,6 +16,8 @@ A clear and concise description of what you expected to happen.
**Flight controller configuration** **Flight controller configuration**
Create a `diff` and post it here in a code block. Put ``` (three backticks) at the start and end of the `diff` block (instructions on how to do a diff: https://oscarliang.com/use-diff-not-dump-betaflight/) Create a `diff` and post it here in a code block. Put ``` (three backticks) at the start and end of the `diff` block (instructions on how to do a diff: https://oscarliang.com/use-diff-not-dump-betaflight/)
Use `resource show all` to create a resource allocation list and post it here in a code block. Put ``` (three backticks) at the start and end of the output block.
**Setup / Versions** **Setup / Versions**
- Flight controller [what type is it, where was it bought from]; - Flight controller [what type is it, where was it bought from];
- Other components [RX, VTX, brand / model for all of them, firmware version where applicable]; - Other components [RX, VTX, brand / model for all of them, firmware version where applicable];

View file

@ -61,6 +61,7 @@ uint8_t cliMode = 0;
#include "drivers/adc.h" #include "drivers/adc.h"
#include "drivers/buf_writer.h" #include "drivers/buf_writer.h"
#include "drivers/bus_spi.h" #include "drivers/bus_spi.h"
#include "drivers/dma.h"
#include "drivers/dma_reqmap.h" #include "drivers/dma_reqmap.h"
#include "drivers/dshot.h" #include "drivers/dshot.h"
#include "drivers/dshot_command.h" #include "drivers/dshot_command.h"
@ -76,6 +77,7 @@ uint8_t cliMode = 0;
#include "drivers/light_led.h" #include "drivers/light_led.h"
#include "drivers/motor.h" #include "drivers/motor.h"
#include "drivers/rangefinder/rangefinder_hcsr04.h" #include "drivers/rangefinder/rangefinder_hcsr04.h"
#include "drivers/resource.h"
#include "drivers/sdcard.h" #include "drivers/sdcard.h"
#include "drivers/sensor.h" #include "drivers/sensor.h"
#include "drivers/serial.h" #include "drivers/serial.h"
@ -4911,7 +4913,7 @@ static bool strToPin(char *pch, ioTag_t *tag)
} }
#ifdef USE_DMA #ifdef USE_DMA
static void printDma(void) static void showDma(void)
{ {
cliPrintLinefeed(); cliPrintLinefeed();
@ -4922,15 +4924,13 @@ static void printDma(void)
cliRepeat('-', 20); cliRepeat('-', 20);
#endif #endif
for (int i = 1; i <= DMA_LAST_HANDLER; i++) { for (int i = 1; i <= DMA_LAST_HANDLER; i++) {
const char* owner; const resourceOwner_t *owner = dmaGetOwner(i);
owner = ownerNames[dmaGetOwner(i)];
cliPrintf(DMA_OUTPUT_STRING, DMA_DEVICE_NO(i), DMA_DEVICE_INDEX(i)); cliPrintf(DMA_OUTPUT_STRING, DMA_DEVICE_NO(i), DMA_DEVICE_INDEX(i));
uint8_t resourceIndex = dmaGetResourceIndex(i); if (owner->resourceIndex > 0) {
if (resourceIndex > 0) { cliPrintLinef(" %s %d", ownerNames[owner->owner], owner->resourceIndex);
cliPrintLinef(" %s %d", owner, resourceIndex);
} else { } else {
cliPrintLinef(" %s", owner); cliPrintLinef(" %s", ownerNames[owner->owner]);
} }
} }
} }
@ -5323,7 +5323,7 @@ static void cliDma(char* cmdline)
{ {
int len = strlen(cmdline); int len = strlen(cmdline);
if (len && strncasecmp(cmdline, "show", len) == 0) { if (len && strncasecmp(cmdline, "show", len) == 0) {
printDma(); showDma();
return; return;
} }
@ -5335,103 +5335,6 @@ static void cliDma(char* cmdline)
#endif #endif
} }
#endif #endif
static void cliResource(char *cmdline)
{
char *pch = NULL;
char *saveptr;
pch = strtok_r(cmdline, " ", &saveptr);
if (!pch) {
printResource(DUMP_MASTER | HIDE_UNUSED, NULL);
return;
} else if (strcasecmp(pch, "show") == 0) {
#ifdef MINIMAL_CLI
cliPrintLine("IO");
#else
cliPrintLine("Currently active IO resource assignments:\r\n(reboot to update)");
cliRepeat('-', 20);
#endif
for (int i = 0; i < DEFIO_IO_USED_COUNT; i++) {
const char* owner;
owner = ownerNames[ioRecs[i].owner];
cliPrintf("%c%02d: %s", IO_GPIOPortIdx(ioRecs + i) + 'A', IO_GPIOPinIdx(ioRecs + i), owner);
if (ioRecs[i].index > 0) {
cliPrintf(" %d", ioRecs[i].index);
}
cliPrintLinefeed();
}
#if defined(USE_DMA)
pch = strtok_r(NULL, " ", &saveptr);
if (strcasecmp(pch, "all") == 0) {
cliDma("show");
}
#endif
return;
}
uint8_t resourceIndex = 0;
int index = 0;
for (resourceIndex = 0; ; resourceIndex++) {
if (resourceIndex >= ARRAYLEN(resourceTable)) {
cliPrintErrorLinef("INVALID RESOURCE NAME: '%s'", pch);
return;
}
const char * resourceName = ownerNames[resourceTable[resourceIndex].owner];
if (strncasecmp(pch, resourceName, strlen(resourceName)) == 0) {
break;
}
}
pch = strtok_r(NULL, " ", &saveptr);
index = atoi(pch);
if (resourceTable[resourceIndex].maxIndex > 0 || index > 0) {
if (index <= 0 || index > MAX_RESOURCE_INDEX(resourceTable[resourceIndex].maxIndex)) {
cliShowArgumentRangeError("INDEX", 1, MAX_RESOURCE_INDEX(resourceTable[resourceIndex].maxIndex));
return;
}
index -= 1;
pch = strtok_r(NULL, " ", &saveptr);
}
ioTag_t *tag = getIoTag(resourceTable[resourceIndex], index);
if (strlen(pch) > 0) {
if (strToPin(pch, tag)) {
if (*tag == IO_TAG_NONE) {
#ifdef MINIMAL_CLI
cliPrintLine("Freed");
#else
cliPrintLine("Resource is freed");
#endif
return;
} else {
ioRec_t *rec = IO_Rec(IOGetByTag(*tag));
if (rec) {
resourceCheck(resourceIndex, index, *tag);
#ifdef MINIMAL_CLI
cliPrintLinef(" %c%02d set", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#else
cliPrintLinef("\r\nResource is set to %c%02d", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#endif
} else {
cliShowParseError();
}
return;
}
}
}
cliShowParseError();
}
#endif // USE_RESOURCE_MGMT #endif // USE_RESOURCE_MGMT
#ifdef USE_TIMER_MGMT #ifdef USE_TIMER_MGMT
@ -5536,6 +5439,44 @@ static void alternateFunctionToString(const ioTag_t ioTag, const int index, char
} }
} }
static void showTimers(void)
{
cliPrintLinefeed();
#ifdef MINIMAL_CLI
cliPrintLine("Timers:");
#else
cliPrintLine("Currently active Timers:");
cliRepeat('-', 23);
#endif
int8_t timerNumber;
for (int i = 0; (timerNumber = timerGetNumberByIndex(i)); i++) {
cliPrintf("TIM%d:", timerNumber);
bool timerUsed = false;
for (unsigned timerIndex = 0; timerIndex < CC_CHANNELS_PER_TIMER; timerIndex++) {
const resourceOwner_t *timerOwner = timerGetOwner(timerNumber, CC_CHANNEL_FROM_INDEX(timerIndex));
if (timerOwner->owner) {
if (!timerUsed) {
timerUsed = true;
cliPrintLinefeed();
}
if (timerOwner->resourceIndex > 0) {
cliPrintLinef(" CH%d: %s %d", timerIndex + 1, ownerNames[timerOwner->owner], timerOwner->resourceIndex);
} else {
cliPrintLinef(" CH%d: %s", timerIndex + 1, ownerNames[timerOwner->owner]);
}
}
}
if (!timerUsed) {
cliPrintLine(" FREE");
}
}
}
static void cliTimer(char *cmdline) static void cliTimer(char *cmdline)
{ {
int len = strlen(cmdline); int len = strlen(cmdline);
@ -5549,7 +5490,7 @@ static void cliTimer(char *cmdline)
return; return;
} else if (strncasecmp(cmdline, "show", len) == 0) { } else if (strncasecmp(cmdline, "show", len) == 0) {
cliPrintErrorLinef("NOT IMPLEMENTED YET"); showTimers();
return; return;
} }
@ -5665,6 +5606,107 @@ static void cliTimer(char *cmdline)
} }
#endif #endif
#if defined(USE_RESOURCE_MGMT)
static void cliResource(char *cmdline)
{
char *pch = NULL;
char *saveptr;
pch = strtok_r(cmdline, " ", &saveptr);
if (!pch) {
printResource(DUMP_MASTER | HIDE_UNUSED, NULL);
return;
} else if (strcasecmp(pch, "show") == 0) {
#ifdef MINIMAL_CLI
cliPrintLine("IO");
#else
cliPrintLine("Currently active IO resource assignments:\r\n(reboot to update)");
cliRepeat('-', 20);
#endif
for (int i = 0; i < DEFIO_IO_USED_COUNT; i++) {
const char* owner;
owner = ownerNames[ioRecs[i].owner];
cliPrintf("%c%02d: %s", IO_GPIOPortIdx(ioRecs + i) + 'A', IO_GPIOPinIdx(ioRecs + i), owner);
if (ioRecs[i].index > 0) {
cliPrintf(" %d", ioRecs[i].index);
}
cliPrintLinefeed();
}
pch = strtok_r(NULL, " ", &saveptr);
if (strcasecmp(pch, "all") == 0) {
#if defined(USE_TIMER_MGMT)
cliTimer("show");
#endif
#if defined(USE_DMA)
cliDma("show");
#endif
}
return;
}
uint8_t resourceIndex = 0;
int index = 0;
for (resourceIndex = 0; ; resourceIndex++) {
if (resourceIndex >= ARRAYLEN(resourceTable)) {
cliPrintErrorLinef("INVALID RESOURCE NAME: '%s'", pch);
return;
}
const char * resourceName = ownerNames[resourceTable[resourceIndex].owner];
if (strncasecmp(pch, resourceName, strlen(resourceName)) == 0) {
break;
}
}
pch = strtok_r(NULL, " ", &saveptr);
index = atoi(pch);
if (resourceTable[resourceIndex].maxIndex > 0 || index > 0) {
if (index <= 0 || index > MAX_RESOURCE_INDEX(resourceTable[resourceIndex].maxIndex)) {
cliShowArgumentRangeError("INDEX", 1, MAX_RESOURCE_INDEX(resourceTable[resourceIndex].maxIndex));
return;
}
index -= 1;
pch = strtok_r(NULL, " ", &saveptr);
}
ioTag_t *tag = getIoTag(resourceTable[resourceIndex], index);
if (strlen(pch) > 0) {
if (strToPin(pch, tag)) {
if (*tag == IO_TAG_NONE) {
#ifdef MINIMAL_CLI
cliPrintLine("Freed");
#else
cliPrintLine("Resource is freed");
#endif
return;
} else {
ioRec_t *rec = IO_Rec(IOGetByTag(*tag));
if (rec) {
resourceCheck(resourceIndex, index, *tag);
#ifdef MINIMAL_CLI
cliPrintLinef(" %c%02d set", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#else
cliPrintLinef("\r\nResource is set to %c%02d", IO_GPIOPortIdx(rec) + 'A', IO_GPIOPinIdx(rec));
#endif
} else {
cliShowParseError();
}
return;
}
}
}
cliShowParseError();
}
#endif
#ifdef USE_DSHOT_TELEMETRY #ifdef USE_DSHOT_TELEMETRY
static void cliDshotTelemetryInfo(char *cmdline) static void cliDshotTelemetryInfo(char *cmdline)
{ {

View file

@ -131,7 +131,7 @@ void cameraControlInit(void)
if (CAMERA_CONTROL_MODE_HARDWARE_PWM == cameraControlConfig()->mode) { if (CAMERA_CONTROL_MODE_HARDWARE_PWM == cameraControlConfig()->mode) {
#ifdef CAMERA_CONTROL_HARDWARE_PWM_AVAILABLE #ifdef CAMERA_CONTROL_HARDWARE_PWM_AVAILABLE
const timerHardware_t *timerHardware = timerGetByTag(cameraControlConfig()->ioTag); const timerHardware_t *timerHardware = timerAllocate(cameraControlConfig()->ioTag, OWNER_CAMERA_CONTROL, 0);
if (!timerHardware) { if (!timerHardware) {
return; return;

View file

@ -93,8 +93,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource
const int index = DMA_IDENTIFIER_TO_INDEX(identifier); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
RCC_AHBPeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE); RCC_AHBPeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[index].owner = owner; dmaDescriptors[index].owner.owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex; dmaDescriptors[index].owner.resourceIndex = resourceIndex;
} }
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
@ -115,14 +115,9 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
} }
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* channel) dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* channel)

View file

@ -20,7 +20,7 @@
#pragma once #pragma once
#include "resource.h" #include "drivers/resource.h"
// dmaResource_t is a opaque data type which represents a single DMA engine, // dmaResource_t is a opaque data type which represents a single DMA engine,
// called and implemented differently in different families of STM32s. // called and implemented differently in different families of STM32s.
@ -52,7 +52,7 @@ typedef struct dmaChannelDescriptor_s {
uint8_t flagsShift; uint8_t flagsShift;
IRQn_Type irqN; IRQn_Type irqN;
uint32_t userParam; uint32_t userParam;
resourceOwner_e owner; resourceOwner_t owner;
uint8_t resourceIndex; uint8_t resourceIndex;
uint32_t completeFlag; uint32_t completeFlag;
} dmaChannelDescriptor_t; } dmaChannelDescriptor_t;
@ -102,8 +102,8 @@ typedef enum {
.flagsShift = f, \ .flagsShift = f, \
.irqN = d ## _Stream ## s ## _IRQn, \ .irqN = d ## _Stream ## s ## _IRQn, \
.userParam = 0, \ .userParam = 0, \
.owner = 0, \ .owner.owner = 0, \
.resourceIndex = 0 \ .owner.resourceIndex = 0 \
} }
#define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\ #define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\
@ -163,8 +163,8 @@ typedef enum {
.flagsShift = f, \ .flagsShift = f, \
.irqN = d ## _Channel ## c ## _IRQn, \ .irqN = d ## _Channel ## c ## _IRQn, \
.userParam = 0, \ .userParam = 0, \
.owner = 0, \ .owner.owner = 0, \
.resourceIndex = 0 \ .owner.resourceIndex = 0 \
} }
#define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\ #define DEFINE_DMA_IRQ_HANDLER(d, c, i) void DMA ## d ## _Channel ## c ## _IRQHandler(void) {\
@ -212,8 +212,7 @@ dmaResource_t* dmaGetRefByIdentifier(const dmaIdentifier_e identifier);
void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex); void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resourceIndex);
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam); void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam);
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier); const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier);
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier);
dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier); dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier);
// //

View file

@ -78,8 +78,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource
{ {
const int index = DMA_IDENTIFIER_TO_INDEX(identifier); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
RCC_AHB1PeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE); RCC_AHB1PeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE);
dmaDescriptors[index].owner = owner; dmaDescriptors[index].owner.owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex; dmaDescriptors[index].owner.resourceIndex = resourceIndex;
} }
#define RETURN_TCIF_FLAG(s, n) if (s == DMA1_Stream ## n || s == DMA2_Stream ## n) return DMA_IT_TCIF ## n #define RETURN_TCIF_FLAG(s, n) if (s == DMA1_Stream ## n || s == DMA2_Stream ## n) return DMA_IT_TCIF ## n
@ -115,14 +115,9 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
NVIC_Init(&NVIC_InitStructure); NVIC_Init(&NVIC_InitStructure);
} }
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* instance) dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* instance)

View file

@ -91,8 +91,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource
const int index = DMA_IDENTIFIER_TO_INDEX(identifier); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
enableDmaClock(index); enableDmaClock(index);
dmaDescriptors[index].owner = owner; dmaDescriptors[index].owner.owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex; dmaDescriptors[index].owner.resourceIndex = resourceIndex;
} }
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
@ -107,14 +107,9 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
HAL_NVIC_EnableIRQ(dmaDescriptors[index].irqN); HAL_NVIC_EnableIRQ(dmaDescriptors[index].irqN);
} }
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* stream) dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* stream)

View file

@ -95,8 +95,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource
const int index = DMA_IDENTIFIER_TO_INDEX(identifier); const int index = DMA_IDENTIFIER_TO_INDEX(identifier);
enableDmaClock(index); enableDmaClock(index);
dmaDescriptors[index].owner = owner; dmaDescriptors[index].owner.owner = owner;
dmaDescriptors[index].resourceIndex = resourceIndex; dmaDescriptors[index].owner.resourceIndex = resourceIndex;
} }
void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam) void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam)
@ -111,14 +111,9 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac
HAL_NVIC_EnableIRQ(dmaDescriptors[index].irqN); HAL_NVIC_EnableIRQ(dmaDescriptors[index].irqN);
} }
resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier)
{ {
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner;
}
uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier)
{
return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex;
} }
dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* stream) dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* stream)

View file

@ -177,7 +177,7 @@ motorDevice_t *dshotPwmDevInit(const motorDevConfig_t *motorConfig, uint16_t idl
for (int motorIndex = 0; motorIndex < MAX_SUPPORTED_MOTORS && motorIndex < motorCount; motorIndex++) { for (int motorIndex = 0; motorIndex < MAX_SUPPORTED_MOTORS && motorIndex < motorCount; motorIndex++) {
const ioTag_t tag = motorConfig->ioTags[motorIndex]; const ioTag_t tag = motorConfig->ioTags[motorIndex];
const timerHardware_t *timerHardware = timerGetByTag(tag); const timerHardware_t *timerHardware = timerAllocate(tag, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
if (timerHardware == NULL) { if (timerHardware == NULL) {
/* not enough motors initialised for the mixer or a break in the motors */ /* not enough motors initialised for the mixer or a break in the motors */

View file

@ -55,7 +55,7 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
return false; return false;
} }
const timerHardware_t *timerHardware = timerGetByTag(ioTag); const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_LED_STRIP, 0);
if (timerHardware == NULL) { if (timerHardware == NULL) {
return false; return false;

View file

@ -83,7 +83,7 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag)
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
const timerHardware_t *timerHardware = timerGetByTag(ioTag); const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_LED_STRIP, 0);
if (timerHardware == NULL) { if (timerHardware == NULL) {
return false; return false;

View file

@ -213,7 +213,7 @@ motorDevice_t *motorPwmDevInit(const motorDevConfig_t *motorConfig, uint16_t idl
for (int motorIndex = 0; motorIndex < MAX_SUPPORTED_MOTORS && motorIndex < motorCount; motorIndex++) { for (int motorIndex = 0; motorIndex < MAX_SUPPORTED_MOTORS && motorIndex < motorCount; motorIndex++) {
const ioTag_t tag = motorConfig->ioTags[motorIndex]; const ioTag_t tag = motorConfig->ioTags[motorIndex];
const timerHardware_t *timerHardware = timerGetByTag(tag); const timerHardware_t *timerHardware = timerAllocate(tag, OWNER_MOTOR, RESOURCE_INDEX(motorIndex));
if (timerHardware == NULL) { if (timerHardware == NULL) {
/* not enough motors initialised for the mixer or a break in the motors */ /* not enough motors initialised for the mixer or a break in the motors */
@ -294,7 +294,7 @@ void servoDevInit(const servoDevConfig_t *servoConfig)
IOInit(servos[servoIndex].io, OWNER_SERVO, RESOURCE_INDEX(servoIndex)); IOInit(servos[servoIndex].io, OWNER_SERVO, RESOURCE_INDEX(servoIndex));
const timerHardware_t *timer = timerGetByTag(tag); const timerHardware_t *timer = timerAllocate(tag, OWNER_SERVO, RESOURCE_INDEX(servoIndex));
if (timer == NULL) { if (timer == NULL) {
/* flag failure and disable ability to arm */ /* flag failure and disable ability to arm */

View file

@ -100,6 +100,11 @@ typedef enum {
OWNER_TOTAL_COUNT OWNER_TOTAL_COUNT
} resourceOwner_e; } resourceOwner_e;
typedef struct resourceOwner_s {
resourceOwner_e owner;
uint8_t resourceIndex;
} resourceOwner_t;
extern const char * const ownerNames[OWNER_TOTAL_COUNT]; extern const char * const ownerNames[OWNER_TOTAL_COUNT];
#define RESOURCE_INDEX(x) (x + 1) #define RESOURCE_INDEX(x) (x + 1)

View file

@ -371,7 +371,7 @@ void pwmRxInit(const pwmConfig_t *pwmConfig)
pwmInputPort_t *port = &pwmInputPorts[channel]; pwmInputPort_t *port = &pwmInputPorts[channel];
const timerHardware_t *timer = timerGetByTag(pwmConfig->ioTags[channel]); const timerHardware_t *timer = timerAllocate(pwmConfig->ioTags[channel], OWNER_PWMINPUT, RESOURCE_INDEX(channel));
if (!timer) { if (!timer) {
/* TODO: maybe fail here if not enough channels? */ /* TODO: maybe fail here if not enough channels? */
@ -428,7 +428,7 @@ void ppmRxInit(const ppmConfig_t *ppmConfig)
pwmInputPort_t *port = &pwmInputPorts[FIRST_PWM_PORT]; pwmInputPort_t *port = &pwmInputPorts[FIRST_PWM_PORT];
const timerHardware_t *timer = timerGetByTag(ppmConfig->ioTag); const timerHardware_t *timer = timerAllocate(ppmConfig->ioTag, OWNER_PPMINPUT, 0);
if (!timer) { if (!timer) {
/* TODO: fail here? */ /* TODO: fail here? */
return; return;

View file

@ -668,7 +668,7 @@ static serialPort_t *openEscSerial(const motorDevConfig_t *motorConfig, escSeria
} }
if (mode != PROTOCOL_KISSALL) { if (mode != PROTOCOL_KISSALL) {
const ioTag_t tag = motorConfig->ioTags[output]; const ioTag_t tag = motorConfig->ioTags[output];
const timerHardware_t *timerHardware = timerGetByTag(tag); const timerHardware_t *timerHardware = timerAllocate(tag, OWNER_MOTOR, 0);
if (timerHardware == NULL) { if (timerHardware == NULL) {
return NULL; return NULL;
@ -686,7 +686,7 @@ static serialPort_t *openEscSerial(const motorDevConfig_t *motorConfig, escSeria
} }
escSerial->mode = mode; escSerial->mode = mode;
escSerial->txTimerHardware = timerGetByTag(escSerialConfig()->ioTag); escSerial->txTimerHardware = timerAllocate(escSerialConfig()->ioTag, OWNER_MOTOR, 0);
if (escSerial->txTimerHardware == NULL) { if (escSerial->txTimerHardware == NULL) {
return NULL; return NULL;
} }
@ -745,7 +745,7 @@ static serialPort_t *openEscSerial(const motorDevConfig_t *motorConfig, escSeria
if (pwmMotors[i].enabled && pwmMotors[i].io != IO_NONE) { if (pwmMotors[i].enabled && pwmMotors[i].io != IO_NONE) {
const ioTag_t tag = motorConfig->ioTags[i]; const ioTag_t tag = motorConfig->ioTags[i];
if (tag != IO_TAG_NONE) { if (tag != IO_TAG_NONE) {
const timerHardware_t *timerHardware = timerGetByTag(tag); const timerHardware_t *timerHardware = timerAllocate(tag, OWNER_MOTOR, 0);
if (timerHardware) { if (timerHardware) {
escSerialOutputPortConfig(timerHardware); escSerialOutputPortConfig(timerHardware);
escOutputs[escSerial->outputCount].io = pwmMotors[i].io; escOutputs[escSerial->outputCount].io = pwmMotors[i].io;

View file

@ -242,8 +242,8 @@ serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallb
ioTag_t tagRx = serialPinConfig()->ioTagRx[pinCfgIndex]; ioTag_t tagRx = serialPinConfig()->ioTagRx[pinCfgIndex];
ioTag_t tagTx = serialPinConfig()->ioTagTx[pinCfgIndex]; ioTag_t tagTx = serialPinConfig()->ioTagTx[pinCfgIndex];
const timerHardware_t *timerRx = timerGetByTag(tagRx); const timerHardware_t *timerRx = timerAllocate(tagRx, OWNER_SERIAL_RX, RESOURCE_INDEX(portIndex + RESOURCE_SOFT_OFFSET));
const timerHardware_t *timerTx = timerGetByTag(tagTx); const timerHardware_t *timerTx = timerAllocate(tagTx, OWNER_SERIAL_TX, RESOURCE_INDEX(portIndex + RESOURCE_SOFT_OFFSET));
IO_t rxIO = IOGetByTag(tagRx); IO_t rxIO = IOGetByTag(tagRx);
IO_t txIO = IOGetByTag(tagTx); IO_t txIO = IOGetByTag(tagTx);

View file

@ -61,12 +61,12 @@ static void pwmToggleBeeper(void)
static void beeperPwmInit(const ioTag_t tag, uint16_t frequency) static void beeperPwmInit(const ioTag_t tag, uint16_t frequency)
{ {
const timerHardware_t *timer = timerGetByTag(tag); const timerHardware_t *timer = timerAllocate(tag, OWNER_BEEPER, 0);
IO_t beeperIO = IOGetByTag(tag); IO_t beeperIO = IOGetByTag(tag);
if (beeperIO && timer) { if (beeperIO && timer) {
beeperPwm.io = beeperIO; beeperPwm.io = beeperIO;
IOInit(beeperPwm.io, OWNER_BEEPER, RESOURCE_INDEX(0)); IOInit(beeperPwm.io, OWNER_BEEPER, 0);
#if defined(STM32F1) #if defined(STM32F1)
IOConfigGPIO(beeperPwm.io, IOCFG_AF_PP); IOConfigGPIO(beeperPwm.io, IOCFG_AF_PP);
#else #else

View file

@ -257,10 +257,8 @@ const int8_t timerNumbers[USED_TIMER_COUNT] = {
#undef _DEF #undef _DEF
}; };
int8_t timerGetTIMNumber(const TIM_TypeDef *tim) int8_t timerGetNumberByIndex(uint8_t index)
{ {
uint8_t index = lookupTimerIndex(tim);
if (index < USED_TIMER_COUNT) { if (index < USED_TIMER_COUNT) {
return timerNumbers[index]; return timerNumbers[index];
} else { } else {
@ -268,6 +266,13 @@ int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
} }
} }
int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
{
const uint8_t index = lookupTimerIndex(tim);
return timerGetNumberByIndex(index);
}
static inline uint8_t lookupChannelIndex(const uint16_t channel) static inline uint8_t lookupChannelIndex(const uint16_t channel)
{ {
return channel >> 2; return channel >> 2;

View file

@ -26,6 +26,7 @@
#include "drivers/dma.h" #include "drivers/dma.h"
#include "drivers/io_types.h" #include "drivers/io_types.h"
#include "drivers/rcc_types.h" #include "drivers/rcc_types.h"
#include "drivers/resource.h"
#include "drivers/timer_def.h" #include "drivers/timer_def.h"
#include "pg/timerio.h" #include "pg/timerio.h"
@ -270,8 +271,10 @@ uint8_t timerInputIrq(TIM_TypeDef *tim);
#if defined(USE_TIMER_MGMT) #if defined(USE_TIMER_MGMT)
timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag); timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag);
const resourceOwner_t *timerGetOwner(int8_t timerNumber, uint16_t timerChannel);
#endif #endif
const timerHardware_t *timerGetByTag(ioTag_t ioTag); const timerHardware_t *timerGetByTag(ioTag_t ioTag);
const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex);
const timerHardware_t *timerGetByTagAndIndex(ioTag_t ioTag, unsigned timerIndex); const timerHardware_t *timerGetByTagAndIndex(ioTag_t ioTag, unsigned timerIndex);
ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index); ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index);
@ -292,5 +295,6 @@ uint16_t timerGetPrescalerByDesiredHertz(TIM_TypeDef *tim, uint32_t hz);
uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz); uint16_t timerGetPrescalerByDesiredMhz(TIM_TypeDef *tim, uint16_t mhz);
uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz); uint16_t timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz);
int8_t timerGetNumberByIndex(uint8_t index);
int8_t timerGetTIMNumber(const TIM_TypeDef *tim); int8_t timerGetTIMNumber(const TIM_TypeDef *tim);
uint8_t timerLookupChannelIndex(const uint16_t channel); uint8_t timerLookupChannelIndex(const uint16_t channel);

View file

@ -27,9 +27,9 @@
#ifdef USE_TIMER_MGMT #ifdef USE_TIMER_MGMT
#include "pg/timerio.h" #include "pg/timerio.h"
#endif
#ifdef USE_TIMER_MGMT static resourceOwner_t timerOwners[MAX_TIMER_PINMAP_COUNT];
timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag) timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag)
{ {
for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) { for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
@ -37,7 +37,7 @@ timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag)
return timerIOConfigMutable(i); return timerIOConfigMutable(i);
} }
} }
UNUSED(ioTag);
return NULL; return NULL;
} }
@ -78,6 +78,43 @@ const timerHardware_t *timerGetByTag(ioTag_t ioTag)
return timerGetByTagAndIndex(ioTag, timerIndex); return timerGetByTagAndIndex(ioTag, timerIndex);
} }
const resourceOwner_t *timerGetOwner(int8_t timerNumber, uint16_t timerChannel)
{
static resourceOwner_t freeOwner = { .owner = OWNER_FREE, .resourceIndex = 0 };
for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
const timerHardware_t *timer = timerGetByTagAndIndex(timerIOConfig(i)->ioTag, timerIOConfig(i)->index);
if (timer && timerGetTIMNumber(timer->tim) == timerNumber && timer->channel == timerChannel) {
return &timerOwners[i];
}
}
return &freeOwner;
}
const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex)
{
if (!ioTag) {
return NULL;
}
for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
if (timerIOConfig(i)->ioTag == ioTag) {
const timerHardware_t *timer = timerGetByTagAndIndex(ioTag, timerIOConfig(i)->index);
if (timerGetOwner(timerGetTIMNumber(timer->tim), timer->channel)->owner) {
return NULL;
}
timerOwners[i].owner = owner;
timerOwners[i].resourceIndex = resourceIndex;
return timer;
}
}
return NULL;
}
#else #else
const timerHardware_t *timerGetByTag(ioTag_t ioTag) const timerHardware_t *timerGetByTag(ioTag_t ioTag)
@ -93,6 +130,14 @@ const timerHardware_t *timerGetByTag(ioTag_t ioTag)
#endif #endif
return NULL; return NULL;
} }
const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex)
{
UNUSED(owner);
UNUSED(resourceIndex);
return timerGetByTag(ioTag);
}
#endif #endif
ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index) ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index)
@ -114,3 +159,4 @@ ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index)
return IO_TAG_NONE; return IO_TAG_NONE;
} }
#endif #endif

View file

@ -264,10 +264,8 @@ const int8_t timerNumbers[USED_TIMER_COUNT] = {
#undef _DEF #undef _DEF
}; };
int8_t timerGetTIMNumber(const TIM_TypeDef *tim) int8_t timerGetNumberByIndex(uint8_t index)
{ {
uint8_t index = lookupTimerIndex(tim);
if (index < USED_TIMER_COUNT) { if (index < USED_TIMER_COUNT) {
return timerNumbers[index]; return timerNumbers[index];
} else { } else {
@ -275,6 +273,13 @@ int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
} }
} }
int8_t timerGetTIMNumber(const TIM_TypeDef *tim)
{
uint8_t index = lookupTimerIndex(tim);
return timerGetNumberByIndex(index);
}
static inline uint8_t lookupChannelIndex(const uint16_t channel) static inline uint8_t lookupChannelIndex(const uint16_t channel)
{ {
return channel >> 2; return channel >> 2;

View file

@ -72,7 +72,7 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
return; return;
} }
const timerHardware_t *timerHardware = timerGetByTag(ioTag); const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_TRANSPONDER, 0);
TIM_TypeDef *timer = timerHardware->tim; TIM_TypeDef *timer = timerHardware->tim;
timerChannel = timerHardware->channel; timerChannel = timerHardware->channel;
output = timerHardware->output; output = timerHardware->output;

View file

@ -67,7 +67,7 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder)
TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitTypeDef TIM_OCInitStructure;
DMA_InitTypeDef DMA_InitStructure; DMA_InitTypeDef DMA_InitStructure;
const timerHardware_t *timerHardware = timerGetByTag(ioTag); const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_TRANSPONDER, 0);
timer = timerHardware->tim; timer = timerHardware->tim;
alternateFunction = timerHardware->alternateFunction; alternateFunction = timerHardware->alternateFunction;