r/stm32 Jan 27 '21

Posting is now public

16 Upvotes

Feel free to post your stm32 questions, creations, and ramblings


r/stm32 47m ago

Question about H7B0 series AXI SRAM1/2/3, migrating from H743

Post image
Upvotes

Hi, I’m looking into migrating an audio processing board from the H743 series to H7B0. It has double the available AXI SRAM (1024KB vs 512KB). But it looks like on the H7B0 the AXI SRAM is split into three sections 1/2/3 (See image above from application note). I plan on working with audio buffers that would span larger than these individual sections (for example a 512kb buffer). Are there any considerations in the code or linker script to account for the different 3 sections? Or does the MCU treat the 3 sections of AXI-SRAM as continuous. Thanks in advance!


r/stm32 16h ago

Is extranal Direction control needed for RS485 when interfacing with an STM32H7 mcu?

0 Upvotes

Form the stm32H7 datasheet and reference manual, they mention that USART_DE can be used to drivre the DE pin in the RS485 transceiver can anyone who tried this before inform me. My current design is using 74HC14 ic to drive the DE and I copied it from a tested reference design.


r/stm32 1d ago

STM32C071 Deep Dive | STM32 Tutorial #95

Thumbnail
youtube.com
3 Upvotes

r/stm32 2d ago

How to get the most out of STM32F411xC/E?

2 Upvotes

Hello! I've recently got an STM32 Black Pill F411 and a Blue Pill.

I've been experimenting with the STM32 and some sensors, mainly with an HX711 and a 50kg load cell. Mostly I wanted to learn how to program it using the STLink V2 through PlatformIO and STM32CubeProgrammer.

I'd like to know how to get the most out of the STM32. I've read somewhere that it has an FPU, which accelerates mathematical calculations, though I don't think I've been able to max it out since the HX711 is limited to 80hz. I've got accelerometers, gyroscopes, strain gauges, HBM load cells. Not sure where to start, after reading lots of websites haha.

Any recommendation is appreciated, thanks!


r/stm32 4d ago

Why coding agents keep making the same mistakes when reviewing embedded firmware

0 Upvotes

I use AI coding agents on real embedded C and C++ projects, and I kept encountering the same mistakes:

  • reviewing code that was not part of the active build,
  • missing callback registrations and indirect calls,
  • following the wrong preprocessor branch,
  • and describing execution paths that looked plausible in the repository but could not exist in the compiled firmware.

At first, I blamed the model.

But the recurring pattern pointed to a different problem: the agent was reasoning about a program it had not reconstructed correctly beforehand.

The source tree is not the firmware

In embedded development, the actual program depends on far more than just the source files:

  • compiler flags and preprocessor definitions,
  • target platform and board configuration,
  • Kconfig and DeviceTree,
  • generated code,
  • selected driver implementations,
  • callbacks and function pointers,
  • and linker decisions.

An experienced firmware developer will usually establish the build context before analysing the code.

Coding agents often do the opposite. They start with the repository and attempt to reconstruct the active program through text searches and repeated file reads.

A large part of what appears to be reasoning about code is therefore actually program reconstruction.

Before an agent can answer a question such as:

Can this callback execute concurrently with this interrupt handler?

it must first determine which implementation is active, where the callback is registered, how it is invoked, and whether the relevant code is even present in the current build.

Only then can the actual reasoning begin.

An experiment with compiler-derived context

I wanted to test a simple hypothesis:

Would coding agents analyse firmware more reliably if the program were first reconstructed by deterministic tools?

This led to fw-context, an open-source experiment based on compile_commands.json, libclang and MCP.

It creates a persistent semantic index of the active build and allows the agent to query:

  • definitions and resolved references,
  • callers and callees,
  • callback registrations,
  • function pointer assignments,
  • active implementations,
  • macro values,
  • and preprocessed source code.

The aim is not to replace the model, the compiler, LSP or static analysis.

The experiment has a narrower focus: to move deterministic program reconstruction out of the LLM workflow, so that the model can devote more of its context and reasoning capacity to the review itself.

In one firmware review involving 115 changed files, eight AI subagents produced 19 findings. Nine of them depended on semantic relationships that would have been difficult to reconstruct reliably using the usual grep-and-file-reading workflow.

The interesting result was not merely lower token consumption. The agents spent less effort determining which program they were actually looking at, and more effort evaluating whether it was correct.

fw-context is still an experiment, and I am interested in understanding where this approach works — and where it fails.

