Files
TMS320F28027-dualboost/src/bsp_gpio.h
nicoboy 26c1d499e0 Champ FAULT, decharge HT active, et surtemperature par voie
Circuit de decharge rapide (GPIO5, broche 40)

  Commande DISCHARGE du circuit de la carte de puissance : MOSFET en serie
  avec 47 kOhm aux bornes du condensateur de sortie, soit tau = 0,94 s et
  environ 2 s pour passer de 500 V a 50 V. Sans lui, le seul bleeder de
  1 MOhm demandait ~42 s.

  POLARITE INVERSEE, et c'est le coeur du montage. Le GPIO pilote un NPN
  qui court-circuite la grille du MOSFET :
    niveau haut -> NPN conduit -> grille a la masse -> decharge INHIBEE
    niveau bas ou broche non pilotee -> grille tiree a 12 V -> decharge ACTIVE

  GPIO5 est une broche a fonction PWM : pas de pull-up au reset (PROMPT §6
  etape 3), elle flotte. La decharge est donc active au reset, pendant un
  plantage, et surtout ALIMENTATION COUPEE -- exactement le cas ou le
  firmware ne garantit plus rien et ou l'operateur croit la carte
  inoffensive. C'est precisement le cas impose par le choix de n'effacer un
  defaut que par cycle d'alimentation.

  Sequencement explicite :
   - enter_safe_state() active la decharge APRES avoir coupe HV_EN : la
     charge est isolee d'abord, le condensateur vide ensuite ;
   - le retour au nominal inhibe la decharge AVANT d'autoriser les etages,
     jamais l'inverse ;
   - bsp_gpio_control_init() la laisse ACTIVE au demarrage : au boot le
     condensateur peut encore etre charge par une session precedente.

Champ FAULT dans la trame $T

  Codes 0-5, priorite 2 > 3 > 4 > 5 > 1. EMUSTOP (code 1) a donc la
  priorite la PLUS BASSE malgre son numero : en developpement il se
  declenche a chaque halte du debogueur et ne doit jamais masquer une
  surintensite reelle.

  Pas de code court-circuit : il franchit le meme comparateur et le meme
  seuil qu'une surintensite, le firmware ne peut pas les distinguer.

  Aucun effacement automatique ni par commande UART : le verrouillage
  n'est leve que par un cycle d'alimentation (PROMPT §8).

Surtemperature suivie PAR VOIE

  s_overtemp_t1 / s_overtemp_t2 separes, avec hysteresis chacun. L'ancien
  maximum des deux voies ne permettait pas de distinguer les codes 4 et 5.
  Seuil ramene a 80 degC pour coller au protocole.

Divers
  UART_LINE_MAX porte a 200 (buffer ESP32 g_lineBuf[200]).
  append_field_int() pour les champs entiers, meme convention de bornage
  que append_field : un champ qui ne tient pas est abandonne entierement.

Documentation
  docs/mesure-cartepuissance.md ajoute au depot (source de tracabilite des
  coefficients de calib.h).
  docs/ESP32-UART.md mis a jour, avec deux corrections de fond :
   - la mention "remettre FAULT=0 automatiquement des que la cause a
     disparu" est remplacee par une section sur le verrouillage ; elle
     contredisait le comportement reel, le TMS320 reemettant indefiniment
     le code latche ;
   - l'icone danger est specifiee comme dependant UNIQUEMENT de VOUT et
     jamais de FAULT. Un defaut ne decharge pas le condensateur : la faire
     disparaitre reviendrait a rassurer l'operateur quand le risque est
     maximal.
  Le piege strtol / uint8_t 16 bits y est documente pour eviter qu'il soit
  reintroduit ailleurs.

A cabler cote materiel : liaison broche 40 vers la carte de puissance, et
pull-down 10 kOhm sur la base du NPN.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 17:00:32 +02:00

74 lines
2.9 KiB
C

#ifndef BSP_GPIO_H
#define BSP_GPIO_H
#include <stdbool.h>
typedef enum
{
LED_BLUE = 0,
LED_RED
} led_id_t;
typedef enum
{
STAGE_1 = 0,
STAGE_2
} stage_id_t;
void bsp_gpio_leds_init(void);
void led_set(led_id_t led, bool on);
// Bascule AIO2, AIO4, AIO10, AIO12, AIO14 en mode analogique (shunts,
// COMP1A/COMP2A, VOUT, V1, NTC1). A appeler avant safety_init()/adc_init().
void bsp_gpio_analog_init(void);
// Sorties de commande dans leur etat sur : HV_EN, Stage1-EN et Stage2-EN a 0.
// Desactive aussi les pull-ups internes de GPIO16/17, qui sinon presentent un
// niveau haut sur une entree de chaque porte ET des la mise sous tension
// (PROMPT §6 etape 3).
void bsp_gpio_control_init(void);
// Stagex-EN : entree "autorisation logicielle" de la porte ET de l'etage.
void stage_enable_set(stage_id_t stage, bool enabled);
// HV_EN (GPIO32) : commande de la sortie HT via l'optocoupleur VOM1271.
// Seul organe qui isole reellement la charge -- un boost a 0 % de duty ne
// donne PAS 0 V en sortie (PROMPT §6 etape 6).
void hv_enable_set(bool enabled);
// DISCHARGE (GPIO5, broche 40) : circuit de decharge rapide du condensateur
// de sortie, sur la carte de puissance. 47 kOhm en serie avec un MOSFET,
// soit ~2 s pour passer de 500 V a 50 V (tau = 0,94 s).
//
// POLARITE INVERSEE, et c'est le coeur du montage. Le GPIO pilote un NPN
// qui court-circuite la grille du MOSFET :
// niveau HAUT -> NPN conduit -> grille a la masse -> MOSFET bloque
// -> decharge INHIBEE (fonctionnement normal)
// niveau BAS, ou broche non pilotee
// -> NPN bloque -> grille tiree a 12 V (chaine 3x1 MOhm
// depuis le +500 V, ecretee par Zener) -> MOSFET conduit
// -> decharge ACTIVE
//
// GPIO5 est une broche a fonction PWM : ses pull-ups ne sont PAS actives au
// reset (PROMPT §6 etape 3), elle flotte donc. La decharge est par
// consequent active au reset, pendant un plantage, et surtout ALIMENTATION
// COUPEE -- c'est-a-dire exactement le cas ou le firmware ne peut plus rien
// garantir et ou l'operateur croit la carte inoffensive.
void hv_discharge_set(bool active);
// BRING-UP UNIQUEMENT -- bascule Stage1/2-default (GPIO1/GPIO3) en sortie
// GPIO pilotee par logiciel, pour verifier le cablage des portes ET sans
// etage de puissance actif. Laisse les deux broches a 0.
//
// INCOMPATIBLE avec safety_init(), qui mux ces memes broches vers COMP1OUT /
// COMP2OUT : en fonctionnement normal ce sont les comparateurs qui les
// pilotent, et le logiciel ne doit JAMAIS pouvoir outrepasser la protection
// materielle (PROMPT §2 et §8). Ne jamais appeler les deux.
void bsp_gpio_stage_default_override_init(void);
// Pilote une broche Stagex-default apres l'override ci-dessus. N'ecrit que
// GPASET/GPACLEAR (non proteges par EALLOW) : utilisable depuis une ISR.
void stage_default_set(stage_id_t stage, bool level);
#endif