# C13 — GPIO, zbocza i debounce na RV32I/Hazard3 Karta zamyka serię raw C czterema wykonywalnymi przykładami: 1. polling `DIR`, `OUT` i `IN` z kontrolowanym `TEST_IN`; 2. rising edge → GPIO `PENDING` → external IRQ18 → dispatcher → W1C; 3. bounce `1 → 0 → 1` i akceptacja dopiero po quiet window mierzonym `mtime`; 4. superloop łączący machine timer, UART RX IRQ16 i GPIO IRQ18. Programy są freestanding RV32I+Zicsr+Zifencei i wykonują się w RTL Hazard3/Verilator. Nie ma modelu hostowego, RTOS, kolejki ani semafora. ## Rejestry modelu GPIO zaczyna się pod `0xc0000300` i udostępnia `OUT`, `OUT_SET`, `OUT_CLR`, `IN`, `TEST_IN`, `RISE_EN`, `FALL_EN`, `PENDING` W1C oraz `DIR`. GPIO używa external IRQ18. UART0 używa external IRQ16, a machine timer standardowego machine timer interrupt o `mcause=0x80000007`. `TEST_IN` i UART `TEST_RX` są wyłącznie bodźcami testbencha. Symulują zmianę otoczenia bez TCP lub fizycznego pinu. Nie są rejestrami produkcyjnego GPIO, nie opisują RP2350 i nie mogą znaleźć się w sterowniku fizycznej płytki. ## Budowanie i test ```sh make tasks ./tests/test_hazard3.sh ``` Oracle sprawdza kod wyjścia, timeout, nieobsłużone pułapki i raportowane rejestry. Dodatkowo niezależnie przelicza odstępy bounce, granicę quiet window i obecność `mret` w handlerze machine timer. Bieżący pomiar RTL: - Task01: `DIR=1`, wejście zewnętrzne `2`, po ustawieniu wyjścia `IN=3`, po wyzerowaniu `IN=0`; - Task02: jeden IRQ18, `PENDING=0x4` w ISR, W1C usuwa źródło i ponowny wysoki poziom nie tworzy nowego zbocza; - Task03: czasy low `0x591`, `0x8ea`, `0xc43`, odstępy po `0x359`, quiet `0x7d0`, akceptacja po `0x878`, bez wczesnej akceptacji; - Task04: po jednym timer IRQ, UART16 i GPIO18, bajt `U`, trzy działania main, `OUT=0x7`, widoczne `IN=0x17`. Wartości czasowe zależą od bieżącego RTL i buildu. Kontraktem są relacje: dwa odstępy bounce są dodatnie i krótsze od quiet window, a akceptacja następuje nie wcześniej niż quiet po ostatnim zboczu. ## Podział odpowiedzialności W Task02–Task04 ISR potwierdza źródło i publikuje minimalny stan. Debounce oraz aktualizacja wyjść należą do kodu normalnego. Task04 używa prostych flag jednozdarzeniowych; nie jest odporną na dowolne przeciążenie kolejką zdarzeń. To świadoma granica między raw C a kolejną serią FreeRTOS. ## Karta ```sh ./scripts/render_card_layouts.sh ./scripts/render_new_pdf.sh ./tests/test_card.sh ``` Każdy przykład ma dokładnie A1–A8. Tylko Task01.A3 jest N/D, ponieważ polling nie ma mechanizmu dispatchu.