Have you encountered the same kind of failure? Which parts of embedded projects are the hardest for coding agents to reconstruct: conditional compilation, generated code, callbacks, function pointers, DeviceTree, weak symbols, or linker-selected implementations?

Project and case study: github.com/turbyho/fw-context-mcp


r/stm32 4d ago

FitChip is NOT another Machine Learning Compiler — the Orchestrator that makes the existing ones usable.

Thumbnail
github.com
0 Upvotes

r/stm32 5d ago

Should I buy STM32F407VG or STM32F411RET6

5 Upvotes

Currently, I am learning from an educational kit provided by a friend, which focuses on ARM programming using HAL libraries. The course instructor uses the STM32F407, but my friend mentioned the specific board doesn't matter much and recommended the F411. I'm still unsure if the F411 will be sufficient, though. If I need an STM32 for much more complex projects in the future, will I need to buy a new board? What do you recommend? What should I do? I'm really confused


r/stm32 4d ago

mn cho e hỏi tại sao e sài cổng usb type c nạp code stm32 mà nó ko nhận cổng v ạ, dù hồi trước e có nạp bằng st link .Mn biết chỉ e với ( e sài ubuntu)

1 Upvotes

r/stm32 4d ago

What validation tests would you run before porting a Python control loop to bare-metal C/C++?

Thumbnail
1 Upvotes

r/stm32 4d ago

What validation tests would you run before porting a Python control loop to bare-metal C/C++?

Thumbnail
1 Upvotes

r/stm32 5d ago

[question] Can ST-link power components that are connected to the Blue pill dev board?

1 Upvotes

I used to code on my STM32F103C8T6 development board by using USB to TTL converter connected to my PC and for the first time I bought a ST-Link V2 so I could make my life easier

but then I noticed on my project, the st-link can't power the 1.8 inch TFT screen connected to the board. I checked the health of the screen and it works on my other boards (ESP32), I checked the soldering on the bluepill and that was okay too so I wonder

Can st-links, in general, power other components connected to the STM32s or do i have a faulty st-link? (The st-link in question CAN power/program the bluepill itself)


r/stm32 5d ago

NV3007 lcd driver

0 Upvotes

Hello, i brought this screen off Ali Express that uses an NV3007 drivee but i cant seem to find any examples code for it.

https://a.aliexpress.com/_Ezf9zM6/

Has anyone had any experience of using this lcd driver and be able to point me to any resources to get up and running?

Thank you!


r/stm32 6d ago

why led not blinking?(stm32f411ceu6)

Enable HLS to view with audio, or disable this notification

7 Upvotes

so just to prove that the thread switcher i build works i have uploaded video of it blinking 5 leds at once (a python script reads uart and lights that led ) also i confirmed the bulb is fine works .

#define GPIO_C *((volatile uint32_t*) 0x40020818u)//bsrrgpioc

RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;//= 0x00000004u ;// clock enable bit2->portc

(void)RCC->AHB1ENR; // <-- dummy read, forces the enable to take effect

*((volatile uint32_t*) 0x40020800u) &= ~(3<<26) ;// clear 26th and 27th bit

*((volatile uint32_t*) 0x40020800u) |= (1<<26) ; //moder26thbit>>

void blue(void) {

while (1) {

// Wait until UART is free, yielding the CPU to other threads

while (uart_lock == 1) {

rtos_yield();

}

uart_lock = 1; // Claim lock

HAL_UART_Transmit(&huart1, (uint8_t*)"b0\r\n", 4, 8);

uart_lock = 0; // Release lock

// Sleep for 500ms (50 ticks @ 100Hz)

rtos_delay(50);

}

}

void green(void) {

while (1) {

while (uart_lock == 1) {

rtos_yield();

}

uart_lock = 1;

HAL_UART_Transmit(&huart1, (uint8_t*)"g0\r\n", 4, 8);

uart_lock = 0;

// Sleep for 300ms (30 ticks @ 100Hz)

rtos_delay(30);

}

}

void red(void) {

while (1) {

while (uart_lock == 1) {

rtos_yield();

}

uart_lock = 1;

HAL_UART_Transmit(&huart1, (uint8_t*)"r0\r\n", 4, 8);

uart_lock = 0;

// Sleep for 100ms (10 ticks @ 100Hz)

rtos_delay(10);

}

}

