chore: New module/serial API (#3055)

* WiP: new module interface

* WiP: softserial timer DMA

* WiP: setup() and send() in one step

and remove methods specific to internal or external module

* fixes and extra port config

* horus targets

* module ports have moved

* T8 support (only internal module)

* fix nv14

* stupid GCC....

* disable BT

* remove nv14 telem driver

* remove old aux serial driver

* Move module buffers out of pulses.h

* Soft serial fixes and PXX1 support

* Fixed PPM module output

* Fixed CLI

* compilation fixes

* Ported bluetooth and flysky gimbal to new serial driver

* Re-enable soft-serial RX

* fixes and cleanup

* nv14 fixes

* Fix flysky gimbals

* Ghost module

* 16 bytes of RAM

* Remove getByte from module API

* Ghost cleanup

* fix: _half_duplex_input() must be called after usart init

* WiP

* more cleanup

* Remove board specific settings from PXX1 / PXX2 drivers

* A bit of PXX2 header cleanup

* Add support for OVER8 and ONEBIT

* Add some support for inverters (NV14 / EL18)

* Support NV14 power fixes in generic board

* Fix polarity handling

* Fix RX DMA

* Fix mixer not running

* Add soft-serial polarity control

* Quick fix for telemetry polling while module port is changed

* Fix bootloader DEBUG

* Fix MPM telemetry

* Fix pulse start

* DSM2 soft-serial fallback

* DSMP async module restart

* Fix CRSF LUA upstream

* Remove global variable telemetryProtocol

* Use HAL/LL constants

* Fix various issue with AFHDS3 and NV14/EL18 internal module

* Fixed S.PORT unit tests

* fix: update widx after writing at current index

* fix: init error condition

* Fix: possible infinite loop in _find_port()

* Add support for bidir S.PORT init

* Add support for "getLastByte" in HW serial driver

* PXX1: Add support for S.PORT based on IDLE callback

* Fix rebase error

* Fix softserial _rx_fifo_push()

* Add softserial support for waitForTxCompleted()

* Fix MPM flashing (internal / external)

* Fixed external MPM

* Activate RX DMA on internal module

Seems to work with serial passthrough without issues, at least on the L3R PRO.

* Fix softserial DMA on stdlcd F4 targets

* Add softserial support for 32bit timers (mostly TIM2)

* More precise soft-serial

* Fix MPM update using inverters & HW uart

* Raise S.PORT DMA/USART IRQ prio to achieve faster switching to input

* Remove useless delays

* Fix flashing external ELRS module

* Added a retry mechanism for FrSky S.PORT update

* Remove useless enableRx()

* External FrSky modules are all flashed via S.PORT

* Remove power management unit update

This was only used on the first batch of X-lite.
This commit is contained in:
Raphael Coeffic
2023-02-09 19:44:32 +10:00
committed by GitHub
parent d80adc6c4d
commit 72193eda82
189 changed files with 7960 additions and 8364 deletions
@@ -19,107 +19,100 @@
* GNU General Public License for more details.
*/
#include "bluetooth_driver.h"
#include "stm32_hal_ll.h"
#include "board.h"
#include "debug.h"
#if !defined(BOOT)
#include "fifo.h"
#include "stm32_serial_driver.h"
Fifo<uint8_t, BT_TX_FIFO_SIZE> btTxFifo;
Fifo<uint8_t, BT_RX_FIFO_SIZE> btRxFifo;
#define BT_USART_IRQ_PRIORITY 6
static const stm32_usart_t btUSART = {
.USARTx = BT_USART,
.GPIOx = BT_USART_GPIO,
.GPIO_Pin = BT_TX_GPIO_PIN | BT_RX_GPIO_PIN,
.IRQn = BT_USART_IRQn,
.IRQ_Prio = BT_USART_IRQ_PRIORITY,
.txDMA = nullptr,
.txDMA_Stream = 0,
.txDMA_Channel = 0,
.rxDMA = nullptr,
.rxDMA_Stream = 0,
.rxDMA_Channel = 0,
};
DEFINE_STM32_SERIAL_PORT(BTModule, btUSART, BT_RX_FIFO_SIZE, BT_TX_FIFO_SIZE);
#if defined(BLUETOOTH_PROBE)
volatile uint8_t btChipPresent = 0;
#endif
enum BluetoothWriteState
{
BLUETOOTH_WRITE_IDLE,
#if defined(BT_BRTS_GPIO_PIN)
BLUETOOTH_WRITE_INIT,
#endif
BLUETOOTH_WRITING,
#if defined(BT_BRTS_GPIO_PIN)
BLUETOOTH_WRITE_DONE
#else
BLUETOOTH_WRITE_DONE = BLUETOOTH_WRITE_IDLE
#endif
};
volatile uint8_t bluetoothWriteState = BLUETOOTH_WRITE_IDLE;
// const etx_serial_driver_t* _bt_usart_drv = nullptr;
void* _bt_usart_ctx = nullptr;
#endif
void bluetoothInit(uint32_t baudrate, bool enable)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = BT_EN_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(BT_EN_GPIO, &GPIO_InitStructure);
LL_GPIO_InitTypeDef pinInit;
LL_GPIO_StructInit(&pinInit);
#if defined(BT_BRTS_GPIO_PIN)
GPIO_InitStructure.GPIO_Pin = BT_BRTS_GPIO_PIN;
GPIO_Init(BT_BRTS_GPIO, &GPIO_InitStructure);
GPIO_SetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
#endif
pinInit.Pin = BT_EN_GPIO_PIN;
pinInit.Mode = LL_GPIO_MODE_OUTPUT;
pinInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
pinInit.Pull = LL_GPIO_PULL_NO;
#if defined(BT_BCTS_GPIO_PIN)
GPIO_InitStructure.GPIO_Pin = BT_BCTS_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(BT_BCTS_GPIO, &GPIO_InitStructure);
#endif
LL_GPIO_Init(BT_EN_GPIO, &pinInit);
#if !defined(BOOT)
GPIO_PinAFConfig(BT_USART_GPIO, BT_TX_GPIO_PinSource, BT_GPIO_AF);
GPIO_PinAFConfig(BT_USART_GPIO, BT_RX_GPIO_PinSource, BT_GPIO_AF);
etx_serial_init cfg = {
.baudrate = baudrate,
.encoding = ETX_Encoding_8N1,
.direction = ETX_Dir_TX_RX,
.polarity = ETX_Pol_Normal,
};
GPIO_InitStructure.GPIO_Pin = BT_TX_GPIO_PIN | BT_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(BT_USART_GPIO, &GPIO_InitStructure);
USART_DeInit(BT_USART);
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = baudrate;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_Init(BT_USART, &USART_InitStructure);
USART_Cmd(BT_USART, ENABLE);
USART_ITConfig(BT_USART, USART_IT_RXNE, ENABLE);
NVIC_SetPriority(BT_USART_IRQn, 6);
NVIC_EnableIRQ(BT_USART_IRQn);
bluetoothWriteState = BLUETOOTH_WRITE_IDLE;
btRxFifo.clear();
btTxFifo.clear();
if (!_bt_usart_ctx) {
auto hw_def = REF_STM32_SERIAL_PORT(BTModule);
_bt_usart_ctx = STM32SerialDriver.init(hw_def, &cfg);
} else {
STM32SerialDriver.setBaudrate(_bt_usart_ctx, baudrate);
}
#endif
if (enable)
GPIO_ResetBits(BT_EN_GPIO, BT_EN_GPIO_PIN);
else
GPIO_SetBits(BT_EN_GPIO, BT_EN_GPIO_PIN);
if (enable) {
LL_GPIO_ResetOutputPin(BT_EN_GPIO, BT_EN_GPIO_PIN);
} else {
LL_GPIO_SetOutputPin(BT_EN_GPIO, BT_EN_GPIO_PIN);
}
}
#if !defined(BOOT)
void bluetoothDisable()
{
GPIO_SetBits(BT_EN_GPIO, BT_EN_GPIO_PIN); // close bluetooth (recent modules will go to bootloader mode)
USART_ITConfig(BT_USART, USART_IT_RXNE, DISABLE);
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = BT_RX_GPIO_PIN;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_Init(BT_USART_GPIO, &GPIO_InitStructure);
USART_DeInit(BT_USART);
// close bluetooth (recent modules will go to bootloader mode)
LL_GPIO_SetOutputPin(BT_EN_GPIO, BT_EN_GPIO_PIN);
if (_bt_usart_ctx) {
STM32SerialDriver.deinit(_bt_usart_ctx);
}
}
// @Cliff
// ISR is handled by the serial driver,
// however, it is unclear at this point
// how the detection should be implemented.
// Maybe setting a temporary callback on
// the interface, or trying to pull some data.
//
// Also, it is quite unclear why we would need
// to disable sending when the TX buffer is exahausted.
// The serial driver does take care of that but does not
// set any particular piece of state that could be queried
// to deduct the state of this TX buffer.
#if _OBSOLETE_
extern "C" void BT_USART_IRQHandler(void)
{
DEBUG_INTERRUPT(INT_BLUETOOTH);
@@ -144,38 +137,30 @@ extern "C" void BT_USART_IRQHandler(void)
}
else {
USART_ITConfig(BT_USART, USART_IT_TXE, DISABLE);
// => BLUETOOTH_WRITE_IDLE
bluetoothWriteState = BLUETOOTH_WRITE_DONE;
}
}
}
#endif
void bluetoothWriteWakeup()
void bluetoothWrite(const void* buffer, uint32_t len)
{
if (bluetoothWriteState == BLUETOOTH_WRITE_IDLE) {
if (!btTxFifo.isEmpty()) {
#if defined(BT_BRTS_GPIO_PIN)
bluetoothWriteState = BLUETOOTH_WRITE_INIT;
GPIO_ResetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
#else
bluetoothWriteState = BLUETOOTH_WRITING;
USART_ITConfig(BT_USART, USART_IT_TXE, ENABLE);
#endif
}
}
#if defined(BT_BRTS_GPIO_PIN)
else if (bluetoothWriteState == BLUETOOTH_WRITE_INIT) {
bluetoothWriteState = BLUETOOTH_WRITING;
USART_ITConfig(BT_USART, USART_IT_TXE, ENABLE);
}
else if (bluetoothWriteState == BLUETOOTH_WRITE_DONE) {
bluetoothWriteState = BLUETOOTH_WRITE_IDLE;
GPIO_SetBits(BT_BRTS_GPIO, BT_BRTS_GPIO_PIN);
}
#endif
if (!_bt_usart_ctx) return;
STM32SerialDriver.sendBuffer(_bt_usart_ctx, (const uint8_t*)buffer, len);
}
int bluetoothRead(uint8_t* data)
{
if (!_bt_usart_ctx) return 0;
return STM32SerialDriver.getByte(_bt_usart_ctx, data);
}
uint8_t bluetoothIsWriting(void)
{
return bluetoothWriteState != BLUETOOTH_WRITE_IDLE;
if (!_bt_usart_ctx)
return false;
return STM32SerialDriver.txCompleted(_bt_usart_ctx);
}
#endif // !BOOT