This reverts commit 239f5c1f97.
PR #34359 was merged by mistake. On the bench, with an ESC on
YJUAV_A6SE_H743 output 1, the hold presents a continuous high (full
throttle to a PWM ESC) for about 10.5s after every reset, and for as
long as safety is engaged when output 1 is a motor outside
BRD_SAFETY_MASK, which is Copter's default. The ESC started to enter
throttle calibration. Back the change out until the hold can be
chosen per output.
The STM32 JTAG pins JTDI (PA15) and NJTRST (PB4) come out of every
reset, and out of power-on, with an internal pull-up enabled, and 84
hwdef directories in the tree route a PWM output through one of them:
61 through PA15, 38 through PB4, 15 through both. A servo on such an
output sees the line pulled high from then until firmware reconfigures
the pin. On the H743 that measured 692us to the bootloader's board init
on a warm reset, and 496us and 520us on two cold power-ons. Each is a
pulse inside the range servos accept, so the servo drives to an endpoint
and holds it through the rest of the boot. Nothing can shorten that
window, since no code runs during it.
Give hwdef a HOLD_HIGH keyword for PWM pins. The generator emits such a
pin as a pulled-up input with its timer alternate function preset, and a
HAL_PWM_HOLD_HIGH_MASK of the channels concerned. It rejects the keyword
on any pin RCOutput will never hand back to a timer: anything other than
a PWM(n) timer output in the main configuration, so also an RC input, the
alarm and an ALT(n) pin. One predicate decides both that and which pins
get a mask bit, so the two cannot disagree. The check is made when the
pin is parsed, which covers bootloader builds too. STM32F1 is rejected
outright, since its pin setup does not honour the keyword at all.
RCOutput keeps each channel an input until the first non-zero value is
pushed to it, in the PWM and DShot output paths, and only then switches
the pin to the timer. With the bootloader also keeping the pull-up, the
line is high continuously from the reset until the first real frame,
which for a channel outside BRD_SAFETY_MASK means until safety is
disarmed, so the servo sees a high far longer than any valid pulse
rather than a plausible short one followed by seconds of silence. On
the bench the test servo did not move at all across ten reboots.
The mode switch is an unlocked read-modify-write of the port registers,
and other threads change the modes of other pins on the same port, so
a single write can be lost. The channel is therefore not marked handed
over until a later output finds the pin already in alternate mode; until
then each output writes the mode again, so a lost write is repaired one
output later rather than leaving the pin an input until reboot.
Several other owners of a pad have to take it explicitly, because none
of them goes through the normal output path:
- the alarm driver configures a timer and never the pad, and disables
the group's channels first, so the hold on the alarm's own channel is
released before that. Only that channel: no real frame will ever
arrive for the rest of the group, so a HOLD_HIGH pin among them is
correctly left held;
- soft serial saves and restores the pad's mode, so BLHeli passthrough
hands the pin over when it selects it, or it would save "input" and
transmit nothing;
- neopixel and ProfiLED output is chosen at runtime by SERVOx_FUNCTION
on an ordinary PWM(n) pin and is sent without push_local(), so the
serial LED path releases its group's pads before driving them;
- DShot commands such as beeps are sent before arming, when nothing has
released the pad yet, so the command path releases every channel it
transmits on;
- bidirectional DShot, when enabled at runtime, takes the pads of a
whole group during init, so it clears the pending bit there. A pin
merely declared BIDIR keeps its hold; one whose group has bidirectional
DShot enabled gets no protection. The hwdef allows HOLD_HIGH and BIDIR
together deliberately.
Verified under Renode on YJUAV_A6SE_H743 with ArduPlane: the
application's board init leaves PA15 an input, it stays one through
24.8s of init, and the mode write that puts it on TIM2 lands at the same
microsecond as the first non-zero CCR1 write. With the first mode write
dropped on purpose, the next output found PA15 still an input and wrote
it; unmodified, the second output sees the mode has held and later
outputs no longer read the port. MatekF405-TE and the IOMCU
firmware still build, and a no-mask board's firmware is byte-identical.
RCOutput_iofirmware.cpp carried a second copy of the decode table, used by
the reversed-channel decoder on STM32F1. That copy is live: PB8 and PA1 are
declared BIDIR on iomcu-f103-dshot, so those channels kept the old
one-in-sixteen false accept rate while the main path was fixed.
Hoist the table, the quintet check and the checksum into one helper so the
two cannot drift again. Removing the duplicate saves 172 bytes on the F103,
which has 8k of flash left.
The GCR decode table used 0 for the sixteen quintets the encoding never emits,
which is indistinguishable from the legitimate 0 at index 25. A corrupt quintet
therefore decoded silently to nibble 0, leaving only the checksum between it and
a bad eRPM - and four bits of checksum let roughly one in sixteen corruptions
through.
Mark the impossible quintets and reject any word containing one. Betaflight
reports 5-8% of frames failing to decode with motors running, so this path is
exercised constantly, and a bad eRPM feeds RPM-referenced harmonic notch
tracking.
add support to tell if shared DMA channel is actually shared
avoid starting and stopping the timer peripheral with bdshot
ensure that rcout DMA allocation and deallocation happens entirely within the lock
increase rcout thread working area for bdshot
fix mode mask that is sent to the iomcu
ensure iomcu rcout thread gets timeouts for callbacks
control bdshot input and output line levels on f103
use input capture channel pairs to read rising and falling edges of telemetry on f103
reset channel pairs together on iomcu
generalize the bdshot input path to support suitable buffer sizes for iomcu
generalize DMAR reading of CCR registers to read two at a time on iomcu
enable bi-directional dshot channels on PWM1-4 on iomcu
add methods to directly access erpm values from rcout
update erpm mask and esc telemetry correctly for firmware supporting dshot
add support for propagating bdmask to iomcu
dshot commands to all channels need to be aware of iomcu
ensure esc type is propagated to iomcu
cope with iomcu channel numbering when using EDT
ensure pwm driver is reset properly for dshot commands on iomcu
correctly reset pwm for dshot commands
correctly mask off bdshot bits going to iomcu
don't reset GPIO modes on disabled lines
don't reset pwm_started when sharing DMA channels
set thread name on iomcu rcout and reduce stack size on iomcu
ensure that bdshot pulses with no response are handled correctly
correctly setup DMA for input capture on f103
deal with out of order captured bytes when decoding bdshot telemetry
ensure DMA sharing on f103 does not pull lines low
only disable the timer peripheral when switching DMA channels on iomcu
add support for waiting for _UP to finish before proceeding with dshot
re-order iomcu dshot channels to let TIM4_UP go first
ensure that a cascading event will always come when expected on rcout
allow timeouts when using cascading dshot
always rotate telemetry channel after trying to capture input
cater for both in order and out-of-order bdshot telemetry packets
cope with reversed packets when decoding bdshot telemetry
ensure UP DMA channel is fully free on iomcu before starting next dshot cycle
refactor rcout for iofirmware into separate file
convert RCOutput to new virtual timer interface
cope with SDC vs SDMMC
use new SPIv3 driver. Correct clocks for SDMMCv2.
add STM32L431 support
port ChibiOS config to version 8
support SPIv3 driver model v2 on H7
use currcore in debug options
use new mmc API
disable speed optimizations in the bootloader to save a little flash
upgrade to halconf v8.4
relax constraints on QSP/flash clock.
add support for disabling QSPI reset in main firmware
make sure debug will compile
take into account active channels when configuring bdshot
add channel mask debug output
correct set bdshot telemetry position at startup
make sure all channels in a bdshot group are pulled high to prevent spurious pulses
hwdef for DevEBoxH7v2
pin definitions for STM32H750
add QSPI to DevEBox bootloader
add external flash to DevEBox
rename EXTERNAL_PROG_FLASH_MB to EXT_FLASH_SIZE_MB
Add support for EXT_FLASH_RESERVE_START_KB and EXT_FLASH_RESERVE_END_KB
Disable HAL_ENABLE_SAVE_PERSISTENT_PARAMS when there is no bootloader flash available
relax storage health status with SD card backend
don't check SD card health unless USE_POSIX
binary sections rearranged on external ram
manage RAMFUNC through ldscript and optimize function placement in external flash
inline timer functions
optimize placement of ChibiOS and functions in ITCM and AXI RAM
fix chibios features on bootloader build with external flash
change H750 memory layout
increase line storage for SD card based parameters
comment external flash linker script
move vtables into DTCM
update ram map for H757
enable crashdump support with external flash
correct bootloader pins and generator on SPRacingH7/DevEBoxH7v2
setup external flash reserve regions
allow different RAM_MAP for external flash on H750 and H757
add support for dshot beepcodes through tonealarm
add support for dshot reversal and command queue
add support for dshot commands to all channels
correctly manage channel enablement in PWM groups
Correctly send dshot commands when using bi-dir dshot
allow reversible settings to be changed
ChibiOS: allow more than one type of ESC for dshot commands
Only execute reverse/reversible commands on BLHeli
add support for checking active ESCS
mark ESCs active when bdshot telemetry is returned
allow dshot alarm to be disabled
allow priroitized dshot commands
allow faster rates synchronized to the loop rate
synchronize 1Khz and use Betaflight definition for prescaler
adjust dshot bitrates
don't allocate IC DMA if already allocated
cancel DMA pulses correctly
try really hard to align pulses with push() by making each dshot pulse event driven
refactor rcout into separate thread and process all dshot requests there
move uart DMA completion to event model
process dshot locks in strick reverse order when unlocking
convert Shared_DMA to use mutexes
move UART transmit to a thread-per-uart
do blocking UART DMA transactions
do blocking dshot DMA transactions
trim stack sizes
cancel dma transactions on dshot when timeout occurs
support contention stats on blocking locking
move thread supression into chibios_hwdef.py
invalidate DMA bounce buffer correctly
separate UART initialisation into two halves
cleanup UART transaction timeouts
add @SYS/uarts.txt
move half-duplex handling to TX thread
correct thread statistics after use of ExpandingString
set unbuffered TX thread priority owner + 1
correctly unlock serial_led_send()
don't share IMU RX on KakuteF7Mini
observe dshot pulse time more accurately.
set TRBUFF bit for UART DMA transfers
deal with UART DMA timeouts correctly
don't deadlock on reverse ordered DMA locks
change PORT_INT_REQUIRED_STACK to 128
calculate DMAR pulse times correctly
ensure 50us pulse separation for LED
make sure the LEDs are signalled for output
only allow LED length to be set once
add support for sampling GPIO pins using timer
don't restart pwm group when not doing bi-dir
fix hwdef generation preproc for TIM DMA
decode telemetry at the start of the dshot cycle
calculate dshot pulse separation correctly and ensure we output rapidly enough
calculate dshot min periods and timeouts correctly
refactor dshot_send() into dshot_send_groups()
use bi-dir dshot channel mask
selectively enable bi-dir RC Channels
process bi-dir mask correctly when allocating DMA channels
allow UP and CH DMA channel sharing
optionally enable bidir vars in hwdef.
enable bi-dir dshot in KakuteF7Mini
enable bi-dir dshot in OmnibusF4Pro
enable bi-dir dshot in OmnibusNanoV6
enable bi-dir dshot in MatekF405
enable bi-dir dshot in fmuv5
enable bi-dir dshot in fmuv3
enable bi-dir dshot in OmnibusF7V2
enable bi-dir dshot in OmnibusNanoV6
enable bi-dir dshot in CubeOrange
enable bi-dir dshot in Pixracer
enable bi-dir dshot in mRoPixracerPro
Co-authored-by: bugobliterator <siddharthbharatpurohit@gmail.com>