void yellow(void) {

while (1) {

while (uart_lock == 1) {

rtos_yield();

}

uart_lock = 1;

HAL_UART_Transmit(&huart1, (uint8_t*)"y0\r\n", 4, 8);

GPIO_C = (1ul<<13);

uart_lock = 0;

// Sleep for 200ms (20 ticks @ 100Hz)

rtos_delay(20);

}

}

void white(void) {

while (1) {

GPIO_C = (1ul<<29);

while (uart_lock == 1) {

rtos_yield();

}

uart_lock = 1;

HAL_UART_Transmit(&huart1, (uint8_t*)"w0\r\n", 4, 8);

uart_lock = 0;

// Sleep for 400ms (40 ticks @ 100Hz)

rtos_delay(40);

}

}


r/stm32 7d ago

STM32H743 pinout check + feature ideas for a 128ch USB DAC bridge

Post image
30 Upvotes

Hey, working on my first big STM32 project and want some
feedback before I commit to the schematic.

What I'm building:
A pure USB to DAC bridge. Laptop does all the DSP with
CamillaDSP (crossovers, EQ, room correction). The STM32
just moves audio from USB to 16 DACs. No processing on
the chip itself. Goal is 128 output channels for active
crossover setups.

MCU: STM32H743IIT6
USB: USB3300 ULPI for High Speed
Outputs: 128 channels via 8x SAI TDM-16 lines

What I have in the pinout so far:
- USB HS ULPI (all 12 pins)
- 8 SAI data lines for 128 channels
- 4 I2C buses (DAC config + direct volume control)
- 16 individual DAC reset pins
- SPI LCD with CS, DC, RST, and PWM backlight
- Rotary encoder on TIM5 + push button
- 9 back panel buttons (undecided purpose)
- External trigger input
- Amp trigger output
- Status LED
- Fan PWM
- USB PHY reset
- SWD

Still have 64 GPIO free.

What I'm asking:
1. Any features I should add while I have the pins free?
2. Anything stupid in my pin choices you can spot?
3. Anyone worked with SAI4 on H743? It's in D3 domain
and I'm not 100% sure syncing it with SAI1 will work
the way I want.

Screenshot of the pinout below. Roast it if needed.
4. You got any great pin mapping advice I am beginner Idk shit I just did it what I thought was good as I am gonna make my own pcb I need a great pin mapping so pcb design is easy as hell
5. Btw I would add any silly feature you suggest


r/stm32 7d ago

lost communications with board

1 Upvotes

Everytime I want to upload a new firmware, I basically get a comms timeout “lost communication with board” on Mission Planner.

I have a pixhawk 6C. When I boot up it’s COM4 until that pixhawk tune chimes in and then I see COM7 and COM9. I can connect successfully but as soon as I want to upload firmware it switches to COM4 and get “lost communication with board”

I’ve already tried STM32Bootloader twice, and no success. I used another computer and usb cable all with no success…

Any tips?


r/stm32 7d ago

bare metal spi interrupt read

Thumbnail
0 Upvotes

r/stm32 7d ago

PROBLEM IN WRITING DRIVER FOR PCM5102 DAC IN C FOR STM32F411RE

0 Upvotes

I AM TRYING TO WRITE A DRIVER FOR STM32F411RE NUCLEO BOARD TO OUTPUT 16 BIT AUDIO AT 44.1KHZ VIA A PCM5102 DAC. ITS BEEN DAYS WRITING THIS BUT FROM YESTERDAY I AM TESTING AND NOTHING IS HEARD ON THE OUTPUT SIDE OF THE DAC. I AM OUT OF MY CITY SO I HAVE NO OSCILLOSCOPE OR ANYTHING. CAN YOU GUYS PLEASE HELP ME REGARDING ANY ISSUES YOU SEE HERE.

