cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F446ZET6 won’t execute app (SWD OK, vectors OK). PA8/PA15 stay low on rev7 board

samprince
Visitor

Context
Custom 3D-printer controller that I'm developing from scratch, currently on rev7. Rev6 (very similar) runs the same blinky fine. On rev7 I can connect/erase/flash/verify over SWD, but code doesn’t run—GPIOs stay at ~0 V.

MCU / Tooling

  • MCU: STM32F446ZET6 (no bootloader)

  • Programmer: ST-Link V2, STM32CubeProgrammer (SWD)

  • Build: STM32Duino / Generic F446ZETx (144-pin), USB support = None, Clock = HAL, Debug = Serial Wire

  • Test firmware: blinker for the LEDs on PA8 and PA15 

Symptoms

  • Flash + verify at 0x08000000 succeed.

  • Vector table @0x08000000 looks sane (SP=0x200xxxxx, PC=0x0800xxxx|1).

  • After reset, PA8 and PA15 don’t toggle (measured at MCU pins). PA15 blips only when debugger attaches.

  • Same binary works on rev6.

Measured the following:

  • VDD = 3.3 V on all banks (decoupled).

  • VDDA = 3.3 V, local 100 n + 1 µF.

  • VCAP1/VCAP2 ≈ 1.3 V each (2.2 µF caps fitted).

  • NRST ≈ 3.3 V idle, pulses on connect.

  • BOOT0 pulled low (confirmed low during reset).

  • LEDs both been verified to work by injecting 3.3v to their circuits

What I tried

  • Full erase, re-flash minimal register blinker

  • Rebuilt with USB=None, HSI only.

  • Tried lower BOR level.

  • JTAG vs SWD: using Serial Wire to free PA15 (still no PA8 toggle).

Attachments

  • Schematic fragment: MCU core

samprince_0-1760071154182.png

  • Board photo around MCU

IMG_7584.jpgIMG_7585.jpg

 

Would anyone know what could be wrong here? I've not encountered such an issue before where I could connect, interact, and flash the chip, but not be able to execute the sketch I flashed.

 

Any help would be greatly appreciated.

Thanks!

 

 

#include <Arduino.h>
#include <Servo.h>

// Pins
const uint32_t LED1 = PA8, LED2 = PA15; // PA15 PA12
const uint32_t BED = PD7, E0 = PD8, E1 = PD9;
const uint32_t BLT_SERVO_PIN = PD6;    // orange
const uint32_t BLT_PROBE_PIN = PC12;   // white (open-drain)


HardwareSerial Serial2(PA9, PA10);  // (rx, tx)

#define LED_ACTIVE_HIGH 1
#define HEATER_ACTIVE_HIGH 1
const bool ENABLE_HEATER_DEMO = false;

const unsigned long LED_PERIOD_MS    = 500;
const unsigned long HEATER_PERIOD_MS = 5000;
const unsigned long PROBE_CONFIRM_MS = 2;    // LOW must be stable this long
const unsigned long SERVO_MASK_MS    = 300;  // ignore triggers after servo move

unsigned long t_led=0, t_heater=0;
bool led_state1=false, led_state2=true;
bool bed_state=false, e0_state=false, e1_state=false;

Servo blt;
volatile bool edgeSeen=false;
volatile unsigned long edgeAt=0;
unsigned long mask_until=0;
bool last_reported_low=false;

inline void setPin(uint32_t pin, bool on, bool ah){ digitalWrite(pin,(on ^ !ah)?HIGH:LOW); }
void mask_after_servo(){ mask_until = millis() + SERVO_MASK_MS; }

void blt_deploy(){ blt.write(10);  mask_after_servo(); }
void blt_stow(){   blt.write(90);  mask_after_servo(); }
void blt_self(){   blt.write(160); mask_after_servo(); }
void blt_reset(){  blt.write(120); mask_after_servo(); }
void blt_cycle(uint16_t dep=800,uint16_t stw=800){ blt_deploy(); delay(dep); blt_stow(); delay(stw); }

