1
0
Fork 0
mirror of https://github.com/betaflight/betaflight.git synced 2025-07-13 19:40:31 +03:00

Improve serial_post.h (#14096)

This commit is contained in:
Petr Ledvina 2024-12-20 19:01:00 +01:00 committed by GitHub
parent 7dec49ce42
commit 2f21754a69
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 120 additions and 37 deletions

View file

@ -197,8 +197,8 @@ static void resetBuffers(softSerial_t *softSerial)
softSerial_t* softSerialFromIdentifier(serialPortIdentifier_e identifier) softSerial_t* softSerialFromIdentifier(serialPortIdentifier_e identifier)
{ {
if (identifier >= SERIAL_PORT_SOFTSERIAL1 && identifier < SERIAL_PORT_SOFTSERIAL1 + SERIAL_SOFTSERIAL_COUNT) { if (identifier >= SERIAL_PORT_SOFTSERIAL_FIRST && identifier < SERIAL_PORT_SOFTSERIAL_FIRST + SERIAL_SOFTSERIAL_COUNT) {
return &softSerialPorts[identifier - SERIAL_PORT_SOFTSERIAL1]; return &softSerialPorts[identifier - SERIAL_PORT_SOFTSERIAL_FIRST];
} }
return NULL; return NULL;
} }

View file

@ -174,7 +174,7 @@ uartDeviceIdx_e uartDeviceIdxFromIdentifier(serialPortIdentifier_e identifier)
} }
#else #else
{ {
const int idx = identifier - SERIAL_PORT_USART1; const int idx = identifier - SERIAL_PORT_UART_FIRST;
if (idx >= 0 && idx < SERIAL_UART_MAX) { if (idx >= 0 && idx < SERIAL_UART_MAX) {
if (BIT(idx) & SERIAL_UART_MASK) { if (BIT(idx) & SERIAL_UART_MASK) {
// return number of enabled UART ports smaller than idx // return number of enabled UART ports smaller than idx

View file

@ -83,7 +83,14 @@ extern const uint32_t baudRates[];
typedef enum { typedef enum {
SERIAL_PORT_ALL = -2, SERIAL_PORT_ALL = -2,
SERIAL_PORT_NONE = -1, SERIAL_PORT_NONE = -1,
SERIAL_PORT_USART1 = 0, // prepare for transition to SERIAL_PORT_UART0
SERIAL_PORT_UART_FIRST = 0,
#if SERIAL_UART_FIRST_INDEX == 0
SERIAL_PORT_UART0 = SERIAL_PORT_UART_FIRST,
SERIAL_PORT_USART1,
#else
SERIAL_PORT_USART1 = SERIAL_PORT_UART_FIRST,
#endif
SERIAL_PORT_UART1 = SERIAL_PORT_USART1, SERIAL_PORT_UART1 = SERIAL_PORT_USART1,
SERIAL_PORT_USART2, SERIAL_PORT_USART2,
SERIAL_PORT_UART2 = SERIAL_PORT_USART2, SERIAL_PORT_UART2 = SERIAL_PORT_USART2,
@ -103,10 +110,12 @@ typedef enum {
SERIAL_PORT_USB_VCP = 20, SERIAL_PORT_USB_VCP = 20,
SERIAL_PORT_SOFTSERIAL1 = 30, SERIAL_PORT_SOFTSERIAL_FIRST = 30,
SERIAL_PORT_SOFTSERIAL1 = SERIAL_PORT_SOFTSERIAL_FIRST,
SERIAL_PORT_SOFTSERIAL2, SERIAL_PORT_SOFTSERIAL2,
SERIAL_PORT_LPUART1 = 40, SERIAL_PORT_LPUART_FIRST = 40,
SERIAL_PORT_LPUART1 = SERIAL_PORT_LPUART_FIRST,
} serialPortIdentifier_e; } serialPortIdentifier_e;
// use value from target serial port normalization // use value from target serial port normalization

View file

@ -36,8 +36,9 @@ serialType_e serialType(serialPortIdentifier_e identifier)
} }
#endif #endif
#ifdef USE_UART #ifdef USE_UART
if (identifier >= SERIAL_PORT_USART1 && identifier < SERIAL_PORT_USART1 + SERIAL_UART_MAX) { if (identifier >= SERIAL_PORT_UART_FIRST
const unsigned idx = identifier - SERIAL_PORT_USART1; && identifier < SERIAL_PORT_UART_FIRST + SERIAL_UART_MAX) {
const unsigned idx = identifier - SERIAL_PORT_UART_FIRST;
if (BIT(idx) & SERIAL_UART_MASK) { if (BIT(idx) & SERIAL_UART_MASK) {
return SERIALTYPE_UART; return SERIALTYPE_UART;
} else { } else {
@ -47,8 +48,9 @@ serialType_e serialType(serialPortIdentifier_e identifier)
} }
#endif #endif
#ifdef USE_LPUART #ifdef USE_LPUART
if (identifier >= SERIAL_PORT_LPUART1 && identifier < SERIAL_PORT_LPUART1 + SERIAL_LPUART_MAX) { if (identifier >= SERIAL_PORT_LPUART_FIRST
const unsigned idx = identifier - SERIAL_PORT_LPUART1; && identifier < SERIAL_PORT_LPUART_FIRST + SERIAL_LPUART_MAX) {
const unsigned idx = identifier - SERIAL_PORT_LPUART_FIRST;
if (BIT(idx) & SERIAL_LPUART_MASK) { if (BIT(idx) & SERIAL_LPUART_MASK) {
return SERIALTYPE_LPUART; return SERIALTYPE_LPUART;
} else { } else {
@ -58,8 +60,9 @@ serialType_e serialType(serialPortIdentifier_e identifier)
} }
#endif #endif
#ifdef USE_SOFTSERIAL #ifdef USE_SOFTSERIAL
if (identifier >= SERIAL_PORT_SOFTSERIAL1 && identifier < SERIAL_PORT_SOFTSERIAL1 + SERIAL_SOFTSERIAL_MAX) { if (identifier >= SERIAL_PORT_SOFTSERIAL_FIRST
// sotserials always start from 1, without holes && identifier < SERIAL_PORT_SOFTSERIAL_FIRST + SERIAL_SOFTSERIAL_MAX) {
// sotserials always start from first index, without holes
return SERIALTYPE_SOFTSERIAL; return SERIALTYPE_SOFTSERIAL;
} }
#endif #endif
@ -72,9 +75,9 @@ static const struct SerialTypeInfo {
int8_t resourceOffset; int8_t resourceOffset;
} serialTypeMap[] = { } serialTypeMap[] = {
[SERIALTYPE_USB_VCP] = { OWNER_FREE /* no owner*/, SERIAL_PORT_USB_VCP, -1 }, [SERIALTYPE_USB_VCP] = { OWNER_FREE /* no owner*/, SERIAL_PORT_USB_VCP, -1 },
[SERIALTYPE_UART] = { OWNER_SERIAL_TX, SERIAL_PORT_USART1, RESOURCE_UART_OFFSET }, [SERIALTYPE_UART] = { OWNER_SERIAL_TX, SERIAL_PORT_UART_FIRST, RESOURCE_UART_OFFSET },
[SERIALTYPE_LPUART] = { OWNER_LPUART_TX, SERIAL_PORT_LPUART1, RESOURCE_LPUART_OFFSET }, [SERIALTYPE_LPUART] = { OWNER_LPUART_TX, SERIAL_PORT_LPUART_FIRST, RESOURCE_LPUART_OFFSET },
[SERIALTYPE_SOFTSERIAL] = { OWNER_SOFTSERIAL_TX, SERIAL_PORT_SOFTSERIAL1, RESOURCE_SOFTSERIAL_OFFSET }, [SERIALTYPE_SOFTSERIAL] = { OWNER_SOFTSERIAL_TX, SERIAL_PORT_SOFTSERIAL_FIRST, RESOURCE_SOFTSERIAL_OFFSET },
}; };
STATIC_ASSERT(ARRAYLEN(serialTypeMap) == SERIALTYPE_COUNT, "type table mismatch"); STATIC_ASSERT(ARRAYLEN(serialTypeMap) == SERIALTYPE_COUNT, "type table mismatch");

View file

@ -30,7 +30,7 @@ in Betaflight topmost directory.
This include will provide following defines: This include will provide following defines:
SERIAL_<type><n>_USED 0/1 - always defined, value depends on target configuration SERIAL_<type><n>_USED 0/1 - always defined, value depends on target configuration
SERIAL_<type>_MASK - bitmask of used ports or given type. <port>1 is BIT(0) SERIAL_<type>_MASK - bitmask of used ports or given type. <port>0 or <port>1 is BIT(0), based on port first_index
SERIAL_<type>_COUNT - number of enabled ports of given type SERIAL_<type>_COUNT - number of enabled ports of given type
SERIAL_<type>_MAX - <index of highest used port> + 1, 0 when no port is enabled SERIAL_<type>_MAX - <index of highest used port> + 1, 0 when no port is enabled
@ -39,22 +39,41 @@ All <type><n>_(RX|TX)_PINS are normalized too:
- if port is not enable, both will be undefined, possibly with warning - if port is not enable, both will be undefined, possibly with warning
- pass -DWARN_UNUSED_SERIAL_PORT to compiler to check pin defined without corresponding port being enabled. - pass -DWARN_UNUSED_SERIAL_PORT to compiler to check pin defined without corresponding port being enabled.
Generated on 2024-11-04 Generated on 2024-12-20
Configuration used: Configuration used:
{ 'LPUART': {'depends': {'UART'}, 'ids': [1]}, { 'LPUART': {'depends': {'UART'}, 'ids': [1]},
'SOFTSERIAL': { 'force_continuous': True, 'SOFTSERIAL': { 'force_continuous': True,
'ids': [1, 2], 'ids': [1, 2],
'use_enables_all': True}, 'use_enables_all': True},
'UART': {'ids': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 'inverter': True}, 'UART': { 'first_index': True,
'ids': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
'inverter': True},
'VCP': {'no_pins': True, 'singleton': True}} 'VCP': {'no_pins': True, 'singleton': True}}
*/ */
#include "common/utils.h" // BIT, LOG2 #include "common/utils.h" // BIT, LOG2
/**** UART *****/ /**** UART *****/
// normalize SERIAL_UART_FIRST_INDEX
#ifndef SERIAL_UART_FIRST_INDEX
#define SERIAL_UART_FIRST_INDEX 1
#endif
#if SERIAL_UART_FIRST_INDEX == 0
#if defined(USE_UART0)
# define SERIAL_UART0_USED 1
#else
# define SERIAL_UART0_USED 0
#endif
#else // USE_UART0 is not allowed
# if defined(USE_UART0)
# error "USE_UART0 is defined, but SERIAL_UART does not allow index 0"
# else
# define SERIAL_UART0_USED 0
# endif
#endif
#if defined(USE_UART1) #if defined(USE_UART1)
# define SERIAL_UART1_USED 1 # define SERIAL_UART1_USED 1
#else #else
@ -106,16 +125,43 @@ Configuration used:
# define SERIAL_UART10_USED 0 # define SERIAL_UART10_USED 0
#endif #endif
#define SERIAL_UART_MASK ((SERIAL_UART1_USED * BIT(1 - 1)) | (SERIAL_UART2_USED * BIT(2 - 1)) | (SERIAL_UART3_USED * BIT(3 - 1)) | (SERIAL_UART4_USED * BIT(4 - 1)) | (SERIAL_UART5_USED * BIT(5 - 1)) | (SERIAL_UART6_USED * BIT(6 - 1)) | (SERIAL_UART7_USED * BIT(7 - 1)) | (SERIAL_UART8_USED * BIT(8 - 1)) | (SERIAL_UART9_USED * BIT(9 - 1)) | (SERIAL_UART10_USED * BIT(10 - 1))) #define SERIAL_UART_MASK ((SERIAL_UART0_USED * BIT(0)) | (SERIAL_UART1_USED * BIT(1 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART2_USED * BIT(2 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART3_USED * BIT(3 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART4_USED * BIT(4 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART5_USED * BIT(5 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART6_USED * BIT(6 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART7_USED * BIT(7 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART8_USED * BIT(8 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART9_USED * BIT(9 - SERIAL_UART_FIRST_INDEX)) | (SERIAL_UART10_USED * BIT(10 - SERIAL_UART_FIRST_INDEX)))
#define SERIAL_UART_COUNT (SERIAL_UART1_USED + SERIAL_UART2_USED + SERIAL_UART3_USED + SERIAL_UART4_USED + SERIAL_UART5_USED + SERIAL_UART6_USED + SERIAL_UART7_USED + SERIAL_UART8_USED + SERIAL_UART9_USED + SERIAL_UART10_USED) #define SERIAL_UART_COUNT (SERIAL_UART0_USED + SERIAL_UART1_USED + SERIAL_UART2_USED + SERIAL_UART3_USED + SERIAL_UART4_USED + SERIAL_UART5_USED + SERIAL_UART6_USED + SERIAL_UART7_USED + SERIAL_UART8_USED + SERIAL_UART9_USED + SERIAL_UART10_USED)
// 0 if no port is defined // 0 if no port is defined
#define SERIAL_UART_MAX (SERIAL_UART_MASK ? LOG2(SERIAL_UART_MASK) + 1 : 0) #define SERIAL_UART_MAX (SERIAL_UART_MASK ? LOG2(SERIAL_UART_MASK) + 1 : 0)
// enable USE_INVERTED first, before normalization // enable USE_INVERTED first, before normalization
#if !defined(USE_INVERTER) && (INVERTER_PIN_UART1 || INVERTER_PIN_UART2 || INVERTER_PIN_UART3 || INVERTER_PIN_UART4 || INVERTER_PIN_UART5 || INVERTER_PIN_UART6 || INVERTER_PIN_UART7 || INVERTER_PIN_UART8 || INVERTER_PIN_UART9 || INVERTER_PIN_UART10) #if !defined(USE_INVERTER) && (INVERTER_PIN_UART0 || INVERTER_PIN_UART1 || INVERTER_PIN_UART2 || INVERTER_PIN_UART3 || INVERTER_PIN_UART4 || INVERTER_PIN_UART5 || INVERTER_PIN_UART6 || INVERTER_PIN_UART7 || INVERTER_PIN_UART8 || INVERTER_PIN_UART9 || INVERTER_PIN_UART10)
# define USE_INVERTER # define USE_INVERTER
#endif #endif
// Normalize UART TX/RX/INVERTER // Normalize UART TX/RX/INVERTER
#if SERIAL_UART0_USED && !defined(UART0_RX_PIN)
# define UART0_RX_PIN NONE
#endif
#if defined(WARN_UNUSED_SERIAL_PORT) && !SERIAL_UART0_USED && defined(UART0_RX_PIN)
# warning "UART0_RX_PIN is defined but UART0 is not enabled"
#endif
#if !SERIAL_UART0_USED && defined(UART0_RX_PIN)
# undef UART0_RX_PIN
#endif
#if SERIAL_UART0_USED && !defined(UART0_TX_PIN)
# define UART0_TX_PIN NONE
#endif
#if defined(WARN_UNUSED_SERIAL_PORT) && !SERIAL_UART0_USED && defined(UART0_TX_PIN)
# warning "UART0_TX_PIN is defined but UART0 is not enabled"
#endif
#if !SERIAL_UART0_USED && defined(UART0_TX_PIN)
# undef UART0_TX_PIN
#endif
#if SERIAL_UART0_USED && !defined(INVERTER_PIN_UART0)
# define INVERTER_PIN_UART0 NONE
#endif
#if defined(WARN_UNUSED_SERIAL_PORT) && !SERIAL_UART0_USED && defined(INVERTER_PIN_UART0)
# warning "INVERTER_PIN_UART0 is defined but UART0 is not enabled"
#endif
#if !SERIAL_UART0_USED && defined(INVERTER_PIN_UART0)
# undef INVERTER_PIN_UART0
#endif
#if SERIAL_UART1_USED && !defined(UART1_RX_PIN) #if SERIAL_UART1_USED && !defined(UART1_RX_PIN)
# define UART1_RX_PIN NONE # define UART1_RX_PIN NONE
#endif #endif
@ -421,7 +467,9 @@ Configuration used:
#endif #endif
/**** SOFTSERIAL *****/ /**** SOFTSERIAL *****/
#if defined(USE_SOFTSERIAL) #if defined(USE_SOFTSERIAL)
// USE_SOFTSERIAL enables all SOFTSERIAL ports
# if !defined(USE_SOFTSERIAL1) # if !defined(USE_SOFTSERIAL1)
# define USE_SOFTSERIAL1 # define USE_SOFTSERIAL1
# endif # endif
@ -496,7 +544,7 @@ Configuration used:
# define SERIAL_VCP_USED 0 # define SERIAL_VCP_USED 0
#endif #endif
// set one bit if port is enabled for consistency // for consistency, set one bit if port is enabled
#define SERIAL_VCP_MASK (SERIAL_VCP_USED * BIT(0)) #define SERIAL_VCP_MASK (SERIAL_VCP_USED * BIT(0))
#define SERIAL_VCP_COUNT (SERIAL_VCP_USED) #define SERIAL_VCP_COUNT (SERIAL_VCP_USED)
// 0 if no port is defined // 0 if no port is defined

View file

@ -8,14 +8,15 @@ import pprint
# configuration for template generation # configuration for template generation
serials = { serials = {
"UART": {"ids": [i + 1 for i in range(10)], "UART": {"ids": list(range(0, 10 + 1)),
"inverter": True, "inverter": True,
"first_index": True, # support configurable first index for this port
}, },
"LPUART": {"ids": [1], "LPUART": {"ids": [1],
"depends": {"UART"}, "depends": {"UART"},
# "inverter": True, # TODO: old code compatibility only, disabled # "inverter": True, # TODO: old code compatibility only, disabled
}, },
"SOFTSERIAL": {"ids": [i + 1 for i in range(2)], "SOFTSERIAL": {"ids": list(range(1, 2 + 1)),
"use_enables_all": True, "use_enables_all": True,
"force_continuous": True, "force_continuous": True,
}, },
@ -69,6 +70,7 @@ def main():
singleton = cfg.setdefault('singleton', False) singleton = cfg.setdefault('singleton', False)
no_pins = cfg.setdefault('no_pins', False) no_pins = cfg.setdefault('no_pins', False)
inverter = cfg.setdefault('inverter', False) inverter = cfg.setdefault('inverter', False)
cfg.setdefault('first_index', False)
cfg.setdefault("use_enables_all", False) cfg.setdefault("use_enables_all", False)
cfg.setdefault("force_continuous", False) cfg.setdefault("force_continuous", False)
cfg.setdefault("depends", {}) cfg.setdefault("depends", {})

View file

@ -1,7 +1,6 @@
{# serial_post.h #} {# serial_post.h #}
{# DEFAULT_LICENCE.md is used #} {# DEFAULT_LICENCE.md is used #}
{{ license|safe }} {{ license|safe }}
/* /*
{# Start with generated warning. It you want to change something, edit this file #} {# Start with generated warning. It you want to change something, edit this file #}
This file is automatically generated by src/utils/gen-serial.py script from src/utils/templates/serial_post.h jinja2 template. This file is automatically generated by src/utils/gen-serial.py script from src/utils/templates/serial_post.h jinja2 template.
@ -14,7 +13,7 @@ in Betaflight topmost directory.
This include will provide following defines: This include will provide following defines:
SERIAL_<type><n>_USED 0/1 - always defined, value depends on target configuration SERIAL_<type><n>_USED 0/1 - always defined, value depends on target configuration
SERIAL_<type>_MASK - bitmask of used ports or given type. <port>1 is BIT(0) SERIAL_<type>_MASK - bitmask of used ports or given type. <port>0 or <port>1 is BIT(0), based on port first_index
SERIAL_<type>_COUNT - number of enabled ports of given type SERIAL_<type>_COUNT - number of enabled ports of given type
SERIAL_<type>_MAX - <index of highest used port> + 1, 0 when no port is enabled SERIAL_<type>_MAX - <index of highest used port> + 1, 0 when no port is enabled
@ -30,56 +29,77 @@ Configuration used:
{# TODO - maybe store configuration in this file, not Python one #} {# TODO - maybe store configuration in this file, not Python one #}
{# TODO - pretty is not enough pretty #} {# TODO - pretty is not enough pretty #}
{{ user_config|pprint|safe }} {{ user_config|pprint|safe }}
*/ */
#include "common/utils.h" // BIT, LOG2 #include "common/utils.h" // BIT, LOG2
{# config array is passed to this script. It is flattened version of user_config, with default fileld in #} {# config array is passed to this script. It is flattened version of user_config, with defaults filled in #}
{% for cfg in config %} {% for cfg in config %}
/**** {{ cfg.typ }} *****/ /**** {{ cfg.typ }} *****/
{% if cfg.first_index %}
// normalize SERIAL_{{ cfg.typ }}_FIRST_INDEX
#ifndef SERIAL_{{ cfg.typ }}_FIRST_INDEX
#define SERIAL_{{ cfg.typ }}_FIRST_INDEX 1
#endif
{% endif %}
{# use_enables_all - USE_<type> enables all ports of this type #} {# use_enables_all - USE_<type> enables all ports of this type #}
{% if cfg.use_enables_all %} {% if cfg.use_enables_all %}
#if defined(USE_{{cfg.typ}}) #if defined(USE_{{cfg.typ}})
// USE_{{cfg.typ}} enables all {{cfg.typ}} ports
{% for port in cfg.ports %} {% for port in cfg.ports %}
# if !defined(USE_{{port}}) # if !defined(USE_{{port}})
# define USE_{{port}} # define USE_{{port}}
# endif # endif
{% endfor %} {% endfor %}
#endif #endif
{% endif %}
{% endif %}
{# USE_<port> - SERIAL_<port>_USED 0/1 #} {# USE_<port> - SERIAL_<port>_USED 0/1 #}
{% for port in cfg.ports %} {% for port, i in cfg.ports|zip(cfg.ids|default([-1])) %}{# handle singleton without ids #}
{% if i == 0 and cfg.first_index %}{# port 0, test if it is allowed #}
#if SERIAL_{{ cfg.typ }}_FIRST_INDEX == 0
{% endif %}
#if defined(USE_{{port}}) #if defined(USE_{{port}})
# define SERIAL_{{port}}_USED 1 # define SERIAL_{{port}}_USED 1
#else #else
# define SERIAL_{{port}}_USED 0 # define SERIAL_{{port}}_USED 0
#endif #endif
{% if i == 0 and cfg.first_index %}{# port 0, #else branch #}
#else // USE_{{port}} is not allowed
# if defined(USE_{{port}})
# error "USE_{{port}} is defined, but SERIAL_{{ cfg.typ }} does not allow index 0"
# else
# define SERIAL_{{port}}_USED 0
# endif
#endif
{% endif %}
{% endfor %} {% endfor %}
{# SERIAL_<port>_* summary macros #} {# SERIAL_<port>_* summary macros #}
{% if not cfg.singleton %} {% if not cfg.singleton %}
{% set pipe = joiner(' | ') %} {% set pipe = joiner(' | ') %}
#define SERIAL_{{ cfg.typ }}_MASK ({% for port, i in cfg.ports|zip(cfg.ids) %}{{ pipe() }}(SERIAL_{{ port }}_USED * BIT({{ i }} - 1)){% endfor %}) #define SERIAL_{{ cfg.typ }}_MASK ({% for port, i in cfg.ports|zip(cfg.ids) %}
{{- pipe() }}(SERIAL_{{ port }}_USED * BIT({{ "0" if i==0 else "{} - SERIAL_{}_FIRST_INDEX".format(i, cfg.typ) if cfg.first_index else "{} - 1".format(i) }})){% endfor %})
{# export first index information, so serial.h can assert that it does match #}
{% else %} {% else %}
{# one port without number is defined #} {# one port without number is defined #}
// set one bit if port is enabled for consistency // for consistency, set one bit if port is enabled
#define SERIAL_{{ cfg.typ }}_MASK (SERIAL_{{ cfg.ports[0] }}_USED * BIT(0)) #define SERIAL_{{ cfg.typ }}_MASK (SERIAL_{{ cfg.ports[0] }}_USED * BIT(0))
{% endif %} {% endif %}
{% set plus = joiner(' + ') %} {% set plus = joiner(' + ') %}
#define SERIAL_{{ cfg.typ }}_COUNT ({% for port in cfg.ports %}{{ plus() }}SERIAL_{{ port }}_USED{% endfor %}) #define SERIAL_{{ cfg.typ }}_COUNT ({% for port in cfg.ports %}{{ plus() }}SERIAL_{{ port }}_USED{% endfor %})
{# LOG2 is simpler than chaining MAX(SERIAL_x1_USED * 1, MAX(SERIAL_x2_USED * 2, ... #}
// 0 if no port is defined // 0 if no port is defined
{# LOG2 is simpler than chaining MAX(SERIAL_x1_USED * 1, MAX(SERIAL_x2_USED * 2, ... #}
#define SERIAL_{{ cfg.typ }}_MAX (SERIAL_{{cfg.typ}}_MASK ? LOG2(SERIAL_{{cfg.typ}}_MASK) + 1 : 0) #define SERIAL_{{ cfg.typ }}_MAX (SERIAL_{{cfg.typ}}_MASK ? LOG2(SERIAL_{{cfg.typ}}_MASK) + 1 : 0)
{# for softserial, we don't want softserial2 only #} {# for softserial, we don't want softserial2 only #}
{% if cfg.force_continuous %} {% if cfg.force_continuous %}
#if SERIAL_{{cfg.typ}}_COUNT != SERIAL_{{cfg.typ}}_MAX #if SERIAL_{{cfg.typ}}_COUNT != SERIAL_{{cfg.typ}}_MAX
# error {{cfg.typ}} ports must start with {{cfg.typ}}1 and be continuous # error {{cfg.typ}} ports must start with {{cfg.typ}}1 and be continuous
#endif #endif
{% endif %} {% endif %}
{# backward compatibility, code did set USE_INVERTER this way. It must be done before normalizing to NONE #} {# backward compatibility, code did set USE_INVERTER this way. It must be done before normalizing to NONE #}
{% if cfg.inverter %} {% if cfg.inverter %}
// enable USE_INVERTED first, before normalization // enable USE_INVERTED first, before normalization
@ -90,6 +110,7 @@ Configuration used:
{% endif %} {% endif %}
{# no pins for VCP port #} {# no pins for VCP port #}
{% if not cfg.no_pins %} {% if not cfg.no_pins %}
// Normalize {{cfg.typ}} TX/RX{{ "/INVERTER" if cfg.inverter else "" }} // Normalize {{cfg.typ}} TX/RX{{ "/INVERTER" if cfg.inverter else "" }}
{% for port in cfg.ports %} {% for port in cfg.ports %}
{% set pins = [ port ~ '_RX_PIN', port ~ '_TX_PIN' ] + (['INVERTER_PIN_' ~ port] if cfg.inverter else []) %} {% set pins = [ port ~ '_RX_PIN', port ~ '_TX_PIN' ] + (['INVERTER_PIN_' ~ port] if cfg.inverter else []) %}