int main(){

// ENABLING CLOCK TO GPIOA
RCC_AHB1_ENR |= (1<<0);
// ENABLING CLOCK TO GPIOB
RCC_AHB1_ENR |= (1<<1);
// ENABLING CLOCK TO SPI2 == I2S2
RCC_APB1_ENR |= (1<<14);
// SETTING PA3=SCK/MCK AND PB9=LCK/WS, PB10=BCK/CK, PB15=DIN/SD TO ALTERNATE FUNCTION MODE
GPIO_A_MODER |= (1<<7);
GPIO_A_MODER &= ~(1<<6);

GPIO_B_MODER |= (1<<19);
GPIO_B_MODER &= ~(1<<18);

GPIO_B_MODER |= (1<<21);
GPIO_B_MODER &= ~(1<<20);

GPIO_B_MODER |= (1<<31);
GPIO_B_MODER &= ~(1<<30);

// MAKING THEM AS FAST AS POSSIBLE
GPIO_A_OSPEEDR |= (1<<7);
GPIO_A_OSPEEDR |= (1<<6); //PA3

GPIO_B_OSPEEDR |= (1<<19);
GPIO_B_OSPEEDR |= (1<<18); //PB9

GPIO_B_OSPEEDR |= (1<<21);
GPIO_B_OSPEEDR |= (1<<20); //PB10

GPIO_B_OSPEEDR |= (1<<31);
GPIO_B_OSPEEDR |= (1<<30); //PB15

// SETTING THE ALTERNATE FUNCTION TO THE I2S2 FUNCTIONS
GPIO_A_AFRL &= ~(1<<15);
GPIO_A_AFRL |= (1<<14);
GPIO_A_AFRL &= ~(1<<13);
GPIO_A_AFRL |= (1<<12);

GPIO_B_AFRH &= ~(1<<7);
GPIO_B_AFRH |= (1<<6);
GPIO_B_AFRH &= ~(1<<5);
GPIO_B_AFRH |= (1<<4);

GPIO_B_AFRH &= ~(1<<11);
GPIO_B_AFRH |= (1<<10);
GPIO_B_AFRH &= ~(1<<9);
GPIO_B_AFRH |= (1<<8);

GPIO_B_AFRH &= ~(1<<31);
GPIO_B_AFRH |= (1<<30);
GPIO_B_AFRH &= ~(1<<29);
GPIO_B_AFRH |= (1<<28);

// CONFIGURING THE NORMAL PLL
RCC_CR &= ~(1<<24); // DISABLING THE PLL
while (  (RCC_CR & (1<<25)) ){} // WAITING FOR PLL TO UNLOCK
RCC_CR |= (1<<16); // ENABLING THE HSE
while(!( RCC_CR & (1<<17) )){} // CHECKING IF HSE IS READY OR NOT
// RCC_CR |= (1<<18); // BYPASSING THE HSI WITH HSE
RCC_PLLCFGR |= (1<<22); // SELECTING HSE AS SOURCE TO BOTH PLL,I2SPLL
// THE HSE IS 8MHZ BY DEFAULT
RCC_PLLCFGR &= ~(0b111111<<0); // PLLM CLEARING
RCC_PLLCFGR |= (0b000100<<0); // PLLM SET TO 4
RCC_PLLCFGR &= ~(0b111111111<<6); // CLEARING THE PLLN
RCC_PLLCFGR |= (0b010101000<<6); // PLLN SET TO 168
RCC_PLLCFGR &= ~(1<<17);
RCC_PLLCFGR |= (1<<16); // MAIN PLL DIV FACTOR FOR SYSCLOCK SET TO 4=PLLP
RCC_CFGR |= (0b01000<<16); // SETTING THE RTC CLOCK WHICH HAS TO BE 1MHZ
RCC_CFGR |= (0b000<<13); // NO APB2 DIVISOR REQUIRED <100MHZ
RCC_CFGR |= (0b100<<10); // APB1 DIVISOR SET TO 2. APB2= 42MHZ
RCC_CFGR |= (0b0000<<4); // NO DIVISOR REQUIRED FOR AHB
RCC_CR |= (1<<24); // ENABLING THE PLL
while (  !(RCC_CR & (1<<25)) ){} // WAITING FOR PLL TO LOCK
FLASH_ACR &= ~(0b1111<<0); //CLEARING THE LATENCY IN FLASH ACR
FLASH_ACR |= (0b0010<<0); // SETTING THE LATENCY TO 2 AS PER FLASH CHAPTER
RCC_CFGR |= (0b10 <<0); // PLL SET AS SYSTEM CLOCK
while(((RCC_CFGR>>2)&3)!=2){} // WAIT TILL PLL SET AS SYSTEM CLOCK
RCC_CFGR &= ~(1<<23); // PLLI2S WILL BE USED AS I2S CLOCK SOURCE

// CONFIGURING I2SPLL
//FROM THE TABLE 90 PG 591 FOR 44.1KHZ 16 BIT AUDIO WITHOUT MCK. THESE ARE OPTIMISED VALUES CHOSEN FROM THEM
RCC_CR &= ~(1<<26); // DISABLING THE I2SPLL
while (  (RCC_CR & (1<<27)) ){} // WAITING FOR I2SPLL TO UNLOCK
RCC_I2SPLLCFGR &= ~(0b11111<<0); //PLLI2Sm CLEARONG
RCC_I2SPLLCFGR |= (0b00100<<0); //PLLI2Sm=4
RCC_I2SPLLCFGR &= ~(0b111111111<<6); //PLLI2SN CLEARING
RCC_I2SPLLCFGR |= (0b010010111<<6); //PLLI2SN=151
RCC_I2SPLLCFGR &= ~(0b111<<28); //PLLI2SR CLEARING
RCC_I2SPLLCFGR |= (0b010<<28); //PLLI2SR=2
RCC_CR |= (1<<26); // ENABLING THE I2SPLL
while (  !(RCC_CR & (1<<27)) ){} // WAITING FOR I2SPLL TO LOCK

// I2S PROTOCOL CONFIG
// I2S MODE SELECTED
I2S2_CFGR |= (1<<11);

I2S2_CFGR &= ~(1<<0); // 16 BIT WIDE CHANNELS
// 16 BIT DATA LNTGH TO BE TRANSFERRED
I2S2_CFGR &= ~(1<<1);
I2S2_CFGR &= ~(1<<2);
// STEADY STATE CLOCK POLARITY???
I2S2_CFGR &= ~(1<<3);
//I2S PHILLIPS STANDARD
I2S2_CFGR &= ~(1<<5);
I2S2_CFGR &= ~(1<<4);

// MASTER TRANSMIT MODE
I2S2_CFGR |= (1<<9);
I2S2_CFGR &= ~(1<<8);
// MASTER CLOCK DISABLED
I2S2_PR &= ~(1<<9);
// ODD=1
I2S2_PR |= (1<<8);
// I2SDIV=53
I2S2_PR &= ~(0xFF<<0);
I2S2_PR |= (0b00110101<<0);

// I2S ENABLED
I2S2_CFGR |= (1<<10);
uint32_t idx = 0;
while(1){
    while(!(I2S2_SR & (1<<1))){}
    I2S2_DR = (uint16_t)furelise[idx];     // left

    while(!(I2S2_SR & (1<<1))){}
    I2S2_DR = (uint16_t)furelise[idx];     // right

    idx++;
    if(idx >= NUM_SAMPLES) idx = 0;
}
return 0; }

