diff --git a/.github/ISSUE_TEMPLATE/firmware-bug-report.md b/.github/ISSUE_TEMPLATE/firmware-bug-report.md index 86e7d66151..9f8de8d6fc 100644 --- a/.github/ISSUE_TEMPLATE/firmware-bug-report.md +++ b/.github/ISSUE_TEMPLATE/firmware-bug-report.md @@ -16,6 +16,8 @@ A clear and concise description of what you expected to happen. **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/) +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** - 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]; diff --git a/src/main/cli/cli.c b/src/main/cli/cli.c index 43063b4cbe..2e7a153831 100644 --- a/src/main/cli/cli.c +++ b/src/main/cli/cli.c @@ -61,6 +61,7 @@ uint8_t cliMode = 0; #include "drivers/adc.h" #include "drivers/buf_writer.h" #include "drivers/bus_spi.h" +#include "drivers/dma.h" #include "drivers/dma_reqmap.h" #include "drivers/dshot.h" #include "drivers/dshot_command.h" @@ -76,6 +77,7 @@ uint8_t cliMode = 0; #include "drivers/light_led.h" #include "drivers/motor.h" #include "drivers/rangefinder/rangefinder_hcsr04.h" +#include "drivers/resource.h" #include "drivers/sdcard.h" #include "drivers/sensor.h" #include "drivers/serial.h" @@ -4911,7 +4913,7 @@ static bool strToPin(char *pch, ioTag_t *tag) } #ifdef USE_DMA -static void printDma(void) +static void showDma(void) { cliPrintLinefeed(); @@ -4922,15 +4924,13 @@ static void printDma(void) cliRepeat('-', 20); #endif for (int i = 1; i <= DMA_LAST_HANDLER; i++) { - const char* owner; - owner = ownerNames[dmaGetOwner(i)]; + const resourceOwner_t *owner = dmaGetOwner(i); cliPrintf(DMA_OUTPUT_STRING, DMA_DEVICE_NO(i), DMA_DEVICE_INDEX(i)); - uint8_t resourceIndex = dmaGetResourceIndex(i); - if (resourceIndex > 0) { - cliPrintLinef(" %s %d", owner, resourceIndex); + if (owner->resourceIndex > 0) { + cliPrintLinef(" %s %d", ownerNames[owner->owner], owner->resourceIndex); } else { - cliPrintLinef(" %s", owner); + cliPrintLinef(" %s", ownerNames[owner->owner]); } } } @@ -5323,7 +5323,7 @@ static void cliDma(char* cmdline) { int len = strlen(cmdline); if (len && strncasecmp(cmdline, "show", len) == 0) { - printDma(); + showDma(); return; } @@ -5335,103 +5335,6 @@ static void cliDma(char* cmdline) #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 #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) { int len = strlen(cmdline); @@ -5549,7 +5490,7 @@ static void cliTimer(char *cmdline) return; } else if (strncasecmp(cmdline, "show", len) == 0) { - cliPrintErrorLinef("NOT IMPLEMENTED YET"); + showTimers(); return; } @@ -5665,6 +5606,107 @@ static void cliTimer(char *cmdline) } #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 static void cliDshotTelemetryInfo(char *cmdline) { diff --git a/src/main/drivers/camera_control.c b/src/main/drivers/camera_control.c index 88f2150f3a..45c14fa76f 100644 --- a/src/main/drivers/camera_control.c +++ b/src/main/drivers/camera_control.c @@ -131,7 +131,7 @@ void cameraControlInit(void) if (CAMERA_CONTROL_MODE_HARDWARE_PWM == cameraControlConfig()->mode) { #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) { return; diff --git a/src/main/drivers/dma.c b/src/main/drivers/dma.c index c0155381c9..c128ac1ac8 100644 --- a/src/main/drivers/dma.c +++ b/src/main/drivers/dma.c @@ -93,8 +93,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource const int index = DMA_IDENTIFIER_TO_INDEX(identifier); RCC_AHBPeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE); - dmaDescriptors[index].owner = owner; - dmaDescriptors[index].resourceIndex = resourceIndex; + dmaDescriptors[index].owner.owner = owner; + dmaDescriptors[index].owner.resourceIndex = resourceIndex; } 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); } -resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) +const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier) { - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; -} - -uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) -{ - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex; + return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; } dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* channel) diff --git a/src/main/drivers/dma.h b/src/main/drivers/dma.h index 82a9a2bb1f..701a978017 100644 --- a/src/main/drivers/dma.h +++ b/src/main/drivers/dma.h @@ -20,7 +20,7 @@ #pragma once -#include "resource.h" +#include "drivers/resource.h" // dmaResource_t is a opaque data type which represents a single DMA engine, // called and implemented differently in different families of STM32s. @@ -52,7 +52,7 @@ typedef struct dmaChannelDescriptor_s { uint8_t flagsShift; IRQn_Type irqN; uint32_t userParam; - resourceOwner_e owner; + resourceOwner_t owner; uint8_t resourceIndex; uint32_t completeFlag; } dmaChannelDescriptor_t; @@ -102,8 +102,8 @@ typedef enum { .flagsShift = f, \ .irqN = d ## _Stream ## s ## _IRQn, \ .userParam = 0, \ - .owner = 0, \ - .resourceIndex = 0 \ + .owner.owner = 0, \ + .owner.resourceIndex = 0 \ } #define DEFINE_DMA_IRQ_HANDLER(d, s, i) void DMA ## d ## _Stream ## s ## _IRQHandler(void) {\ @@ -163,8 +163,8 @@ typedef enum { .flagsShift = f, \ .irqN = d ## _Channel ## c ## _IRQn, \ .userParam = 0, \ - .owner = 0, \ - .resourceIndex = 0 \ + .owner.owner = 0, \ + .owner.resourceIndex = 0 \ } #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 dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callback, uint32_t priority, uint32_t userParam); -resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier); -uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier); +const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier); dmaChannelDescriptor_t* dmaGetDescriptorByIdentifier(const dmaIdentifier_e identifier); // diff --git a/src/main/drivers/dma_stm32f4xx.c b/src/main/drivers/dma_stm32f4xx.c index 8e4c338faa..25359bc37e 100644 --- a/src/main/drivers/dma_stm32f4xx.c +++ b/src/main/drivers/dma_stm32f4xx.c @@ -78,8 +78,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource { const int index = DMA_IDENTIFIER_TO_INDEX(identifier); RCC_AHB1PeriphClockCmd(DMA_RCC(dmaDescriptors[index].dma), ENABLE); - dmaDescriptors[index].owner = owner; - dmaDescriptors[index].resourceIndex = resourceIndex; + dmaDescriptors[index].owner.owner = owner; + 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 @@ -115,14 +115,9 @@ void dmaSetHandler(dmaIdentifier_e identifier, dmaCallbackHandlerFuncPtr callbac 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; -} - -uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) -{ - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex; + return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; } dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* instance) diff --git a/src/main/drivers/dma_stm32f7xx.c b/src/main/drivers/dma_stm32f7xx.c index 492e4da4e8..38a0b653dd 100644 --- a/src/main/drivers/dma_stm32f7xx.c +++ b/src/main/drivers/dma_stm32f7xx.c @@ -91,8 +91,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource const int index = DMA_IDENTIFIER_TO_INDEX(identifier); enableDmaClock(index); - dmaDescriptors[index].owner = owner; - dmaDescriptors[index].resourceIndex = resourceIndex; + dmaDescriptors[index].owner.owner = owner; + dmaDescriptors[index].owner.resourceIndex = resourceIndex; } 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); } -resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) +const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier) { - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; -} - -uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) -{ - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex; + return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; } dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* stream) diff --git a/src/main/drivers/dma_stm32h7xx.c b/src/main/drivers/dma_stm32h7xx.c index f3e80a929e..b7b87aca55 100644 --- a/src/main/drivers/dma_stm32h7xx.c +++ b/src/main/drivers/dma_stm32h7xx.c @@ -95,8 +95,8 @@ void dmaInit(dmaIdentifier_e identifier, resourceOwner_e owner, uint8_t resource const int index = DMA_IDENTIFIER_TO_INDEX(identifier); enableDmaClock(index); - dmaDescriptors[index].owner = owner; - dmaDescriptors[index].resourceIndex = resourceIndex; + dmaDescriptors[index].owner.owner = owner; + dmaDescriptors[index].owner.resourceIndex = resourceIndex; } 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); } -resourceOwner_e dmaGetOwner(dmaIdentifier_e identifier) +const resourceOwner_t *dmaGetOwner(dmaIdentifier_e identifier) { - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; -} - -uint8_t dmaGetResourceIndex(dmaIdentifier_e identifier) -{ - return dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].resourceIndex; + return &dmaDescriptors[DMA_IDENTIFIER_TO_INDEX(identifier)].owner; } dmaIdentifier_e dmaGetIdentifier(const dmaResource_t* stream) diff --git a/src/main/drivers/dshot_dpwm.c b/src/main/drivers/dshot_dpwm.c index 861bd7e50e..70f233f0e4 100644 --- a/src/main/drivers/dshot_dpwm.c +++ b/src/main/drivers/dshot_dpwm.c @@ -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++) { 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) { /* not enough motors initialised for the mixer or a break in the motors */ diff --git a/src/main/drivers/light_ws2811strip_hal.c b/src/main/drivers/light_ws2811strip_hal.c index 03c39c5e2f..3a101da08c 100644 --- a/src/main/drivers/light_ws2811strip_hal.c +++ b/src/main/drivers/light_ws2811strip_hal.c @@ -55,7 +55,7 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag) return false; } - const timerHardware_t *timerHardware = timerGetByTag(ioTag); + const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_LED_STRIP, 0); if (timerHardware == NULL) { return false; diff --git a/src/main/drivers/light_ws2811strip_stdperiph.c b/src/main/drivers/light_ws2811strip_stdperiph.c index a1a95481b1..65cc3a3be9 100644 --- a/src/main/drivers/light_ws2811strip_stdperiph.c +++ b/src/main/drivers/light_ws2811strip_stdperiph.c @@ -83,7 +83,7 @@ bool ws2811LedStripHardwareInit(ioTag_t ioTag) TIM_OCInitTypeDef TIM_OCInitStructure; DMA_InitTypeDef DMA_InitStructure; - const timerHardware_t *timerHardware = timerGetByTag(ioTag); + const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_LED_STRIP, 0); if (timerHardware == NULL) { return false; diff --git a/src/main/drivers/pwm_output.c b/src/main/drivers/pwm_output.c index 0f65d88d19..f04ec5281b 100644 --- a/src/main/drivers/pwm_output.c +++ b/src/main/drivers/pwm_output.c @@ -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++) { 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) { /* 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)); - const timerHardware_t *timer = timerGetByTag(tag); + const timerHardware_t *timer = timerAllocate(tag, OWNER_SERVO, RESOURCE_INDEX(servoIndex)); if (timer == NULL) { /* flag failure and disable ability to arm */ diff --git a/src/main/drivers/resource.h b/src/main/drivers/resource.h index 01192c2274..757d4d34b0 100644 --- a/src/main/drivers/resource.h +++ b/src/main/drivers/resource.h @@ -100,6 +100,11 @@ typedef enum { OWNER_TOTAL_COUNT } resourceOwner_e; +typedef struct resourceOwner_s { + resourceOwner_e owner; + uint8_t resourceIndex; +} resourceOwner_t; + extern const char * const ownerNames[OWNER_TOTAL_COUNT]; #define RESOURCE_INDEX(x) (x + 1) diff --git a/src/main/drivers/rx/rx_pwm.c b/src/main/drivers/rx/rx_pwm.c index 5cbbddb63d..d871b80d59 100644 --- a/src/main/drivers/rx/rx_pwm.c +++ b/src/main/drivers/rx/rx_pwm.c @@ -371,7 +371,7 @@ void pwmRxInit(const pwmConfig_t *pwmConfig) 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) { /* 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]; - const timerHardware_t *timer = timerGetByTag(ppmConfig->ioTag); + const timerHardware_t *timer = timerAllocate(ppmConfig->ioTag, OWNER_PPMINPUT, 0); if (!timer) { /* TODO: fail here? */ return; diff --git a/src/main/drivers/serial_escserial.c b/src/main/drivers/serial_escserial.c index cad6692782..1c837a8a11 100644 --- a/src/main/drivers/serial_escserial.c +++ b/src/main/drivers/serial_escserial.c @@ -668,7 +668,7 @@ static serialPort_t *openEscSerial(const motorDevConfig_t *motorConfig, escSeria } if (mode != PROTOCOL_KISSALL) { 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) { return NULL; @@ -686,7 +686,7 @@ static serialPort_t *openEscSerial(const motorDevConfig_t *motorConfig, escSeria } escSerial->mode = mode; - escSerial->txTimerHardware = timerGetByTag(escSerialConfig()->ioTag); + escSerial->txTimerHardware = timerAllocate(escSerialConfig()->ioTag, OWNER_MOTOR, 0); if (escSerial->txTimerHardware == 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) { const ioTag_t tag = motorConfig->ioTags[i]; if (tag != IO_TAG_NONE) { - const timerHardware_t *timerHardware = timerGetByTag(tag); + const timerHardware_t *timerHardware = timerAllocate(tag, OWNER_MOTOR, 0); if (timerHardware) { escSerialOutputPortConfig(timerHardware); escOutputs[escSerial->outputCount].io = pwmMotors[i].io; diff --git a/src/main/drivers/serial_softserial.c b/src/main/drivers/serial_softserial.c index 69841de7df..880f7675b8 100644 --- a/src/main/drivers/serial_softserial.c +++ b/src/main/drivers/serial_softserial.c @@ -242,8 +242,8 @@ serialPort_t *openSoftSerial(softSerialPortIndex_e portIndex, serialReceiveCallb ioTag_t tagRx = serialPinConfig()->ioTagRx[pinCfgIndex]; ioTag_t tagTx = serialPinConfig()->ioTagTx[pinCfgIndex]; - const timerHardware_t *timerRx = timerGetByTag(tagRx); - const timerHardware_t *timerTx = timerGetByTag(tagTx); + const timerHardware_t *timerRx = timerAllocate(tagRx, OWNER_SERIAL_RX, RESOURCE_INDEX(portIndex + RESOURCE_SOFT_OFFSET)); + const timerHardware_t *timerTx = timerAllocate(tagTx, OWNER_SERIAL_TX, RESOURCE_INDEX(portIndex + RESOURCE_SOFT_OFFSET)); IO_t rxIO = IOGetByTag(tagRx); IO_t txIO = IOGetByTag(tagTx); diff --git a/src/main/drivers/sound_beeper.c b/src/main/drivers/sound_beeper.c index 1481e117ef..5ea45f3698 100644 --- a/src/main/drivers/sound_beeper.c +++ b/src/main/drivers/sound_beeper.c @@ -61,12 +61,12 @@ static void pwmToggleBeeper(void) 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); if (beeperIO && timer) { beeperPwm.io = beeperIO; - IOInit(beeperPwm.io, OWNER_BEEPER, RESOURCE_INDEX(0)); + IOInit(beeperPwm.io, OWNER_BEEPER, 0); #if defined(STM32F1) IOConfigGPIO(beeperPwm.io, IOCFG_AF_PP); #else diff --git a/src/main/drivers/timer.c b/src/main/drivers/timer.c index f617302689..114bb4bf7b 100644 --- a/src/main/drivers/timer.c +++ b/src/main/drivers/timer.c @@ -257,10 +257,8 @@ const int8_t timerNumbers[USED_TIMER_COUNT] = { #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) { return timerNumbers[index]; } 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) { return channel >> 2; diff --git a/src/main/drivers/timer.h b/src/main/drivers/timer.h index 14272afe88..45f1256524 100644 --- a/src/main/drivers/timer.h +++ b/src/main/drivers/timer.h @@ -26,6 +26,7 @@ #include "drivers/dma.h" #include "drivers/io_types.h" #include "drivers/rcc_types.h" +#include "drivers/resource.h" #include "drivers/timer_def.h" #include "pg/timerio.h" @@ -270,8 +271,10 @@ uint8_t timerInputIrq(TIM_TypeDef *tim); #if defined(USE_TIMER_MGMT) timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag); +const resourceOwner_t *timerGetOwner(int8_t timerNumber, uint16_t timerChannel); #endif 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); 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 timerGetPeriodByPrescaler(TIM_TypeDef *tim, uint16_t prescaler, uint32_t hz); +int8_t timerGetNumberByIndex(uint8_t index); int8_t timerGetTIMNumber(const TIM_TypeDef *tim); uint8_t timerLookupChannelIndex(const uint16_t channel); diff --git a/src/main/drivers/timer_common.c b/src/main/drivers/timer_common.c index 5335362142..0101b982cd 100644 --- a/src/main/drivers/timer_common.c +++ b/src/main/drivers/timer_common.c @@ -27,9 +27,9 @@ #ifdef USE_TIMER_MGMT #include "pg/timerio.h" -#endif -#ifdef USE_TIMER_MGMT +static resourceOwner_t timerOwners[MAX_TIMER_PINMAP_COUNT]; + timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag) { for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) { @@ -37,7 +37,7 @@ timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag) return timerIOConfigMutable(i); } } - UNUSED(ioTag); + return NULL; } @@ -78,6 +78,43 @@ const timerHardware_t *timerGetByTag(ioTag_t ioTag) 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 const timerHardware_t *timerGetByTag(ioTag_t ioTag) @@ -93,6 +130,14 @@ const timerHardware_t *timerGetByTag(ioTag_t ioTag) #endif return NULL; } + +const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex) +{ + UNUSED(owner); + UNUSED(resourceIndex); + + return timerGetByTag(ioTag); +} #endif 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; } #endif + diff --git a/src/main/drivers/timer_hal.c b/src/main/drivers/timer_hal.c index ae5aed74b5..9cd4294903 100644 --- a/src/main/drivers/timer_hal.c +++ b/src/main/drivers/timer_hal.c @@ -264,10 +264,8 @@ const int8_t timerNumbers[USED_TIMER_COUNT] = { #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) { return timerNumbers[index]; } 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) { return channel >> 2; diff --git a/src/main/drivers/transponder_ir_io_hal.c b/src/main/drivers/transponder_ir_io_hal.c index 6da26f2b49..f8e3a0a0cf 100644 --- a/src/main/drivers/transponder_ir_io_hal.c +++ b/src/main/drivers/transponder_ir_io_hal.c @@ -72,7 +72,7 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder) return; } - const timerHardware_t *timerHardware = timerGetByTag(ioTag); + const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_TRANSPONDER, 0); TIM_TypeDef *timer = timerHardware->tim; timerChannel = timerHardware->channel; output = timerHardware->output; diff --git a/src/main/drivers/transponder_ir_io_stdperiph.c b/src/main/drivers/transponder_ir_io_stdperiph.c index 426c185345..9e24dd277b 100644 --- a/src/main/drivers/transponder_ir_io_stdperiph.c +++ b/src/main/drivers/transponder_ir_io_stdperiph.c @@ -67,7 +67,7 @@ void transponderIrHardwareInit(ioTag_t ioTag, transponder_t *transponder) TIM_OCInitTypeDef TIM_OCInitStructure; DMA_InitTypeDef DMA_InitStructure; - const timerHardware_t *timerHardware = timerGetByTag(ioTag); + const timerHardware_t *timerHardware = timerAllocate(ioTag, OWNER_TRANSPONDER, 0); timer = timerHardware->tim; alternateFunction = timerHardware->alternateFunction;