New memory section types for DMA
[betaflight.git] / src / main / drivers / timer_common.c
blobc3ecaa4939ba1f599d97f2d054c920b57d8fac69
1 /*
2 * This file is part of Cleanflight and Betaflight.
4 * Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include "platform.h"
23 #ifdef USE_TIMER
25 #include "drivers/dshot_bitbang.h"
26 #include "drivers/io.h"
27 #include "timer.h"
29 #ifdef USE_TIMER_MGMT
30 #include "pg/timerio.h"
32 const resourceOwner_t freeOwner = { .owner = OWNER_FREE, .resourceIndex = 0 };
34 static resourceOwner_t timerOwners[MAX_TIMER_PINMAP_COUNT];
36 timerIOConfig_t *timerIoConfigByTag(ioTag_t ioTag)
38 for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
39 if (timerIOConfig(i)->ioTag == ioTag) {
40 return timerIOConfigMutable(i);
44 return NULL;
47 static uint8_t timerIndexByTag(ioTag_t ioTag)
49 for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
50 if (timerIOConfig(i)->ioTag == ioTag) {
51 return timerIOConfig(i)->index;
54 return 0;
57 const timerHardware_t *timerGetByTagAndIndex(ioTag_t ioTag, unsigned timerIndex)
60 if (!ioTag || !timerIndex) {
61 return NULL;
64 uint8_t index = 1;
65 for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
66 if (TIMER_HARDWARE[i].tag == ioTag) {
67 if (index == timerIndex) {
68 return &TIMER_HARDWARE[i];
70 ++index;
74 return NULL;
77 const timerHardware_t *timerGetByTag(ioTag_t ioTag)
79 uint8_t timerIndex = timerIndexByTag(ioTag);
81 return timerGetByTagAndIndex(ioTag, timerIndex);
84 const resourceOwner_t *timerGetOwner(int8_t timerNumber, uint16_t timerChannel)
86 const resourceOwner_t *timerOwner = &freeOwner;
87 for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
88 const timerHardware_t *timer = timerGetByTagAndIndex(timerIOConfig(i)->ioTag, timerIOConfig(i)->index);
89 if (timer && timerGetTIMNumber(timer->tim) == timerNumber && timer->channel == timerChannel) {
90 timerOwner = &timerOwners[i];
92 break;
96 #if defined(USE_DSHOT_BITBANG)
97 if (!timerOwner->owner) {
98 timerOwner = dshotBitbangTimerGetOwner(timerNumber, timerChannel);
100 #endif
102 return timerOwner;
105 const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex)
107 if (!ioTag) {
108 return NULL;
111 for (unsigned i = 0; i < MAX_TIMER_PINMAP_COUNT; i++) {
112 if (timerIOConfig(i)->ioTag == ioTag) {
113 const timerHardware_t *timer = timerGetByTagAndIndex(ioTag, timerIOConfig(i)->index);
115 if (timerGetOwner(timerGetTIMNumber(timer->tim), timer->channel)->owner) {
116 return NULL;
119 timerOwners[i].owner = owner;
120 timerOwners[i].resourceIndex = resourceIndex;
122 return timer;
126 return NULL;
128 #else
130 const timerHardware_t *timerGetByTag(ioTag_t ioTag)
132 #if TIMER_CHANNEL_COUNT > 0
133 for (unsigned i = 0; i < TIMER_CHANNEL_COUNT; i++) {
134 if (TIMER_HARDWARE[i].tag == ioTag) {
135 return &TIMER_HARDWARE[i];
138 #else
139 UNUSED(ioTag);
140 #endif
141 return NULL;
144 const timerHardware_t *timerAllocate(ioTag_t ioTag, resourceOwner_e owner, uint8_t resourceIndex)
146 UNUSED(owner);
147 UNUSED(resourceIndex);
149 return timerGetByTag(ioTag);
151 #endif
153 ioTag_t timerioTagGetByUsage(timerUsageFlag_e usageFlag, uint8_t index)
155 #if !defined(USE_UNIFIED_TARGET) && USABLE_TIMER_CHANNEL_COUNT > 0
156 uint8_t currentIndex = 0;
157 for (unsigned i = 0; i < USABLE_TIMER_CHANNEL_COUNT; i++) {
158 if ((timerHardware[i].usageFlags & usageFlag) == usageFlag) {
159 if (currentIndex == index) {
160 return timerHardware[i].tag;
162 currentIndex++;
165 #else
166 UNUSED(usageFlag);
167 UNUSED(index);
168 #endif
169 return IO_TAG_NONE;
171 #endif