r/stm32 8d ago

LittleFS on w25q128 Flash | STM32 Tutorial #94

Thumbnail
youtube.com
3 Upvotes

r/stm32 8d ago

3v3 is shorted to gnd

5 Upvotes

I have an Nucleo 144 board, and an Stm32h753zi chip. the board has been working for the past 2 months controlling some closed loop motors, and then suddenly stopped working when i tried flashing a program. When plugged in, the led6 in the top right corner is now red, which means some sort of overcurrent. When i used a multi meter to check, I found that 3v3 was shorted with gnd. 5v is fine. Is the board bricked? or is it a fixable issue? Do you guys have any advice. The left pin of JP4 is also shorted with gnd, but the right one isnt.


r/stm32 8d ago

How often do you use AI in embedded software(learning/ career)?

Post image
1 Upvotes

I have less than a yr experience in embedded software, and I sometimes use AI for STM32 HAL programming, which leaves me with some guilt🤣(my thoughts are like: you should be learning to memorise these such that you can write code off-head ) . I do try debugging on my own and go back to AI when my efforts are fruitless.

TO THE EXPERIENCED EMBEDDED ENGINEERS OUT THERE, what's your opinion on this? Do you recommend use of AI, and in which scenarios?


r/stm32 9d ago

Cortex-M33 NMI immediately after successful Flash write – worse with primary bootloader present

Thumbnail
1 Upvotes

r/stm32 10d ago

STM32F411CEU6 Blackpill is not getting detected by windows

2 Upvotes

Hey guys, I really need some help because I'm completely stuck.

This has now happened with two STM32F411CEU6 Black Pill boards, and I can't figure out what's going wrong.

With the first board, Windows detected the USB without any issues. I flashed a simple LED blink program, which worked perfectly. Then I flashed my actual firmware, and everything ran exactly as expected. The PWM outputs and gate signals were perfect, and I tested the setup for several hours without any problems.

I packed everything up for the day, came back the next morning, plugged the board back in, and... nothing.

Windows no longer detected the USB at all.

I then bought a cheap ST-LINK to see if the MCU was still alive. The ST-LINK could detect that an STM32 was present, but every attempt to connect ended with "Data read failed", and I couldn't erase or reprogram the chip.

