23.3.2008 Jelikož jsem takový šťoura, co se rád
vrtá v kódech BIOSů počítačů a nedá si pokoj dokud obrazovka nadobro nezčerná :), tak také potřebuju mít
možnost FlashROM ručně přeprogramovat. Dříve jsem to u paralelních flashek, které byly na desce v DIL32
nebo PLCC32 patici, řešil jednoduše hotflashem, kdy jsem měl v záloze připravený druhý čip s funkčním BIOSem.
Ten jsem strčil do patice, za běhu vyměnil za špatně naprogramovaný čip a přeprogramoval.
Teď jsem se na své nové základní desce
Gigabyte GA-P31-DS3L setkal s novým typem paměti - vysokorychlostní
sériovou SPI FlashROM Winbond 25X40VSIG
v SMD pouzdru SOIC-8, která je připájená přímo na desku. Jižní můstky intel ICHx již delší dobu podporují obě
varianty FWH a SPI. Pomocí určitých registrů a pinů chipsetu lze vybírat, které z rozhraní se primárně použije
pro BIOS. Díky tomu, že se u SMD součástky ušetří desetník za patici, celkově klesnou náklady na výrobu a
manažeři tak mají více $ na lepší auta a kurvy ;). Nám šťouralům pak nezbývá, než vzít do ruky pájku...
Aby se s tou flash dalo rozumně pracovat, připájel jsem ji na precizní DIL8 patici. Druhou patici DIL8
jsem pak připájel na základní desku. Protože bych se na daném místě s pájkou kolem patice (naproti SATA konektoru)
už nedostal, nechal jsem ji plandat na dvou kouskách 4-žilové kšandy:
Následovala výroba programátoru. K připojení SPI zařízení k PC však stačí
obyčejný paralelní port, 5 drátů, pár odporů a konektory. Zapojení vychází z programovacího SPI kabelu
typu BSD na programování mikrokontrolérů
Atmel AVR. Zmiňovaná paměť W25X40V je určená pro napájecí napětí 3,3V, proto jsem datové linky oddělil
odpory, aby netrpěla vyšším napětím z LPT. Zároveň odpory plní funkci tlumení, bez nich totiž na delším
(cca 1,5m) plochém kabelu bez stínicích linek mezi signálovými docházelo k přeslechům a tím chybnému
přenosu dat. Zajímavé, že AVRka mi se stejným káblem fungujou bez potíží. K napájení jsem použil externí
zdroj.
Celé to pak splácané na univerzálním plošňáku vypadá nějako takhle:
Další už je jen věc software, který jsem si musel napsat. Nejprve bylo
třeba naprogramovat nejnižší vrstvu, která pracuje s registry LPT a nastavuje/čte požadované úrovně
na daných SPI linkách. K tomuto tématu můžu odkázat na knížku Burkhard Kainka - Využití rozhraní PC
z nakladatelství HEL 1997, z které jsem se kdysi učil, jak rozblikat svoji první LEDku na LPT.
Ale i na Internetu je zdrojů k tomuto tématu víc než dost.
Dále bych něco řekl k samotné sběrnici SPI. Ta sestává ze tří linek:
SCK - Serial ClocK (až desítky MHz), MISO - Master Input Slave Output, MOSI - Master Output Slave Input
a v tomto případě je zde ještě pomocná řídicí linka CS# - Chip Select. Komunikace typicky probíhá mezi
dvěma zařízeními, z nichž jedno je Master (v tomto případě PC), který ovládá hodiny SCK (zde je klidová
úroveň log. 0) a posílá příkazy/data na linku MOSI a přitom zároveň čte data z linky MISO.
Slave zařízení (v tomto případě paměť) pak reaguje na hodiny SCK tím, že při sestupné hraně hodin
odešle bit na linku MISO a při vzestupné hraně hodin čte bit z linky MOSI. Byte se odesílá v pořadí
MSB jako první, LSB jako poslední. Po dokončení přenosu Master vrací hodiny na klidovou úroveň (log. 0).
Sběrnice je tedy narozdíl třeba od I2C plně duplexní. Slave zařízení se neidentifikují žádnou adresou.
Aby bylo možno připojit na linky SPI více Slave zařízení, musí být Master s každým zařízením propojen
samostatnou řídicí linkou CS#, která úrovní log. 0 aktivuje jedno z n Slave zařízení (ostatní
mají SPI výstupy ve stavu vysoké impedance, aby neovlivňovali probíhající komunikaci (SPI zařízení
mají 3-stavové výstupy, nejsou potřeba pull-upy). V případě SPI Flash paměti se CS# používá pro začátek
a konec rámce, takže ho nelze jednoduše spojit se zemí. Více napoví následující obrázek jak probíhá
čtení z paměti:
Nejprve Master zahájí rámec přechodem CS# do log. 0 a tím se aktivuje
paměť. Pak Master spustí hodiny a vysílá první Byte příkaz 3h - čtení z paměti. Paměť zjišťuje,
cože to po ní chceme a ví, že musí ještě dostat adresu. Tu posílá master v následujících 3 Bytech.
Paměť adresu dekóduje a okamžitě začíná v dalším Byte posílat data. Pokud Master požaduje data i
z následujících adres, nechá spuštěné hodiny a paměť automaticky inkrementuje adresu. Další příchozí
data od Mastera se ignorují. Konec rámce pak Master ukončí přechodem hodin do klidového stavu log. 0
a přechodem CS# do klidového stavu log. 1.
Paměť podporuje určitou standardní množinu příkazů, mezi něž patří
třeba čtení, zápis, mazání stránky, mazání sektoru, mazaní celého čipu, zamknutí, odemknutí,
identifikace výrobce a typu čipu JEDEC ID, čtení stavového registru, ... Některé příkazy jsou
jednobajtové, jiné mají parametry a data. Na některé paměť odpovídá vysláním dat, na jiné ne.
Další podrobnosti viz datasheet ke konkrétní paměti.
Dalším krokem bylo tedy napsání funkcí pro odesílání a příjem
Bytů a bloků dat a nakonec funkce pro zpracování jednotlivých příkazů Flash paměti. Současná
verze programu umožňuje identifikovat typ paměti /i, číst a zobrazit
blok dat dané velikosti od dané adresy /r, přečíst celou paměť do souboru
/d, naprogramovat celou paměť ze souboru /p,
smazat celou paměť /e a odemknout write protect bity /u.
Dalšími parametry /l= lze nastavit bázovou adresu LPT a pomocí
/d= prodloužit dobu trvání SCK pulsu v mikrosekundách. V balíčku
SPIPGM jsou k dispozici 4 verze pro systémy DOS,
Windows, Linux 32b a Linux 64b. Pokud máte nějaké dotazy, přečtěte si napřed důkladně
FAQ.
Vzhledem k limitované rychlosti LPT a sériovému způsobu přenosu
trvá čtení nebo zápis desítky sekund až minuty. Doba mazání čipu závisí na rychlosti interních
mechanismů v paměti a trvá zhruba jednotky až desítky sekund. Rychlejší komunikace by šlo
dosáhnout pomocí mikrokontroléru, nejlépe s hardwarovým SPI řadičem, který by s PC komunikoval
buď 8-bitově po LPT nebo po USB. Ukázka akce programu s pamětí ST M25P32:
SPI FlashROM Programmer 1.0 (C) 2008 by Martin Rehak; rayer^seznam*cz
Compiled by GCC 3.4.5 (mingw special) at 18:41:28, Mar 26 2008
SPI connected to LPT port at I/O base address: 378h, SCK pulse width: t+0us
FlashROM JEDEC ID, type: 202016h
ST Microelectronic M25P32 (4MB)
Reading sector at: 00396000h (89%)
|
21.7.2010 Ve spolupráci s lidmi z
projektů Flashrom a Coreboot,
kterým jsem poskytl zdrojový kód SPIPGM, byla přidána podpora mojeho SPI programátoru do
tohoto univerzálního flashovacího nástroje. Zároveň byla také vytvořena i DOSová verze
(kompilovaná v DJGPP), kterou si můžete stáhnout
zde.
Uživatelé flashromu tak získali možnost programování přes LPT port a uživatelé SPIPGM zas
širokou podporu různých typů flash pamětí. SPI programátor na LPT portu se vybere přepínačem:
flashrom -p rayer_spi [další příkazy]
Udělal jsem srovnávací test s 4MB FlashROM pamětí ST M25P32:
program |
čtení |
mazání |
SPIPGM |
2:41 |
0:21 (bez verifikace) |
flashrom |
2:44 |
3:34 (s verifikací) |
Rychlost čtení je tedy plně srovnatelná, zatímco mazání je ve flashromu pomalejší, protože
obsahuje i nucenou verifikaci (tedy kompletní čtení). Navíc já používám jediný příkaz chip erase.
Stávající verze flashromu zatím neobsahuje žádný indikátor průběhu prováděných operací, takže
nepanikařte a zajděte si mezitím na kafe :)
19.3.2011 Abych se nemusel stydět za ten
bastl vyfocený výše (navíc na neprakticky velké desce), rozhodl jsem se postavit si nový SPI FlashROM
programátor. Hlavním důvodem však byla potřeba umět pohodlně programovat i SMD paměti v pouzdru SOIC-8,
které jsou v současnosti nejrozšířenější. Nastal tedy problém, kde sehnat odpovídající ZIF patici,
což se ukázalo jako tvrdý oříšek. Patice vyrábí např. taiwanská společnost
LOTES Co., Ltd.,
která nemá u nás distributora, nebo je lze koupit min. po 1000 ks. u americké firmy
Larsen Associates
či za 48$ hotovou redukci na DigiKey.
UPDATE: Na eBay se už objevily levné redukce.
bílá vrána: Advantech AIMB-766 se ZIF soketem
Na tyto podmínky jsem nechtěl přistoupit a tak jsem bádal, jak si tu ZIFku
vyrobit doma na koleně. Zkoumal jsem své zásoby různých počítačových konektorů a vybral 3 potenciální
kandidáty: RJ-45 zásuvku z ethernet karty, DIMM slot, a PCI slot. Jako nejlepší se ukázal PCI slot,
protože má dlouhá a pružná pérka a po rozříznutí se nerozsype. Z PCI slotu jsem uřízl kousek s 2 x 4
piny a ten pak rozřízl na půl. Částečně jsem také ubrousil vršek konektoru tak, aby konce pérek vylezly ven.
Při této operaci jsem pérka z konektoru vytáhl a pak zase zastrčil zpět. Peánem to jde docela snadno.
Na plošňáku jsou obě poloviny konektoru od sebe vzdálené na šířku čipu, tj. asi 5,5 mm i s rezervou
a tím vymezují jeho horizontální polohu. Po přiložení na pérka se čip zatlačí dolů tak, že plastové
přepážky mezi pérky jednoznačně vymezují vertikální polohu nožiček a v této poloze se čip zajistí nasunutím
"C" profilu z plexiskla. Průhyb pérek je asi o 1 mm dolů. Zakládání čipu chce trochu cvik, ale teď
už to umím docela rychle.
Plošňák jsem vyrobil rychlou metodou z hlavy pomocí lihové fixy a vyleptal
ve FeCl3. Hodnoty odporů pro linky MISO, MOSI, SCK a CS# jsem zvýšil na
220 Ω. O blokování napájení se stará 100µF tantal a 3 keramiky. Na desku jsem dal také
3,3V LDO stabilizátor LE33CZ.
Napájení pro něj lze získat např. z PC zdroje, USB portu nebo PS/2 portu. Programátor mi funguje bez
problémů na plnou rychlost. Zkoušel jsem naprogramovat a zverifikovat několik čipů a neobjevila se žádná
neshoda (s dřívějším bastlem se mi to občas stávalo). Na digitálním osciloskopu jsem ještě zkontroloval
průběh signálu SCK, na jehož hranách se vyskytují zákmity max. 0,4 V, což je v pohodě. Pokud bych
chtěl být perfekcionista, přidal bych na desku ještě oddělovací 3,3V buffer, který by pomohl některým
PC s neduživým LPT, ale zatím jsem neměl problém. SPIPGM fungoval i na novém kompu v práci, kde je PCI-E
adaptér s 2x COM a 1x LPT na vysoké I/O adrese E800h. Zde je ke stažení aktuální verze
SPIPGM 1.9c.
24.10.2014 Už dříve jsem dostal několik dotazů
jak naprogramovat 1,8V paměti a tak jsem dotyčné odkázal, ať si vyberou nějaký voltage level translator
např. od Texas Instruments.
Teď jsem se dostal sám do situace, kdy jsem potřeboval přeflashnout paměť Macronix
MX25U6435F,
když jsem si při pokusech s Corebootem bricknul své 86Duino ZERO.
V práci jsem našel v šuplíku vzorek převodníku TXS0108E
pouzdru TSSOP20 (pro bastlení zrovna nic moc), ale říkal jsem si, že ho aspoň vyzkouším.
Jedná se o převodník s automatickou detekcí směru toku, ke kterému stačí
připojit 2 napájení a zapnout enable. Uříznul jsem si kousek univerzální destičky a švába na ni přibastlil
pomocí tenkých drátků. Byla to docela piplačka. Napájecí napětí 1,8 V jsem si vytvořil z 5 V
pomocí malého LDO TLV70018.
Datové linky z LPT jsem připojil na port B a stávající destičku programátoru s paměti k portu A.
Oměřil jsem klidové hodnoty bez připojené paměti a vše se zdálo být v pořádku. Tak jsem to připojil k paměti
a k PC, ale detekce se paměti nezdařila. Vzal jsem si tedy k ruce digitální osciloskop a zjistil, že se
obvod chová poněkud nevyzpytatelně - např. signál SCK měl na 1,8V straně A první 3 pulzy amplitudy asi
1,2 V a teprve další měly správně 1,8 V. MISO zas na výstupu převodníku B (na straně LPT)
nedosahovalo v log. 0 dostatečně nízké napětí. I když jsem linku portu A natvrdo uzemnil, bylo na
výstupu B asi 0,5 V a pokud sem ho stáhnul přes odpor 220 Ω, tak už bylo na výstupu B
2,6 V, což lze těžko brát za log. 0. Pokud jsem výstup B odpojil od LPT, spadlo napětí na
35 mV. Jelikož vstup LPT tahá nahoru, tak to vypadá, že převodník asi nemá dostatečně tvrdé výstupy.
Nakonec jsem po další hodině laborování švába naštvaně odpájel a zahodil. Možná, že by byl vhodnější obvod
TXB0104,
(případně dvojice jednosměrných translátorů), ale ten jsem k dispozici neměl a nechtělo se mi na něj čekat.
Jak se ukazuje, někdy ta jednodušší řešení fungují lépe a tak jsem se
vrátil k pasivnímu omezení napětí z LPT pomocí odporů a diod. Diody jsem dopájel na stávající destičku
programátoru, viz aktualizované schéma výše. Výstup paměti MISO jsem zvednul
pomocí kaskády 2 tranzistorů BC547.
Dohromady s připojeným programátorem to pak vypadá takto:
S tímto zapojením jsem už neměl problém paměť naprogramovat. Ještě bych upozornil na poslední aktualizaci
mého programu SPIPGM 2.22, kde jsem přidal experimentální
podporu 32-bitového adresního režimu pro paměti větší než 16 MB.
10.4.2019 Pokud už na žádném PC nemáte paralelní
port, tak se nabízí levná alternativa v podobě čínského USB převodníku CH341A
s rozhraními UART, SPI a I2C. K dispozici jsou ovladače pro Windows, Linux, MAC OS, Android
a knihovna pro vývojáře. Na eBay
jsem objevil malý USB programátor
SPI FlashROM a I2C EEPROM s tímto čipem za 56,- Kč, který jsem si na zkoušku objednal a nyní mi dorazil.
Už kvůli té ZIF patici se to za tu cenu vyplatí. Nízká cena se poněkud projevila na kvalitě pájení.
Jak vidíte na fotce, jsou pin headery vedle patice připájené nakřivo, tak jsem si je musel přepájet,
což jsem Číňanovi reklamoval a dostal za to drobnou slevu. Další problém je, že při návrhu programátoru
někdo asi přemýšlel prdelí - deska sice obsahuje 3,3V LDO stabilizátor z kterého se napájí paměť v patici,
ale samotný čip je napájen 5 V z USB a rve tak do paměti 5V úrovně po linkách MOSI, SCK, CS#. Přitom
čip lze provozovat jak z 5 V, tak z 3,3 V (má vnitřní 3,3V regulátor). Aplikoval jsem tedy
drobný workaround,
spočívající v nadzvednutí pinu 28 - VCC a jeho připojení na 3,3V výstup LDO a taktéž propojení pinu
9 - V3 (resp. jeho blokovacího kondenzátoru) na výstup LDO. Pak už je vše v pořádku, mohli tam na to
aspoň přidat jumpery. Jako ovládací software lze použít AsProgrammer
nebo flashrom.
Přečtení 1MB paměti EN25T80 AsProgrammerem trvalo 8 s, tj. rychlostí 125 kB/s.