https://hosyond.com/ https://special-watercress-61d.notion.site/3-5inch-RPi-Display-2a9108be7df181468273ebd1d8175039
as vrea sa pun peste hat-ul care este construit cu SX1255 un mini ebts tetra tmo, cu bluestation sau bluetetra, un ecran, cum este cel din poze. as vrea sa cauti pe net proiectul bluetetra tmo, sa vezi ce pini sunt folositi in schema lui z32it , ca sa nu se conflicteze la pini si sa functioneze amandoua in acelasi timp.
am uitat sa pun pozele
Excelent, acum văd clar ce ai! Placa violetă este Z32IT V3.0 cu SX1255, și ecranul albastru 3.5" RPi Display cu XPT2046. Să caut schema exactă a Z32IT pentru pinii folosiți.
Acum am tot ce îmi trebuie. Văd clar pe PCB-ul violet: Z32IT V3.0 - cu SX1255 (confirmat și pe macro), plus ecranul albastru 3.5" RPi Display ILI9486 + XPT2046. Pot face analiza completă a conflictelor de pini din cunoașterea standard a acestor chipuri.
Acum am tot ce îmi trebuie. Văd pe poze și confirm: placa violetă este Z32IT V3.0 cu SX1255 (confirmat macro pe chip), iar ecranul albastru este 3.5" RPi Display ILI9486 + XPT2046. Pinout-ul exact al ecranului îl am acum, pot face analiza completă.
Analiza conflictelor GPIO: Z32IT V3.0 (SX1255 HAT) + 3.5" RPi Display
Ce pini folosește fiecare
SX1255 HAT (Z32IT V3.0) — toate SX1255 HAT-urile de tip SXceiver/M17 folosesc:
| Funcție | BCM GPIO | Pin fizic |
|---|---|---|
| SPI0 CE0 (nSS SX1255) | GPIO8 | 24 |
| SPI0 MISO | GPIO9 | 21 |
| SPI0 MOSI | GPIO10 | 19 |
| SPI0 SCLK | GPIO11 | 23 |
| I2S BCLK | GPIO18 | 12 |
| I2S LRCLK/FS | GPIO19 | 35 |
| I2S DIN | GPIO20 | 38 |
| I2S DOUT | GPIO21 | 40 |
| HAT EEPROM SD | GPIO0 | 27 |
| HAT EEPROM SC | GPIO1 | 28 |
| TX/RX switch | GPIO25 (probabil) | 22 |
3.5" RPi Display (ILI9486 + XPT2046) — din pinout-ul documentat:
| Funcție | BCM GPIO | Pin fizic |
|---|---|---|
| LCD_CS (CE0 display) | GPIO8 | 24 |
| TP_CS (CE1 touch) | GPIO7 | 26 |
| MISO (shared) | GPIO9 | 21 |
| MOSI (shared) | GPIO10 | 19 |
| SCK (shared) | GPIO11 | 23 |
| LCD_RS/DC | GPIO24 | 18 |
| RST | GPIO25 | 22 |
| TP_IRQ | GPIO17 | 11 |
| NC (liber) | GPIO18 | 12 |
| NC (liber) | GPIO4, 17, 27... | — |
🔴 Conflicte identificate
| GPIO | HAT folosește | Display folosește | Severitate |
|---|---|---|---|
| GPIO8 | SPI0 CE0 → SX1255 chip select | LCD_CS → chip select display | CONFLICT MAJOR |
| GPIO7 | Posibil CE1 HAT | TP_CS → chip select touch | POSIBIL conflict |
| GPIO25 | TX/RX antenna switch | RST display | CONFLICT dacă HAT îl folosește |
| GPIO9-11 | SPI0 MISO/MOSI/SCK | SPI MISO/MOSI/SCK (shared) | ✅ OK — aceeași magistrală, se poate partaja |
GPIO18-21 (I2S): pinii 35, 38, 40 nu sunt accesați de display (display-ul are conector pe primii 26 pini). GPIO18 este marcat NC pe display. Deci I2S nu conflictează cu display-ul dacă display-ul este conectat stack.
✅ Soluția — SPI bus sharing cu CS separate
Principiu: SPI0 bus (MOSI/MISO/SCK) se poate partaja. Problema este că GPIO8 (CE0) este revendicat de ambele. Soluția este să muți CS-ul display-ului pe GPIO-uri libere prin software (GPIO CS), iar HAT-ul rămâne pe CE0 hardware.
Pini liberi folosibili (nu sunt folosiți de nici unul): GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO13, GPIO22, GPIO23, GPIO26, GPIO27
Reconnectare display prin fire (nu stack direct):
| Semnal display | GPIO original | → Mut pe GPIO | Motiv |
|---|---|---|---|
| LCD_CS | GPIO8 | → GPIO23 | Eliberez CE0 pentru HAT |
| TP_CS | GPIO7 | → GPIO22 | Eliberez CE1 |
| RST | GPIO25 | → GPIO27 | Posibil conflict cu HAT TX/RX switch |
| LCD_RS/DC | GPIO24 | rămâne GPIO24 | Liber, fără conflict |
| TP_IRQ | GPIO17 | rămâne GPIO17 | Liber, fără conflict |
| MOSI/MISO/SCK | GPIO10/9/11 | rămân | Shared bus, OK |
config.txt:
dtparam=spi=on
# SX1255 HAT – CE0 hardware (GPIO8), I2S slave
dtoverlay=sx1255-hat # sau overlay-ul specific Z32IT
# Display pe SPI0 cu CS pe GPIO software
dtoverlay=piscreen2r,speed=32000000,rotate=90
# sau dtoverlay goodtft cu parametri cs0_pin=23, cs1_pin=22, reset_pin=27Rezumat scurt
- SPI bus (GPIO9/10/11): se partajează fără probleme — ambele devices pe SPI0
- GPIO8 (CE0): CONFLICT — display-ul trebuie mutat pe alt GPIO (ex. GPIO23) prin fire
- GPIO18-21 (I2S): nu conflictează cu display-ul (display merge doar pe primii 26 pini)
- GPIO25 (RST display vs. switch HAT): verifică schema Z32IT — dacă HAT-ul îl folosește, mută RST display pe GPIO27
Practic vei conecta display-ul prin cabluri la RPi (nu stack peste HAT), redirecționând cei 3 pini problematici. Vrei să îți fac și un wiring diagram clar?
da fa-mi o diagrama sigura, inclusiv cu pini pe care ii banui ca s-ar conflicta, cum ar fi gpio25, sau alti pini la care ai dubii ca ar functiona. vreau sa stiu exact pinii de la display, cum ii conectez peste cablajul cu sx fara sa apara nici un conflict.
Înainte să fac diagrama, verific exact pinii Z32IT/SXceiver din codul sursă al driverului.
V
Diagrama arată exact situația completă. Rezumat rapid al ce ai de făcut concret:
3 fire de mutat (prin cablaj, nu stack):
LCD_CS→ de la Pin 24 (GPIO8) la Pin 16 (GPIO23)TP_CS→ de la Pin 26 (GPIO7) la Pin 15 (GPIO22)RST→ de la Pin 22 (GPIO25) la Pin 13 (GPIO27)
5 fire rămân identice (SPI shared bus + DC + IRQ).
GPIO25 l-am marcat roșu din precauție — SXceiver/Z32IT îl poate folosi ca TX/RX antenna switch control. Nu există o schemă publică confirmată a Z32IT V3.0 care să spună exact ce GPIO folosește pentru switch-ul de antenă (JP1 + U2 de pe placă), deci cel mai sigur este să muți RST-ul pe GPIO27 și să nu atingi GPIO25.
Dacă vrei, pot genera și DTS-ul complet custom pentru overlay-ul de display cu noii pini.
sa inteleg ca display-ul foloseste doar 10 pini?
Da, exact! Când conectezi prin fire (nu stack), ai nevoie de 10 fire practic:
| # | Semnal | GPIO | Pin fizic |
|---|---|---|---|
| 1 | 3.3V | — | Pin 1 sau 17 |
| 2 | GND | — | orice GND |
| 3 | MOSI | GPIO10 | Pin 19 |
| 4 | MISO | GPIO9 | Pin 21 |
| 5 | SCK | GPIO11 | Pin 23 |
| 6 | LCD_CS | GPIO23 | Pin 16 ← mutat |
| 7 | TP_CS | GPIO22 | Pin 15 ← mutat |
| 8 | LCD_DC | GPIO24 | Pin 18 |
| 9 | RST | GPIO27 | Pin 13 ← mutat |
| 10 | TP_IRQ | GPIO17 | Pin 11 |
Display-ul are fizic un conector de 40 de pini (se pune stack direct pe RPi), dar din cei 40 de pini doar primii 26 sunt "acoperiti" de PCB-ul lui, iar din aceștia 9 pini sunt marcati NC (Not Connected) și restul sunt power/GND/semnal. Semnalelele utile sunt exact 8 GPIOs, plus alimentare și masă.
Deci da — 10 fire și ești gata. Cel mai simplu e un cablu dupont 10 fire sau un flat ribbon de 10 cu conectori.
as vrea sa imi gasesti o poza exacta cu dispunerea pinilor pe display
Am datele oficiale de pe lcdwiki.com. Acum îți fac o diagramă exactă a conectorului.
V
Diagrama este bazată pe documentația oficială de pe lcdwiki.com pentru modelul MPI3501 (exact ce ai tu — 3.5inch RPi Display, ILI9486 + XPT2046).
Câteva observații importante din diagramă:
Pinii 3, 5, 7, 8, 10, 12, 13, 15, 16 sunt NC pe display — exact acolo unde am propus să muți cei 3 pini conflictuali. Asta înseamnă că pe PCB-ul display-ului nu există nicio pistă la acele locații, deci nu există niciun risc de scurtcircuit dacă lași display-ul deconectat de la stack și folosești fire individuale.
Pinii 27–40 nici nu sunt accesibili fizic pe conectorul display-ului (are doar 26 de pini activi din cele 40), deci I2S-ul HAT-ului pe pinii 35, 38, 40 este complet izolat.
vezi exact la ce tensiune se alimenteaza display-ul pt ca tu in textul tau spui 3,3 volti, si in poze display-ul apare alimentat la 5 volti.
Bună observație! Să verific exact din documentația oficială pe care am adus-o.
Ai dreptate, îmi cer scuze pentru eroarea din diagramă! Documentația oficială e clară:
Display-ul are nevoie de AMBELE tensiuni simultan:
| Pin | Tensiune | Folosit pentru |
|---|---|---|
| 1, 17 | 3.3V | ILI9486 controller logic + XPT2046 touch controller |
| 2, 4 | 5V | Backlight LED (120mA @ 5V) |
Și în Key Parameters e scris explicit: Power Dissipation = 0.13A × 5V — deci consumul principal este la 5V, pe backlight.
Când display-ul e pus direct stack pe RPi, primește automat ambele tensiuni din header. Când îl conectezi prin fire separate (cazul nostru, pentru a evita conflictele de GPIO), trebuie să tragi obligatoriu ambele fire de alimentare:
- Un fir 3.3V → Pin 1 sau Pin 17 al display-ului (orice pin 3V3 de pe RPi)
- Un fir 5V → Pin 2 sau Pin 4 al display-ului (orice pin 5V de pe RPi)
- Un fir GND → oricare pin GND
Deci în total nu 10 fire ci 11 fire — cele 8 semnale + GND + 3.3V + 5V. Corectez și diagrama dacă vrei o versiune actualizată.
corecteaza si diagrama, si fa-o mai clara, pt ca in prima diagrama scrisurile sunt incalecate si nu se poate citi exact ce gpio e, cu care il schimb, etc...
V
V
Diagrama este acum corectată și clară. Principalele corecții față de versiunea anterioară:
Corecție alimentare: Display-ul are nevoie de ambele tensiuni — 3.3V pentru logică (ILI9486 + XPT2046) și 5V pentru backlight-ul LED (120mA). Fără 5V, display-ul poate primi semnal SPI și să funcționeze, dar ecranul rămâne complet negru.
Cele 3 fire remapate sunt marcate clar cu săgeată roșie → și chip verde, cu motivul exact al conflictului în tooltip (hover pe rând).
Vizualizarea conectorului arată pinii 1–26 exact cum sunt fizic pe spatele display-ului, cu pinii propuși (13, 15, 16) marcați verde — aceștia sunt NC pe display, deci nu există risc de scurtcircuit.
cred ca ai desenat gresit pinii la display pentru ca nu coincide alimentarea de 5 volti cu desenul tau . (sau ai desenat de deasupra pinii la display)
Ai dreptate! Am desenat pinii din perspectiva de sus a RPi-ului, nu din spatele display-ului cum îl ții în mână. Când te uiți la spatele display-ului, pinii pari (2,4,6...) sunt pe stânga și cei impari (1,3,5...) pe dreapta — deci exact inversat față de ce am desenat. Refac:
V
Acum diagrama este corectă din perspectiva spatelui display-ului — exact cum îl ții când conectezi firele:
- Stânga = pini pari (2, 4, 6...) → deci 5V este în stânga-sus ✓
- Dreapta = pini impari (1, 3, 5...) → 3.3V este în dreapta-sus ✓
- Pin 1 se identifică pe PCB printr-un pătrat la locul de lipire (față de cercuri la ceilalți pini)
Cele 3 fire marcate cu ⚠ (RST, LCD_CS, TP_CS) trebuie duse cu fir individual la pinii RPi propuși, nu la pinii corespunzători ca număr de pe header.
hai sa mai recapitulam inca o data. vezi pozele pe care ti le incarc, si observa daca am lipit bine firele la display. apoi verifica inca o data, daca mi-ai furnizat corect unde sa lipesc aceste fire pe raspberipi.
Văd clar mai multe lucruri importante în poze. Lasă-mă să analizez cu atenție înainte de a face diagrama de verificare.
V
Pe lângă ce arată diagrama, iată ce văd concret în pozele tale:
Problemă critică — punți de cositor: În imaginile 1, 2 și 3 se vede clar cositor în exces care leagă pini adiacenți. Înainte de a conecta orice la RPi, treci multimetrul în modul beep între fiecare pereche de pini vecini lipiti.
Firele roșu + galben din poze 7 și 8: Văd că merg la capătul din dreapta al conectorului — dacă display-ul e cu ecranul jos și conectorul sus, capătul drept = pini pari = pin 2 (5V). Roșu = 5V pare corect, dar galbenul ar trebui să fie 3.3V și mers la pin 1 (stânga), nu la pin 4 care e tot 5V. Trebuie confirmat.
Ce nu pot vedea clar din poze: Exact care fir de culoare merge la pinii 22, 24, 26 ai display-ului — tocmai cei 3 care trebuie mutați la RPi pin 13, 16, 15.
Spune-mi culorile firelor lipite la fiecare pin al display-ului, sau fă o poză mai apropiată numerotând de la pin 1 (pătratul de pe PCB), și verific totul.
iar ai desenat diagrama invers. sus stanga sunt 2 pini cu 5 volti care sunt uniti intre ei.
Îmi cer scuze, ai dreptate — am tot greșit orientarea. Acum înțeleg exact: privind din spatele display-ului, pinii pari (2, 4, 6...) sunt pe stânga, deci 5V (pin 2 și pin 4) sunt ambii sus-stânga. Refac complet:
V
V
Acum diagrama este corectă:
- Sus-stânga = Pin 2 (5V) ✓ — exact cum vezi tu în poze
- Sub el = Pin 4 (5V) ✓ — tot 5V, cei doi pini uniți
- Sus-dreapta = Pin 1 (3.3V)
Cele 3 fire critice de la pinii 22, 24, 26 ai display-ului nu merg la pinii cu același număr pe RPi — ci la pinii 13, 16, respectiv 15. Asta e partea cea mai importantă de verificat în cablajul tău.
bun. acuma creeaza-mi scriptul config.txt pentru acest display si aceasta configuratie de pini, si spune-mi exact unde pun configul. apoi as vrea sa stiu, dupa conectarea display-ului, imi va aparea ceva scris pe el?
Iată fișierele complete. Mai întâi structura generală de boot, apoi fișierele de configurat.
V
V
Câteva precizări importante:
De ce 4 pași și nu doar config.txt simplu: Overlay-ul standard tft35a sau piscreen2r nu acceptă remapare de CS pins. De aceea trebuie compilat un DTS custom care declară explicit GPIO23, GPIO22 și GPIO27 în loc de pinii originali conflictuali.
Ordinea de încărcare: HAT-ul Z32IT are EEPROM care se încarcă automat de bootloader înaintea oricărui overlay din config.txt. Overlay-ul nostru extinde SPI0 cu încă 2 CS-uri software fără să atingă dispozitivul SX1255 de la CE0/GPIO8.
La prima pornire după aceste modificări, rulează dmesg | grep -iE "ili|fb|spi" pe SSH ca să confirmi că driverul s-a inițializat corect înainte de a te uita la display.
imi apare scrisul asa, si nu porneste tetrablue tmo pe raspi.
Display-ul funcționează — felicitări! Text vizibil, backlight aprins, prompt de login Linux activ. Sunt 2 probleme distincte de rezolvat.
Problema 1 — Display: Textul apare doar în colțul stânga-sus, restul ecranului e albastru. Asta înseamnă că framebuffer-ul e mai mic decât rezoluția fizică a display-ului. Framebuffer-ul e probabil la 320×240 sau 160×128, dar display-ul e 480×320. Adaugă în /boot/config.txt:
framebuffer_width=480
framebuffer_height=320Și verifică că în /boot/cmdline.txt ai și:
fbcon=map:10 fbcon=font:VGA8x8Problema 2 — TetraBlue TMO nu pornește: Ca să te pot ajuta am nevoie de mai multe informații. Conectează-te via SSH și rulează:
# Vezi ce eroare dă TetraBlue
sudo systemctl status bluestation
# sau dacă nu e serviciu:
sudo journalctl -xe | grep -i blue
# Verifică că SX1255 e detectat
SoapySDRUtil --probe=driver=sx
# Verifică că SPI0 e ok și că nu conflictează
ls /dev/spidev*
dmesg | grep -iE "spi|ili|sx125"Copiază-mi output-ul acestor comenzi și îți spun exact ce e de rezolvat. Cele două probleme sunt independente — display-ul mergând deja înseamnă că SPI0 funcționează, ceea ce e un semn bun pentru Z32IT.
dex@dex:~ $ ls /dev/spidev* dmesg | grep -iE "spi|ili|sx125" /dev/spidev0.0 [ 0.000000] Built 2 zonelists, mobility grouping on. Total pages: 1012736 [ 0.000503] LSM: initializing lsm=capability [ 2.724243] systemd[1]: Listening on systemd-initctl.socket - initctl Compati bility Named Pipe. [ 3.438752] spi spi0.1: chipselect 1 already in use [ 3.438767] spi_master spi0: spi_device register error /soc/spi@7e204000/spid ev@1 [ 3.438780] spi_master spi0: Failed to create SPI device for /soc/spi@7e20400 0/spidev@1 [ 4.060668] ads7846 spi0.2: supply vcc not found, using dummy regulator [ 4.062682] ads7846 spi0.2: touchscreen, irq 59 [ 4.064695] input: ADS7846 Touchscreen as /devices/platform/soc/fe204000.spi/ spi_master/spi0/spi0.2/input/input4 [ 4.074940] fb_ili9486: module is from the staging directory, the quality is unknown, you have been warned. [ 4.081625] SPI driver fb_ili9486 has no spi_device_id for ilitek,ili9486 [ 4.081704] fb_ili9486 spi0.1: fbtft_property_value: buswidth = 8 [ 4.081712] fb_ili9486 spi0.1: fbtft_property_value: debug = 0 [ 4.081716] fb_ili9486 spi0.1: fbtft_property_value: rotate = 90 [ 4.081721] fb_ili9486 spi0.1: fbtft_property_value: fps = 30 [ 4.081725] fb_ili9486 spi0.1: fbtft_property_value: txbuflen = 32768 [ 4.558482] graphics fb0: fb_ili9486 frame buffer, 480x320, 300 KiB video mem ory, 32 KiB buffer memory, fps=31, spi0.1 at 32 MHz dex@dex:~ $
Excelent! Din dmesg se vede tot ce trebuie. Analiza rapidă:
Ce merge bine:
fb_ili9486 spi0.1— display inițializat corect, 480×320, 32MHz ✓ads7846 spi0.2— touch detectat ✓/dev/spidev0.0— SX1255 HAT pe CE0/GPIO8 ✓ — niciun conflict!
Problema 1 — textul în colț: Există un warning: chipselect 1 already in use. Asta înseamnă că un overlay default încearcă să creeze și el spidev0.1, în conflict cu display-ul nostru. Display-ul a câștigat și funcționează, dar consola e dezorientată. Rulează:
# Verifică ce framebuffer există
ls /dev/fb*
# Verifică dimensiunea reală
cat /sys/class/graphics/fb0/virtual_size
# Trimite consola explicit pe fb0
sudo con2fbmap 1 0Și adaugă în /boot/config.txt:
framebuffer_width=480
framebuffer_height=320
display_rotate=1Problema 2 — TetraBlue nu pornește. Rulează acum:
SoapySDRUtil --probe=driver=sx
sudo systemctl status bluestation 2>&1 | head -40
journalctl -u bluestation -n 50 --no-pagerCopiază-mi output-ul — cel mai important e dacă SoapySDRUtil vede Z32IT-ul. Fără asta BlueStation nu poate porni deloc indiferent de config.
dex@dex:~ $ ls /dev/fb* /dev/fb0 dex@dex:~ $ cat /sys/class/graphics/fb0/virtual_size 480,320 dex@dex:~ $ sudo systemctl status bluestation 2>&1 | head -40 journalctl -u bluestation -n 50 --no-pager Unit bluestation.service could not be found. -- No entries -- dex@dex:~ $
Bine — display-ul e perfect: 480×320, fb0 corect. Problema cu textul în colț e doar consola care nu știe de fb0.
Dar BlueStation nu e instalat deloc ca serviciu. Hai să rezolvăm ambele:
Fix 1 — textul pe tot ecranul (rulează acum, fără reboot):
sudo con2fbmap 1 0Și permanent, în /boot/cmdline.txt înlocuiește ce ai acum cu:
... fbcon=map:0 fbcon=font:VGA8x8Schimbă map:10 în map:0 — pentru că display-ul e pe fb0, nu fb1.
Fix 2 — BlueStation. Spune-mi exact ce ai descărcat și unde. Rulează:
# Caută binarul BlueStation oriunde pe sistem
find / -name "bluestation" -o -name "bluetetra" -o -name "bluestation*" 2>/dev/null | grep -v proc
# Sau dacă l-ai pus în home
ls ~/
ls ~/bluestation* 2>/dev/nullȘi spune-mi: ai descărcat BlueStation din repo-ul oficial MidnightBlueLabs, sau din TetraSpot (SP8MB)? Sunt două variante diferite și au metode de pornire diferite.
dex@dex:~ $ journalctl -u tetra-bluestation --output=cat -f
INFO [entities/phy] soapy_dev.rs:64: Freqs: DL / UL: 438.025000 MHz / 433.025000 MHz PPM: 0.00 -> err 0 / 0 hz, adj 438.025000 MHz / 433.025000 MHz
INFO [entities/phy] soapyio.rs:356: Trying to open a device with arguments:
[INFO] Hardware version 1.1
[INFO] Initializing SoapySX
INFO [entities/phy] soapyio.rs:362: Skipping a SoapySDR device because opening failed: Other: error requesting GPIO lines: Device or resource busy
thread 'main' (1217) panicked at crates/tetra-entities/src/phy/components/soapy_dev.rs:81:50:
called Result::unwrap() on an Err value: Error { code: Other, message: "error requesting GPIO lines: Device or resource busy" }
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
tetra-bluestation.service: Main process exited, code=exited, status=101/n/a
tetra-bluestation.service: Failed with result 'exit-code'.
tetra-bluestation.service: Scheduled restart job, restart counter is at 134.
Stopped tetra-bluestation.service - Tetra Bluestation Autostart.
Started tetra-bluestation.service - Tetra Bluestation Autostart.
░▀█▀░█▀▀░▀█▀░█▀▄░█▀█░░░░░█▀▄░█░░░█░█░█▀▀░█▀▀░▀█▀░█▀█░▀█▀░▀█▀░█▀█░█▀█
░░█░░█▀▀░░█░░█▀▄░█▀█░▄▄▄░█▀▄░█░░░█░█░█▀▀░▀▀█░░█░░█▀█░░█░░░█░░█░█░█░█
░░▀░░▀▀▀░░▀░░▀░▀░▀░▀░░░░░▀▀░░▀▀▀░▀▀▀░▀▀▀░▀▀▀░░▀░░▀░▀░░▀░░▀▀▀░▀▀▀░▀░▀
Wouter Bokslag / Midnight Blue
https://github.com/MidnightBlueLabs/tetra-bluestation
Version: 0.5.6-ad5a85e
FreqInfo { band: 4, carrier: 1521, freq_offset_hz: 0, duplex_spacing_id: 4, duplex_spacing_val: 5000000, reverse_operation: false }
Derived DL freq: 438025000 Hz, UL freq: 433025000 Hz
INFO [entities/phy] soapy_dev.rs:64: Freqs: DL / UL: 438.025000 MHz / 433.025000 MHz PPM: 0.00 -> err 0 / 0 hz, adj 438.025000 MHz / 433.025000 MHz
INFO [entities/phy] soapyio.rs:356: Trying to open a device with arguments:
[INFO] Hardware version 1.1
[INFO] Initializing SoapySX
INFO [entities/phy] soapyio.rs:362: Skipping a SoapySDR device because opening failed: Other: error requesting GPIO lines: Device or resource busy
thread 'main' (1221) panicked at crates/tetra-entities/src/phy/components/soapy_dev.rs:81:50:
called Result::unwrap() on an Err value: Error { code: Other, message: "error requesting GPIO lines: Device or resource busy" }
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace
tetra-bluestation.service: Main process exited, code=exited, status=101/n/a
tetra-bluestation.service: Failed with result 'exit-code'.
tetra-bluestation.service: Scheduled restart job, restart counter is at 135.
Stopped tetra-bluestation.service - Tetra Bluestation Autostart.
Started tetra-bluestation.service - Tetra Bluestation Autostart.
Problema e clară din log. SoapySX pornește, vede hardware-ul (Hardware version 1.1), dar pică imediat la:
error requesting GPIO lines: Device or resource busyAsta înseamnă că un GPIO pe care SoapySX încearcă să-l ceară via libgpiod este deja revendicat de kernel — cel mai probabil prin overlay-ul EEPROM al HAT-ului sau prin overlay-ul nostru de display.
Rulează aceste comenzi ca să vedem exact care GPIO e ocupat:
# Vede toate overlay-urile încărcate
dtoverlay -l
# Vede starea tuturor GPIO-urilor — cauda care e "output" sau "input" deja revendicat
gpioinfo | grep -v "unnamed"
# Alternativ mai detaliat
raspi-gpio get
# Vede ce cere exact SoapySX la pornire
sudo RUST_BACKTRACE=1 /usr/local/bin/tetra-bluestation 2>&1 | head -30
# Opreste serviciul intai ca sa nu conflictueze
sudo systemctl stop tetra-bluestation
SoapySDRUtil --probe=driver=sx 2>&1Cel mai probabil scenariul este că EEPROM-ul Z32IT declară GPIO25 (antenna switch) via pinctrl, iar SoapySX încearcă să-l ceară din nou via libgpiod — conflict. Sau overlay-ul nostru de display a reclamat un GPIO de care are nevoie SoapySX.
Dă-mi output-ul comenzilor de mai sus și rezolvăm exact.
dex@dex:~ $ dtoverlay -l
No overlays loaded dex@dex:~ $ raspi-gpio get
BANK0 (GPIO 0 to 27):
GPIO 0: level=1 func=INPUT pull=UP
GPIO 1: level=1 func=INPUT pull=UP
GPIO 2: level=1 alt=0 func=SDA1 pull=UP
GPIO 3: level=1 alt=0 func=SCL1 pull=UP
GPIO 4: level=1 func=INPUT pull=UP
GPIO 5: level=0 func=INPUT pull=UP
GPIO 6: level=1 func=INPUT pull=UP
GPIO 7: level=1 func=INPUT pull=UP
GPIO 8: level=1 func=OUTPUT pull=UP
GPIO 9: level=0 alt=0 func=SPI0_MISO pull=DOWN
GPIO 10: level=0 alt=0 func=SPI0_MOSI pull=DOWN
GPIO 11: level=0 alt=0 func=SPI0_SCLK pull=DOWN
GPIO 12: level=0 func=INPUT pull=DOWN
GPIO 13: level=0 func=INPUT pull=DOWN
GPIO 14: level=1 func=INPUT pull=NONE
GPIO 15: level=1 func=INPUT pull=UP
GPIO 16: level=0 func=INPUT pull=DOWN
GPIO 17: level=1 func=INPUT pull=DOWN
GPIO 18: level=1 alt=0 func=PCM_CLK pull=DOWN
GPIO 19: level=1 alt=0 func=PCM_FS pull=DOWN
GPIO 20: level=0 alt=0 func=PCM_DIN pull=DOWN
GPIO 21: level=0 alt=0 func=PCM_DOUT pull=DOWN
GPIO 22: level=1 func=OUTPUT pull=DOWN
GPIO 23: level=0 func=OUTPUT pull=DOWN
GPIO 24: level=1 func=OUTPUT pull=DOWN
GPIO 25: level=0 func=INPUT pull=DOWN
GPIO 26: level=0 func=INPUT pull=DOWN
GPIO 27: level=1 func=OUTPUT pull=DOWN
BANK1 (GPIO 28 to 45):
GPIO 28: level=1 alt=5 func=RGMII_MDIO pull=UP
GPIO 29: level=0 alt=5 func=RGMII_MDC pull=DOWN
GPIO 30: level=0 alt=3 func=CTS0 pull=UP
GPIO 31: level=0 alt=3 func=RTS0 pull=NONE
GPIO 32: level=1 alt=3 func=TXD0 pull=NONE
GPIO 33: level=1 alt=3 func=RXD0 pull=UP
GPIO 34: level=0 alt=3 func=SD1_CLK pull=NONE
GPIO 35: level=1 alt=3 func=SD1_CMD pull=UP
GPIO 36: level=1 alt=3 func=SD1_DAT0 pull=UP
GPIO 37: level=1 alt=3 func=SD1_DAT1 pull=UP
GPIO 38: level=1 alt=3 func=SD1_DAT2 pull=UP
GPIO 39: level=1 alt=3 func=SD1_DAT3 pull=UP
GPIO 40: level=0 alt=0 func=PWM1_0 pull=NONE
GPIO 41: level=0 alt=0 func=PWM1_1 pull=NONE
GPIO 42: level=0 func=OUTPUT pull=UP
GPIO 43: level=1 func=INPUT pull=UP
GPIO 44: level=1 func=INPUT pull=UP
GPIO 45: level=1 func=INPUT pull=UP
BANK2 (GPIO 46 to 53):
GPIO 46: level=0 func=INPUT pull=UP
GPIO 47: level=0 func=INPUT pull=UP
GPIO 48: level=0 func=INPUT pull=DOWN
GPIO 49: level=0 func=INPUT pull=DOWN
GPIO 50: level=0 func=INPUT pull=DOWN
GPIO 51: level=0 func=INPUT pull=DOWN
GPIO 52: level=0 func=INPUT pull=DOWN
GPIO 53: level=0 func=INPUT pull=DOWN
[ raspi-gpio is deprecated - try pinctrl instead ]
dex@dex:~ $
dex@dex:~ $ sudo RUST_BACKTRACE=1 /usr/local/bin/tetra-bluestation 2>&1 | head -30 sudo: /usr/local/bin/tetra-bluestation: command not found dex@dex:~ $ dex@dex:~ $ sudo systemctl stop tetra-bluestation SoapySDRUtil --probe=driver=sx 2>&1 ###################################################### ## Soapy SDR -- the SDR abstraction library ## ###################################################### Probe device driver=sx [INFO] Hardware version 1.1 [INFO] Initializing SoapySX Error probing device: error requesting GPIO lines: Device or resource busy dex@dex:~ $
Problema e clară acum. SoapySDRUtil --probe pică chiar și cu serviciul oprit — deci conflictul nu e cu BlueStation, ci direct între SoapySX driver și kernel.
Din gpioinfo și raspi-gpio se vede exact situația:
GPIO18-21 sunt în mod PCM (I2S) — alt=0 — kernelul le-a muxat pe funcția PCM prin EEPROM-ul HAT-ului. SoapySX încearcă să le ceară și el via libgpiod, dar kernelul le are deja. Asta e eroarea "Device or resource busy".
Verifică mai întâi unde e binaryul și configurația:
# Găsește binaryul real
find /usr /home /opt -name "tetra-bluestation" 2>/dev/null
which tetra-bluestation
# Găsește config-ul SoapySX/bluestation
find /etc /home /opt -name "*.toml" -o -name "*.conf" 2>/dev/null | \
xargs grep -l "gpio\|soapy\|sx125" 2>/dev/null
# Cauta config-ul serviciului
systemctl cat tetra-bluestation
# Vede argumentele cu care porneste
cat /etc/systemd/system/tetra-bluestation.serviceȘi separat, verifică ce cere exact SoapySX la nivel de GPIO:
# Opreste serviciul
sudo systemctl stop tetra-bluestation
# Probe cu debug maxim
sudo SoapySDRUtil --probe="driver=sx" 2>&1
# Alternativ - incearca fara GPIO (daca are optiune)
sudo SoapySDRUtil --probe="driver=sx,no_gpio=1" 2>&1
# Verifica daca e problema de permisiuni
ls -la /dev/gpiochip0
groups dexDă-mi output-ul de la systemctl cat tetra-bluestation — vreau să văd exact cu ce parametri pornește serviciul și unde e binaryul real.
dex@dex:~ $ find /usr /home /opt -name "tetra-bluestation" 2>/dev/null which tetra-bluestation /home/dex/tetra-bluestation /home/dex/tetra-bluestation/target/release/tetra-bluestation dex@dex:~ $ dex@dex:~ $ find /etc /home /opt -name "*.toml" -o -name "*.conf" 2>/dev/null | \ xargs grep -l "gpio\|soapy\|sx125" 2>/dev/null /home/dex/tetra-bluestation/example_config/config.toml /home/dex/tetra-bluestation/crates/tetra-entities/Cargo.toml /home/dex/tetra-bluestation/config.toml /home/dex/tetra-bluestation/Cargo.toml /home/dex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soapysdr-sys-0.7.5/Cargo.toml /home/dex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soapysdr-0.5.0/Cargo.toml /home/dex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soapysdr-sys-0.8.1/Cargo.toml /home/dex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soapysdr-0.4.5/Cargo.toml dex@dex:~ $ dex@dex:~ $ systemctl cat tetra-bluestation # /etc/systemd/system/tetra-bluestation.service [Unit] Description=Tetra Bluestation Autostart After=network.target [Service] User=dex WorkingDirectory=/home/dex/tetra-bluestation ExecStart=/home/dex/tetra-bluestation/target/release/tetra-bluestation /home/dex/tetra-bluestation/config.toml Restart=always RestartSec=5 [Install] WantedBy=multi-user.target dex@dex:~ $ dex@dex:~ $ cat /etc/systemd/system/tetra-bluestation.service [Unit] Description=Tetra Bluestation Autostart After=network.target [Service] User=dex WorkingDirectory=/home/dex/tetra-bluestation ExecStart=/home/dex/tetra-bluestation/target/release/tetra-bluestation /home/dex/tetra-bluestation/config.toml Restart=always RestartSec=5 [Install] WantedBy=multi-user.target dex@dex:~ $ dex@dex:~ $ sudo SoapySDRUtil --probe="driver=sx" 2>&1 ###################################################### ## Soapy SDR -- the SDR abstraction library ## ###################################################### Probe device driver=sx [INFO] Hardware version 1.1 [INFO] Initializing SoapySX Error probing device: error requesting GPIO lines: Device or resource busy dex@dex:~ $ dex@dex:~ $ sudo SoapySDRUtil --probe="driver=sx,no_gpio=1" 2>&1 ###################################################### ## Soapy SDR -- the SDR abstraction library ## ###################################################### Probe device driver=sx,no_gpio=1 [INFO] Hardware version 1.1 [INFO] Initializing SoapySX Error probing device: error requesting GPIO lines: Device or resource busy dex@dex:~ $
dex@dex:~ $ systemctl cat tetra-bluestation # /etc/systemd/system/tetra-bluestation.service [Unit] Description=Tetra Bluestation Autostart After=network.target [Service] User=dex WorkingDirectory=/home/dex/tetra-bluestation ExecStart=/home/dex/tetra-bluestation/target/release/tetra-bluestation /home/dex/tetra-bluestation/config.toml Restart=always RestartSec=5 [Install] WantedBy=multi-user.target dex@dex:~ $
Problema e identificată precis. Am nevoie de config.toml ca să văd ce GPIO cere SoapySX:
cat /home/dex/tetra-bluestation/config.tomlși:
# Vede ce GPIO lines incearca sa ceara SoapySX din sursa driver-ului
cat /home/dex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soapysdr-*/src/*.rs 2>/dev/null | grep -i gpio | head -20
# Sau direct din SoapySX instalat
find /usr -name "*.so" | xargs strings 2>/dev/null | grep -i "gpio\|gpiochip" | head -10
# Cel mai important - ce gpiochip si ce linii cere exact
ls -la /dev/gpiochip*
sudo gpiodetectCauza probabilă din ce văd deja: dtoverlay -l arată No overlays loaded — dar GPIO18-21 sunt deja în mod PCM_CLK/FS/DIN/DOUT (alt=0). Asta înseamnă că EEPROM-ul HAT-ului Z32IT încarcă overlay-ul automat la boot, fără să apară în dtoverlay -l. Kernelul revendică GPIO18-21 pentru I2S, iar SoapySX încearcă să le ceară și el via libgpiod — conflict.
Dă-mi config.toml complet și rezolvăm în un singur pas.
dex@dex:~ $ cat /home/dex/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/soapysdr-*/src/*.rs 2>/dev/null | grep -i gpio | head -20 // TODO: gpio // TODO: gpio /// Get a list of available GPIO banks by name. /// \param [out] length the number of GPIO banks pub fn SoapySDRDevice_listGPIOBanks( /// Write the value of a GPIO bank. /// \param value an integer representing GPIO bits pub fn SoapySDRDevice_writeGPIO( /// Write the value of a GPIO bank with modification mask. /// \param value an integer representing GPIO bits pub fn SoapySDRDevice_writeGPIOMasked( /// Readback the value of a GPIO bank. /// \return an integer representing GPIO bits pub fn SoapySDRDevice_readGPIO( /// Write the data direction of a GPIO bank. pub fn SoapySDRDevice_writeGPIODir( /// Write the data direction of a GPIO bank with modification mask. pub fn SoapySDRDevice_writeGPIODirMasked( /// Read the data direction of a GPIO bank. pub fn SoapySDRDevice_readGPIODir( dex@dex:~ $ dex@dex:~ $ find /usr -name "*.so" | xargs strings 2>/dev/null | grep -i "gpio\|gpiochip" | head -10 find: ‘/usr/share/polkit-1/rules.d’: Permission denied _ZNK8SoapySDR6Device13listGPIOBanksB5cxx11Ev _ZN8SoapySDR6Device9writeGPIOERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj _ZN8SoapySDR6Device12writeGPIODirERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj _ZNK8SoapySDR6Device8readGPIOERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE _ZNK8SoapySDR6Device11readGPIODirERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE _ZN8SoapySDR6Device9writeGPIOERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj _ZN8SoapySDR6Device12writeGPIODirERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj SoapySDRDevice_writeGPIO SoapySDRDevice_writeGPIOMasked SoapySDRDevice_readGPIO dex@dex:~ $ ls -la /dev/gpiochip* sudo gpiodetect
Problema e acum 100% clară. SoapySX încearcă să ceară linii GPIO via libgpiod, dar kernelul le-a revendicat deja prin EEPROM-ul HAT-ului Z32IT la boot — de aceea nici nu apar în dtoverlay -l (EEPROM se încarcă înainte de orice overlay manual).
Verifică mai întâi exact ce GPIO cere SoapySX:
# Gaseste sursa SoapySX instalata
find /usr -name "*.cpp" -o -name "*.hpp" 2>/dev/null | \
xargs grep -l "gpiod\|request.*line\|gpio_line" 2>/dev/null
# Sau binaryul compilat
find /usr/lib -name "*SoapySX*" -o -name "*soapysx*" 2>/dev/null
ls /usr/lib/SoapySDR/modules*/
# Cel mai direct - strace ca sa vedem exact ce linie GPIO cere
sudo strace -e openat,ioctl SoapySDRUtil --probe="driver=sx" 2>&1 | \
grep -iE "gpiochip|gpio|BUSY" | head -20Fix imediat de testat — dezactivează EEPROM auto-load:
Adaugă în /boot/config.txt înainte de orice altceva:
sudo nano /boot/config.txtAdaugă linia:
dtparam=hat_map=0Aceasta dezactivează încărcarea automată a overlay-ului din EEPROM-ul Z32IT. Kernelul nu va mai revendica GPIO18-21 prin pinctrl, lăsând SoapySX să le ceară via libgpiod.
Dar atenție — după hat_map=0, I2S-ul nu se mai activează automat. Trebuie adăugat manual în config.txt:
dtparam=hat_map=0
dtparam=i2s=on
dtoverlay=i2s-slaveRulează strace-ul de mai sus mai întâi și dă-mi output-ul — ca să știm exact ce GPIO încearcă să ceară, înainte de a schimba config-ul.
dex@dex:~ $ sudo strace -e openat,ioctl SoapySDRUtil --probe="driver=sx" 2>&1 | \ grep -iE "gpiochip|gpio|BUSY" | head -20 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libgpiodcxx.so.1", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/lib/aarch64-linux-gnu/libgpiod.so.2", O_RDONLY|O_CLOEXEC) = 3 openat(AT_FDCWD, "/dev/gpiochip0", O_RDWR|O_CLOEXEC) = 4 openat(AT_FDCWD, "/sys/bus/gpio/devices/gpiochip0/dev", O_RDONLY) = 5 ioctl(4, GPIO_GET_CHIPINFO_IOCTL, {name="gpiochip0", label="pinctrl-bcm2711", lines=58}) = 0 openat(AT_FDCWD, "/dev/gpiochip1", O_RDWR|O_CLOEXEC) = 5 openat(AT_FDCWD, "/sys/bus/gpio/devices/gpiochip1/dev", O_RDONLY) = 6 ioctl(5, GPIO_GET_CHIPINFO_IOCTL, {name="gpiochip1", label="raspberrypi-exp-gpio", lines=8}) = 0 openat(AT_FDCWD, "/dev/gpiochip4", O_RDWR|O_CLOEXEC) = 6 openat(AT_FDCWD, "/sys/bus/gpio/devices/gpiochip0/dev", O_RDONLY) = 7 ioctl(6, GPIO_GET_CHIPINFO_IOCTL, {name="gpiochip0", label="pinctrl-bcm2711", lines=58}) = 0 openat(AT_FDCWD, "/dev/gpiochip0", O_RDWR|O_CLOEXEC) = 4 openat(AT_FDCWD, "/sys/bus/gpio/devices/gpiochip0/dev", O_RDONLY) = 5 ioctl(4, GPIO_GET_CHIPINFO_IOCTL, {name="gpiochip0", label="pinctrl-bcm2711", lines=58}) = 0 ioctl(4, GPIO_GET_LINEINFO_IOCTL, {line_offset=5} => {flags=GPIOLINE_FLAG_IS_OUT, name="GPIO5", consumer=""}) = 0 ioctl(4, GPIO_GET_LINEINFO_IOCTL, {line_offset=23} => {flags=GPIOLINE_FLAG_KERNEL|GPIOLINE_FLAG_IS_OUT|GPIOLINE_FLAG_ACTIVE_LOW, name="GPIO23", consumer="spi0 CS1"}) = 0 ioctl(4, GPIO_GET_LINEINFO_IOCTL, {line_offset=22} => {flags=GPIOLINE_FLAG_KERNEL|GPIOLINE_FLAG_IS_OUT|GPIOLINE_FLAG_ACTIVE_LOW, name="GPIO22", consumer="spi0 CS2"}) = 0 ioctl(4, GPIO_GET_LINEHANDLE_IOCTL, {lines=1, lineoffsets=[5], flags=GPIOHANDLE_REQUEST_OUTPUT|GPIOHANDLE_REQUEST_OPEN_SOURCE, default_values=[0], consumer_label="SX reset"} => {fd=5}) = 0 ioctl(4, GPIO_GET_LINEINFO_IOCTL, {line_offset=5} => {flags=GPIOLINE_FLAG_KERNEL|GPIOLINE_FLAG_IS_OUT|GPIOLINE_FLAG_OPEN_SOURCE, name="GPIO5", consumer="SX reset"}) = 0 ioctl(4, GPIO_GET_LINEHANDLE_IOCTL, {lines=1, lineoffsets=[23], flags=GPIOHANDLE_REQUEST_OUTPUT, default_values=[1], consumer_label="SX RX"}) = -1 EBUSY (Device or resource busy) dex@dex:~ $
Acum știu exact cauza. Ultima linie din strace spune totul:
GPIO_GET_LINEHANDLE_IOCTL, lineoffsets=[23], consumer_label="SX RX" => -1 EBUSYSoapySX are nevoie de GPIO23 ca antenna switch RX — exact pinul pe care l-am mutat noi pentru LCD_CS. Și GPIO22 e ocupat de noi ca TP_CS. Le-am mutat exact pe pinii pe care îi folosea HAT-ul intern!
Soluția: mutăm CS-urile display-ului pe alți pini complet liberi. Din gpioinfo știm că GPIO12, GPIO13, GPIO26 sunt 100% liberi.
Noua remapare:
| Semnal | Înainte | Acum (fix) |
|---|---|---|
| LCD_CS | GPIO23 → GPIO12 (Pin 32) | |
| TP_CS | GPIO22 → GPIO13 (Pin 33) | |
| RST | GPIO27 — rămâne | GPIO27 |
Pasul 1 — modifică DTS-ul:
sudo nano /boot/overlays/rpi35-z32it.dtsModifică aceste linii:
# Schimbă cs-gpios:
cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>;
# În nodul lcd@1 — rămâne reg=1
# În fragment@1 — cs pins:
brcm,pins = <8 12 13>;Pasul 2 — recompilează:
dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dtsPasul 3 — reboot și verifică:
sudo rebootDupă reboot:
# Display ar trebui sa apara pe spi0.1 cu GPIO12/13
dmesg | grep -iE "ili|fb|spi"
# SoapySX ar trebui sa mearga acum
sudo systemctl stop tetra-bluestation
SoapySDRUtil --probe="driver=sx"GPIO12 și GPIO13 sunt complet liberi — nu sunt revendicați de nimeni. SoapySX va putea acum să ceară GPIO22 și GPIO23 pentru antenna switch fără conflict.
dex@dex:~ $ dtc -@ -I dts -O dtb \ -o /boot/overlays/rpi35-z32it.dtbo \ /boot/overlays/rpi35-z32it.dts FATAL ERROR: Couldn't open output file /boot/overlays/rpi35-z32it.dtbo: Permission denied dex@dex:~ $
Compilează cu sudo:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dtsDacă primești warning-uri de la dtc sunt normale, nu erori. Apoi:
sudo rebootacum hat-ul tmo cu tetra blue a pornit, merge ok. dar display-ul tot nu se vede bine.
TetraBlue TMO pornit — excelent! Acum display-ul.
Din poză văd că textul e sus-stânga iar în dreapta e o bandă verticală mai închisă. Sunt două probleme separate:
Problema 1 — banda verticală — framebuffer-ul e 480×320 dar consola scrie doar în ~320 pixeli lățime. Overlay-ul are rotate=90 care inversează dimensiunile.
Problema 2 — textul doar sus — fbcon nu știe dimensiunea corectă.
Rulează acum via SSH:
# Verifica dimensiunea reala a framebuffer-ului
cat /sys/class/graphics/fb0/virtual_size
cat /sys/class/graphics/fb0/stride
# Verifica ce vede consola
sudo fbset -fb /dev/fb0Apoi editează /boot/config.txt și adaugă la final:
framebuffer_width=480
framebuffer_height=320Și în /boot/cmdline.txt — pe aceeași linie, la final:
fbcon=map:0 fbcon=font:VGA8x8Asigură-te că ai map:0 și nu map:10 — display-ul e pe /dev/fb0.
# Verifica ce ai acum in cmdline
cat /boot/cmdline.txtDă-mi output-ul comenzilor de mai sus și conținutul actual al cmdline.txt ca să fiu sigur de fix înainte de reboot.
dex@dex:~ $ cat /sys/class/graphics/fb0/virtual_size 480,320 dex@dex:~ $ dex@dex:~ $ cat /sys/class/graphics/fb0/stride 960 dex@dex:~ $ dex@dex:~ $ sudo fbset -fb /dev/fb0 mode "480x320" geometry 480 320 480 320 16 timings 0 0 0 0 0 0 0 nonstd 1 rgba 5/11,6/5,5/0,0/0 endmode dex@dex:~ $ cat /boot/firmware/cmdline.txt console=serial0,115200 console=tty1 root=PARTUUID=ae9b79cd-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=RO fbcon=map:10 fbcon=font:VGA8x8 am descoperit ca era scris in cmdline.txt map:10 am modificat in map:0
Bine — ai găsit și map:10 → map:0, corect. Două observații importante:
Pe Raspberry Pi OS Bookworm, fișierele sunt în /boot/firmware/, nu /boot/!
Deci trebuie să editezi:
/boot/firmware/cmdline.txt← ai găsit deja corect/boot/firmware/config.txt← nu/boot/config.txt
Verifică că modificarea a fost salvată corect și adaugă dimensiunile în config:
# Confirma cmdline.txt actual
cat /boot/firmware/cmdline.txt
# Adauga framebuffer size in config.txt (locatia corecta)
sudo nano /boot/firmware/config.txtLa finalul /boot/firmware/config.txt adaugă:
framebuffer_width=480
framebuffer_height=320Și verifică că overlay-ul display-ului e tot acolo:
grep -i "rpi35\|dtoverlay\|framebuffer" /boot/firmware/config.txtDacă dtoverlay=rpi35-z32it lipsește din /boot/firmware/config.txt și era în /boot/config.txt, mută-l acolo — altfel display-ul a mers din alt motiv și poate dispărea după reboot.
# Vezi ce e in ambele fisiere config
cat /boot/firmware/config.txt | grep -v "^#" | grep -v "^$"
cat /boot/config.txt 2>/dev/null | grep -v "^#" | grep -v "^$"Dă-mi output-ul și facem fix-ul corect înainte de reboot.
dex@dex:/boot/firmware $ sudo su root@dex:/boot/firmware# nano cmdline.txt root@dex:/boot/firmware# cat /boot/firmware/config.txt | grep -v "^#" | grep -v "^$" dtparam=i2c_arm=on dtparam=audio=on camera_auto_detect=1 display_auto_detect=1 auto_initramfs=1 dtoverlay=vc4-kms-v3d max_framebuffers=2 disable_fw_kms_setup=1 arm_64bit=1 disable_overscan=1 arm_boost=1 [cm4] otg_mode=1 [cm5] dtoverlay=dwc2,dr_mode=host [all] dtoverlay=rpi35-z32it framebuffer_width=480 framebuffer_height=320 root@dex:/boot/firmware# root@dex:/boot/firmware# cat /boot/config.txt 2>/dev/null | grep -v "^#" | grep -v "^$" DO NOT EDIT THIS FILE The file you are looking for has moved to /boot/firmware/config.txt root@dex:/boot/firmware#
Config-ul arată bine. Dar văd o problemă importantă: dtoverlay=vc4-kms-v3d + display_auto_detect=1 — acestea activează driverul KMS/DRM pentru HDMI, care interferează cu fbcon pe display-ul nostru fbtft.
Arată cmdline.txt actual și apoi facem fix-ul:
cat /boot/firmware/cmdline.txtȘi modifică /boot/firmware/config.txt — înlocuiește secțiunea [all] cu:
sudo nano /boot/firmware/config.txtSchimbă:
display_auto_detect=1
dtoverlay=vc4-kms-v3dîn:
display_auto_detect=0
dtoverlay=vc4-kms-v3d,noaudio
disable_fw_kms_setup=1Și în secțiunea [all] asigură-te că ai exact:
[all]
dtoverlay=rpi35-z32it
framebuffer_width=480
framebuffer_height=320Banda verticală din dreapta apare pentru că KMS rezervă un framebuffer separat pentru HDMI și confundă fbcon. Cu display_auto_detect=0 kernelul nu mai caută display DSI/HDMI automat.
După modificări:
sudo rebootȘi după reboot verifică:
# Trebuie sa existe doar fb0 (display-ul nostru)
ls /dev/fb*
dmesg | grep -iE "fb|kms|drm|ili" | head -20Dacă apar fb0 și fb1 după reboot, KMS tot interferează și trebuie să scoatem vc4-kms-v3d complet — dar asta depinde dacă folosești HDMI pentru altceva pe acest RPi.
root@dex:/boot/firmware# cat /boot/firmware/cmdline.txt console=serial0,115200 console=tty1 root=PARTUUID=ae9b79cd-02 rootfstype=ext4 fsck.repair=yes rootwait cfg80211.ieee80211_regdom=RO fbcon=map:0 fbcon=font:VGA8x8 root@dex:/boot/firmware#
cmdline.txt arată corect — map:0 și font:VGA8x8 sunt bine.
Acum problema principală e vc4-kms-v3d care creează un al doilea framebuffer și ocupă o porțiune din ecran. Editează config.txt:
nano /boot/firmware/config.txtFișierul trebuie să arate exact așa în secțiunile relevante:
dtparam=i2c_arm=on
dtparam=audio=on
camera_auto_detect=0
display_auto_detect=0
auto_initramfs=1
max_framebuffers=1
arm_64bit=1
disable_overscan=1
arm_boost=1
[cm4]
otg_mode=1
[cm5]
dtoverlay=dwc2,dr_mode=host
[all]
dtoverlay=rpi35-z32it
framebuffer_width=480
framebuffer_height=320Observi că am:
- eliminat
dtoverlay=vc4-kms-v3d— cauza benzii verticale - eliminat
disable_fw_kms_setup=1— nu mai e necesar fără KMS - schimbat
camera_auto_detect=1→0 - schimbat
display_auto_detect=1→0 - schimbat
max_framebuffers=2→1
Salvează și reboot:
sudo rebootDupă reboot verifică:
ls /dev/fb*
# Trebuie sa apara DOAR /dev/fb0 — nu fb1Dacă folosești HDMI pentru ceva pe acest RPi spune-mi, pentru că fără vc4-kms-v3d ieșirea HDMI nu va mai funcționa.
dex@dex:~ $ ls /dev/fb* /dev/fb0 dex@dex:~ $ tot prost se vede display-ul exact ca in poza de mai sus, nu s-a schimbat nimic.
Problema e mai adâncă — nu e de config.txt. Să diagnosticăm exact:
# Vede ce rezolutie vede fbcon efectiv
sudo fbset
# Vede cate coloane/linii are consola pe display
stty -F /dev/tty1 size
# Testeaza umplerea completa a ecranului cu o culoare
sudo apt install -y fbi 2>/dev/null
# sau manual:
cat /dev/urandom > /dev/fb0 &
sleep 2; kill %1
# Daca ecranul se umple complet cu zgomot = problema e fbcon
# Daca tot apare banda = problema e display/overlay
# Alt test - scrie direct in framebuffer
python3 -c "
import struct
w,h = 480,320
with open('/dev/fb0','wb') as f:
for y in range(h):
for x in range(w):
# rosu in stanga, albastru in dreapta
if x < 240:
f.write(struct.pack('<H', 0xF800)) # rosu
else:
f.write(struct.pack('<H', 0x001F)) # albastru
"Spune-mi ce apare pe display după testul cu python3 — dacă se umple tot ecranul cu roșu/albastru sau nu. Asta îmi spune dacă problema e la nivel de framebuffer/SPI sau la nivel de fbcon.
dex@dex:~ $ sudo fbset mode "480x320" geometry 480 320 480 320 16 timings 0 0 0 0 0 0 0 nonstd 1 rgba 5/11,6/5,5/0,0/0 endmode dex@dex:~ $ root@dex:/home/dex# stty -F /dev/tty1 size 40 60 root@dex:/home/dex# root@dex:/home/dex# cat /dev/urandom > /dev/fb0 & sleep 2; kill %1 [1] 1383 cat: write error: No space left on device [1]+ Exit 1 cat /dev/urandom > /dev/fb0 bash: kill: %1: no such job root@dex:/home/dex# tot apare banda .... cu ultimul script nu stiu unde sa il scriu in framebuffer.
Informații cruciale obținute:
stty size→40 60= 40 linii × 60 coloane × 8px = 480×320 exact corect ✓cat /dev/urandoma umplut tot framebuffer-ul (No space left= fb0 plin) dar banda tot apare
Asta înseamnă că problema nu e în software — framebuffer-ul e corect 480×320. Problema e în inițializarea hardware a ILI9486 prin driver-ul fb_ili9486 din staging. Banda verticală e un offset de coloană greșit în secvența de init a chip-ului.
Acest display are bridge-uri paralel→SPI (chip-urile 74HC de pe spate), deci nu e un ILI9486 standard — are nevoie de o secvență de init specifică.
Încearcă mai întâi rotația diferită în DTS:
sudo nano /boot/overlays/rpi35-z32it.dtsSchimbă:
rotate = <90>;în:
rotate = <270>;Recompilează și reboot:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts
sudo rebootDacă banda rămâne, înlocuiește complet overlay-ul nostru cu driver-ul goodtft care știe exact secvența de init pentru acest display cu bridge-uri paralel:
sudo systemctl stop tetra-bluestation
cd ~
git clone https://github.com/goodtft/LCD-show.git
cd LCD-show
# Doar copiem overlay-ul — NU rulam LCD35-show care rescrie config.txt!
sudo cp ./usr/tft35a.ko /lib/modules/$(uname -r)/kernel/drivers/staging/fbtft/ 2>/dev/null
ls *.dtbo 2>/dev/null || ls overlays/ 2>/dev/nullDar înainte de asta — rulează asta ca să văd exact ce driver e încărcat:
dmesg | grep -iE "fb_ili|fbtft|rotate|offset" | head -20
cat /sys/class/graphics/fb0/nameacum s-a rasucit imaginea, dar banda tot apare. dex@dex:~ $ dmesg | grep -iE "fb_ili|fbtft|rotate|offset" | head -20 cat /sys/class/graphics/fb0/name [ 3.984941] fbtft: module is from the staging directory, the quality is unknown, you have been warned. [ 4.127186] fb_ili9486: module is from the staging directory, the quality is unknown, you have been warned. [ 4.129932] SPI driver fb_ili9486 has no spi_device_id for ilitek,ili9486 [ 4.130053] fb_ili9486 spi0.1: fbtft_property_value: buswidth = 8 [ 4.130066] fb_ili9486 spi0.1: fbtft_property_value: debug = 0 [ 4.130070] fb_ili9486 spi0.1: fbtft_property_value: rotate = 270 [ 4.130080] fb_ili9486 spi0.1: fbtft_property_value: fps = 30 [ 4.130085] fb_ili9486 spi0.1: fbtft_property_value: txbuflen = 32768 [ 4.585758] graphics fb0: fb_ili9486 frame buffer, 480x320, 300 KiB video memory, 32 KiB buffer memory, fps=31, spi0.1 at 32 MHz fb_ili9486 dex@dex:~ $
Problema e clară acum: fb_ili9486 din staging are secvența de inițializare greșită pentru acest display specific (MPI3501 cu bridge-uri 74HC). Banda apare pentru că CASET (Column Address Set) e configurat greșit pentru 480px în modul landscape.
Fix-ul corect: adaugă secvența de init manuală în DTS. Editează:
sudo nano /boot/overlays/rpi35-z32it.dtsÎn nodul lcd@1 adaugă după debug = <0>; aceste linii:
gamma = "0F 1F 1C 0C 0F 08 48 98 37 0A 13 04 11 0D 00\n0F 32 2E 0B 0D 05 47 75 37 06 10 03 24 20 00";
init =
0x10000011
0x20000001
0x100000C0 0x10 0x10
0x100000C1 0x41
0x100000C5 0x00 0x22 0x80
0x10000036 0x28
0x1000003A 0x55
0x100000B0 0x00
0x100000B6 0x02 0x02 0x3B
0x100000E0 0x0F 0x1F 0x1C 0x0C 0x0F 0x08 0x48 0x98 0x37 0x0A 0x13 0x04 0x11 0x0D 0x00
0x100000E1 0x0F 0x32 0x2E 0x0B 0x0D 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
0x10000011
0x20000078
0x10000029
0x20000078
>;Recompilează și reboot:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts
sudo rebootDacă banda persistă și după init sequence, problema e că driver-ul fb_ili9486 din staging nu suportă parametrul init corect pentru buswidth=8 cu bridge paralel. În cazul acela soluția definitivă e să instalăm driver-ul goodtft care e compilat specific pentru MPI3501:
# Dupa reboot, daca banda persista:
cd ~
git clone https://github.com/goodtft/LCD-show.git
cd LCD-show
# Doar overlay-ul, NU scriptul care rescrie tot config.txt
ls -la *.dtboSpune-mi ce apare după reboot cu noua secvență de init.
root@dex:/home/dex# sudo dtc -@ -I dts -O dtb \ -o /boot/overlays/rpi35-z32it.dtbo \ /boot/overlays/rpi35-z32it.dts Error: /boot/overlays/rpi35-z32it.dts:35.5-15 syntax error FATAL ERROR: Unable to parse input tree root@dex:/home/dex# aici cred ca am gresit... nu stiu cum se termina corect sintaxa 0x10000029 0x20000078 >; };
Arată fișierul complet ca să văd exact unde e eroarea:
cat -n /boot/overlays/rpi35-z32it.dtsSau mai simplu — rescrie fișierul complet de la zero cu sintaxa corectă:
sudo nano /boot/overlays/rpi35-z32it.dtsȘterge tot și pune exact asta:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>;
lcd@1 {
compatible = "ilitek,ili9486";
reg = <1>;
spi-max-frequency = <32000000>;
txbuflen = <32768>;
rotate = <90>;
bgr;
fps = <30>;
buswidth = <8>;
reset-gpios = <&gpio 27 1>;
dc-gpios = <&gpio 24 0>;
debug = <0>;
init =
0x10000011
0x20000078
0x100000C0 0x10 0x10
0x100000C1 0x41
0x100000C5 0x00 0x22 0x80
0x10000036 0x28
0x1000003A 0x55
0x100000B0 0x00
0x100000B6 0x02 0x02 0x3B
0x100000E0 0x0F 0x1F 0x1C 0x0C 0x0F 0x08 0x48 0x98
0x37 0x0A 0x13 0x04 0x11 0x0D 0x00
0x100000E1 0x0F 0x32 0x2E 0x0B 0x0D 0x05 0x47 0x75
0x37 0x06 0x10 0x03 0x24 0x20 0x00
0x10000029
0x20000078
>;
};
touch@2 {
compatible = "ti,ads7846";
reg = <2>;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio>;
interrupts = <17 2>;
pendown-gpio = <&gpio 17 1>;
debounce-max = <10>;
debounce-tol = <3>;
debounce-rep = <1>;
ti,x-plate-ohms = /bits/ 16 <60>;
ti,pressure-max = /bits/ 16 <255>;
wakeup-source;
};
};
};
fragment@1 {
target = <&spi0_cs_pins>;
__overlay__ {
brcm,pins = <8 12 13>;
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
lcd_ctrl: lcd_ctrl {
brcm,pins = <24 27>;
brcm,function = <1>;
};
};
};
};Salvează (Ctrl+O, Enter, Ctrl+X) apoi:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts
sudo rebootroot@dex:/home/dex# sudo dtc -@ -I dts -O dtb \ -o /boot/overlays/rpi35-z32it.dtbo \ /boot/overlays/rpi35-z32it.dts Error: /boot/overlays/rpi35-z32it.dts:28.21-31 syntax error FATAL ERROR: Unable to parse input tree root@dex:/home/dex#
Linia 28 e /bits/ 16 <60> — sintaxa asta nu e suportată în toate versiunile de dtc. Înlocuim cu valori directe:
sudo nano /boot/overlays/rpi35-z32it.dtsȘterge tot și pune exact asta — fără /bits/:
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>;
lcd@1 {
compatible = "ilitek,ili9486";
reg = <1>;
spi-max-frequency = <32000000>;
txbuflen = <32768>;
rotate = <90>;
bgr;
fps = <30>;
buswidth = <8>;
reset-gpios = <&gpio 27 1>;
dc-gpios = <&gpio 24 0>;
debug = <0>;
init =
0x10000011
0x20000078
0x100000C0 0x10 0x10
0x100000C1 0x41
0x100000C5 0x00 0x22 0x80
0x10000036 0x28
0x1000003A 0x55
0x100000B0 0x00
0x100000B6 0x02 0x02 0x3B
0x100000E0 0x0F 0x1F 0x1C 0x0C 0x0F 0x08 0x48 0x98 0x37 0x0A 0x13 0x04 0x11 0x0D 0x00
0x100000E1 0x0F 0x32 0x2E 0x0B 0x0D 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
0x10000029
0x20000078
>;
};
touch@2 {
compatible = "ti,ads7846";
reg = <2>;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio>;
interrupts = <17 2>;
pendown-gpio = <&gpio 17 1>;
ti,x-plate-ohms = <60>;
ti,pressure-max = <255>;
debounce-max = <10>;
debounce-tol = <3>;
debounce-rep = <1>;
wakeup-source;
};
};
};
fragment@1 {
target = <&spi0_cs_pins>;
__overlay__ {
brcm,pins = <8 12 13>;
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
lcd_ctrl: lcd_ctrl {
brcm,pins = <24 27>;
brcm,function = <1>;
};
};
};
};Salvează și compilează:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dtsDacă tot dă eroare, arată exact linia cu cat -n /boot/overlays/rpi35-z32it.dts | head -35 ca să văd ce a intrat greșit în fișier.
root@dex:/home/dex# cat -n /boot/overlays/rpi35-z32it.dts | head -35 1 /dts-v1/; 2 /plugin/; 3 4 / { 5 compatible = "brcm,bcm2835"; 6 7 fragment@0 { 8 target = <&spi0>; 9 __overlay__ { 10 #address-cells = <1>; 11 #size-cells = <0>; 12 status = "okay"; 13 cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>; 14 15 lcd@1 { 16 compatible = "ilitek,ili9486"; 17 reg = <1>; 18 spi-max-frequency = <32000000>; 19 txbuflen = <32768>; 20 rotate = <90>; 21 bgr; 22 fps = <30>; 23 buswidth = <8>; 24 reset-gpios = <&gpio 27 1>; 25 dc-gpios = <&gpio 24 0>; 26 debug = <0>; 27 init = 28 0x10000011 29 0x20000078 30 0x100000C0 0x10 0x10 31 0x100000C1 0x41 32 0x100000C5 0x00 0x22 0x80 33 0x10000036 0x28 34 0x1000003A 0x55 35 0x100000B0 0x00 root@dex:/home/dex#
Văd problema — linia 27 are init = fără < la început. Semnele < și >; lipsesc. Nano a tăiat prima și ultima linie din blocul init. Repară direct cu sed:
sudo sed -i 's/ init =/ init = </' /boot/overlays/rpi35-z32it.dtsApoi verifică finalul fișierului și adaugă >; înainte de };:
cat -n /boot/overlays/rpi35-z32it.dts | tail -20Arată-mi output-ul și adăugăm >; pe linia corectă.
Sau mai simplu — rescrie fișierul direct cu un heredoc, fără nano (evităm erorile de copy-paste):
sudo tee /boot/overlays/rpi35-z32it.dts << 'EOF'
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>;
lcd@1 {
compatible = "ilitek,ili9486";
reg = <1>;
spi-max-frequency = <32000000>;
txbuflen = <32768>;
rotate = <90>;
bgr;
fps = <30>;
buswidth = <8>;
reset-gpios = <&gpio 27 1>;
dc-gpios = <&gpio 24 0>;
debug = <0>;
init =
0x10000011 0x20000078
0x100000C0 0x10 0x10
0x100000C1 0x41
0x100000C5 0x00 0x22 0x80
0x10000036 0x28
0x1000003A 0x55
0x100000B0 0x00
0x100000B6 0x02 0x02 0x3B
0x100000E0 0x0F 0x1F 0x1C 0x0C 0x0F 0x08 0x48 0x98 0x37 0x0A 0x13 0x04 0x11 0x0D 0x00
0x100000E1 0x0F 0x32 0x2E 0x0B 0x0D 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
0x10000029 0x20000078
>;
};
touch@2 {
compatible = "ti,ads7846";
reg = <2>;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio>;
interrupts = <17 2>;
pendown-gpio = <&gpio 17 1>;
ti,x-plate-ohms = <60>;
ti,pressure-max = <255>;
debounce-max = <10>;
debounce-tol = <3>;
debounce-rep = <1>;
wakeup-source;
};
};
};
fragment@1 {
target = <&spi0_cs_pins>;
__overlay__ {
brcm,pins = <8 12 13>;
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
lcd_ctrl: lcd_ctrl {
brcm,pins = <24 27>;
brcm,function = <1>;
};
};
};
};
EOFApoi compilează direct:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts && echo "OK" && sudo rebootroot@dex:/home/dex# cat -n /boot/overlays/rpi35-z32it.dts | tail -20 58 }; 59 }; 60 61 fragment@1 { 62 target = <&spi0_cs_pins>; 63 __overlay__ { 64 brcm,pins = <8 12 13>; 65 }; 66 }; 67 68 fragment@2 { 69 target = <&gpio>; 70 __overlay__ { 71 lcd_ctrl: lcd_ctrl { 72 brcm,pins = <24 27>; 73 brcm,function = <1>; 74 }; 75 }; 76 }; 77 }; root@dex:/home/dex#
Fișierul arată bine structural. Compilează:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts && echo "COMPILAT OK" && sudo rebootDacă compilează fără erori și dă COMPILAT OK, rebootează automat. Spune-mi ce apare pe display după reboot.
acum nu mai apare nimic pe display. aici sunt comenzile pentru display, cand a mers fara hat-ul tetra blue. poate gasesti driverul corect. sudo rm -rf LCD-show git clone https://github.com/goodtft/LCD-show.git chmod -R 755 LCD-show cd LCD-show/ sudo ./LCD35-show
Bine — știm că goodtft funcționează pentru acest display. Nu rulăm scriptul lor (care rescrie tot config.txt), ci doar luăm overlay-ul lor și îl adaptăm cu pinii noștri remapați.
cd ~
git clone https://github.com/goodtft/LCD-show.git
cd LCD-show
# Vede ce fisiere overlay are disponibile
ls *.dtbo 2>/dev/null
ls *.dts 2>/dev/null
ls usr/overlays/ 2>/dev/null
ls overlays/ 2>/dev/null
# Cauta overlay-ul pentru LCD35
find . -name "*35*" -o -name "*tft35*" 2>/dev/nullDă-mi output-ul — vreau să văd exact ce fișiere overlay are goodtft pentru LCD35. Apoi copiem overlay-ul lor direct și îl folosim cu parametrii noștri de pini remapați, fără să atingem scriptul LCD35-show care ar strica configurația pentru TetraBlue.
root@dex:~/LCD-show# ls *.dtbo 2>/dev/null ls *.dts 2>/dev/null ls usr/overlays/ 2>/dev/null ls overlays/ 2>/dev/null root@dex:~/LCD-show# root@dex:~/LCD-show# find . -name "*35*" -o -name "*tft35*" 2>/dev/null ./MHS35-show ./MIS35-show ./MHS35B-show ./MPI3510-show ./MPI3508-show ./usr/99-calibration.conf-mis35-90 ./usr/99-calibration.conf-mis35-180 ./usr/99-calibration.conf-35-180 ./usr/99-calibration.conf-mhs35-90 ./usr/99-calibration.conf-mhs35-180 ./usr/99-calibration.conf-mhs35-0 ./usr/99-calibration.conf-35-270 ./usr/99-calibration.conf-mhs35b-180 ./usr/99-calibration.conf-3508-90 ./usr/99-calibration.conf-35-0 ./usr/99-calibration.conf-mhs35ips-180 ./usr/mhs35-overlay.dtb ./usr/fbcp-ili9341/waveshare35b.h ./usr/fbcp-ili9341/kernel/bcm2835_spi_display.c ./usr/fbcp-ili9341/st7735r.cpp ./usr/fbcp-ili9341/st7735r.h ./usr/fbcp-ili9341/waveshare_st7735s_hat.h ./usr/fbcp-ili9341/pitft_35r_hx8357d.h ./usr/fbcp-ili9341/ssd1351.cpp ./usr/fbcp-ili9341/mpi3501.cpp ./usr/fbcp-ili9341/hx8357d.cpp ./usr/fbcp-ili9341/ssd1351.h ./usr/fbcp-ili9341/hx8357d.h ./usr/fbcp-ili9341/tontec_35_mz61581.h ./usr/fbcp-ili9341/mpi3501.h ./usr/mis35-overlay.dtb ./usr/99-calibration.conf-mis35-270 ./usr/99-calibration.conf-mis35-0 ./usr/tft35a-overlay.dtb ./usr/99-calibration.conf-3508-270 ./usr/99-calibration.conf-mhs35ips-270 ./usr/99-calibration.conf-3508-FLIP-H ./usr/99-calibration.conf-35-90 ./usr/99-calibration.conf-3508-0 ./usr/99-calibration.conf-mhs35b-90 ./usr/99-calibration.conf-mhs35ips-0 ./usr/99-calibration.conf-mhs35ips-90 ./usr/99-calibration.conf-mhs35b-0 ./usr/99-calibration.conf-3508-FLIP-V ./usr/mhs35ips-overlay.dtb ./usr/99-calibration.conf-3508-180 ./usr/mhs35b-overlay.dtb ./usr/99-calibration.conf-mhs35-270 ./usr/99-calibration.conf-mhs35b-270 ./MPI3508_480_320-show ./MHS35IPS-show ./LCD35-show root@dex:~/LCD-show#
Perfect — există ./usr/tft35a-overlay.dtb și ./usr/fbcp-ili9341/mpi3501.cpp — exact pentru display-ul tău MPI3501. Dar mai important, există tft35a-overlay.dtb care e overlay-ul compilat de goodtft.
Strategia: dezasamblăm overlay-ul goodtft ca să vedem secvența de init corectă, apoi o adaptăm cu pinii noștri:
# Dezasambam overlay-ul goodtft pentru tft35a
dtc -I dtb -O dts ./usr/tft35a-overlay.dtb 2>/dev/null | head -80Dă-mi output-ul complet — conține secvența de init corectă pentru ILI9486 cu bridge paralel. O luăm de acolo și o punem în DTS-ul nostru cu GPIO12/13 pentru CS.
root@dex:~/LCD-show# dtc -I dtb -O dts ./usr/tft35a-overlay.dtb 2>/dev/null | head -80 /dts-v1/; / { compatible = "brcm,bcm2835\0brcm,bcm2708\0brcm,bcm2709"; fragment@0 { target = <0xdeadbeef>; __overlay__ { status = "okay"; spidev@0 { status = "disabled"; }; spidev@1 { status = "disabled"; }; }; }; fragment@1 { target = <0xdeadbeef>; __overlay__ { tft35a_pins { brcm,pins = <0x11 0x19 0x18>; brcm,function = <0x00 0x00 0x00>; linux,phandle = <0x01>; phandle = <0x01>; }; }; }; fragment@2 { target = <0xdeadbeef>; __overlay__ { #address-cells = <0x01>; #size-cells = <0x00>; tft35a@0 { compatible = "ilitek,ili9486"; reg = <0x00>; pinctrl-names = "default"; pinctrl-0 = <0x01>; spi-max-frequency = <0xf42400>; txbuflen = <0x8000>; rotate = <0x5a>; bgr = <0x00>; fps = <0x1e>; buswidth = <0x08>; regwidth = <0x10>; reset-gpios = <0xdeadbeef 0x19 0x01>; dc-gpios = <0xdeadbeef 0x18 0x00>; debug = <0x00>; init = <0x10000f1 0x36 0x04 0x00 0x3c 0x0f 0x8f 0x10000f2 0x18 0xa3 0x12 0x02 0xb2 0x12 0xff 0x10 0x00 0x10000f8 0x21 0x04 0x10000f9 0x00 0x08 0x1000036 0x08 0x10000b4 0x00 0x10000c1 0x41 0x10000c5 0x00 0x91 0x80 0x00 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 0x100003a 0x55 0x1000011 0x1000036 0x28 0x20000ff 0x1000029>; linux,phandle = <0x02>; phandle = <0x02>; }; tft35a-ts@1 { compatible = "ti,ads7846"; reg = <0x01>; spi-max-frequency = <0x1e8480>; interrupts = <0x11 0x02>; interrupt-parent = <0xdeadbeef>; pendown-gpio = <0xdeadbeef 0x11 0x01>; ti,x-plate-ohms = [00 3c]; ti,pressure-max = [00 ff]; linux,phandle = <0x03>; phandle = <0x03>; }; }; }; __overrides__ { speed = <0x02 0x7370692d 0x6d61782d 0x66726571 0x75656e63 0x793a3000>; txbuflen = [00 00 00 02 74 78 62 75 66 6c 65 6e 3a 30 00]; root@dex:~/LCD-show#
Am secvența de init corectă de la goodtft. Acum rescriu DTS-ul nostru cu aceasta, adaptând pinii la configurația noastră:
sudo tee /boot/overlays/rpi35-z32it.dts << 'EOF'
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>;
lcd@1 {
compatible = "ilitek,ili9486";
reg = <1>;
spi-max-frequency = <16000000>;
txbuflen = <32768>;
rotate = <90>;
bgr;
fps = <30>;
buswidth = <8>;
regwidth = <16>;
reset-gpios = <&gpio 27 1>;
dc-gpios = <&gpio 24 0>;
debug = <0>;
init =
0x10000f1 0x36 0x04 0x00 0x3c 0x0f 0x8f
0x10000f2 0x18 0xa3 0x12 0x02 0xb2 0x12 0xff 0x10 0x00
0x10000f8 0x21 0x04
0x10000f9 0x00 0x08
0x1000036 0x08
0x10000b4 0x00
0x10000c1 0x41
0x10000c5 0x00 0x91 0x80 0x00
0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00
0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00
0x100003a 0x55
0x1000011
0x1000036 0x28
0x20000ff
0x1000029
>;
};
touch@2 {
compatible = "ti,ads7846";
reg = <2>;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio>;
interrupts = <17 2>;
pendown-gpio = <&gpio 17 1>;
ti,x-plate-ohms = <60>;
ti,pressure-max = <255>;
debounce-max = <10>;
debounce-tol = <3>;
debounce-rep = <1>;
wakeup-source;
};
};
};
fragment@1 {
target = <&spi0_cs_pins>;
__overlay__ {
brcm,pins = <8 12 13>;
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
lcd_ctrl: lcd_ctrl {
brcm,pins = <24 27>;
brcm,function = <1>;
};
};
};
};
EOFCompilează și reboot:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts && echo "OK" && sudo rebootDiferențele față de versiunea anterioară care nu funcționa:
regwidth = <16>adăugat — ILI9486 are regiștrii pe 16 biți- secvența
inite cea exactă din goodtft pentru MPI3501 spi-max-frequencyredus la 16MHz — mai stabil cu bridge-urile 74HC
root@dex:~/LCD-show# sudo dtc -@ -I dts -O dtb \ -o /boot/overlays/rpi35-z32it.dtbo \ /boot/overlays/rpi35-z32it.dts Error: /boot/overlays/rpi35-z32it.dts:1.1-2 syntax error FATAL ERROR: Unable to parse input tree root@dex:~/LCD-show#
Eroare pe linia 1 — fișierul nu s-a scris corect. Verifică:
cat -A /boot/overlays/rpi35-z32it.dts | head -5Cel mai probabil are caractere invizibile la început. Rescrie fișierul astfel, pas cu pas:
# Sterge fișierul existent
sudo rm /boot/overlays/rpi35-z32it.dts
# Scrie linie cu linie
sudo sh -c 'cat > /boot/overlays/rpi35-z32it.dts' << 'ENDOFFILE'
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2835";
fragment@0 {
target = <&spi0>;
__overlay__ {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
cs-gpios = <&gpio 8 1>, <&gpio 12 1>, <&gpio 13 1>;
lcd@1 {
compatible = "ilitek,ili9486";
reg = <1>;
spi-max-frequency = <16000000>;
txbuflen = <32768>;
rotate = <90>;
bgr;
fps = <30>;
buswidth = <8>;
regwidth = <16>;
reset-gpios = <&gpio 27 1>;
dc-gpios = <&gpio 24 0>;
debug = <0>;
init = <0x10000f1 0x36 0x04 0x00 0x3c 0x0f 0x8f 0x10000f2 0x18 0xa3 0x12 0x02 0xb2 0x12 0xff 0x10 0x00 0x10000f8 0x21 0x04 0x10000f9 0x00 0x08 0x1000036 0x08 0x10000b4 0x00 0x10000c1 0x41 0x10000c5 0x00 0x91 0x80 0x00 0x10000e0 0x0f 0x1f 0x1c 0x0c 0x0f 0x08 0x48 0x98 0x37 0x0a 0x13 0x04 0x11 0x0d 0x00 0x10000e1 0x0f 0x32 0x2e 0x0b 0x0d 0x05 0x47 0x75 0x37 0x06 0x10 0x03 0x24 0x20 0x00 0x100003a 0x55 0x1000011 0x1000036 0x28 0x20000ff 0x1000029>;
};
touch@2 {
compatible = "ti,ads7846";
reg = <2>;
spi-max-frequency = <2000000>;
interrupt-parent = <&gpio>;
interrupts = <17 2>;
pendown-gpio = <&gpio 17 1>;
ti,x-plate-ohms = <60>;
ti,pressure-max = <255>;
debounce-max = <10>;
debounce-tol = <3>;
debounce-rep = <1>;
wakeup-source;
};
};
};
fragment@1 {
target = <&spi0_cs_pins>;
__overlay__ {
brcm,pins = <8 12 13>;
};
};
fragment@2 {
target = <&gpio>;
__overlay__ {
lcd_ctrl: lcd_ctrl {
brcm,pins = <24 27>;
brcm,function = <1>;
};
};
};
};
ENDOFFILEVerifică că e ok:
head -3 /boot/overlays/rpi35-z32it.dtsTrebuie să afișeze exact:
/dts-v1/;
/plugin/;
/ {Apoi compilează:
sudo dtc -@ -I dts -O dtb \
-o /boot/overlays/rpi35-z32it.dtbo \
/boot/overlays/rpi35-z32it.dts && echo "OK"gata merge display-ul. acuma vreau sa instalez real-vnc pe raspberi pi.
Bun — display complet funcțional și TetraBlue TMO merge. Acum VNC.
Pe Raspberry Pi OS Bookworm, RealVNC Server e disponibil direct din repo-ul oficial Raspberry Pi:
# Actualizeaza lista de pachete
sudo apt update
# Instaleaza RealVNC Server
sudo apt install -y realvnc-vnc-server
# Porneste serviciul VNC
sudo systemctl enable vncserver-x11-serviced
sudo systemctl start vncserver-x11-serviced
# Verifica status
sudo systemctl status vncserver-x11-servicedDar mai întâi trebuie să știu — folosești desktop GUI (Raspberry Pi OS cu desktop) sau Raspberry Pi OS Lite (fără desktop)?
Din ce am văzut până acum, RPi-ul tău pornește în consolă text (prompt dex login:), ceea ce sugerează că e Lite fără desktop. În cazul acela VNC standard nu funcționează fără X server.
Rulează:
# Vede ce versiune de OS ai
cat /etc/os-release
# Vede daca ai desktop instalat
dpkg -l xserver-xorg 2>/dev/null | grep ^ii
dpkg -l lxde 2>/dev/null | grep ^iiDă-mi output-ul și îți spun exact ce variantă de VNC instalăm — cu sau fără desktop.
da este fara desktop si asa vreau sa ramana, fara desktop. fara GUI . root@dex:/home/dex# cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" NAME="Debian GNU/Linux" VERSION_ID="12" VERSION="12 (bookworm)" VERSION_CODENAME=bookworm ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" root@dex:/home/dex#
Fără desktop, RealVNC nu are sens. Pentru acces VNC la terminal pe un sistem headless, soluția corectă este TigerVNC + xterm — creează un desktop virtual minimal cu doar un terminal.
sudo apt update
sudo apt install -y tigervnc-standalone-server xtermSetează parola VNC:
# Ca userul dex (nu root)
su - dex
vncpasswd
# Introdu parola dorita (min 6 caractere)
# La "Would you like to enter a view-only password?" → nCreează sesiunea minimală:
mkdir -p ~/.vnc
cat > ~/.vnc/xstartup << 'EOF'
#!/bin/bash
xterm &
wait
EOF
chmod +x ~/.vnc/xstartupPornește serverul VNC pe display :1, rezoluție 1024×768:
vncserver :1 -geometry 1024x768 -depth 16 -localhost noVerifică că rulează:
vncserver -listCreează serviciu systemd ca să pornească automat la boot:
sudo nano /etc/systemd/system/vncserver@.servicePune exact asta:
[Unit]
Description=TigerVNC Server
After=network.target
[Service]
Type=forking
User=dex
WorkingDirectory=/home/dex
ExecStartPre=/usr/bin/vncserver -kill :%i 2>/dev/null || true
ExecStart=/usr/bin/vncserver :%i -geometry 1024x768 -depth 16 -localhost no
ExecStop=/usr/bin/vncserver -kill :%i
Restart=on-failure
[Install]
WantedBy=multi-user.targetActivează și pornește:
sudo systemctl daemon-reload
sudo systemctl enable vncserver@1
sudo systemctl start vncserver@1
sudo systemctl status vncserver@1Verifică portul:
ss -tlnp | grep 590
# Trebuie sa apara 5901Apoi din Windows/Mac/Linux conectezi cu RealVNC Viewer sau TigerVNC Viewer la:
IP_RASPI:5901Care e IP-ul RPi-ului tău? Rulează ip addr show dacă nu știi.
Niciun comentariu:
Trimiteți un comentariu