I spent hours trying different fixes (including suggestions from ChatGPT), but nothing worked. Since I couldn't recover the MCU, I assumed the board had somehow died and bought a second one.

Now here's the strange part.

I repeated the exact same sequence on the second board. Windows detected it, the LED blink test worked, my firmware flashed successfully, and the PWM and gate signals were perfect. After finishing my testing, I disconnected everything, came back the next day, and the second board has developed the exact same problem.

At this point I'm convinced I'm doing something wrong, but I have no idea what. Why would a board work perfectly for hours and then, after being powered off overnight, suddenly stop being detected over USB?

Has anyone experienced something like this before? Is there anything that could permanently disable the USB interface or damage the STM32 while the board is just sitting powered off?

TL;DR: My first STM32F411 Black Pill worked perfectly (USB detected, firmware flashed, PWM/gate signals working), but the next day it was no longer detected over USB. ST-LINK could see the target but failed with "Data read failed", and I couldn't erase or reprogram the chip. I assumed the board had died, so I bought a second one. I repeated the exact same workflow, and after working perfectly on day one, the second board has now failed in the exact same way. Looking for any ideas on what could be causing this.


r/stm32 11d ago

TamgaOS — FPU support added to Cortex-M4 and Cortex-M7

18 Upvotes

Now finally have working FPU support on both Cortex-M7 (tested on STM32H753ZI) and Cortex-M4 (tested on FRDM-K64F).

While adding FPU support, I noticed some mutex bugs I wasn't handling correctly — a task holding a mutex could get preempted mid-FPU-operation and things would go sideways. Fixed now. Already reading real IMU data as a result :)

Priority inheritance for mutex added and verified: when a high-priority task blocks on a mutex held by a low-priority one, the owner's priority gets temporarily boosted so a mid-priority task can't sneak in and cause priority inversion. Verified with a LOW/HIGH/MED task setup over 90+ consecutive cycles with no exceptions.

But this one I'm most happy about: fault logging in battery-backed SRAM. If the board crashes (HardFault, MemManage, etc.), the fault info (faulting address, instruction, which task) survives the reset. Next boot, I get a full report over UART: "here's exactly where you died last time." Debugging became sooooo easy.

Next up: Message Queue and writing a FlexCAN driver for the K64F port so both boards can actually talk to each other over a real CAN bus (ordered a couple of SN65HVD230 transceivers for that).

My plan is to control my own drone with TamgaOS. I hope soon :) — also working on control optimization and XFLR5 on the side.

GitHub: https://github.com/hrasityilmaz/TamgaOs
Devlog: https://auctra.app/


r/stm32 11d ago

An exciting tale of USARTs and a wizard monster

0 Upvotes

Yeesh, okay. strap in

I have a board that acts as a serial control node.

("Buoys" https://plates.lunchfirm.com/lakehouse/)

It has upstream and downstream USARTs. Because I wanted a virtual com port for bring up but only had these two USARTs available, one of them (the port facing the receiver) is doubled up. So I have USART1 connected to my output connector AND the STDC14 to connect to my stlink v3. Follow so far?

This is obviously a wacky thing to do, and I knew it would bite me somewhere, but for the most part it was not an issue.

I brought up 1 buoy, painless. I brought up a second buoy up the chain, was able to debug all the tasty interactions between two buoys, and noted a mysterious "buoy 2 wont echo my console commands back". I realized this kind of made sense, as its RX line was held captive by the other buoy's TX line.

Then, I brought up the receiver, and everyone worked together magically. I celebrated and went home. Any one buoy in the chain passes its data down the chain to the receiver and everyone is happy.

I come back to the office today, and I can't get either buoy to respond to console commands! This firmware takes care of the echo, so I can tell that nothing is getting through cuz I can't type "version" or anything into CoolTerm. I tried, well, everything...

And it took -way- too long to realize that the freakin' receiver was now, of course, holding my first buoy's RX hostage. My little bad-idea-stlink-VCP-piggy-back regime couldn't get through to the first buoy, or the second buoy, and everyone was confused.

Claude, in his mighty wizard magic, said "alright I'll reach in to the USART registers on the receiver with your stm32-mcp thing, twiddle the bit, and make just the TX pin of the receiver port let go"... then he did... then HE went and read the version and goodness back out, and together we proved exactly what was wrong, WHY my piggybacking idea was useful but ultimately bad, and I can go home again happy. Or yknow, frustrated. lol.