```mermaid graph TD; A-->B; A-->C; B-->D; C-->D; ``` ```mermaid flowchart TD %% --- STILI --- classDef hw fill:#ffcccc,stroke:#333,stroke-width:2px; classDef memory fill:#e1f5fe,stroke:#333,stroke-width:1px; classDef logic fill:#fff9c4,stroke:#333,stroke-width:1px; Start((START)) --> Init %% --- BLOCCO INIZIALIZZAZIONE --- subgraph Init ["1. Inizializzazione Bare Metal"] direction TB RCC["RCC AHB4ENR & APB1ENR\nAbilita Clock GPIO & USART"]:::hw GPIO["GPIO MODER & AFR\nButton=Input, LED=Output, TX=AF"]:::hw UART["USART3 CR1 & BRR\nConfigura Baud & Abilita UE"]:::hw NVIC["NVIC_EnableIRQ\nAbilita Interrupts al processore"]:::hw RCC --> GPIO --> UART --> NVIC end Init --> MainLoop %% --- BLOCCO MAIN LOOP --- subgraph Main ["2. Main Loop (Polling Button)"] direction TB MainLoop(while 1) ReadIDR["Leggi GPIOC->IDR\n(Stato Bottone)"]:::hw Debounce[Debounce Delay]:::logic EdgeCheck{"Rising Edge?\n(Curr=1 && Prev=0)"}:::logic ToggleOps[Toggle Logic]:::memory UpdatePrev[Prev = Curr]:::logic MainLoop --> ReadIDR --> EdgeCheck EdgeCheck -- NO --> UpdatePrev EdgeCheck -- SI --> ToggleOps subgraph Toggle ["Logica XOR LED"] ReadODR["Leggi GPIOB->ODR"]:::hw XOR["Calcola: ODR ^ LED_MASK"]:::logic WriteODR["Scrivi GPIOB->ODR"]:::hw ReadODR --> XOR --> WriteODR end ToggleOps --> UpdatePrev UpdatePrev --> Debounce --> MainLoop end %% --- BLOCCO INTERRUPT --- subgraph ISR ["3. USART3 IRQ Handler"] direction TB Trigger((IRQ)) CheckTXE{"Flag TXE?\n(Data Reg Empty)"}:::logic CheckTC{"Flag TC?\n(Tx Complete)"}:::logic LoadDR["Scrivi USART3->DR\n(Invia Byte)"]:::hw EnableTC["Abilita TCIE\nDisabilita TXEIE"]:::hw DisableTC["Disabilita TCIE\nClear TC Flag"]:::hw FreeBusy[Set tx_busy = 0]:::memory Trigger --> CheckTXE CheckTXE -- "SI: Buffer Pieno" --> LoadDR CheckTXE -- "SI: Buffer Finito" --> EnableTC CheckTXE -- NO --> CheckTC CheckTC -- "SI: Fine Trasmissione" --> DisableTC --> FreeBusy CheckTC -- NO --> Return((RTI)) end %% --- CONNESSIONI LOGICHE --- WriteODR -.-> |"Opzionale: Avvia TX"| Trigger ``` ```mermaid flowchart TD %% --- DEFINIZIONE CLASSI GRAFICHE --- classDef userFill fill:#e1f5fe,stroke:#0277bd,stroke-width:2px; classDef stmFill fill:#fff9c4,stroke:#fbc02d,stroke-width:2px; classDef pcFill fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px; classDef term fill:#212121,color:#fff,stroke:#000; %% --- CORSIA 1: UTENTE --- subgraph User ["👤 Utente (Mondo Fisico)"] direction TB Start((Inizio)) PressBtn["Premi Bottone Blu"]:::userFill CheckLeds["Osserva i LED"]:::userFill CheckPC["Leggi Terminale PC"]:::userFill end %% --- CORSIA 2: STM32 (FIRMWARE) --- subgraph STM32 ["⚙️ STM32 H7 (Bare Metal)"] direction TB Polling("Ciclo While Infinito"):::stmFill IsPressed{"Rilevato\nFronte Salita?"}:::stmFill ToggleAction["XOR Toggle LEDs\n(ODR ^ Mask)"]:::stmFill LoadBuffer["Carica Buffer TX\nAbilita TXE IE"]:::stmFill subgraph ISR ["Interrupt Service Routine"] direction TB SendByte["Hardware Invia Byte"]:::stmFill CheckDone{"Finito?"}:::stmFill end end %% --- CORSIA 3: PC (SOFTWARE) --- subgraph PC ["💻 PC (Arch Linux + Julia)"] direction TB Listen{"Script Julia\nIn ascolto"}:::pcFill ReceiveData["Ricezione Byte\n(/dev/ttyACM0)"]:::pcFill PrintTerm["> Stampa a Video"]:::term end %% --- COLLEGAMENTI --- %% Flusso Utente -> STM32 Start --> PressBtn PressBtn -- "Pressione fisica" --> Polling %% Logica STM32 Polling --> IsPressed IsPressed -- No --> Polling IsPressed -- Si --> ToggleAction ToggleAction --> LoadBuffer LoadBuffer -.-> |"Trigger IRQ"| SendByte SendByte --> CheckDone CheckDone -- No --> SendByte CheckDone -- Si --> Polling %% Feedback Visivo (STM32 -> Utente) ToggleAction -.-> |"Luce LED"| CheckLeds %% Comunicazione Seriale (STM32 -> PC) SendByte == "Cavo USB (Serial)" ==> ReceiveData %% Logica PC Listen --> ReceiveData ReceiveData --> PrintTerm %% Feedback Terminale (PC -> Utente) PrintTerm -.-> |"Lettura"| CheckPC CheckPC --> PressBtn ``` ```mermaid flowchart TD %% --- STILI --- classDef cpu fill:#e3f2fd,stroke:#1565c0,stroke-width:2px classDef tim fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px classDef adc fill:#fff9c4,stroke:#fbc02d,stroke-width:2px classDef dma fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px classDef mem fill:#eeeeee,stroke:#616161,stroke-width:2px,stroke-dasharray: 5 5 %% --- CORSIA 1: CPU (INIZIALIZZAZIONE) --- subgraph Setup ["1. INIZIALIZZAZIONE (CPU)"] direction TB InitDMA["DMA Setup:\n- Mode: CIRC (Circolare)\n- PData: ADC_DR\n- MData: Buffer[0]\n- Size: 128\n- Incr: Memory (MINC)"]:::cpu InitADC["ADC Setup:\n- Conv: Single/Continuous\n- Trig: External (Timer)\n- DMA: Enable (Circular)"]:::cpu InitTIM["TIM Setup:\n- Periodo: Freq Campionamento\n- Master Mode (MMS): Update (TRGO)"]:::cpu StartAll["START:\n1. ADC_CR |= ADEN\n2. DMA_SxCR |= EN\n3. ADC_CR |= ADSTART\n4. TIM_CR1 |= CEN"]:::cpu InitDMA --> InitADC --> InitTIM --> StartAll end StartAll --> LoopTIM %% --- CORSIA 2: HARDWARE AUTOMATICO --- subgraph Hardware ["2. LOOP HARDWARE (Senza CPU)"] direction TB %% TIM LoopTIM(Timer Conta):::tim EventUpdate{"Update Event?\n(CNT == ARR)"}:::tim TriggerTRGO["Output TRGO\n(Hardware Signal)"]:::tim LoopTIM --> EventUpdate EventUpdate -- NO --> LoopTIM EventUpdate -- SI --> TriggerTRGO %% ADC TriggerTRGO --> ADC_Start["ADC Avvia Conv.\n(EXTEN rising)"]:::adc ADC_Conv[Campionamento...]:::adc FlagEOC{"Fine Conv?\n(ISR & EOC)"}:::adc ADC_Start --> ADC_Conv --> FlagEOC %% DMA FlagEOC -- SI --> DMA_Req["Richiesta DMA\n(ADC -> DR)"]:::dma DMA_Move["Sposta Dato:\nADC_DR -> Buffer[idx]"]:::dma DMA_Inc["Incrementa idx:\nidx = (idx + 1) & 127"]:::dma DMA_Req --> DMA_Move --> DMA_Inc %% BUFFER BufferState{"Buffer Pieno/Metà?\n(TCIF / HTIF)"}:::mem DMA_Inc --> BufferState BufferState -- "Ancora spazio" --> LoopTIM end %% --- CORSIA 3: INTERRUPT DMA (CPU) --- subgraph IRQ ["3. ELABORAZIONE (CPU - Interrupt DMA)"] direction TB CheckFlag{"Quale Flag DMA?"}:::cpu TaskHT["Half Transfer (HTIF):Elabora prima metà (0-63)"]:::cpu TaskTC["Transfer Complete (TCIF):\nElabora seconda metà (64-127)"]:::cpu Clear["Clear Flags:\nDMA_LIFCR / HIFCR"]:::cpu BufferState -.-> |"IRQ Trigger"| CheckFlag CheckFlag --> |HTIF| TaskHT CheckFlag --> |TCIF| TaskTC TaskHT --> Clear TaskTC --> Clear end ```