// ISR (plain STM32)
void probeISR(){ edgeSeen=true; edgeAt=millis(); }

void setup() {
  pinMode(LED1, OUTPUT); pinMode(LED2, OUTPUT);
  pinMode(BED, OUTPUT);  pinMode(E0, OUTPUT); pinMode(E1, OUTPUT);
  setPin(LED1,false,LED_ACTIVE_HIGH); setPin(LED2,false,LED_ACTIVE_HIGH);
  setPin(BED,false,HEATER_ACTIVE_HIGH); setPin(E0,false,HEATER_ACTIVE_HIGH); setPin(E1,false,HEATER_ACTIVE_HIGH);

  // Prefer external pull-up 4.7k–10k to 3.3V + 0.01–0.1uF to GND on PC12
  pinMode(BLT_PROBE_PIN, INPUT); // if you lack external PU, use INPUT_PULLUP and FALLING
  attachInterrupt(digitalPinToInterrupt(BLT_PROBE_PIN), probeISR, CHANGE);

  blt.attach(BLT_SERVO_PIN);
  blt_stow();

  Serial2.begin(115200);
  delay(50);
  Serial2.println("\n[BLTouch Test + Debounce @ USART2]");
  Serial2.println("d=deploy s=stow t=self r=reset c=cycle p=probe h=help");

  t_led = t_heater = millis();
}

void loop() {
  const unsigned long now = millis();

  if (now - t_led >= LED_PERIOD_MS) {
    t_led += LED_PERIOD_MS;
    led_state1=!led_state1; led_state2=!led_state2;
    setPin(LED1, led_state1, LED_ACTIVE_HIGH);
    setPin(LED2, led_state2, LED_ACTIVE_HIGH);
  }

  if (ENABLE_HEATER_DEMO && (now - t_heater >= HEATER_PERIOD_MS)) {
    t_heater += HEATER_PERIOD_MS;
    bed_state=!bed_state; e0_state=!e0_state; e1_state=!e1_state;
    setPin(BED, bed_state, HEATER_ACTIVE_HIGH);
    setPin(E0,  e0_state,  HEATER_ACTIVE_HIGH);
    setPin(E1,  e1_state,  HEATER_ACTIVE_HIGH);
  }

  // Debounced probe read
  bool raw = digitalRead(BLT_PROBE_PIN);           // HIGH idle, LOW trigger
  static unsigned long low_since = 0;
  if (!raw) { if (!low_since) low_since = now; }
  else low_since = 0;

  bool debounced_low = (low_since && (now - low_since >= PROBE_CONFIRM_MS));
  setPin(LED1, debounced_low, LED_ACTIVE_HIGH);

  if (edgeSeen) edgeSeen=false;

  if (now >= mask_until) {
    if (debounced_low && !last_reported_low) {
      last_reported_low = true;
      Serial2.println("[BLT] TRIGGER (debounced)");
    } else if (!debounced_low && last_reported_low) {
      last_reported_low = false;
      Serial2.println("[BLT] RELEASE");
    }
  }

  if (Serial2.available()) {
    switch ((char)Serial2.read()) {
      case 'd': blt_deploy();      Serial2.println("[BLT] Deploy"); break;
      case 's': blt_stow();        Serial2.println("[BLT] Stow"); break;
      case 't': blt_self();        Serial2.println("[BLT] Self-test"); break;
      case 'r': blt_reset();       Serial2.println("[BLT] Reset"); break;
      case 'c': Serial2.println("[BLT] Cycle"); blt_cycle(); break;
      case 'p': Serial2.println(raw ? "[BLT] HIGH (idle)" : "[BLT] LOW (TRIGGER)"); break;
      case 'h': default: Serial2.println("d s t r c p h"); break;
    }
  }
}

 

0 REPLIES 0