Tijek razvoja softvera za CPLD i MCU
Programiranje CPLD-a
Za programiranje EPM570 (kao i raznih drugih FPGA i CPLD čipova) namijenjen je programski softver Quartus II (Intel Quartus Prime), a programski jezik za opis hardvera (HDL) zove se Verilog. Quartus II omogućuje cijeli proces razvoja FPGA, od pisanja koda i crtanja logičkih shema do simulacije, optimizacije i konačnog prebacivanja dizajna na hardver. Softver također uključuje alate za analizu i sintezu (pretvaranje koda u logička vrata), analizu vremena (timing analysis) te programiranje samog uređaja.
Za programiranje EPM570 morate kupiti i namjenski USB Blaster Programmer koji košta oko 3 eura. Ovaj programator se s jedne strane spaja na USB port računala, a s druge strane na 10-pinski JTAG konektor na razvojnoj pločici EPM570. Jednostavnije ne može biti.
Verilog je kao što smo već spomenuli jezik za opis hardvera (HDL) koji se koristi za modeliranje i simulaciju elektroničkih sustava. Ovaj programski jezik se bitno razlikuje od standardnih programskih jezika (poput C-a) jer ne opisuje slijedne naredbe za MCU (softver) nego opisuje strukturu i ponašanje hardvera, odnosno kako su žice povezane i kako logička vrata međusobno komuniciraju. U tipičnom radnom procesu, Verilog se koristi za pisanje koda koji opisuje kako bi digitalni sklop trebao raditi, a zatim se koristi Quartus II kako bi taj kod kompajlirao i fizički implementirao u FPGA/CPLD čip.
Sve ovo na prvi pogled djeluje komplicirano, odnosno djeluje kao nešto čemu treba posvetiti ogromno vremena za učenje. Međutim, jednostavno programiranje kao ovo za naš projekt u potpunosti može za vas odraditi AI. Uz pomoć AI meni su bila dovoljna 2-3 sata da naučim rad u Quartus II do dovoljne razine da konfiguriran I/O pinove i programiram CPLD pomoću Verilog koda kojeg mi je u potpunosti generirala AI.
Za programiranje svih onih diskretnih logičkih čipova za svaki pojedinačni senzor (Schmitt inverteri, RS Latchevi, multipleksori) treba napisati svega 30-tak linija Verilog koda. Osim toga, unutar CPLD također je sada programirana logika koja detektira promjenu stanja na bilo kojem senzoru kao prolazak metka. Time ESP32 ne mora stalno brzo skenirati sve senzonske linije ne bi li otkrio prolaz metka, već to za njega neusporedivo brže radi sam CPLD i informacije prema ESP32 šalje samo kada postoji neka promjena na senzorima.
Ovime smo dobili izuzetno brz detektorski sustav kojeg ćemo u ESP32 u jednom dijelu morati i znatno usporiti jer bi jedna dijabola (zbog svog oblika) mogla izazvati nekoliko brzih detekcija.
Osnovne upute za rad sa Quartus programom
Sučelje programa Quartus za programiranje našeg CPLD-a EPM570. Evo kratkih uputa kako se vrši samo programiranje kad imate gotovu datoteku s programom (.pof):
- Kreiranje novog projekta (New Project)
- Odabir EPM570 uređaja u projektu (Assignments -> Device)
- Family -> MAX II
- Available devices -> EPM570T100C5
- Postavljanje USB Blastera u Programatoru (Tools -> Programmer)
- Hardware Setup
- Currently selected hardware -> USB-Blaster
- Auto Detect
- Programiranje
- Add File -> odabir .pof datoteke
- Program/Configure -> čekiraj polje (označi kvačicu)
- Start
Programiranje je dakle vrlo jednostavno i ne razlikuje se puno od programiranja u mnogim drugim sličnim programatorima. A sada evo jednostavnog vodiča kako napraviti datoteku s programom (.pof) za EPM570T100C5 pločicu koristeći Verilog jezik, koji ste napisali sami ili uz pomoć AI:
- Izrada projekta u Quartusu (File -> New Project Wizard)
- Odredite mapu gdje će projekt biti spremljen i naziv projekta -> Next
- Family & Device Settings
- Family -> MAX II
- Available devices -> EPM570T100C5
- Finish
- Pisanje koda
- File -> New -> Verilog HDL File (kreiranje datoteke sa programom)
- Nakon što je kod napisan (ili kopiran) datoteka se sprema (File -> Save) pod istim nazivom kako je odabrano u nazivu projekta s time da će ekstenzija datoteke biti .v
Vidimo da je i ovo posve jednostavno, no CPLD još uvijek ne zna na kojim I/O pinovima je fizički spojeni vanjski hardver. To mu morate reći:
- Dodjela pinova (Pin Planner)
- Prvo se klikne na ikonu Start Compilation (ili pritisne Ctrl+L) da Quartus analizira kod
- Nakon što analiza uspješno završi, ide se na Assignments -> Pin Planner
- U donjoj tablici vidjet će se nazivi kojima treba odrediti I/O pinove i ostale atribute poput ulaznog Schmitt trigera za senzorske pinove
- Nakon definiranja pinova Pin Planner se zatvara (automatski sprema unose) i ponovno se pokrene Start Compilation
Nakon što imamo spremljenu programsku datoteku, programiranje se vrši kako smo opisali na početku:
- Spojite USB Blaster na PC i na JTAG konektor pločice. Uključite napajanje pločice.
- Idite na Tools -> Programmer.
- Provjerite piše li gore desno USB-Blaster. Ako ne, kliknite Hardware Setup i odaberite ga.
- Kliknite Auto Detect. Trebao bi se pojaviti EPM570 na slici.
- Ako datoteka nije automatski učitana, kliknite na nju (ili Add File) i odaberite .pof datoteku iz mape output_files.
- Označite kvačicu pod Program/Configure i kliknite Start.
Napomena: Ako se bilo što mijenjate u programu ili Pin Planneru, morate ponovno pokrenuti kompilaciju (plava strelica Start Compilation u glavnom prozoru Quartusa). Tek tada će te promjene biti upisane .pof datoteku koju šaljete na čip.
Programiranje Verilog koda za CPLD MAX II EPM570
Iako u osnovnim uputama za Quartus sve izgleda jednostavno, tijekom programiranja i definiranja pinova može se dogoditi niz grešaka i problema koje je onda potrebno sustavno rješavati. Tako je bilo i tijekom kreiranja programa za našu elektroničku metu. Program ima svoje „mušice“ i neke radnje je potrebno vršiti po točno određenom protokolu i hijerarhiji.
U Verilogu i Quartusu, hijerarhija nije samo način organizacije koda, već temelj načina na koji softver vidi hardver. Stoga su mi se često događale frustrirajuće situacije gdje prvi put neka naredba ili radnja prvi put prođe bez problema, a nakon modifikacija ili promjena u kodu (ili čak kod izrade nove verzije programskog koda) iste naredbe više ne prolaze.
Quartus uvijek traži jedan Top-Level Entity. Ako napravite novi modul ili promijenite ime postojećeg, a niste ga u postavkama postavili kao “Top-Level” (Hierarchy -> Set as Top-Level Entity), Quartus će uporno kompajlirati staru verziju ili javiti grešku jer ne vidi put do vaših novih naredbi. Quartus pokušava uštedjeti vrijeme tako da ne kompajlira sve ispočetka. Ako promijenite nešto duboko u hijerarhiji (npr. u nekom malom modulu koji se poziva unutar pet drugih), Quartus ponekad ne prepozna tu promjenu ispravno. Na primjer, ako dodate novu programsku datoteku u mapu projekta, ali ju ne dodate u “Files” listu unutar Quartusa, on će koristiti staru verziju datoteke koju još uvijek ima u memoriji, dok vi gledate u novi kod i pitate se zašto nema promjena.
Za razliku od klasičnog programiranja, u Verilogu svaki put kad pozovete modul, vi stvarate fizičku kopiju tog hardvera. Ako promijenite logiku unutar modula, to utječe na svaki dio projekta gdje se taj modul koristi. Ako imate grešku u hijerarhiji (npr. krivo spojene žice/portove između modula), program će možda proći analizu, ali će pasti na “Fitteru” (smještanju na čip) jer fizički ne može povezati te dijelove.
Iako je moj programski kod relativno jednostavan (da ne kažem malen) tijekom razvoja i testiranja radio sam dosta promjena i preinaka. Prvi put je sve prošlo „od prve“, a što sam više kasnije modificirao Verilog kod to sam i sve više vremena trošio na traženje načina kako da Quartus i u potpunosti prihvati taj novi kod.
Nakon što nekoliko desetaka puta izmijenite raspored pinova i promijenite osnovni Verilog kod, stvari počinju sjedati na mjesto i naučite kako i gdje najbolje raditi promjene tako da programiranje svaki puta prođe ispravno.
Meni je Verilog kod 99% pisao AI, međutim, prvi kod posve sigurno nikad neće raditi dobro. Bilo je potrebno nekoliko desetaka izmjena koda, a također i nekih izmjena na hardveru, kako bi dobio stabilan sustav detekcije.
Arhitektura Verilog koda za elektroničku metu
Prvo sam radio program za kontrolu samo 64 senzora preko jednog EPM570 i ESP32, no na puno stvari se ipak trebalo gledati unaprijed, dakle za buduću kontrolu svih 128 (2×64) senzora.
Arhitektura prvog rješenja je bila slijedeća:
- 64 interna Schmitt triggera (Assignment Editor -> Input Termination -> Schmitt Trigger).
- 64 RS Latcha (svaki ulaz ima svoj registar koji se postavlja na 1 čim senzor okine)
- Reset linija (ESP32 će poslati jedan signal na EPM570 koji istovremeno briše svih 64 latch-eva nakon čitanja)
- SPI-like Protokol – Umjesto sporog I2C-a, koristi se jednostavan Shift Register (posmični registar). ESP32 će slati “Clock” impulse, a EPM570 će izbacivati bit po bit (64 bita u nizu).
EPM570 pločica ima dostupnih 72 I/O pinova. 64 pina ide na senzore, 6 pinova je komunikacija sa ESP32, a 2 pina ostaju slobodna (kasnije ćemo iskoristiti još jedan pin za Alarm). Ručni unos 70 pina u Pin Planneru bi bio dugotrajan pa sam koristio Tcl skriptu koju mi je generirao AI (View -> Utility Windows -> Tcl Console). Učitavanjem ove skripte svi pinovi se definiraju istog trenutka.
Naravno, ne možete puno toga provjeriti ako ne pišete paralelno kodove za EPM570 i ESP32. Također, s obzirom da će se podaci bežično slati preko LoRa Modula (usko grlo), onda je već na samom početku potrebno razvijati kod tako da paketi podataka koji se šalju budu što manji. Na ovo se ne može puno utjecati jer se mora slati 64/128 bita podataka, međutim, sustav se može optimizirati tako da potreba za slanjem tih podataka bude minimalna, odnosno samo kad se dogodi neka promjena (kad metak aktivira zavjesu).
Osnovna arhitektura sustava, kako smo i prikazali u uvodnoj objavi, izgleda ovako:
- Na Meti: EPM570 (detekcija) -> ESP32 (obrada) -> LoRa Modul (slanje)
- Kod Strijelca: LoRa Modul (Prijem) -> ESP32 (obrada) -> Elecrow CrowPanel 7.0″ ESP32 Display (prikaz rezultata)
Pozitivna ili negativna senzorska logika
Nakon što opisani sustav proradio, trebalo se konačno odlučiti o senzorskoj logici, odnosno da li će aktivno stanje slati logičku nulu ili logičku jedinicu. Odlučio sam da senzori rade u negativnoj logici (1 = mirno, 0 = metak). Sve bi zapravo isto funkcioniralo i u suprotnoj logici, no ako se otpornici nalaze na masi (umjesto na plus polu napajanja) onda oni stalno drže I/O linije EPM570 na masi (pull-down) što doprinosi stabilnosti I/O ulaza kad su laseri isključeni. U slučaju pozitivne logike morali bi uključiti interne pull-up otpornike unutar EPM570 tako da pinove drže u nekom određenom stanju kad su senzori isključeni.
Trebalo je dakle prilagoditi Verilog kod tako da reagira na padajući brid, odnosno da detektira logičku nulu kao prolaz projektila. Međutim, postoji još jedan problem sa tom pozitivnom ili negativnom logikom, a to je odluka da li ću koristiti interne Schmitt triggere ili ne. Uobičajeno bi ih bilo dobro koristiti ali kako smo već opisivali u objavi o senzorima, za male kalibre od 4,5 mm sigurnija detekcija bi bila bez Schmitt triggera (zbog većeg naponskog praga promjene stanja u logičku nulu).
Ako ne koristim interne Schmitt triggere (koji su također i inverteri) onda negativnu logiku sa senzora mogu promijeniti u pozitivnu korištenjem if naredbe u Verilogu koja provjerava da li je senzor 0. Međutim, puno bolji je drugi način uz upotrebu internih invertera gdje se na samom početku invertira cijeli 128-bitni bus u pozitivnu logiku (1 = pogodak, 0 = mirno stanje) te interni RS latchevi rade dalje s čistom pozitivnom logikom. Ovo je bio također jedan od razloga zašto sam se odlučio na pull-down senzorski otpornik jer sam svakako želio koristiti interne Schmitt triggere.
Optimizacija upravljanja RS latchevima
Kad smo već spomenuli RS latcheve, kako što smo opisali u objavi o senzorima, oni služe za ispravnu detekciju nepravilnih impulsa koje ostavlja projektil prolazeći kroz 4 svjetlosne zavjese (dvije horizontalno i dvije vertikalno). Oblik dijabole (pješčani sat) i zračni vrtlozi iza nje mogu uzrokovati “titranje” signala (optički bounce). Također, zbog dvije dvostruke zavjese s razmakom od 7,2 mm znači da će ista dijabola aktivirati senzore u najmanje dva vala.
RS Latch pristup unutar EPM570 je savršeno rješenje za ovaj problem, međutim mora se implementirati na razini svakog pojedinačnog bita. U Verilog kodu svaki od 128 senzora ima svoj neovisni RS latch:
- Prvi kontakt (glava dijabole): Senzor pada na 0, latch skače na 1 i ostaje na 1.
- Prolazak “struka” dijabole: Senzor se na trenutak vrati na 1 (svjetlo prođe), ali latch to ignorira jer je već “zaključan”.
- Prolazak druge zavjese (7,2 mm kasnije): Čak i ako isti senzor ponovno padne na 0 zbog drugog reda zavjese, latch je već na 1 od prvog reda.
EPM570 će dakle zabilježiti “sjenu” (siluetu) dijabole kao uniju svih pogođenih senzora u oba dvostruka reda, bez obzira na titranje signala. Međutim, ovdje moramo biti sigurni da je dijabola potpuno napustila sve zavjese prije nego što se RS latchevi resetiraju za čekanje nove dijabole. Stoga je potrebno dodati softverski delay na ESP32 strani:
- Metak prolazi -> EPM570 digne trigger_alarm.
- ESP32 detektira alarm -> Odmah očita 128 bita (to traje < 1ms).
- ESP32 šalje podatke preko LoRa-e.
- Wait (100 ms): ESP32 čeka da metak fizički napusti prostor mete, 100 ms je više nego dovoljno i za najsporije projektile, a s druge strane čak ni rafalna paljba ne šalje dva projektila za redom tom brzinom.
- Reset: ESP32 šalje kratki impuls na pinRESET.
U ESP32 je dakle dodan kod za čekanje od 100 ms, a u Verilog je dodan kod koji osigurava da jednom postavljeni bit (pogodak) ne može biti poništen ničim osim hardverskim resetom.
Raspored funkcija
Tijekom razvoja i testiranja projekta događale su se različite nadogradnje sustava kao i promjene osnovnog funkcioniranja detektorske elektronike. Uvedena je dvosmjerna LoRa komunikacija, a funkcije su u konačnici raspoređene na CPLD-ove i ESP-32 na ovaj način:
Što se vrši na CPLD-ovima (brzi hardverski nivo, reda ns)
CPLD moduli (za X-os i Y-os identično) rade na taktu od 50 MHz (20 ns) i izvršavaju tri kritične funkcije koje se ne smiju oslanjati na (spori) softver:
Brzo “hvatanje” i trajno zaključavanje pogotka (sjene)
Projektil koji leti visokom podzvučnom ili nadzvučnom brzinom presijeca laserske zrake foto-rešetke u iznimno kratkom vremenu (par mikrosekundi). CPLD provjerava stanje svih 64 senzora svakih 20 ns. Ako projektil baci sjenu na senzor makar i na jedan jedini takt oscilatora, CPLD tu sjenu trajno zaključava (latcha) u registar. Ta sjena ostaje zapamćena sve dok je ESP32 ne pročita i zatim namjerno obriše preko reset linije.
Automatska selekcija geometrijske plohe (START okidač) za mjerenje brzine projektila
Senzorske rešetke za X i Y os ne leže u istoj ravnini. Laseri za svaku os (2×64 komada) raspoređeni su u dvije ravnine međusobno razmaknute 7,2 mm. To znači da su 32 senzora svake osi u jednoj plohi, a druga 32 senzora u drugoj plohi. Treća svjetlosna zavjesa koja služi samo za mjerenje brzine (STOP zavjesa) nalazi se 100 mm iza prvih zavjesa (START zavjese), odnosno 107,2 mm iza prve zavjese i 100 mm iza druge zavjese. Kod mjerenja brzine ovo može biti problem jer za svaku os može biti aktivirana prva ili druga zavjesa, a razlika od 7,2 mm na ukupnoj udaljenosti između START i STOP zavjese unosi preveliku pogrešku u mjerenju.
Sustav za mjerenje brzine stoga mora registrirati na kojoj zavjesi se dogodio START prekid i na osnovu toga prilagoditi račun za mjerenje brzine.
Prva zavjesa sadrži neparne senzore za X-os u rasponu 1-63 i parne senzore za Y-os u rasponu 2-64. Druga zavjesa sadrži parne senzore za X-os u rasponu 2-64 i neparne senzore za Y-os u rasponu 1-63. CPLD preko parnih i neparnih logičkih maski prepoznaje je li projektil aktiviralo Plohu A (parni senzori sa geometrijskom bazom 107,2 mm) ili Plohu B (neparni senzori sa geometrijskom bazom 100,0 mm).
Kronometar visoke rezolucije (mjerenje vremena leta)
U trenutku kad prva ploha (A ili B) detektira sjenu, CPLD u roku od 20 ns pokreće unutrašnji 32-bitni brojač. Brojač broji impulse oscilatora sve dok projektil ne presiječe treću zavjesu (STOP). Rezultat je određeni broj taktova (tikova) koji predstavlja čisto vrijeme leta projektila između START i STOP zavjesa, izmjereno s točnošću od ±20 ns.
Paralelno-serijska SPI pretvorba (96 bita)
CPLD na kraju pakira sve podatke (64 bita sjena + 1 bit odabira plohe + 31 bit tajmera = 96 bita) u jedan veliki paket. Kada ESP32 podigne load_data, CPLD te podatke zaključa u pomični registar (shift_reg), te ih preko jedne linije (spi_out) šalje u ESP32 u ritmu frekvencije takta (spi_clk).
Što se vrši na ESP-32 (spori softverski nivo, reda ms)
Nakon što CPLD odradi brzo (ns) hvatanje stanja, ESP32 se budi i preuzima računakni i komunikacijski dio posla kroz svoj programski kôd.
Upravljanje SPI sabirnicom i iščitavane podataka sa CPLD-a (96 Bita)
ESP-32 na znak CPLD-a da je došlo do promjene stanja (alarm) počinje proces čitanja podataka sa CPLD-a.
Ocjena ispravnosti detekcije
U prvom koraku ESP-32 mora prepoznati da li je promjenu stanja izazvao prolazak projektila ili neki drug kvar na senzorima (trajna sjena uslijed otkaza senzorske linije, uslijed pada nekog predmeta na senzore i slično). Stoga, nakon što pročita 64 bita podataka o senzorima sa svakog CPLD-a, ESP-32 radi logičku provjeru tih podataka. Provjera se radi na način da se nakon svakog čitanja novih podataka, CPLD-ovi resetiraju, a zatim se nakon 100 ms ponovno čitaju podaci sa CPLD-ova. Ukoliko je promjenu (sjenu) izazvao brzi projektil, drugo čitanje podataka će se razlikovati od prvog (bit će pročitane sve nule). Ukoliko pak drugo čitanje bude isto kao i prvo, to znači da postoji neka trajna sjena, odnosno kvar. U tom slučaju ESP-32 automatski ažurira masku kvarova i šalje paket tipa 4 (Kvar) na CrowPanel kod strijelca, kako bi se na ekranu detektirao kvar.
Fizikalni proračun brzine projektila
ESP32 iz CPLD-a dobiva samo sirove tikove (broj impulsa u određenom vremenu) i zastavice (da li je aktivirana prva ili druga START zavjesa). Stoga, za točan izračun brzine, ESP-32 prvo provjerava koja je START baza okinuta te na temelju toga postavlja bazu za duljinu na 0,1000 m ili na 0,1072 m. Nakon toga pretvara broj tikova u sekunde kako bi se dobila vremenska baza (vrijeme = broj tikova x 0,00000002 s). Iz ovih podataka računa brzinu (brzina = duljina / vrijeme). S obzirom da podaci dolaze sa oba CPLD-a neovisno, ESP-32 izračunava brzinu na oba CPLD-a, a zatim računa srednju vrijednost kako bi mjerenje bilo točnije. Na kraju ESP-32 taj prosjek pretvara u format formule kako bi ga spakirao u 32-bitnu varijablu za LoRa slanje.
Prikupljanje telemetrije i bežično odašiljanje (LoRa upravljanje)
ESP32 periodički (svake sekunde) očitava vanjske senzore za brzinu i smjer vjetra (anemometre), senzore za temperature sistema (DS18B20), te na ADC ulazu mjeri napon akumulatora. Sve te podatke pakira u točnu definiranu strukturu od 32 bajta i preko LoRa podatke šalje na CrowPanel.
Prihvat naredbi sa CrowPanela (Ventilator, Kalibracija, Reset)
U unutrašnjosti loop() petlje, ESP32 neprekidno provjerava dolazne podatke sa LoRa. Kada sa CrowPanela stigne paket koji počinje s 0xBB, ESP32 provjerava Checksum i na osnovu toga inicira paljenje određenih elektroničkih releja ili pokreće automatsku kalibraciju lasera preko digitalnog potenciometra.
ESP32-WROOM-32D vs ESP32-S3-WROOM-1
Projekt sam počeo razvijati za ESP32-WROOM-32D, no pokazalo se da ipak trebam MCU sa više GPIO pinova. Stoga sam prešao na prvi jači ESP-32 razvojni model naziva ESP32-S3-WROOM-1.
Razlika između ESP32-32D i naprednijeg ESP32-S3 je prilično velika. Iako oba čipa dolaze iz iste tvornice (Espressif) i imaju dvojezgrene procesore na 240 MHz, ESP32-32D koristi stariji Xtensa LX6, dok ESP32-S3 koristi napredniji Xtensa LX7 procesor. Ovaj procesor je razvijen s potpuno novom arhitekturom, većim brojem pinova i namjenskim hardverom za grafiku, umjetnu inteligenciju i bežičnu stabilnost.
Glavna prednost LX7 za moj projekt je ugradnja vektorskih uputa (vektorska proširenja). To znači da S3 može unutar samo jednog takta procesora izvršiti teške matematičke operacije nad više brojeva odjednom, što je poželjno primjerice za moj proračun brzine iz CPLD tikova.
Ipak, glavni razlog prelaska na ESP32-S3 je taj što ESP32-32D ima premali broj iskoristivih GPIO pinova. Fizički ih na modulu ima 25, međutim, 4 pina su samo ulazna i ne mogu generirati nikakav izlazni napon. Također, 6 pinova su strapping pinovi koji moraju prilikom boota biti u određenom logičkom stanju, inače procesor ulazi u neki drugi mod rada ili je boot blokiran na drugačiji način. To znači da je kod ESP32-32D pločice na raspolaganju svega 15 „čistih“ GPIO pinova. ESP32-S3 pak ima na modulu 36 GPIO pinova, od čega je 5 pinova strapping, a još dva su rezervirana za Flash i PSRAM. To znači da je na raspolaganju 29 „čistih“ GPIO pinova ili 14 više nego kod ESP32-32D.
“Sigurni” GPIO pinovi na ESP32-WROOM-32D.
“Sigurni” GPIO pinovi na ESP32-S3-WROOM-1.
Kritični “Strapping” pinovi na ESP32-WROOM-32D:
- GPIO 1 (TX0 – Transmit) – Preko njega ESP32 šalje podatke na Serial Monitor. Ovaj pin treba izbjegavati za drugo korištenje.
- GPIO 2 – Kod početnog paljenja uvijek mora biti na LOW ili ostavljen nepovezan (standardni način rada i način programiranja). Ako je ovaj pin povučen na HIGH tijekom paljenja, ESP32 će pokušati ući u nepostojeći mod rada ili će se “zamrznuti” i programski kod se uopće neće pokrenuti. Obično je na njega spojena ugrađena LED dioda.
- GPIO 3 (RX0 – Receive) – Preko njega ESP32 prima novi program s računala. Ovaj pin treba izbjegavati za drugo korištenje.
- GPIO 5 – Kod početnog paljenja mora biti na HIGH (standardni način rada). Ako je ovaj pin povučen na LOW tijekom paljenja, ESP32 pokušava ući u mod za “SDIO slave” (komunikacija s SD karticama na poseban način). To obično uzrokuje da se ESP32 uopće ne pokrene ili uđe u “boot loop”. Budući da ovaj pin ima interni pull-up otpornik, on će sam otići u HIGH, međutim treba paziti da ga spojeni izlaz ne povuče na LOW.
- GPIO 12 – Kod početnog paljenja mora biti na LOW. Ako je HIGH kod paljenja, može doći do problema s naponom flash memorije (pokušat će raditi na 1,8V umjesto 3,3V), što će spriječiti podizanje sustava.
- GPIO 15 – Kod početnog paljenja mora biti na HIGH. Šalje debug poruke na Serial portu pri paljenju. Budući da ovaj pin ima interni pull-up otpornik, on će sam otići u HIGH, međutim treba paziti da ga spojeni izlaz ne povuče na LOW. U tom slučaju će se spriječiti ispis na Serial monitoru, no obično se normalan start ipak pokrene.
- GPIO 34, 35, 36, 39 – isključivo ulazni pinovi
Kritični “Strapping” pinovi na ESP32-S3:
- GPIO 0: Kod početnog paljenja mora biti na HIGH. Kontrolira hoće li se čip pokrenuti u normalnom radnom načinu (HIGH) ili u modu za flashanje koda s računala (LOW). Na ploči obično postoji vanjski otpornik (Pull-up) koji ga drži na HIGH, međutim treba paziti da ga spojeni izlaz ne povuče na LOW.
- GPIO 3: Određuje način rada JTAG debuggera pri podizanju sustava.
- GPIO 45: Izuzetno opasan pin! Kontrolira napon napajanja same unutrašnje Flash/PSRAM memorije (odabir između 3.3V i 1.8V). Ako ga vanjski čip pri paljenju povuče na HIGH, procesor će postaviti pogrešan napon i trajno izgubiti vezu s vlastitom memorijom programskim kodom.
- GPIO 46: Mora strogo biti LOW (uzemljen) u trenutku paljenja kako bi čip uopće dopustio podizanje sustava iz ROM memorije. Ako je u trenutku paljenja na HIGH, boot proces propada.
- GPIO 15 (ili u nekim dokumentacijama označen i kroz OTP postavke): Može utjecati na slanje kontrolnih logova pri podizanju sustava.
- GPIO 47 i 48 – Iako tehnički nisu strapping pinovi, kod velikog broja tvorničkih ESP32-S3 modula (pogotovo onih koji imaju ugrađen ultra-brzi Octal PSRAM) ovi pinovi su interno čvrsto ožičeni za rad same memorije unutar metalnog kućišta. Njihovo korištenje u kodu kao obični ulaz ili izlaz trenutno uzrokuje hardverski krah (Crash/Panic). Zato ih je najbolje izbjegavati za bilo kakvo spajanje.
Wi-Fi komunikacija
Što se tiče bežične Wi-Fi komunikacije, ESP32-WROOM-32D podržava stariji Wi-Fi 4 (802.11 b/g/n) i Bluetooth 4.2 / BLE standard. PCB antena je integrirana na pločici i iznimno je osjetljiva na položaj unutar metalnog ili plastičnog kućišta mete. ESP32-S3 donosi moderniji Wi-Fi 4 sa stabilnijim protokolima i napredni Bluetooth 5.0 / BLE 5.0 s proširenim dometom (Long Range). Modul dolazi s ugrađenim IPEX/U.FL konektorom za vanjsku antenu omogućuje da se koaksijalnim kabelom izvuče antena izvan metalnog kućišta mete. Wi-Fi planiram koristiti za bežično spajanje anemometara.
Raspoloživa memorija
Što se tiče memorija, ESP32-WROOM-32D ima 520 KB unutrašnjeg SRAM-a, a ESP32-S3 ima 512 KB SRAM-a. Iako na papiru ima 8 KB manje od starog ESP32 (512 naspram 520), ova memorija kod S3 modela je konstruirana na potpuno novoj arhitekturi i izravno je povezana s unutrašnjom Cache memorijom. To znači da procesor može komunicirati s radnim prostorom i vanjskim PSRAM-om neusporedivo brže i bez stvaranja uskih grla, što u mojem konkretnom slučaju osigurava da paralelno čitanje 96 bita s CPLD-a prolazi puno brže. Također, memorija od 520 KB unutar ESP32-WROOM-32D je rascjepkana na tri bloka: SRAM0, SRAM1 (koji služe za sustav i drajvere) te SRAM2 (oko 328 KB) koji je zapravo jedini stvarno slobodan prostor za odvijanje programskog koda.
ESP32-WROOM-32D ima 448 KB ROM memorije, a ESP32-S3 ima 384 KB ROM memorije. ROM memorija kod ESP32-S3 je smanjena jer su drajveri optimiziraniji i zauzimanju manje memorije. Ovdje je zapravo bitan dodatni unutrašnji RTC RAM za Deep Sleep mod (čuvanje podataka u modu za uštedu energije) koji je kod ESP32-S3 dvostruko veći, 16 KB u odnosu na 8 KB kod ESP32-WROOM-32D.
Neki ESP-32 moduli imaju dodatni vanjski PSRAM memorijski čip (WROVER modeli). Za stranu mete (TX kôd), gdje nema teške LVGL grafike, velikih jezičnih matrica niti slikovnih buffer-a, vanjski PSRAM čip nije potreban. Čistih 512 KB unutrašnjeg SRAM-a unutar samog ESP32-S3 čipa je i više nego dovoljno za paralelno čitanje CPLD-a i slanje LoRa paketa. Ipak spomenuti ćemo da i ovdje postoje razlike kod dvije razvojne pločice koje uspoređujemo. Kod starijeg ESP32 čipa, veza između procesora i vanjskog PSRAM-a izvedena je preko standardne Quad SPI (4-bitne) sabirnice sa tipičnim radnim taktom od 40 MHz ili maksimalno 80 MHz, ali uz velika unutrašnja kašnjenja (latenciju). Kod S3 modela uveden je napredni Octal SPI (8-bitni) podsustav. Sabirnica radi na stabilnih 80 MHz do 120 MHz, no koristi DDR (Double Data Rate) tehnologiju. To znači da se podaci šalju i na uzlazni i na silazni rub takta, čime se efektivna brzina u praksi penje na ekvivalent od 240 MHz. Kod ESP32-32D Flash i PSRAM dijele istu unutrašnju sabirnicu, dok ESP32-S3 ima potpuno odvojen Cache sustav za Flash i PSRAM. To znači da bi za našu primjenu mogao istovremeno čitati balističke podatke iz Flasha i pisati po PSRAM-u, bez ikakvog međusobnog čekanja ili zagušenja sabirnice.
Razlika u cijeni između ESP32-32D i ESP32-S3 je nekoliko eura (4 eura naspram 8 eura) pa ako radite nešto ozbiljniji projekt ili vam treba ESP32 pločica za različite eksperimente, onda je svakako noviji ESP32-S3 bolji izbor.
Za elektroničku metu GPIO pinove sam definirao na slijedeći način:
Arduino programi za ESP32
Već smo vidjeli kod razvoja Verilog koda da nije moguće potpuno odvojeno programiranje EPM570 modula i ESP32 modula za stranu mete (predajnik) i stranu strijelca (prijemnik). Sustavi moraju međusobno komunicirati te se moraju i paralelno razvijati.
AI je kreirala prve programske kodove za EPM570 i ESP32 prema mojim zahtjevima. Odmah je implementirano i bežično slanje preko LoRa modula. Arduino kodovi za oba ESP32 imaju Debug logove i Serial print naredbe kako bi se mogao provjeriti rad programa jer nije realno očekivati da će sve proraditi od prve.
Trebalo je desetak većih dorada i nadogradnji koda, nekoliko izmjena hardvera te nekoliko desetaka rješavanja raznih bugova da se dobije prvi funkcionalni programi.
Prvi testni kodovi
Općenito gledano, bilo je više “prvih testnih kodova” koji su profunkcionirali u raznim fazama razvoja projekta. Prvi kodovi su uključivali samo komunikaciju između jednog EPM570 CPLD-a i jednog ESP32. U toj fazi svjetlosna zavjesa još uvijek nije bila kompletirana. Mogao sam raditi samo simulaciju okidanja senzora, a i to se moglo izvesti samo probno, na nekoliko senzora. Jednostavno je nemoguće „u zraku“ stabilno povezivati i simulirati sve 64 senzorske linije. Brzina CPLD-a je 50 MHz i bilo kakve nepotrebno duge žice, parazitski kapaciteti i slične pojave mogu izazvati lažna i nasumična okidanja. Kod ovakvih sustava, testiranje koje možete napraviti na testnim pločicama i sa priručnim napajanjima su vrlo ograničena.
Tek kada sam napravio PCB-ove za metu (iako sam znao da to nije konačna verzija istih) mogao sam nastaviti sa proširenim i detaljnijim testovima.
U početku sam bilježio kronologiju razvoja softvera, međutim, gotovo svaka nadogradnja je generirala različite softverske i hardverske probleme koje je trebalo sustavno rješavati. Pojedinačno opisivanje svakog takvog problema bilo bi preopširno, no to su sigurno posve očekivani problemi sa kojima se susreće svaki programer sličnih kodova. U konačnici sam došao do stabilnih inačica koda za CPLD-ove (Verilog), koda za ESP32-S3 (Arduino) na meti i koda za ESP32-P4 za monitor strijelca koji sadrži preko 5000 linija čistog koda. Vjerojatno će i dalje trebati manje dorade ovih kodova, no mogu reći da sustav već i sada radi posve funkcionalno i ispunjava sve postavljene zahtjeve.
Prve PCB
Tiskane pločice (PCB) za EPM570 vjerojatno će zadržati ovakav dizajn i u finalnoj inačici razvoja.
Tiskane pločice za povezivanje dva EPM570 i LoRa modula sa ESP32-32D. S obzirom da sam morao zamijeniti LoRa SX1278 (Ra-2) sa LoRa SX1262 te proširiti broj GPIO pinova i preći na ESP32-S3, ova tiskana pločica će se bitno mijenjati.
Prvo realno testiranje
Kad su programi bili dovoljno razvijeni i PCB kompletirane, napravio sam prvo „sobno“ testiranje detekcije sa zračnim pištoljima na dijabole 4,5 mm i kuglice 6 mm.
Očekivano, dijabole od 4,5 mm u cca 40% slučaja ne prekinu obje zavjese, odnosno dijabola se provuče između dvije laserske zrake bez da ih dovoljno zakloni. Kuglice od 6 mm imaju detekciju od 100%, a vjerujem da bi tako bilo i za kalibar 5,5 mm.
Sada već imam ideju kako poboljšati svjetlosnu zavjesu tako da detektira kalibar 4,5 mm, no ako u tome i ne uspijem, ovo je ipak „long range“ meta predviđena za kalibre 5,5 mm i veće. Problem je u tome što sve laserske zrake trebaju biti cijelom dužinom na međusobnom razmaku od točno 4 mm i svi laseri moraju biti temperaturno stabilizirani tako da daju konstantnu snagu. Ovo tehnički nije lako postići, no radim na tome.
Elektronička meta je prilično složen projekt gdje je potrebno paralelno razvijati i stalno međusobno prilagođavati pojedine hardverske i softverske dijelove. Sam sistem lasera i foto-senzora je sustav kod kojeg treba rješavati niz praktičnih problema. To su problemi svjetlosnih polusjena koji mogu dovesti do nedovoljnog pada napona za promjenu logičkog stanja, problemi temperaturne ovisnosti i drugih nestabilnosti jačine zračenja lasera, problemi same geometrije svjetlosnih linija i tako dalje. Neke problemi se mogu riješiti ili barem ublažiti softverski, neke probleme je treba rješavati isključivo hardverski.
Zbog visoke frekvencije rada detektorskog sustava potrebno je izraditi kvalitetne tiskane pločice, a njih nije baš tako jednostavno i jeftino mijenjati kako se naiđe na neki problem. Stoga je puno stvari treba predvidjeti unaprijed, a ako negdje postoje dvojbe, onda svakako treba ostaviti prostora i osmisliti pločice za što lakšu prenamjenu i mogućnost testiranja što više mogućnosti.
Raspberry Pi Pico 2 (RP2350)
Nakon što je hardver mete (CPLD – ESP32) testiran i dobro radio na Serial monitoru, te nakon što je CrowPanel bio programiran i dobro je radio sa simulatorom, trebalo je napokon spojiti ta dva sustava tako da detektorski hardver mete samostalno preko LoRa sustava radi sa CrowPanelom kod strijelca.
Već sam spomenuo da kod ESP32 na meti imam problem nedostatka GPIO pinova jer CPLD-ovi traže 9 pinova, LoRa traži 7 pinova, a tu je i puno periferije (temperaturni senzori, anemometar, četiri releja, napon baterije). Stoga sam sa ESP32-WROOM-32D prešao na ESP32-S3-WROOM-1. Međutim, ovaj prelazak na noviji i napredniji ESP32 nije donio očekivane rezultate. Sa ESP32-S3 nikako nisam mogao dobiti sinkronizirano čitanje podataka sa CPLD-a.
Zapravo, u jednom trenutku sam preko SPI sabirnice čak i uspio natjerati ESP32 da sinkronizirano čita podatke, no iz nekog razloga odbijao je čitati podatke brzih projektila, odnosno sjena je morala trajati barem 100 ms da bi podatak bio pročitan. U daljnjem razvoju koda uspio bi postići trenutno čitanje svih sjena, uključujući i vrlo kratke sjene brzih projektila, no iščitani podaci ne bi bili sinkronizirani.
Očito je negdje postojao problem u tajmingu, što je čudno, jer CPLD čuva podatke u latch-u i ESP32 ima sve vrijeme svijeta da ih na miru pročita. Stoga sam u slijedećem koraku potpuno odustao od čitanja podataka preko SPI protokola i prešao na primitivno robusni princip pulsno-kodiranog prijenosa duljine niza (Pulse-Distance / Width Modulation).
Ovaj sistem se više ne oslanja na takt (clock) koji generira ESP32, nego CPLD unutar sebe ima svoj neovisni, stabilni generator takta (npr. unutrašnjih 50 MHz podijeljenih na sporih i stabilnih 100 kHz). CPLD šalje točno 64 impulsa za redom (svaki impuls predstavlja jedan senzor), gdje mijenja širinu (trajanje) samog impulsa ovisno o tome je li senzor prekinut ili ispravan. ESP stoga samo mjeri duljinu trajanja svakog impulsa i prevodi ga u stanje senzora:
- Kratki impuls (npr. 10 mikrosekundi): Označava da je senzor ISPRAVAN / SVIJETLI (0).
- Dugi impuls (npr. 30 mikrosekundi): Označava da je senzor PREKINUT / SJENA / KVAR (1).
Ovdje dakle ne bi trebalo biti problema sa pomakom i de-sinkronizacijom čitanja bitova kao kod klasičnog SPI protokola. Ipak, nakon nekoliko različitih pokušaja i modifikacija Verilog i Arduino kodova kojima se mijenjao način čitanja podataka sa oba CPLD-a, sinkronizirano čitanje podataka jednostavno nisam uspio dobiti.
Na kraju sam razdvojio i LOAD pinove oba CPLD-a tako da se podaci mogu čitati posve neovisno sa jednog ili drugog CPLD-a. Međutim, ni ovime nisam uspio postići sinkronizaciju. Iz ispisa Serial monitora bilo je očito da nešto uzrokuje pomak ili zastoj uslijed čitanja nizova od 64 bita tako da pročitani bitovi nisu ni cjeloviti ni na ispravnim pozicijama, niti pripadaju istom latch stanju.
Jedino što je preostalo kao mogući problem, to je sam ESP32-S3 i njegovi FreeRTOS operativni sustav. Pretpostavljam da FreeRTOS drajver i scheduler nasilno prekidaju kontinuirano izvršenje kôda za čitanje stanja senzora (loop) kako bi odradili neko svoje unutrašnje održavanje čipa. CPLD uredno šalje niz od 64 bajta, no negdje usred tog slanja FreeRTOS odluči na kratko zaustaviti proces čitanja podataka da bi odradio nešto drugo. Kad se ponovno vrati na čitanje, dio podataka je već pobjegao u prazno i daljnje čitanje je posve nesinkronizirano.
Stoga sam odlučio preći na mikrokontroler koji nema operativni sustav i izvršava program u čistom hardveru (tzv. Bare-Metal ili “goli hardver”). Dobar kandidat za to je Raspberry Pi Pico ili nešto napredniji Pico 2. Zašto mislim da bi to moglo biti rješenje?
FreeRTOS je operativni sustav za mikrokontrolere u realnom vremenu. On omogućuje ESP32 čipu da radi multitasking, odnosno da prividno vrti više programa (taskova) istovremeno. ESP32 ima dvije jezgre. FreeRTOS neprekidno, svakih nekoliko mikrosekundi, skače s jednog zadatka na drugi (tzv. Scheduler). On kaže: “Sada ću 1 milisekundu održavati Wi-Fi vezu, pa ću 1 milisekundu čitati temperaturu, pa ću 1 milisekundu provjeravati LoRa-u, pa se vraćam na Wi-Fi”. Cijena tog multitaskinga je gubitak kontrole nad vremenom. Budući da operativni sustav u pozadini neprekidno donosi odluke i prekida rad koda radi nekih drugih unutrašnjih potreba ili prioriteta, onda ništa ne može jamčiti da petlja čitanja podataka sa CPLD-a neće biti prekinuta usred čitanja i mjerenja impulsa zbog nekog drugog taskinga.
Raspberry Pi Pico 2 u standardnom Arduino okruženju radi u Bare-Metal načinu rada. To znači da operativni sustav ne postoji. Program se učitava izravno na silicij procesora i kontrolira sve, odnosno ima apsolutnu kontrolu nad svakim tranzistorom i pinom na čipu. Nema unutrašnjeg potprograma koji radi paralelno sa učitanim programskim kodom. Stoga bi Pico trebao biti pouzdanije rješenje za vremenski kritične i precizne sustave, trebao bi biti pouzdaniji glede rušenja i svakako za projekte s brzim softverskim bit-bangingom, kao što je ovaj naš.
S druge strane, na strani strijelca CrowPanel ESP32-P4 je svakako bio dobro rješenje jer tamo itekako treba multitasking, odnosno istovremeno crtanje LVGL grafike, generiranje audio najava te asinkrono primanje LoRa i WiFi paketa. FreeRTOS odlučuje kako će vremenski rasporediti multitasking, a sitna mikro-kašnjenja nastala u tom procesu ne smetaju odvijanju nijednog zadatka i nisu primjetna za operatera.
Istražio sam literaturu može li se u ESP32-S3 arhitekturi prisilno “ugasiti” scheduler FreeRTOS-a i blokirati apsolutno sve asinkrone prekide unutar jezgre dok se čita PWM niz sa CPLD-a. Čini se da je u teoriji moguće napraviti takvo blokiranje, no ono je ipak ograničeno. FreeRTOS po svojoj arhitekturi ne trpi dugotrajno i prisilno oduzimanje kontrole i može se srušiti ili prekinuti brojanje ako mu se nametnu dugačka blokirajuća vremena. To znači da moram brzinu čitanja CPLD-a što je moguće više povećati (npr. sa 100 kHz na 1 MHz), što povećava mogućnost pogreške.
Također, kada u kodu napišemo portENTER_CRITICAL(), mi procesoru kažemo da ignorira standardne softverske i drajverske prekide. Međutim, unutar ESP32-S3 čipa postoje NMI (Ne-maskirajući prekidi) koji kontroliraju kritični hardver, poput rada same Flash memorije iz koje se kôd izvršava i hardverskog Watchdog tajmera. Ako PWM petlja s CPLD-a traje duže od 1 milisekunde, hardverski Watchdog će se aktivirati na razini čistog hardvera, zaobići softverski nametnutu kritičnu zonu, nasilno prekinuti petlju i srušiti/resetirati čip.
Nadalje, ESP32-S3 ima dvije jezgre. Čak i ako prvu jezgru (Core 0) zaključam u kritičnu zonu da u miru čita PWM impulse, druga jezgra (Core 1) i dalje neprekidno radi u pozadini i izvršava radijske LoRa naredbe ili sustavne drajvere. Budući da obje jezgre koriste istu unutrašnju sabirnicu (Crossbar) za pristup GPIO pinovima i RAM memoriji, u trenutku kada druga jezgra zatraži pristup sabirnici, hardverski arbitar čipa će na nekoliko nanosekundi “usporiti” prvu jezgru. Za obične programe to je nevidljivo, ali za funkciju pulseIn() to znači da je brojanje ciklusa na sekundu blago usporilo, što trenutno kvari izmjerene mikrosekunde i stvara nesinkrone blokove podataka.
Čini se da daljnje žongliranje i borba s unutrašnjim preklapanjima ESP32-S3 čipa, “strapping” zamkama pri paljenju, nepredvidljivim FreeRTOS mikroprekidima i vječnim krpanjem polariteta u Verilogu samo trošili vaše vrijeme i energiju, te svakako ne vodi stabilnom i pouzdanom sustavu.
U složenim projektima poput ovog, kada se dođe do točke gdje softver mora silom i kritičnim zonama ispravljati hardverske nesavršenosti čipa, jedini ispravan rez je promjena platforme.
Raspberry Pi Pico 2 (RP2350) dolazi sa 26 GPIO pinova koji su potpuno samostalni, čisti i jednaki. Nema “strapping” pinova koji ruše čip ako CPLD drži napon pri paljenju. Nema unutrašnjih JTAG ili PSRAM preklapanja na razini silicija. Treba se samo držati rasporeda predefiniranih hardverskih pinova SPI i UART komunikacije, a svi ostali GPIO pinovi mogu se odabrati onako kako najbolje pašu za PCB dizajn. Hardverski odvojena komunikacija: LoRa modul, digitalni potenciometar i serijski prijam vjetra radit će preko svojih zasebnih hardverskih krugova (SPI0, SPI1 i UART1), ostavljajući procesor potpuno slobodnim za balistiku.
Sa Pico 2 dobivam potpunu kontrolu nad vremenom (Bare-Metal) budući da nema FreeRTOS-a koji asinkrono skače s taska na task. Kada Pico 2 krene čitati pulseve s CPLD-a, on mjeri vrijeme u nanosekundu točno svaki put. Nema teoretske šanse da pozadinski procesi prekinu ili “osakate” sliku laserske zavjese. Ako ovo neće raditi, onda polako ostajem bez ideja.
Kao što se vidi na shemi, kod Raspberry Pi Pico 2 na vanjske su konektore dovedeni samo oni pinovi koji se ne koriste za nikakve unutrašnje procese. Svih 26 pinova se stoga može koristiti bez ograničenja za digitalni ulaz ili izlaz, od čega su pinovi 26, 27 i 28 također i analogni (ADC).
RUN / RESET (Fizički pin 30)
Ovo je hardverski ulaz za resetiranje mikrokontrolera. Radi na principu niske razine napona (Active-Low). U normalnom radu ovaj pin je unutrašnje povučen na 3,3 V (HIGH). Ako se preko vanjske sklopke ili otvorenog kolektora kratko spoji na masu (GND), procesor RP2350 će se trenutno ponovno pokrenuti (resetirati) kao da ste ugasili i upalili struju. Ovo je u osnovi pin za spajanje Reset tipkala.
ADC VREF (Fizički pin 35)
Ovo je analogni referentni napon za ugrađeni ADC pretvarač. Tvornički je na samoj pločici preko malog otpornika povezan na unutrašnjih stabilnih 3,3 V. Ako se želi posebno precizno mjerenje analognih napona, na ovaj pin se može dovesti vanjski posebno stabiliziran napon (referenca) od točno 3,0V ili 3,3V.
EN / 3V3_EN (Fizički pin 37)
Ovo je Enable pin ugrađenog regulatora napona. Ovaj pin izravno kontrolira hoće li ugrađeni naponski regulstor na pločici proizvoditi 3,3 V. Ako ovaj pin spoji na masu (GND), cijeli unutrašnji regulator se gasi, pločica ostaje bez struje i prelazi u stanje ultra-niske potrošnje (ispod 10 µA), bez obzira što je napajanje i dalje fizički spojeno na VSYS.
VSYS (Fizički pin 39)
Ovo je glavni ulazni pin za vanjsko napajanje pločice. Prihvaća širok raspon ulaznih napona od 1,8 V do 5,5V. Ugrađeni čip (RT6150 buck-boost) će taj napon automatski i stabilno pretvoriti u točno 3,3V za rad cijelog sustava.
VBUS (Fizički pin 40)
Ovo je fizički napon izravno s USB-C utora pločice. Kada je Pico 2 spojen na računalo preko USB kabela, na ovom pinu se nalazi čistih 5 V s računala. Na samoj pločici se između VSYS i VBUS nalazi ugrađena Schottky dioda koja sprječava da struja s USB-a poteče natrag u vanjsko napajanje, što omogućava da se istovremeno programira pločica i drži spojeno vanjsko napajanje bez ikakvih kratkih spojeva.
Četiri opcije razmjene podataka između CPLD-ova i Raspberry Pi Pico 2
Raspberry Pi Pico 2 (RP2350) nudi hardverske mogućnosti koje ESP32 uopće fizički nema. Budući da CPLD radi na 50 MHz i u nanosekundi puni svoje unutrašnje registre pozicije i brzine projektila, na raspolaganju imamo četiri opcije za komunikaciju:
Opcija 1: “Pješački” Sinkroni Takt s Pico 2
Ovo je najjednostavnija opcija koja u potpunosti zaobilazi komplicirane protokole i koristi obične digitalne pinove. CPLD samo čuva podatke i digne alarm. Pico 2 reagira, a procesor ručno (kroz softversku petlju) šalje točno 96 impulsa sata na clock liniju CPLD-a te s MISO linija učitava bit po bit podataka. Budući da sam u novom dizajnu fizički razdvojio linije za Load podataka, Pico 2 ima apsolutnu kontrolu nad vremenom. On može najprije u miru očitati X os, zatim aktivirati load za Y os i očitati Y os. Podaci se ne mogu preliti jer se CPLD shift-registar ne može pomaknuti ni za jedan bit dok mu Pico 2 namjerno ne pošalje impuls sata. Brzina ovakvog prijenosa je oko 200 kHz do 500 kHz što znači da čitanje traje svega nekoliko mikrosekundi.
Opcija 2: Dvostruki Hardverski SPI (Dual-SPI Transakcija)
Pico 2 ima dva potpuno neovisna hardverska SPI kontrolera u siliciju (SPI0 i SPI1). Za LoRa modul smo odredili SPI0, a za digitalni potenciometar SPI1. Ako bi za CPLD-ove htjeli također koristiti klasični hardverski SPI, morali bi ih staviti na sabirnicu SPI1 zajedno s digitalnim potenciometrom i dijeliti istu liniju sata. Međutim, CPLD-ovi nemaju klasični CS (Chip Select) pin koji bi stavio njihove MISO linije u stanje visoke impedancije (isključio ih s mreže) kada čitamo potenciometar, što bi stvorilo električni konflikt na žicama.
Stoga bi za digitalni potenciometar (koji se rijetko koristi) morali odabrati drugu grupu pinova, tako da SPI1 konfiguriramo za CPLD-ove. Budući da Pico 2 dopušta paralelno mapiranje, možemo iskoristiti Dual-MISO opciju gdje procesor preko unutrašnjih silicijskih filtara u istoj nanosekundi učitava i bit s X čipa i bit s Y čipa preko istog hardverskog sata. Ovdje nema softverskih petlji što je prednost za sinkronizaciju, a brzina prijenosa je vrlo visoka, od 1 MHz do 10 MHz.
Većina pokušaja do sada je išla upravo u smjeru SPI komunikacije, međutim, usklađivanje rada tri SPI uređaja od kojih jedan nema CS, na arhitekturi koja podržava samo dva hardverska SPI-a, može stvoriti razne nepredvidljive probleme. LoRa i CPLD-ovi su važni elementi sistema koji stalno rade i bolje je da ne dijele svoju SPI liniju sa drugim periferijama.
Opcija 3: PIO (Programmable I/O) – Specifični alat Pico 2 platforme
Ovo je hardverska tehnologija koju ima isključivo Raspberry Pi obitelj (RP2040 i novi RP2350), a ESP32 je nema. Pico 2 unutar sebe ima minijaturne, neovisne hardverske automate (PIO blokove) koji se programiraju u posebnom, kratkom strojnom jeziku (PIO assembly). Za naš slučaj, u jedan slobodan PIO automat učitaju se 4 linije koda: “čekaj alarm -> spusti LOAD -> generiraj 96 impulsa sata i učitaj MISO -> spremi u DMA”.
Prednost za sinkronizaciju je ta što čim metak proleti i CPLD digne alarm, PIO automat u istom tom djeliću nanosekunde u čistom hardveru povlači podatke iz CPLD-a, bez da glavna loop() petlja ili procesor Pico 2 pločice uopće imaju veze sa tim. Podaci se automatski slažu u memorijski prsten (FIFO buffer). Glavni procesor može slati LoRa telemetriju, obrađivati temperaturu ili raditi bilo koju drugu operaciju, za vrijeme dok je podatak o pogotku posve neovisno učitan i spremljen u pozadini na razini čistog hardvera. Brzina ovakvog prijenos se fleksibilna, može ići i do 20-30 MHz.
Opcija 4: Pulsno-kodirani PWM (Jedna žica bez SPI sata)
Ovo je koncept koji sam također isprobao sa ESP32, a koji u potpunosti briše sat (clock) s pločice. CPLD unutar sebe ima svoj spori generator takta (npr. 100 kHz) i nakon zabilježenog hica samostalno preko MISO žice šalje 96 impulsa: kratki impuls = 0 (svjetlo), dugi impuls = 1 (sjena/tajmer).
Budući da sat ne postoji na tiskanoj pločici, eliminiran je glavni uzrok “shifta” bitova. Najveća prednost za Pico 2 je što on unutar svog unutrašnjeg silicija ima namjenski hardverski blok za mjerenje širine impulsa (PWM Input Capture drajver). Pico 2 u pozadini mjeri mikrosekunde svakog impulsa bez opterećenja drugih procesa.
Kada stigne Pico 2 svakako ću testirati sve opcije osim SPI-a. Opcijom 1 (Pješački sinkroni takt) je najlakša za dijagnostiku preko Serial monitora. Budući da su Load linije razdvojene, Pico 2 će imati apsolutnu kontrolu nad CPLD kontejnerima. To će odmah pokazati jesu li spojevi na PCB-u ispravni i dobivamo li čiste nule i jedinice bez greške.
Najviše pak obećava Opcija 3 (PIO drajver). Kao što smo već opisali, ovdje imamo potpunu autonomiju jer PIO automat ima svoj vlastiti strojni kôd (PIO Assembly) i izvršava se na razini hardvera, potpuno odvojeno od glavnog ARM procesora i loop() petlje.
Čim CPLD podigne alarm, PIO automat to detektira u roku od jedne nanosekunde. On potpuno samostalno spušta load_data liniju, generira točno 96 oštrih impulsa sata brzinom od npr. 2 MHz i učitava bitove s MISO žica direktno u svoj unutrašnji hardverski FIFO međuspremnik (red čekanja u hardveru). Jednom kada tih 96 bita upadne u hardverski FIFO čipa, oni su sigurni od bilo kakvih korupcija. Glavni procesor može u tom trenutku slati LoRa pakete, obrađivati temperaturu, vjetar ili sekundu-dvije raditi bilo što drugo, podatak o pogotku i preciznim ticks-ovima brzine čeka sinkroniziran u izvornom obliku.











