Chtěl jsem si do slajdů k přednášce dokreslit průběh nějakého signálu a nechtělo se mi to malovat ručně v Paintu. Našel jsem na to nádherný nástroj, který by se mohl hodit i někomu jinému, a protože je volně k dispozici, podívejte se, jestli by se vám taky nehodil.
Obvykle takovéhle klikyháky maluju křídou na tabuli, ale co mi to kvůli Čínské chřipce zakázali, musím hledat jiné cesty. A našel jsem – jmenuje se to WaveDrom (počeštil jsem si to jako Vlnodrom) a najdete ho na webu https://wavedrom.com, kde je i řada příkladů, co se s tím dá namalovat.
Na začátek něco jednoduchého:
{ signal: [ { name: "hodiny", wave: "p..." }, { name: "sběrnice", wave: "x=.x", data: "přenos" }, ] }
Ale dá se s tím dělat i složitější věci:
{ signal: [ {name: 'clk', wave: 'p...|..'}, {name: 'req', wave: 'u0u..|..', node: '.A',phase:0.98,}, {name: 'dat', wave: 'u34.|5u', data: ['head', 'data', 'tail'], node: '.B'}, {name: 'ack', wave: 'u...|0u',node:'.....C'}, {name: 'IRQ', wave: 'u...|.0',node:'......D'} ], edge:['A~>B','C~>D'], foot:{text:'ukázka WaveDrom 2'} }
Celý diagram je popsaný v intuitivním formátu, nazvaném WaveJSON (a ten je založený na běžném JSON). Průběh jednotlivých signálů je zapsán v položce ‚signal‘, kde každý má svou část (uzavřenou do složených závorek) a tam se v sekci „wave“ jednotlivými písmeny určuje, jaký je stav signálu na časové ose v konkrétní čas. Například 0 znamená přechod na nízkou úroveň a 1 na vysokou, u a d přitažení směrnice k vysoké nebo nízké úrovni pomocí pull-up nebo pull-down rezistoru, z stav vysoké impedance a podobně. Tečka v průběhu označuje opakování předchozího stavu.
Inspiraci hledejte na webu https://wavedrom.com, kde je jednak Tutorial s mnoha ukázkami, a pak také Editor, kde si můžete všechno vyzkoušet a i stáhnout si hotové obrázky ve formátu SVG nebo PNG (v Editoru hledejte vpravo dole nenápadné tlačítko pro „hamburgerové“ menu).
Pro ukázku, že s tím může udělat něco i někdo jiný, než autor toho nástroje, já jsem teď konkrétně chtěl namalovat zhuštěný popips s i2c, a vyšlo mi tohle (rozklikněte si to, je to moc široký):
{ signal: [ {name: 'SCL', wave: 'u....0.u.0.u.0.u.0.u.0.u.0.u.0.u.0.u.0.u.0.u.0.u....', node: '....S...........................................J'}, {name: '', wave: '', node: '....Q............T.................N............O'}, {name: '', wave: '', node: '..........................................P......'}, {name: 'master 1 wants', wave: 'u...0.=...=...=...=...1u............................',data: "A7 A6 A5 A4 ",node: '....R..................D.........................'}, {name: 'master 2 wants', wave: 'u...0.=...=...=...=...0...=...=...=...=...u...0.u...',data: "A7 A6 A5 A4 A2 A1 A0 R/W ACK ",node: '......................A.......................G.I'}, {name: 'slave wants', wave: 'u.........................................0...u.....',data: "A7 A6 A5 A4 A2 A1 A0 R/W ACK ",node: '......................U.........V.........E......'}, {name: '', wave: '', node: '.......................K.......L..........X.....W'}, {name: 'resulting SDA', wave: 'u...0.=...=...=...=...0...=...=...=...=...0...0.u...',data: "A7 A6 A5 A4 A2 A1 A0 R/W ACK ",node: '......................BC..................F...H..'}, {name: '', wave: ''}, {name: 'meaning', wave: '=.=..z=...=...=...=...=...=...=...=...=...=...z=..=.',data: "idle START A7 A6 A5 A4 A3 A2 A1 A0 R/W ACK STOP idle"}, ], edge: ['C~>D','A~>B','E~>F','I<~>J','L->K ... master 1 loses arbitration',"W->X slave acknowledges",'T->Q START condition (clock HIGH while data goes LOW)','R<->S','V->U master 2 forces LOW and therefore ...','N->O STOP condition (clock HIGH while data goes HIGH)'], head: {text:['tspan', {class:"h2 "},"i2c overview"]}, foot: {text:"Situations: START condition (left), multimaster arbitration (middle), acknowledge (near right), STOP condition (right)"}, config: {skin:'narrow',marks:false} }
No a protože jsou teď Vánoce, tak tedy:
{ signal: [ {name: 'K', wave: '0.....0.....', phase:0.5}, {name: 'l', wave: '0....70.....', node: '.....at'}, {name: 'i', wave: '0....7.0....', node: '.....s.b',phase:0.5}, {name: 'd', wave: '0...7..0....', node: '....c..r'}, {name: 'n', wave: '0...7...0...', node: '....q...d.',phase:0.5}, {name: 'é', wave: '0..7....0...', node: '...e....p'}, {name: ' ', wave: '0..7.....0..', node: '...o.....f',phase:0.5}, {name: 'V', wave: '0.7......0..', node: '..g......n'}, {name: 'á', wave: '0.7.......0.', node: '..m.......h',phase:0.5}, {name: 'n', wave: '07........0.', node: '.i........l'}, {name: 'o', wave: '07.........0', node: '.k.........j',phase:0.5}, {name: 'c', wave: '1...l..h....'}, {name: 'e', wave: '1...l..h....'}, {name: '!', wave: '1...l..h....'}, {name: ' ', wave: '1...........'}, ], edge: [ 'a~b','b~c','c~d','d~e','e~f','f~g','g~h','h~i','i~j','kxl','mxn','oxp','qxr','rxs','sxt' ], config: {skin:'narrow'} }