2 * This file is part of Betaflight.
4 * Betaflight is free software. You can redistribute this software
5 * and/or modify this software under the terms of the GNU General
6 * Public License as published by the Free Software Foundation,
7 * either version 3 of the License, or (at your option) any later
10 * Betaflight is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this software.
19 * If not, see <http://www.gnu.org/licenses/>.
24 #include "drivers/io.h"
25 #include "drivers/io_impl.h"
27 #if DEFIO_PORT_USED_COUNT > 0
28 static const uint16_t ioDefUsedMask
[DEFIO_PORT_USED_COUNT
] = { DEFIO_PORT_USED_LIST
};
29 static const uint8_t ioDefUsedOffset
[DEFIO_PORT_USED_COUNT
] = { DEFIO_PORT_OFFSET_LIST
};
31 // Avoid -Wpedantic warning
32 static const uint16_t ioDefUsedMask
[1] = {0};
33 static const uint8_t ioDefUsedOffset
[1] = {0};
36 // initialize all ioRec_t structures from ROM
37 // currently only bitmask is used, this may change in future
38 void IOInitGlobal(void)
40 ioRec_t
*ioRec
= ioRecs
;
42 for (unsigned port
= 0; port
< ARRAYLEN(ioDefUsedMask
); port
++) {
43 for (unsigned pin
= 0; pin
< sizeof(ioDefUsedMask
[0]) * 8; pin
++) {
44 if (ioDefUsedMask
[port
] & (1 << pin
)) {
45 ioRec
->gpio
= (GPIO_TypeDef
*)(GPIOA_BASE
+ (port
<< 10)); // ports are 0x400 apart
46 ioRec
->pin
= 1 << pin
;
53 IO_t
IOGetByTag(ioTag_t tag
)
55 const int portIdx
= DEFIO_TAG_GPIOID(tag
);
56 const int pinIdx
= DEFIO_TAG_PIN(tag
);
58 if (portIdx
< 0 || portIdx
>= DEFIO_PORT_USED_COUNT
) {
61 // check if pin exists
62 if (!(ioDefUsedMask
[portIdx
] & (1 << pinIdx
))) {
65 // count bits before this pin on single port
66 int offset
= popcount(((1 << pinIdx
) - 1) & ioDefUsedMask
[portIdx
]);
67 // and add port offset
68 offset
+= ioDefUsedOffset
[portIdx
];
69 return ioRecs
+ offset
;
72 int IO_GPIOPortIdx(IO_t io
)
77 return (((size_t)IO_GPIO(io
) - GPIOA_BASE
) >> 10);