Problem with comparison.
/Modules/AVR/AVRUSB01A/AVRUSB01A_Bot_Small.JPG |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/AVRUSB01A_Top_Small.JPG |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/AVRUSB01A.cs.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/FW_USBasp.cs.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A.cs.html |
---|
0,0 → 1,553 |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
<html> |
<head> |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
<title> AVRUSB01A </title> |
<meta name="keywords" content="stavebnice MLAB USB AVR USBasp I2C"> |
<meta name="description" content="Projekt MLAB, Modul pro AVR procesory, převodník USB na I2C, programátor AVR ISP"> |
<!-- AUTOINCLUDE START "Page/Head.cs.ihtml" DO NOT REMOVE --> |
<link rel="StyleSheet" href="../../../../../Web/CSS/MLAB.css" type="text/css" title="MLAB základní styl"> |
<link rel="StyleSheet" href="../../../../../Web/CSS/MLAB_Print.css" type="text/css" media="print"> |
<link rel="shortcut icon" type="image/x-icon" href="../../../../../Web/PIC/MLAB.ico"> |
<script type="text/javascript" src="../../../../../Web/JS/MLAB_Menu.js"></script> |
<!-- AUTOINCLUDE END --> |
</head> |
<body lang="cs"> |
<!-- AUTOINCLUDE START "Page/Header.cs.ihtml" DO NOT REMOVE --> |
<!-- ============== HLAVICKA ============== --> |
<div class="Header"> |
<script type="text/javascript"> |
<!-- |
SetRelativePath("../../../../../"); |
DrawHeader(); |
// --> |
</script> |
<noscript> |
<p><b> Pro zobrazení (vložení) hlavičky je potřeba JavaScript </b></p> |
</noscript> |
</div> |
<!-- AUTOINCLUDE END --> |
<!-- AUTOINCLUDE START "Page/Menu.cs.ihtml" DO NOT REMOVE --> |
<!-- ============== MENU ============== --> |
<div class="Menu"> |
<script type="text/javascript"> |
<!-- |
SetRelativePath("../../../../../"); |
DrawMenu(); |
// --> |
</script> |
<noscript> |
<p><b> Pro zobrazení (vložení) menu je potřeba JavaScript </b></p> |
</noscript> |
</div> |
<!-- AUTOINCLUDE END --> |
<!-- ============== TEXT ============== --> |
<div class="Text"> |
<p class="Title"> |
USB modul pro AVR |
</p> |
<p class=Autor> |
Milan Horkel |
</p> |
<p class="Subtitle"> |
Potřeboval jsem rychle připojit I2C zařízení k Linuxovému počítači. Protože se mi nelíbilo |
"bastl" provedení USB rozhraní s procesorem ATmega, zkomponoval jsem tento modul. Může |
sloužit jako ISP programátor pro AVR procesory, jako převodník USB na I2C a na další pokusy |
se softwarovou realizací USB na procesorech řadu ATmega. Obsahuje také stabilizátor 3,3V. |
</p> |
<p class="Subtitle"> |
<img width="640" height="319" src="AVRUSB01A_soubory/image001.jpg" alt="Obrázek modulu AVRUSB01A"> |
</p> |
<p> |
<a href="../AVRUSB01A.cs.pdf"><img class="NoBorder" |
src="../../../../../Web/PIC/FileIco_PDF.ico" |
alt="Acrobat"> PDF verze</a> |
</p> |
<h1> Technické parametry</h1> |
<table> |
<tr> |
<th> Parametr </th> |
<th> Hodnota </th> |
<th> Poznámka </th> |
</tr> |
<tr> |
<td> Rozhraní </td> |
<td> USB </td> |
<td> Low Speed </td> |
</tr> |
<tr> |
<td> Napájení </td> |
<td> +5V </td> |
<td> Z USB rozhraní </td> |
</tr> |
<tr> |
<td> Napájení vnitřní </td> |
<td> +5V / +3.3V </td> |
<td> Vlastní stabilizátor, max 800mA </td> |
</tr> |
<tr> |
<td> Funkce (dle firmwaru) </td> |
<td> USBasp<br> |
i2c-tiny-usb </td> |
<td> Programátor AVR<br> |
Převodník USB - I2C </td> |
</tr> |
<tr> |
<td> Rozměry </td> |
<td> 60 x 30 x 18 mm </td> |
<td> Výška nad základnou </td> |
</tr> |
</table> |
<h1> Popis konstrukce </h1> |
<h2> Úvodem </h2> |
<p> |
Pro procesory AVR existuje knihovna (ne jedna, dokonce několik), která realizuje USB Low |
Speed (1.5Mbit/s) protokol čistě softwarovými prostředky. Jedná se o řešení kompromisní, |
protože obyčejné vývody procesorů AVR nesplňují elektrické parametry USB specifikace. |
Nicméně existuje spousta konstrukcí, které toto řešení používají a díky přeci jen laxnějším |
požadavkům pro Low Speed USB se jedná o řešení funkční. |
</p> |
<p> |
<i>Pozor, novější operační systémy v souladu s USB specifikací zakazují Bulk |
přenosy pro Low Speed USB zařízení. Takže některé firmwary nemusejí fungovat.</i> |
</p> |
<p> |
Původní řešení ve stavebnici MLAB bylo poněkud neelegantní. Posuďte sami: |
</p> |
<table> |
<tr> |
<td> |
<p> |
<img width="288" height="320" src="AVRUSB01A_soubory/image002.jpg" |
alt="Nelegantní řešení"> |
</p> |
</td> |
<td> |
<p> |
<img width="190" height="96" src="AVRUSB01A_soubory/image003.jpg" |
alt="Nový modul"> |
</p> |
</td> |
</tr> |
</table> |
<p> |
Modul tedy slouží pro běh standardních firmwarů, nebo pro tvorbu a testování vlastních. |
Dále poskytuje stabilizátor napětí 3.3V. Standardní firmwary poskytují tyto například |
tyto služby: |
</p> |
<ul> |
<li> Programování procesorů AVR (firmware USBasp, |
<a href="http://www.fischl.de/usbasp">http://www.fischl.de/usbasp</a>) </li> |
<li> Převodník USB na I2C (firmware i2c-tiny-usb, |
<a href="http://www.harbaum.org/till/i2c_tiny_usb">http://www.harbaum.org/till/i2c_tiny_usb</a>) </li> |
<li> a další... </li> |
</ul> |
<h2> Zapojení modulu </h2> |
<p> |
Zapojení vychází z předdefinovaného přiřazení vývodů USB knihovny <i>usbdrv</i>, různé |
firmwary mohou mít přiřazení (USB) vývodů odlišné a je třeba je před překladem přenastavit |
(a případně opravit, pokud autor nemá konfiguraci správně připravenou). |
</p> |
<p> |
První částí zapojení je napájecí zdroj. Umožňuje pomocí propojky J2 použít jak napětí +5V |
přímo z USB, tak i napětí +3.3V z vestavěného stabilizátoru. Na vstupu je ochranná |
pojistka, protože ji některá zařízení (v rozporu s USB specifikací) nemají a při případné |
zkratu by mohlo někde něco uhořet. <i>Pozor, osazujeme jen jednu pojistku |
(na plošném spoji leží přes sebe).</i> |
</p> |
<p> |
<img width="988" height="294" src="AVRUSB01A_soubory/image004.png" |
alt="Schéma, napájecí zdroj"> |
</p> |
<p> |
Další částí je procesor ATmega88, který je připojen na USB konektor. |
</p> |
<p> |
<img width="988" height="454" src="AVRUSB01A_soubory/image005.png" |
alt="Schéma, procesor"> |
</p> |
<p> |
Pro jeho vlastní programování se používá konektor J9 a je nutné zapojit propojku J6, která |
umožní programování. |
</p> |
<p> |
Po nahrání firmwaru "programátor AVR" je konektor J9 použit pro připojení cílového |
zařízení, které lze napájet napětím 3.3V z modulu přes spojku J10 a případně spojkou J2 |
nastavit napětí +5V. |
</p> |
<p> |
<img width="494" height="254" src="AVRUSB01A_soubory/image006.png" |
alt="Schéma, konektor AVR ISP"> |
<img width="334" height="254" src="AVRUSB01A_soubory/image007.png" |
alt="Schéma, konektor napájení"> |
</p> |
<p> |
Po nahrání firmwaru "převodník I2C" je možné na konektor J8 připojit I2C sběrnici, případně |
povolit její napájení +3.3V přes J7 (J2 zapíná +5V z USB). K dispozici jsou dále LED diody |
D4 a D5 a případně vyvedené rozhraní RS232 (TTL úrovně). |
</p> |
<p> |
<img width="494" height="254" src="AVRUSB01A_soubory/image008.png" |
alt="Schéma, I2C konektor"> |
<img width="334" height="254" src="AVRUSB01A_soubory/image009.png" |
alt="Schéma, diody LED"> |
<img width="334" height="148" src="AVRUSB01A_soubory/image010.png" |
alt="Schéma, konektor RS232"> |
</p> |
<h2> Seznam součástek </h2> |
<table class="Soupiska"> |
<tr> |
<th> Počet </th> |
<th> Reference </th> |
<th> Název </th> |
<th> Pouzdro </th> |
</tr> |
<tr> |
<th colspan="4"> Odpory </th> |
</tr> |
<tr> |
<td> 10 </td> |
<td> R2, R3, R8, R9, R10, R11, R14, R15, R16, R17 </td> |
<td> 68 </td> |
<td> R0805 </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> R7 </td> |
<td> 330 </td> |
<td> R0805 </td> |
</tr> |
<tr> |
<td> 2 </td> |
<td> R5, R6 </td> |
<td> 470 </td> |
<td> R0805 </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> R1 </td> |
<td> 2k2 </td> |
<td> R0805 </td> |
</tr> |
<tr> |
<td> 3 </td> |
<td> R4, R12, R13 </td> |
<td> 4k7 </td> |
<td> R0805 </td> |
</tr> |
<tr> |
<th colspan="4"> Keramické kondenzátory </th> |
</tr> |
<tr> |
<td> 2 </td> |
<td> C4, C5 </td> |
<td> 22pF </td> |
<td> C0805 </td> |
</tr> |
<tr> |
<td> 2 </td> |
<td> C1, C6 </td> |
<td> 100nF </td> |
<td> C0805 </td> |
</tr> |
<tr> |
<td> 2 </td> |
<td> C2, C3 </td> |
<td> 10uF </td> |
<td> C0805 </td> |
</tr> |
<tr> |
<th colspan="4"> Diody </th> |
</tr> |
<tr> |
<td> 2 </td> |
<td> D1, D2 </td> |
<td> 1N4007SMD </td> |
<td> MELF </td> |
</tr> |
<tr> |
<th colspan="4"> Zenerovy diody </th> |
</tr> |
<tr> |
<td> 2 </td> |
<td> D6, D7 </td> |
<td> BZV55C3.6 </td> |
<td> MINIMELF </td> |
</tr> |
<tr> |
<th colspan="4"> Svítivé diody </th> |
</tr> |
<tr> |
<td> 2 </td> |
<td> D3, D4 </td> |
<td> HCL-1505-4(RED) </td> |
<td> LED1206REV </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> D5 </td> |
<td> HCL-1503-4(GREEN) </td> |
<td> LED1206REV </td> |
</tr> |
<tr> |
<th colspan="4"> Pojistky </th> |
</tr> |
<tr> |
<td> 1 </td> |
<td> F1A </td> |
<td> SR075-06 </td> |
<td> R0805 </td> |
</tr> |
<tr> |
<td> 0 </td> |
<td> F1B </td> |
<td> 1812L075PR </td> |
<td> F1812 </td> |
</tr> |
<tr> |
<th colspan="4"> Integrované obvody </th> |
</tr> |
<tr> |
<td> 1 </td> |
<td> U1 </td> |
<td> LT1117-3.3 </td> |
<td> SOT223 </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> U2 </td> |
<td> ATmega88-20AU </td> |
<td> TQFP32 </td> |
</tr> |
<tr> |
<th colspan="4"> Krystaly </th> |
</tr> |
<tr> |
<td> 1 </td> |
<td> X1 </td> |
<td> 12MHz </td> |
<td> XTAL050 </td> |
</tr> |
<tr> |
<th colspan="4"> Mechanické součástky </th> |
</tr> |
<tr> |
<td> 1 </td> |
<td> J1 </td> |
<td> USB_B_01 </td> |
<td> USB_B_01 </td> |
</tr> |
<tr> |
<td> 4 </td> |
<td> J2, J5, J7, J10 </td> |
<td> JUMP2 </td> |
<td> JUMP2 </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> J6 </td> |
<td> JUMP3 </td> |
<td> JUMP3 </td> |
</tr> |
<tr> |
<td> 2 </td> |
<td> J4, J3</td> |
<td> JUMP2X3 </td> |
<td> JUMP2X3 </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> J8 </td> |
<td> JUMP2X5 </td> |
<td> JUMP2X5 </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> J9 </td> |
<td> JUMP2x3 </td> |
<td> JUMP2x3/B </td> |
</tr> |
<tr> |
<th colspan="4"> Konstrukční součástky </th> |
</tr> |
<tr> |
<td> 4 </td> |
<td> </td> |
<td> Šroub M3x12 </td> |
<td> </td> |
</tr> |
<tr> |
<td> 4 </td> |
<td> </td> |
<td> Podložka M3 </td> |
<td> </td> |
</tr> |
<tr> |
<td> 4 </td> |
<td> </td> |
<td> Sloupek M3x5 </td> |
<td> </td> |
</tr> |
<tr> |
<td> 2 </td> |
<td> </td> |
<td> JUMPER </td> |
<td> </td> |
</tr> |
<tr> |
<td> 1 </td> |
<td> </td> |
<td> Plošný spoj </td> |
<td> </td> |
</tr> |
</table> |
<h2> Zapojení použitých IO </h2> |
<p> |
Použitý obvod ATmega88-20 v pouzdru TQFP je možné nahradit procesorem ATmega8, ale je třeba |
použít správnou variantu firmwaru přeloženou pro použitý procesor. Rychlost procesoru a |
krystal volíme dle požadavků firmwaru. USB knihovna podporuje jen vybrané kmitočty. |
</p> |
<p> |
Knihovna USB umožňuje připojení USB datových signálů k libovolnému portu procesoru, ale |
současně potřebuje, aby alespoň jeden signál vyvolával přerušení s dostatečně velkou |
prioritou. Zde je přerušovacím signálem INT0 na signálu D+ (vývod PD2). |
</p> |
<h2> Mechanická konstrukce </h2> |
<p> |
Jedná se o standardní modul pro stavebnici MLAB určený k přišroubování k základní desce. |
</p> |
<h1> Osazení a oživení </h1> |
<h2> Osazení </h2> |
<p> |
Na straně spojů nezapomeneme osadit drátové propojky (platí pro jednostranný plošný spoj). |
</p> |
<p> |
<img width="802" height="404" src="AVRUSB01A_soubory/image011.png" |
alt="Osazovací výkres, strana součástek"> |
</p> |
<p> |
Na straně spojů jsou osazeny standardní SMD součástky, jen LED diody se osazují opačně, |
svítící stranou směrem do desky (je tam otvor velký tak akorát, aby se tam vešlo pouzdro |
standardní diody v pouzdru 1206). |
</p> |
<p> |
<img width="802" height="405" src="AVRUSB01A_soubory/image012.png" |
alt="Osazovací výkres, strana spojů"> |
</p> |
<h2> Oživení </h2> |
<p> |
Oživení spočívá v optické kontrole na zkraty a v elektrické kontrole funkčnosti |
stabilizátoru +3.3V. Pak stačí externím programátorem nahrát příslušný firmware a ozkoušet |
jeho funkčnost. |
</p> |
<h1> Programové vybavení </h1> |
<p> |
Jednotlivé firmwary (nakonfigurované pro tento hardware) jsou součástí tohoto projektu |
spolu s jejich přeloženými binárními soubory v adresáři SW. |
</p> |
<p> |
Firmwary musejí být nakonfigurovány s těmito parametry: |
</p> |
<table> |
<tr> |
<th> Parametr </th> |
<th> Hodnota </th> |
<th> Poznámka </th> |
</tr> |
<tr> |
<td> USB D+ </td> |
<td> PD2/INT0 </td> |
<td> Je současně signálem externího přerušení INT0, obvyklé provedení programátoru USBasp používá port PB1. </td> |
</tr> |
<tr> |
<td> USB D- </td> |
<td> PD4 </td> |
<td> Obvyklé provedení programátoru USBasp používá port PB1. </td> |
</tr> |
<tr> |
<td> Přerušení </td> |
<td> PD2/INT0 </td> |
<td> Obvyklé provedení programátoru USBasp používá port PD2 spojený s portem PB1. </td> |
</tr> |
<tr> |
<td> Krystal </td> |
<td> 12.0MHz </td> |
<td> Obvyklá hodnota frekvence, nutno volit podle toho, jaké frekvence jsou podporované v |
USB knihovně (například 12.0MHz, 12.8MHz, 15.0MHz, 16.0MHz, 16.5MHz, 18.0MHz |
20.0MHz). </td> |
</tr> |
<tr> |
<td> Procesor </td> |
<td> ATmega88 </td> |
<td> Alternativně ATmega8 (nutný překlad firmwaru pro správně nastavený procesor). </td> |
</tr> |
</table> |
</div> |
<!-- AUTOINCLUDE START "Page/Footer.cs.ihtml" DO NOT REMOVE --> |
<!-- ============== PATIČKA ============== --> |
<div class="Footer"> |
<script type="text/javascript"> |
<!-- |
SetRelativePath("../../../../../"); |
DrawFooter(); |
// --> |
</script> |
<noscript> |
<p><b> Pro zobrazení (vložení) hlavičky je potřeba JavaScript </b></p> |
</noscript> |
</div> |
<!-- AUTOINCLUDE END --> |
</body> |
</html> |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image001.jpg |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image002.jpg |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image003.jpg |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image004.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image005.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image006.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image007.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image008.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image009.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image010.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image011.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/AVRUSB01A_soubory/image012.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/HTML/FW_USBasp.cs.html |
---|
0,0 → 1,395 |
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
<html> |
<head> |
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> |
<title> USBasp </title> |
<meta name="keywords" content="USBasp AVRUSB01 MLAB firmware programátor"> |
<meta name="description" content="Firnware USBasp pro modul AVRUSB01, ISP programátor pro procesory AVR"> |
<!-- AUTOINCLUDE START "Page/Head.cs.ihtml" DO NOT REMOVE --> |
<link rel="StyleSheet" href="../../../../../Web/CSS/MLAB.css" type="text/css" title="MLAB základní styl"> |
<link rel="StyleSheet" href="../../../../../Web/CSS/MLAB_Print.css" type="text/css" media="print"> |
<link rel="shortcut icon" type="image/x-icon" href="../../../../../Web/PIC/MLAB.ico"> |
<script type="text/javascript" src="../../../../../Web/JS/MLAB_Menu.js"></script> |
<!-- AUTOINCLUDE END --> |
</head> |
<body lang="cs"> |
<!-- AUTOINCLUDE START "Page/Header.cs.ihtml" DO NOT REMOVE --> |
<!-- ============== HLAVICKA ============== --> |
<div class="Header"> |
<script type="text/javascript"> |
<!-- |
SetRelativePath("../../../../../"); |
DrawHeader(); |
// --> |
</script> |
<noscript> |
<p><b> Pro zobrazení (vložení) hlavičky je potřeba JavaScript </b></p> |
</noscript> |
</div> |
<!-- AUTOINCLUDE END --> |
<!-- AUTOINCLUDE START "Page/Menu.cs.ihtml" DO NOT REMOVE --> |
<!-- ============== MENU ============== --> |
<div class="Menu"> |
<script type="text/javascript"> |
<!-- |
SetRelativePath("../../../../../"); |
DrawMenu(); |
// --> |
</script> |
<noscript> |
<p><b> Pro zobrazení (vložení) menu je potřeba JavaScript </b></p> |
</noscript> |
</div> |
<!-- AUTOINCLUDE END --> |
<!-- ============== TEXT ============== --> |
<div class="Text"> |
<p class="Title"> |
Firmware USBasp pro modul AVRUSB |
</p> |
<p class=Autor> |
Milan Horkel |
</p> |
<p class="Subtitle"> |
Firmware USBasp umožňuje použít modul AVRUSB jako ISP programátor procesorů |
řady AVR pod všemi běžnými operačními systémy. |
</p> |
<p class="Subtitle"> |
<img width="640" height="319" src="FW_USBasp_soubory/image001.jpg" |
alt="Obrázek modulu AVRUSB01"> |
</p> |
<p> |
<a href="../FW_USBasp.cs.pdf"><img class="NoBorder" |
src="../../../../../Web/PIC/FileIco_PDF.ico" |
alt="Acrobat"> PDF verze</a> |
</p> |
<h1> Technické parametry </h1> |
<table> |
<tr> |
<th> Parametr </th> |
<th> Hodnota </th> |
<th> Poznámka </th> |
</tr> |
<tr> |
<td> Rozhraní </td> |
<td> USB </td> |
<td> Low Speed </td> |
</tr> |
<tr> |
<td> Protokol </td> |
<td> USBasp </td> |
<td> VENDOR ID 0x16c0<br> |
DEVICE ID 0x05dc </td> |
</tr> |
<tr> |
<td> Procesor </td> |
<td> ATmega8 ATmega88 </td> |
<td> Varianty překladu </td> |
</tr> |
<tr> |
<td> Podporované systémy </td> |
<td> WindowXP/7/8<br> |
Linux/Ubuntu/...<br> |
Android </td> |
<td> avrdude<br> |
avrdude<br> |
ZFlasher AVR </td> |
</tr> |
</table> |
<h1> Popis </h1> |
<p> |
Firmware USBasp je USB programátor pro procesory AVR s USB rozhraním realizovaným čistě |
programovými prostředky. Jako vhodný ovládací program lze použít rozšířený AVRDUDE. |
Firmware je přeložen ve variantách pro procesor ATmega8 a ATmega88. |
</p> |
<h2> Hardware </h2> |
<p> |
Konektor J9 slouží pro naprogramování firmwaru (při zapojené propojce J5, případně i J10), |
nebo pro připojení zařízení, které chceme programovat tímto USBasp programátorem. Zapojení |
je dle doporučení firmy Atmel (šestipinový ISP konektor). |
</p> |
<p> |
Programátor má vyvedeno USB napětí +5V na konektoru J3 (přes samoopravnou pojistku) a |
vnitřní napětí na J4 (+5V z USB pokud je zapojen J2, nebo +3.3V z vnitřního stabilizátoru). |
Toto vnitřní napětí je možné připojit na ISP konektor J9 pomocí propojky J10. |
</p> |
<p> |
Při programování cílového procesoru, který běží na nízkém kmitočtu je třeba snížit rychlost |
komunikace a toho lze docílit instalací propojky mezi piny 2 a 3 konektoru J6 (označené RX |
a GND). |
</p> |
<p> |
Červená LED indikuje přenos dat, zelená LED svítí jakmile se zařízení zapne. |
</p> |
<table> |
<tr> |
<th> Propojka </th> |
<th> Zapnuto </th> |
<th> Vypnuto </th> |
</tr> |
<tr> |
<td> J2 </td> |
<td> Napájení 5V z USB </td> |
<td> Napájení 3.3V ze stabilizátoru </td> |
</tr> |
<tr> |
<td> J5 </td> |
<td> Programování vlastního procesoru </td> |
<td> Funguje jako programátor </td> |
</tr> |
<tr> |
<td> J10 </td> |
<td> Napájení cílového zařízení </td> |
<td> Bez napájení cílového zařízení </td> |
</tr> |
<tr> |
<td> J6.2 - J6.3 </td> |
<td> Vnucený pomalý režim ISP </td> |
<td> Rychlost přenosu nastavuje program </td> |
</tr> |
</table> |
<h2> USBasp s Windows </h2> |
<p> |
Pod Windows je třeba nainstalovat driver libusb. Pro Windows7/8 jsou novější verze knihovny |
libusb podepsané a tak nepůsobí potíže. Drivery vybalíme z přiloženého originálního balíku, |
nebo stáhneme poslední verzi. |
</p> |
<p> |
<samp>SW/fw_usbasp/original/usbasp.2011-05-28.tar.gz</samp> |
</p> |
<p> |
Pokud používáte starší verzi programu avrdude, musíte použít starší verzi libusb (verze |
0.x) a pod Windows7/8 povolit použití nepodepsaných driverů. Nepodepsané drivery je možné |
povolit při startu systému pomocí volby F8 (při každém startu znova). |
</p> |
<p> |
Ověříme funkčnost (z příkazové řádky): |
</p> |
<code>C:\Users\miho>avrdude -c USBasp -p ATmega88 -F |
avrdude: AVR device initialized and ready to accept instructions |
Reading | ################################################## | 100% 0.00s |
avrdude: Device signature = 0x1e930a |
avrdude: safemode: Fuses OK |
avrdude done. Thank you. |
C:\Users\miho></code> |
<h2> USBasp s Linuxem </h2> |
<p> |
Pod linuxem by vše mělo fungovat bez komplikací. Program avrdude spouštíme s root |
oprávněním, aby se dostal k USB zařízení. Případně je možné systému říci, že pro toto |
zařízení není třeba root oprávnění vytvořením souboru |
<samp>/etc/udev/rules.d/99-USBasp.rules</samp> s tímto obsahem (maso je jedna dlouhá |
řádka): |
</p> |
<code># USBasp - USB programmer for Atmel AVR controllers |
# Copy this file to /etc/udev/rules.d so |
|
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", SYSFS{idVendor}=="16c0", SYSFS{idProduct}=="05dc", MODE="0666"</code> |
<p> |
Vzorový soubor opět nalezneme v přiloženém originálním balíku. |
</p> |
<p> |
<samp>SW/fw_usbasp/original/usbasp.2011-05-28.tar.gz</samp> |
</p> |
<p> |
Ověříme funkčnost (z terminálu): |
</p> |
<code>miho@bobik:~$ avrdude -c USBasp -p ATmega88 -F |
avrdude: AVR device initialized and ready to accept instructions |
Reading | ################################################## | 100% 0.01s |
avrdude: Device signature = 0x1e930a |
avrdude: safemode: Fuses OK |
avrdude done. Thank you. |
miho@bobik:~$</code> |
<h2> USBasp s Androidem </h2> |
<p> |
Do Android zařízení nakoupíme aplikaci ZFlasher AVR (je zdarma) a přes OTG-USB kabel |
připojíme programátor a je to. |
</p> |
<h1> Programování firmwaru </h1> |
<p> |
Do modulu AVRUSB musíme neprogramovat firmware. Děláme to jiným programátorem přes konektor |
J9. Nutno zapojit propojky J5 (povolení programování) a J10 (propojení napájení přes ISP |
konektor). Pokud neumí použitý programátor napájet cílovou aplikaci přes ISP konektor, |
musíme zapojit napájecí zdroj +3.3V nebo +5V na napájecí konektor J4, nebo připojit USB |
kabel. |
</p> |
<p> |
Dejte extra pozor při programování propojek ať si omylem nezakážete ISP programování. |
Raději dvakrát zkontrolujte typ procesoru a hodnotu propojek. |
</p> |
<p> |
Kdo nechce hledat parametry programu avrdude, tady je příklad pro procesor ATmega88 (je to |
1 dlouhá řádka a platí pro programátor picoweb na portu LPT1): |
</p> |
<p> |
<samp>avrdude -c picoweb -p ATmega88 -P lpt1 -u -U hfuse:w:0xDE:m -U lfuse:w:0xD7:m -U |
flash:w: usbasp_atmega88.hex</samp> |
</p> |
<table> |
<tr> |
<th> Procesor </th> |
<th> Soubor </th> |
<th> EFUSE </th> |
<th> HFUSE </th> |
<th> LFUSE </th> |
</tr> |
<tr> |
<td> ATmega8 </td> |
<td> usbasp_atmega8.hex </td> |
<td> </td> |
<td> HFUSE=0xC9 </td> |
<td> LFUSE=0x9F </td> |
</tr> |
<tr> |
<td> ATmega88 </td> |
<td> usbasp_atmega88.hex </td> |
<td> EFUSE=0xF9 </td> |
<td> HFUSE=0xDE </td> |
<td> LFUSE=0xD7 </td> |
</tr> |
</table> |
<h1> Překlad firmwaru </h1> |
<h2> Zdrojáky a úpravy </h2> |
<p> |
Zdojáky jsou z adresy <a href="http://www.fischl.de/usbasp">http://www.fischl.de/usbasp</a> |
</p> |
<p> |
Provedené úpravy spočívají v opravě definic IO vstupů a výstupů (důsledné použití definic |
pinů) a v doplnění překladu o automatický překlad všech variant firmwarů najednou. |
</p> |
<p> |
Pokud budete chtít upravovat zdroják pro jiný hardware, je třeba dát pozor na to, že |
definice hardwaru jsou rozstrkané do více zdrojáků. To jsem upravovat nechtěl, aby byla |
zachována co největší podobnost s původním stavem. |
</p> |
<p> |
Konfiguraci firmwaru shrnuje tabulka |
</p> |
<table> |
<tr> |
<th> Parametr </th> |
<th> Hodnota </th> |
<th> Poznámka </th> |
</tr> |
<tr> |
<td> USB D+ </td> |
<td> PD2 </td> |
<td> USB Data+, je současně signálem externího přerušení INT0 </td> |
</tr> |
<tr> |
<td> USB D- </td> |
<td> PD4 </td> |
<td> USB Data- </td> |
</tr> |
<tr> |
<td> LED Red </td> |
<td> PC0 </td> |
<td> Červená LED, aktivní L, indikuje přenos dat </td> |
</tr> |
<tr> |
<td> LED Green </td> |
<td> PC1 </td> |
<td> Zelená LED, aktivní L, svítí trvale </td> |
</tr> |
<tr> |
<td> SW </td> |
<td> PD0 </td> |
<td> Zpomalení rychlosti ISP komunikace, aktivní L </td> |
</tr> |
<tr> |
<td> Krystal </td> |
<td> 12.0MHz </td> |
<td> Nutno naprogramovat FUSE na externí krystal </td> |
</tr> |
<tr> |
<td> Procesor </td> |
<td> ATmega8<br> |
ATmega88 </td> |
<td> </td> |
</tr> |
</table> |
<h2> Překlad </h2> |
<p> |
Pro překlad je připravený Makefilepro je překlad variant pro procesory ATmega8 i ATmega88. |
</p> |
<p> |
<samp>make all</samp> |
</p> |
<p> |
Pro překlad pod Windows stačí nainstalovat balík <samp>WinAVR</samp> (mám |
WinAVR-20100110-install.exe). |
</p> |
<p> |
Pro překlad pod Linuxem potřebujete balíky <samp>gcc-avr</samp> a <samp>avr-libc</samp>. |
</p> |
</div> |
<!-- AUTOINCLUDE START "Page/Footer.cs.ihtml" DO NOT REMOVE --> |
<!-- ============== PATIČKA ============== --> |
<div class="Footer"> |
<script type="text/javascript"> |
<!-- |
SetRelativePath("../../../../../"); |
DrawFooter(); |
// --> |
</script> |
<noscript> |
<p><b> Pro zobrazení (vložení) hlavičky je potřeba JavaScript </b></p> |
</noscript> |
</div> |
<!-- AUTOINCLUDE END --> |
</body> |
</html> |
/Modules/AVR/AVRUSB01A/DOC/HTML/FW_USBasp_soubory/image001.jpg |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/SRC/AVRUSB01A.cs.doc |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/SRC/AVRUSB01A_Bot.JPG |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/SRC/AVRUSB01A_Top.JPG |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/SRC/FW_USBasp.cs.doc |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/DOC/SRC/i2c-avr-usb_top_big.jpg |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/SW/!____!.txt |
---|
0,0 → 1,5 |
Dalí zajímavé firmwary: |
http://dicks.home.xs4all.nl/avr/usbtiny/ |
http://www.obdev.at/products/vusb/avrdoper.html |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile |
---|
0,0 → 1,28 |
# Supported targets: |
# atmega8 atmega88 attiny45 (attiny45 is not usable in a board AVRUSB01A, it has different package) |
# |
# If compiled on Linux do this |
# chmod +x checksize |
ALL_TARGETS=atmega8 atmega88 attiny45 |
# Execute these steps for each target CPU |
# Do not remove empty line in this definition! |
define EXEC |
echo ************* $(1) ************* avrusb ************* |
rm -f i2c_tiny_usb_avrusb_$(1).hex |
make -f Makefile-avrusb.$(1) clean |
make -f Makefile-avrusb.$(1) all |
cp firmware.hex i2c_tiny_usb_avrusb_$(1).hex |
make -f Makefile-avrusb.$(1) clean |
echo ************* $(1) ************* usbtiny ************* |
rm -f i2c_tiny_usb_usbtiny_$(1).hex |
make -f Makefile-usbtiny.$(1) clobber |
make -f Makefile-usbtiny.$(1) all |
cp main.hex i2c_tiny_usb_usbtiny_$(1).hex |
make -f Makefile-usbtiny.$(1) clobber |
endef |
all: |
@$(foreach III,$(ALL_TARGETS),$(call EXEC,$(III))) |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/bin/i2c_tiny_usb_avrusb_atmega8.hex |
---|
0,0 → 1,338 |
:10000000DDC068C2F6C0F5C0F4C0F3C0F2C0F1C0F4 |
:10001000F0C0EFC0EEC0EDC0ECC0EBC0EAC0E9C07C |
:10002000E8C0E7C0E6C0040309041A0354006900ED |
:100030006C006C00200048006100720062006100EA |
:1000400075006D001A036900320063002D00740012 |
:1000500069006E0079002D007500730062001201C6 |
:100060001001FF000008030431C605010102000170 |
:1000700009021200010100800509040000000000CF |
:1000800000000100FF8E6932632D74696E792D7551 |
:100090007362202D20286329203230303620627987 |
:1000A0002054696C6C204861726261756D0A006E43 |
:1000B0006F7420696E2061636B2073746174650ACC |
:1000C000007772697465206661696C65640A006412 |
:1000D000617461203D2025780A0065786365656458 |
:1000E00073210A007772697465202564206279742F |
:1000F00065732C202564206578700A006E6F74206B |
:10010000696E2061636B2073746174650A006461B9 |
:100110007461203D2025780A006578636565647305 |
:10012000210A007265616420256420627974657318 |
:100130002C202564206578700A00726571756573DE |
:100140007420666F722064656C6179202564757314 |
:100150000A0053657475702025782025782025784D |
:100160002025780A0049324320726561643A206193 |
:10017000646472657373206572726F72204020250B |
:10018000780A006932632025732061742030782555 |
:100190003032782C206C656E203D2025640A0049A1 |
:1001A000324320646576696365206174206164640C |
:1001B0007265737320307825780A000011241FBE01 |
:1001C000CFE5D4E0DEBFCDBF10E0A0E6B0E0E6EEC4 |
:1001D000F4E102C005900D92AA37B107D9F710E0FB |
:1001E000AAE7B0E001C01D92A33BB107E1F7F0D34D |
:1001F00078C906CF85B7836085BF8BB780648BBF16 |
:100200000895FF920F931F93CF93DF936091930014 |
:10021000662351F180919000CCE0D0E0C81BD10959 |
:10022000C956DF4F635080918F008D3279F08091F5 |
:100230007A0087FD11C0CE0102D48F3F09F494C02B |
:10024000882309F48EC090E080E008C08AE580939E |
:100250006100683009F4A7C090E880E090937A00CC |
:1002600080936000109293008091610084FF26C00B |
:10027000809160008F3F11F1182F8930A0F5811B0C |
:100280008093600080917A0080FD35C02BE4F22ECF |
:100290008F5F80937A0087FD35C0112309F054C029 |
:1002A00004E084E890E0612F86D2183019F08FEFD7 |
:1002B00080936000F0928300009361009AE080B325 |
:1002C000847159F49150D9F71092940010928E00D5 |
:1002D0008FEF60E070E040E085D2DF91CF911F9119 |
:1002E0000F91FF90089518E0811B8093600080912A |
:1002F0007A0080FFCBCF93ECF92E8F5F80937A004A |
:1003000087FFCBCFC0919100D091920086FD32C083 |
:10031000112399F01150DE01E4E8F0E0412F50E0A4 |
:100320001F5F9A012B573F4F8D918193E217F3077F |
:10033000D9F74F5F5F4FC40FD51FD0939200C09382 |
:100340009100012F0C5FADCF84E890E0612F29D49C |
:10035000182F893008F4A4C08FEF809360000EE15D |
:10036000A9CF90E08FEF7ACF8EE18093610090E08B |
:100370008FEF74CF112309F311509E01A4E8B0E070 |
:10038000612F70E01F5FAB014B575F4FF901849104 |
:100390008D932F5F3F4FA417B507C1F76F5F7F4F56 |
:1003A000C60FD71FCACF8881807629F52CE830E0A8 |
:1003B00010928C008981882389F410928D003093EB |
:1003C00092002093910090E822E08F81882321F40D |
:1003D0008E81821708F442CF822F40CF8530B9F04A |
:1003E0008630F1F0883031F18930A1F18A3059F14D |
:1003F00090E820E0EACFCE017CD4282F8F3F09F08F |
:100400004DC0888187FD09C08FEF90E027CF8A819A |
:100410008093940090E820E0D8CF8E8190E01ECFAA |
:100420008B81813031F18230D9F0833059F190ECF9 |
:1004300020E0CBCF86E990E09093920080939100EA |
:1004400090E821E0C2CF309392002093910090E891 |
:1004500021E0BBCF8A818093960090E820E0B5CF61 |
:1004600080E790E0909392008093910090EC22E1DD |
:10047000ACCF8EE590E0909392008093910090EC49 |
:1004800022E1A3CF8A81882371F486E290E09093E1 |
:1004900092008093910090EC24E097CF90E895CF64 |
:1004A000082F0C5FFECE813061F0823009F0BFCFA3 |
:1004B00084E490E0909392008093910090EC2AE184 |
:1004C00084CF8AE290E0909392008093910090EC28 |
:1004D0002AE17BCFCF93CFB7CF93849BFECF849B72 |
:1004E00009C0849B07C0849B05C0849B03C0849B78 |
:1004F00001C09EC0DF93C0919000DD27C956DF4F39 |
:10050000849B02C0DF91EBCF2F930F931F9300B317 |
:100510002FEF04FB20F94F933F9310B34FEF0127C8 |
:1005200004FB21F93BE031C04E7F012F10B3216065 |
:1005300028C0102F4D7F2260000000B329C04B7FE0 |
:100540002460012F000010B32BC010B3477F286038 |
:100550002AC04F7E00B320612CC04F7D10B32062B3 |
:100560002FC04F7B00B3206432C0422700B34993B1 |
:100570004FEF0000102714FB20F910B31471A9F1FC |
:10058000297F91F2012704FB21F900B3237F89F22F |
:100590003150F0F1102714FB22F910B3277E79F2C5 |
:1005A000012704FB23F92F7C81F200B3102714FBF1 |
:1005B00024F92F7971F200C010B3012704FB25F94B |
:1005C0002F7359F200C000B3102714FB26F9223014 |
:1005D00040F200C010B3012704FB27F9243028F6AD |
:1005E0004F77206810B30000F9CF3B50319533307E |
:1005F00010E41ABFB8F0C31BD0400881033C41F19E |
:100600000B3431F11981412F1F7720918E00121781 |
:1006100031F4093691F10D3279F0013E69F022276B |
:10062000209395003F914F911F910F912F91DF9152 |
:10063000CF91CFBFCF911895009395003F914F91E7 |
:100640001F910F912F91DF91CAB7C6FD46CFF0CF12 |
:1006500000919500002331F310919300112349F587 |
:1006600034304AF13093930000938F001091900042 |
:100670003BE0311B309390001EC00091930001308D |
:10068000C4F40AE53091610034FD17C000936100A5 |
:10069000C3E8D0E016C0052710E002BB1FC0052745 |
:1006A00022C0052727C005272CC0052710E002BB64 |
:1006B00033C04AE503C042ED01C0432FC4E1D0E09E |
:1006C00032E011B31461949A02B311BB5F9354E109 |
:1006D00020E820FF052702BB279517951C3FD8F679 |
:1006E00020FF0527279502BB17951C3FC0F620FF6A |
:1006F00005272795179502BB1C3F98F620FF052775 |
:10070000279517951C3F02BB70F600C0499120FF4A |
:10071000052702BB279517951C3F38F620FF0527B4 |
:10072000279502BB17951C3F38F520FF0527279515 |
:10073000179502BB1C3F10F520FF0527279517953D |
:100740001C3F02BBE8F4242F3A9519F60B7E5F910B |
:1007500002BB00C010919400C651D04011F010931C |
:100760008E0010E41ABF006111B31B7E402F4B7E38 |
:1007700002BB11BB42BB56CF0527D3CF0527D8CF2D |
:100780000527DDCFA82FB92F8FEF9FEF41E050EA6B |
:10079000615070F02D9138E0722F782796958795EB |
:1007A000269570FF02C0842795273A95A9F7F0CFC8 |
:1007B000809590950895E6DF8D939D930895982FE9 |
:1007C00092959F709A3008F0995D5D9BFECF905D89 |
:1007D0009CB98F708A3008F0895D5D9BFECF805D8B |
:1007E0008CB90895FF920F931F93CF93DF93062F39 |
:1007F000F72E142FE4DF5D9BFECF8AE38CB9112323 |
:10080000A1F01150802F9F2DEC0180E2F82ECE0137 |
:10081000810F911D8C015D9BFECFFCB88881CFDFDD |
:10082000C017D10711F02196F6CF5D9BFECF8DE06A |
:100830008CB95D9BFECF8AE08CB9DF91CF911F917F |
:100840000F91FF9008951F93182F8A3039F05D9B08 |
:10085000FECF1CB980E090E01F9108958DE0F3DF9A |
:10086000F6CF882319F4A49AAC980895A498AC9A6A |
:100870000895E0917800F09179003197F1F788239D |
:1008800059F0A598AD9A9D9BFECF809176009091EE |
:1008900077000197F1F70895A59AAD98F6CF81E01A |
:1008A000E8DF80E0E6DF089580E0DBDF80E0E1DF85 |
:1008B000089580E0D6DF81E0DCDF81E0D2DF0895BB |
:1008C0000F931F93CF93DF93082F10E0C7E0D0E082 |
:1008D00008C081E0C6DFE3DF21978FEFCF3FD80765 |
:1008E00089F0C8010C2E02C0959587950A94E2F70D |
:1008F00080FDEFCF80E0B5DFD2DF21978FEFCF3FD4 |
:10090000D80779F781E0ADDF81E0B3DF13B380E092 |
:10091000B0DF12951F701095812F8170DF91CF91FC |
:100920001F910F910895FF920F931F93F82E81E06E |
:1009300098DF80E09EDF17E000E081E09ADF000FA3 |
:100940009C99016080E095DF1150B8F7FF2051F4C9 |
:1009500080E087DFA4DF81E084DF802F1F910F918B |
:10096000FF90089581E07DDF9ADF81E07ADF802FBC |
:100970001F910F91FF9008950F931F93CF93DF93D3 |
:10098000C0E0D0E00FE911E005C093DF2196CF373A |
:10099000D105C9F089DF9E01220F822F91DF8823C4 |
:1009A000A1F300D000D0EDB7FEB712830183D4834A |
:1009B000C383CFD20F900F900F900F907ADF2196C4 |
:1009C000CF37D10539F7DF91CF911F910F9108955E |
:1009D0002EE088E190E00FB6F894A89581BD0FBE97 |
:1009E00021BD539A82E089B988E690E09093B000E7 |
:1009F0008093AF0000D086E890E0EDB7FEB7928319 |
:100A00008183A7D2A498AC9AA598AD9A1092810040 |
:100A1000109280000F900F90AFDF82B38B7E82BB6D |
:100A200081B3846181BB80E49CE90197F1F781B3D4 |
:100A30008B7E81BBDFDB7894A895E3DBFDCFDF9273 |
:100A4000EF92FF920F931F93CF93DF93D82E092F2E |
:100A5000162F00D000D000D0EDB7FEB7319684EE4F |
:100A600090E0ADB7BEB712969C938E9311976283B8 |
:100A7000138280918000909181009583848369D254 |
:100A8000EDB7FEB736960FB6F894FEBF0FBEEDBFBA |
:100A900080917B00813009F054C0212F30E080919B |
:100AA0008000909181008217930708F464C011239D |
:100AB00009F475C08D2D902F9C01E90100E08FECA9 |
:100AC000E82E80E0F82E80918000909181000197BF |
:100AD000909381008093800000D000D0EDB7FEB7E6 |
:100AE0003196ADB7BEB71296FC92EE9211978881FF |
:100AF000828313822ED20F900F900F900F908991C6 |
:100B0000DFDE882309F401E0FE01ED19E117D8F2D8 |
:100B10008091820081FF06C08091800090918100C9 |
:100B2000892BD9F10023F1F000D081EC90E0ADB732 |
:100B3000BEB712969C938E9311970BD20F900F9085 |
:100B400011C000D08FEA90E0EDB7FEB792838183A9 |
:100B500000D20F900F908D2D902F60E070E0412F0C |
:100B600050E0F0D1812FDF91CF911F910F91FF9035 |
:100B7000EF90DF90089500D08AED90E0ADB7BEB75A |
:100B800012969C938E931197E4D1109180000F9050 |
:100B90000F90112309F08ECF02C08BDEC3CF00E08F |
:100BA000B7CFEF92FF920F931F93CF93DF93082F4E |
:100BB000F92E162F00D000D000D0EDB7FEB7319639 |
:100BC00083E291E0ADB7BEB712969C938E931197D6 |
:100BD0006283138280918000909181009583848349 |
:100BE000B8D1EDB7FEB736960FB6F894FEBF0FBE7C |
:100BF000EDBF80917B00813009F04CC0212F30E0A7 |
:100C000080918000909181008217930708F45DC065 |
:100C1000112371F1802F9F2D9C01E9019EE0E92EA7 |
:100C200091E0F92E8091800090918100019790933E |
:100C300081008093800020E0892B09F421E0822F3D |
:100C400072DE899300D000D0EDB7FEB73196ADB714 |
:100C5000BEB71296FC92EE9211978283138279D1DD |
:100C6000FE01E01B0F900F900F900F90E117D0F254 |
:100C70008091820081FF06C0809180009091810068 |
:100C8000892BA9F1812FDF91CF911F910F91FF90B7 |
:100C9000EF90089500D08CEF90E0ADB7BEB71296FC |
:100CA0009C938E93119755D10F900F90802F9F2D6D |
:100CB00060E070E0412F50E045D1812FDF91CF916E |
:100CC0001F910F91FF90EF90089500D089E191E07E |
:100CD000ADB7BEB712969C938E9311973AD11091EF |
:100CE00080000F900F90112309F094CFC1CFE1DD68 |
:100CF000C9CF0F931F93CF93DF93EC010CE710E064 |
:100D000010939200009391002DB73EB72A503040C7 |
:100D10000FB6F8943EBF0FBE2DBFEDB7FEB73196AC |
:100D200082E591E0ADB7BEB712969C938E93119772 |
:100D30008881828313828981848315828A81868354 |
:100D400017828B818087118604D1EDB7FEB73A9662 |
:100D50000FB6F894FEBF0FBEEDBF8981823009F453 |
:100D600079C0833008F44FC0833009F4A3C08830C1 |
:100D700008F05EC08A8180FDB1C022E630E0EDB7A8 |
:100D8000FEB738970FB6F894FEBF0FBEEDBF319691 |
:100D900083E891E0ADB7BEB712969C938E931197FE |
:100DA000338322838C819D81958384838E819F816F |
:100DB00097838683CED01C81110F8A81EDB7FEB751 |
:100DC00038960FB6F894FEBF0FBEEDBF80FD1160E0 |
:100DD000898180FF86C068DD812F72DD882309F458 |
:100DE00089C081E080937B002E813F813093810018 |
:100DF0002093800089818093820081FF17C0232B7C |
:100E000091F08FEF16C08823C9F0813089F4C801B2 |
:100E100062E870E044E050E08CD084E0DF91CF9154 |
:100E20001F910F91089545DD2E813F81232B49F7B6 |
:100E300080E0DF91CF911F910F9108958A81809377 |
:100E40007C008B8180937D0082E0DF91CF911F91A8 |
:100E50000F9108952A813B8130937700209376008B |
:100E60002115310589F581E090E09093770080931A |
:100E7000760021E030E081E090E09093790080936B |
:100E8000780000D000D08AE391E0ADB7BEB71296EB |
:100E90009C938E93119714963C932E93139759D04D |
:100EA00080E00F900F900F900F90DF91CF911F91E6 |
:100EB0000F91089580917B0080937C0081E0DF9109 |
:100EC000CF911F910F910895C901969587959093A1 |
:100ED000790080937800892BA1F6CDCF25E630E00C |
:100EE0004ECF81E0BEDC81E0C4DC80E0BADC80E093 |
:100EF000C0DC72CF00D000D0EDB7FEB7319685E6EA |
:100F000091E0ADB7BEB712969C938E931197128362 |
:100F100013821FD082E080937B0010928100109298 |
:100F200080000F900F900F900F90C3DC2E813F81B7 |
:100F30007DCFFB01DC0102C005900D924150504075 |
:100F4000D8F70895DC0101C06D9341505040E0F79F |
:100F50000895A0E0B0E0EEEAF7E09CC2FE0135960D |
:100F600061917191A091AF00B091B00013968C91F6 |
:100F70001397886013968C938091AF009091B00086 |
:100F8000AF010AD0E091AF00F091B0002381277F3C |
:100F900023832096E2E09AC2ABE0B0E0E1EDF7E017 |
:100FA00069C23C012B015A01FC0117821682838120 |
:100FB00081FD03C06FEF7FEFB9C19AE0892E1E015A |
:100FC0000894211C311CF3012381F20123FD85913A |
:100FD00023FF81912F01882309F4A5C1853239F4BB |
:100FE00023FD859123FF81912F01853221F490E02B |
:100FF000B301B6D1E8CF982FFF24EE249924FFE166 |
:10100000FF15D0F09B3269F09C3228F4903259F0F1 |
:10101000933291F40EC09D3249F0903369F441E06F |
:1010200024C052E0F52A84E0F82A28C098E0F92A82 |
:1010300025C0E0E1FE2A22C0F7FC29C0892F805399 |
:101040008A3070F4F6FE05C0989C902C1124980EFE |
:1010500015C0E89CE02C1124E80EF0E2FF2A0EC037 |
:101060009E3229F4F6FC5FC140E4F42A07C09C36A6 |
:1010700019F450E8F52A02C0983649F4F20123FD2C |
:10108000959123FF91912F01992309F0B8CF892FD2 |
:101090008554833018F08052833038F444E050E0B7 |
:1010A000A40EB51E5FE359830FC0933631F093371A |
:1010B00079F0933509F052C01FC0F5018081898312 |
:1010C00042E050E0A40EB51E610101E010E011C045 |
:1010D000F501C080D180F6FC03C06FEF7FEF02C046 |
:1010E000692D70E042E050E0A40EB51EC6012DD17E |
:1010F0008C015FE7F52213C0F501C080D180F6FCBA |
:1011000003C06FEF7FEF02C0692D70E042E050E056 |
:10111000A40EB51EC6010ED18C0150E8F52AF3FECF |
:1011200006C018C080E290E0B3011AD1EA948E2D77 |
:1011300090E008171907B0F30DC0F601F7FC859190 |
:10114000F7FE81916F0190E0B3010AD1E110EA94BA |
:10115000015010400115110581F7E2C0943611F0DD |
:10116000993661F5F7FE08C0F50120813181428191 |
:10117000538184E090E00AC0F501808191819C0157 |
:10118000442737FD4095542F82E090E0A80EB91E09 |
:101190009FE6F92257FF09C050954095309521955B |
:1011A0003F4F4F4F5F4FE0E8FE2ACA01B901A1014E |
:1011B0002AE030E001D1D82ED2183FC0953729F46B |
:1011C0001F2D1F7E2AE030E01DC01F2D197F9F3686 |
:1011D00061F0903720F4983509F0A5C00FC0903722 |
:1011E00039F0983709F09FC004C028E030E00AC009 |
:1011F000106114FD146020E130E004C014FD16609D |
:1012000020E132E017FF08C0F50160817181828121 |
:10121000938144E050E008C0F50180819181BC01D8 |
:1012200080E090E042E050E0A40EB51EA101C4D0E1 |
:10123000D82ED2188FE7F82EF122F6FE0BC05EEF03 |
:10124000F522D91438F4F4FE07C0F2FC05C08FEE85 |
:10125000F82202C01D2D01C0192DF4FE0DC0FE01A3 |
:10126000ED0DF11D8081803319F499EEF92208C04B |
:101270001F5FF2FE05C003C08F2D867809F01F5F47 |
:101280000F2DF3FC13C0F0FE0EC01E1510F09D2CA8 |
:101290000AC09D2C9E0C911A1E2D05C080E290E084 |
:1012A000B3015ED01F5F1E15C8F304C01E1510F4F5 |
:1012B000E11A01C0EE2404FF0EC080E390E0B30108 |
:1012C0004FD002FF1BC001FD03C088E790E00EC0B5 |
:1012D00088E590E00BC0802F867881F001FF02C086 |
:1012E0008BE201C080E2F7FC8DE290E0B30138D0E0 |
:1012F00005C080E390E0B30133D09A94D914C8F3C9 |
:10130000DA94F101ED0DF11D808190E0B30128D058 |
:10131000DD20B1F705C080E290E0B30121D0EA946E |
:10132000EE20C9F750CEF30166817781CB012B9671 |
:10133000E2E1BCC0FC010590615070400110D8F79B |
:10134000809590958E0F9F1F0895FC01615070400D |
:1013500001900110D8F7809590958E0F9F1F0895EA |
:101360000F931F93CF93DF938C01EB018B8181FF50 |
:101370001BC082FF0DC02E813F818C819D8128176B |
:10138000390764F4E881F9810193F983E88306C0A1 |
:10139000E885F985802F0995892B31F48E819F810D |
:1013A00001969F838E8302C00FEF1FEFC801DF916C |
:1013B000CF911F910F910895FA01AA27283051F17A |
:1013C000203181F1E8946F936E7F6E5F7F4F8F4F76 |
:1013D0009F4FAF4FB1E03ED0B4E03CD0670F781FD5 |
:1013E000891F9A1FA11D680F791F8A1F911DA11DBA |
:1013F0006A0F711D811D911DA11D20D009F46894F3 |
:101400003F912AE0269F11243019305D3193DEF69A |
:10141000CF010895462F4770405D4193B3E00FD050 |
:10142000C9F7F6CF462F4F70405D4A3318F0495D3B |
:1014300031FD4052419302D0A9F7EACFB4E0A6951E |
:101440009795879577956795BA95C9F70097610540 |
:10145000710508959B01AC010A2E06945795479596 |
:1014600037952795BA95C9F7620F731F841F951F8B |
:10147000A01D08952F923F924F925F926F927F929C |
:101480008F929F92AF92BF92CF92DF92EF92FF9294 |
:101490000F931F93CF93DF93CDB7DEB7CA1BDB0B40 |
:1014A0000FB6F894DEBF0FBECDBF09942A883988E5 |
:1014B00048885F846E847D848C849B84AA84B984EC |
:1014C000C884DF80EE80FD800C811B81AA81B981F8 |
:1014D000CE0FD11D0FB6F894DEBF0FBECDBFED010C |
:0614E0000895F894FFCF0F |
:1014E600FF5A7772007264000000000200000000DC |
:0A14F6002304000000000A000500B6 |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/bin/i2c_tiny_usb_avrusb_atmega88.hex |
---|
0,0 → 1,343 |
:10000000E4C06FC2FDC0FCC0FBC0FAC0F9C0F8C0BC |
:10001000F7C0F6C0F5C0F4C0F3C0F2C0F1C0F0C044 |
:10002000EFC0EEC0EDC0ECC0EBC0EAC0E9C0E8C074 |
:10003000E7C0E6C0040309041A03540069006C0019 |
:100040006C002000480061007200620061007500D1 |
:100050006D001A036900320063002D00740069000E |
:100060006E0079002D00750073006200120110010E |
:10007000FF000008030431C6050101020001090266 |
:1000800012000101008005090400000000000000CA |
:100090000100FF8E6932632D74696E792D7573626C |
:1000A000202D2028632920323030362062792054D8 |
:1000B000696C6C204861726261756D0A006E6F74C4 |
:1000C00020696E2061636B2073746174650A007728 |
:1000D00072697465206661696C65640A00646174A4 |
:1000E00061203D2025780A00657863656564732189 |
:1000F0000A007772697465202564206279746573DB |
:100100002C202564206578700A006E6F7420696E5B |
:100110002061636B2073746174650A0064617461AB |
:10012000203D2025780A0065786365656473210A9F |
:1001300000726561642025642062797465732C20E7 |
:100140002564206578700A00726571756573742086 |
:10015000666F722064656C617920256475730A008E |
:100160005365747570202578202578202578202502 |
:10017000780A0049324320726561643A2061646400 |
:1001800072657373206572726F7220402025780A41 |
:100190000069326320257320617420307825303265 |
:1001A000782C206C656E203D2025640A004932437E |
:1001B000206465766963652061742061646472659A |
:1001C000737320307825780A000011241FBECFEF0A |
:1001D000D4E0DEBFCDBF11E0A0E0B1E0E6E3F5E1A1 |
:1001E00002C005900D92AA31B107D9F711E0AAE13A |
:1001F000B1E001C01D92A335B107E1F707D499C959 |
:10020000FFCEE9E6F0E0808183608083E89A08957C |
:10021000FF920F931F93CF93DF9360913301662377 |
:1002200051F180913001CCE0D0E0C81BD109C95C0C |
:10023000DE4F635080912F018D3279F080911A0149 |
:1002400087FD11C0CE0123D48F3F09F494C08823C9 |
:1002500009F48EC090E080E008C08AE58093010137 |
:10026000683009F4A7C090E880E090931A01809369 |
:100270000001109233018091010184FF26C080911A |
:1002800000018F3F11F1182F8930A0F5811B809359 |
:10029000000180911A0180FD35C02BE4F22E8F5FA2 |
:1002A00080931A0187FD35C0112309F054C004E082 |
:1002B00084E291E0612F86D2183019F08FEF80939D |
:1002C0000001F0922301009301019AE089B1847149 |
:1002D00059F49150D9F71092340110922E018FEFFA |
:1002E00060E070E040E08DD2DF91CF911F910F91DF |
:1002F000FF90089518E0811B8093000180911A01FE |
:1003000080FFCBCF93ECF92E8F5F80931A0187FF8C |
:10031000CBCFC0913101D091320186FD32C0112383 |
:1003200099F01150DE01E4E2F1E0412F50E01F5F4F |
:100330009A012B5D3E4F8D918193E217F307D9F718 |
:100340004F5F5F4FC40FD51FD0933201C09331016F |
:10035000012F0C5FADCF84E291E0612F4AD4182FBA |
:10036000893008F4A4C08FEF809300010EE1A9CF7B |
:1003700090E08FEF7ACF8EE18093010190E08FEFD4 |
:1003800074CF112309F311509E01A4E2B1E0612F53 |
:1003900070E01F5FAB014B5D5E4FF90184918D935F |
:1003A0002F5F3F4FA417B507C1F76F5F7F4FC60F91 |
:1003B000D71FCACF8881807629F52CE231E01092D0 |
:1003C0002C018981882389F410922D013093320108 |
:1003D0002093310190E822E08F81882321F48E81DF |
:1003E000821708F442CF822F40CF8530B9F0863093 |
:1003F000F1F0883031F18930A1F18A3059F190E87B |
:1004000020E0EACFCE019DD4282F8F3F09F04DC0C8 |
:10041000888187FD09C08FEF90E027CF8A81809384 |
:10042000340190E820E0D8CF8E8190E01ECF8B8100 |
:10043000813031F18230D9F0833059F190EC20E0F5 |
:10044000CBCF86E391E0909332018093310190E825 |
:1004500021E0C2CF309332012093310190E821E0B6 |
:10046000BBCF8A818093360190E820E0B5CF8EE73C |
:1004700090E0909332018093310190EC22E1ACCF77 |
:100480008CE690E0909332018093310190EC22E170 |
:10049000A3CF8A81882371F484E390E090933201A2 |
:1004A0008093310190EC24E097CF90E895CF082F0E |
:1004B0000C5FFECE813061F0823009F0BFCF82E563 |
:1004C00090E0909332018093310190EC2AE184CF47 |
:1004D00088E390E0909332018093310190EC2AE11F |
:1004E0007BCFCF93CFB7CF934C9BFECF4C9B09C014 |
:1004F0004C9B07C04C9B05C04C9B03C04C9B01C050 |
:100500009EC0DF93C0913001DD27C95CDE4F4C9B5C |
:1005100002C0DF91EBCF2F930F931F9309B12FEF01 |
:1005200004FB20F94F933F9319B14FEF012704FBD0 |
:1005300021F93BE031C04E7F012F19B1216028C065 |
:10054000102F4D7F2260000009B129C04B7F24602D |
:10055000012F000019B12BC019B1477F28602AC0B4 |
:100560004F7E09B120612CC04F7D19B120622FC090 |
:100570004F7B09B1206432C0422709B149934FEF44 |
:100580000000102714FB20F919B11471A9F1297F7B |
:1005900091F2012704FB21F909B1237F89F231503F |
:1005A000F0F1102714FB22F919B1277E79F2012707 |
:1005B00004FB23F92F7C81F209B1102714FB24F9E5 |
:1005C0002F7971F200C019B1012704FB25F92F73AF |
:1005D00059F200C009B1102714FB26F9223040F26D |
:1005E00000C019B1012704FB27F9243028F64F7702 |
:1005F000206819B10000F9CF3B503195333011E03C |
:100600001CBBB8F0C31BD0400881033C41F10B3444 |
:1006100031F11981412F1F7720912E01121731F4EA |
:10062000093691F10D3279F0013E69F022272093CD |
:1006300035013F914F911F910F912F91DF91CF91F4 |
:10064000CFBFCF911895009335013F914F911F91E6 |
:100650000F912F91DF91CCB3C0FD46CFF0CF009129 |
:100660003501002331F310913301112349F5343062 |
:100670004AF13093330100932F01109130013BE098 |
:10068000311B309330011EC0009133010130C4F49E |
:100690000AE53091010134FD17C000930101C3E266 |
:1006A000D1E016C0052710E00BB91FC0052722C0F6 |
:1006B000052727C005272CC0052710E00BB933C03C |
:1006C0004AE503C042ED01C0432FC4E1D0E032E06F |
:1006D0001AB114615C9A0BB11AB95F9354E120E826 |
:1006E00020FF05270BB9279517951C3FD8F620FF4B |
:1006F000052727950BB917951C3FC0F620FF052746 |
:10070000279517950BB91C3F98F620FF05272795CD |
:1007100017951C3F0BB970F600C0499120FF0527C3 |
:100720000BB9279517951C3F38F620FF052727950D |
:100730000BB917951C3F38F520FF0527279517950E |
:100740000BB91C3F10F520FF0527279517951C3F77 |
:100750000BB9E8F4242F3A9519F60B7E5F910BB98B |
:1007600000C010913401C651D04011F010932E01F9 |
:1007700011E01CBB00611AB11B7E402F4B7E0BB9F0 |
:100780001AB94BB956CF0527D3CF0527D8CF0527A0 |
:10079000DDCFA82FB92F8FEF9FEF41E050EA6150D6 |
:1007A00070F02D9138E0722F7827969587952695D1 |
:1007B00070FF02C0842795273A95A9F7F0CF80955E |
:1007C00090950895E6DF8D939D930895282F982F97 |
:1007D00092959F709A3008F0995D8091C00085FFD6 |
:1007E000FCCF905D9093C600922F9F709A3008F0D6 |
:1007F000995D8091C00085FFFCCF905D9093C6000D |
:100800000895FF920F931F93CF93DF93062FF72E38 |
:10081000142FDCDF8091C00085FFFCCF8AE380933A |
:10082000C6001123B9F01150802F9F2DEC0180E2FA |
:10083000F82ECE01810F911D8C018091C00085FFA3 |
:10084000FCCFF092C6008881C1DFC017D10711F03C |
:100850002196F3CF8091C00085FFFCCF8DE080937F |
:10086000C6008091C00085FFFCCF8AE08093C6005F |
:10087000DF91CF911F910F91FF9008951F93182F33 |
:100880008A3051F08091C00085FFFCCF1093C600E4 |
:1008900080E090E01F9108958DE0F0DFF3CF882392 |
:1008A00019F43C9A449808953C98449A0895E0912C |
:1008B0001801F09119013197F1F7882359F03D980B |
:1008C000459A359BFECF80911601909117010197B3 |
:1008D000F1F708953D9A4598F6CF81E0E8DF80E092 |
:1008E000E6DF089580E0DBDF80E0E1DF089580E06F |
:1008F000D6DF81E0DCDF81E0D2DF08950F931F9324 |
:10090000CF93DF93082F10E0C7E0D0E008C081E06C |
:10091000C6DFE3DF21978FEFCF3FD80789F0C8010B |
:100920000C2E02C0959587950A94E2F780FDEFCFD3 |
:1009300080E0B5DFD2DF21978FEFCF3FD80779F77F |
:1009400081E0ADDF81E0B3DF16B180E0B0DF12956A |
:100950001F701095812F8170DF91CF911F910F91A2 |
:100960000895FF920F931F93F82E81E098DF80E0A7 |
:100970009EDF17E000E081E09ADF000F349901600C |
:1009800080E095DF1150B8F7FF2051F480E087DF59 |
:10099000A4DF81E084DF802F1F910F91FF900895E5 |
:1009A00081E07DDF9ADF81E07ADF802F1F910F9158 |
:1009B000FF9008950F931F93CF93DF93C0E0D0E093 |
:1009C0000DEA11E005C093DF2196CF37D105C9F0BC |
:1009D00089DF9E01220F822F91DF8823A1F300D0AF |
:1009E00000D0EDB7FEB712830183D483C383D9D27D |
:1009F0000F900F900F900F907ADF2196CF37D1058F |
:100A000039F7DF91CF911F910F9108952EE088E182 |
:100A100090E00FB6F894A895809360000FBE2093E5 |
:100A200060008091C10088608093C10082E090E006 |
:100A30009093C5008093C40088E091E090935001AA |
:100A400080934F0100D084E990E0EDB7FEB7928328 |
:100A50008183A7D23C98449A3D98459A10922101EF |
:100A6000109220010F900F90A5DF8BB18B7E8BB978 |
:100A70008AB184618AB980E49CE90197F1F78AB16F |
:100A80008B7E8AB9BEDB7894A895C2DBFDCFDF925E |
:100A9000EF92FF920F931F93CF93DF93D82E092FDE |
:100AA000162F00D000D000D0EDB7FEB7319682EF00 |
:100AB00090E0ADB7BEB712969C938E931197628368 |
:100AC000138280912001909121019583848369D2C2 |
:100AD000EDB7FEB736960FB6F894FEBF0FBEEDBF6A |
:100AE00080911B01813009F054C0212F30E08091AA |
:100AF0002001909121018217930708F464C011230B |
:100B000009F475C08D2D902F9C01E90100E08DED59 |
:100B1000E82E80E0F82E809120019091210101972C |
:100B2000909321018093200100D000D0EDB7FEB753 |
:100B30003196ADB7BEB71296FC92EE9211978881AE |
:100B4000828313822ED20F900F900F900F90899175 |
:100B5000D5DE882309F401E0FE01ED19E117D8F292 |
:100B60008091220181FF06C0809120019091210196 |
:100B7000892BD9F10023F1F000D08FEC90E0ADB7D4 |
:100B8000BEB712969C938E9311970BD20F900F9035 |
:100B900011C000D08DEB90E0EDB7FEB7928381835A |
:100BA00000D20F900F908D2D902F60E070E0412FBC |
:100BB00050E0F0D1812FDF91CF911F910F91FF90E5 |
:100BC000EF90DF90089500D088EE90E0ADB7BEB70B |
:100BD00012969C938E931197E4D1109120010F905F |
:100BE0000F90112309F08ECF02C081DEC3CF00E049 |
:100BF000B7CFEF92FF920F931F93CF93DF93082FFE |
:100C0000F92E162F00D000D000D0EDB7FEB73196E8 |
:100C100081E391E0ADB7BEB712969C938E93119786 |
:100C200062831382809120019091210195838483B6 |
:100C3000B8D1EDB7FEB736960FB6F894FEBF0FBE2B |
:100C4000EDBF80911B01813009F04CC0212F30E0B5 |
:100C500080912001909121018217930708F45DC0D3 |
:100C6000112371F1802F9F2D9C01E9019CE1E92E58 |
:100C700091E0F92E809120019091210101979093AC |
:100C800021018093200120E0892B09F421E0822FAB |
:100C900068DE899300D000D0EDB7FEB73196ADB7CE |
:100CA000BEB71296FC92EE9211978283138279D18D |
:100CB000FE01E01B0F900F900F900F90E117D0F204 |
:100CC0008091220181FF06C0809120019091210135 |
:100CD000892BA9F1812FDF91CF911F910F91FF9067 |
:100CE000EF90089500D08AE091E0ADB7BEB71296BC |
:100CF0009C938E93119755D10F900F90802F9F2D1D |
:100D000060E070E0412F50E045D1812FDF91CF911D |
:100D10001F910F91FF90EF90089500D087E291E02E |
:100D2000ADB7BEB712969C938E9311973AD110919E |
:100D300020010F900F90112309F094CFC1CFD7DD80 |
:100D4000C9CF0F931F93CF93DF93EC010CE111E018 |
:100D500010933201009331012DB73EB72A50304035 |
:100D60000FB6F8943EBF0FBE2DBFEDB7FEB731965C |
:100D700080E691E0ADB7BEB712969C938E93119723 |
:100D80008881828313828981848315828A81868304 |
:100D900017828B818087118604D1EDB7FEB73A9612 |
:100DA0000FB6F894FEBF0FBEEDBF8981823009F403 |
:100DB00079C0833008F44FC0833009F4A3C0883071 |
:100DC00008F05EC08A8180FDB1C022E031E0EDB75D |
:100DD000FEB738970FB6F894FEBF0FBEEDBF319641 |
:100DE00081E991E0ADB7BEB712969C938E931197AF |
:100DF000338322838C819D81958384838E819F811F |
:100E000097838683CED01C81110F8A81EDB7FEB700 |
:100E100038960FB6F894FEBF0FBEEDBF80FD11608F |
:100E2000898180FF86C05EDD812F68DD882309F41B |
:100E300089C081E080931B012E813F813093210185 |
:100E40002093200189818093220181FF17C0232BE9 |
:100E500091F08FEF16C08823C9F0813089F4C80162 |
:100E600060E970E044E050E08CD084E0DF91CF9105 |
:100E70001F910F9108953BDD2E813F81232B49F770 |
:100E800080E0DF91CF911F910F9108958A81809327 |
:100E90001C018B8180931D0182E0DF91CF911F9116 |
:100EA0000F9108952A813B813093170120931601F9 |
:100EB0002115310589F581E090E090931701809329 |
:100EC000160121E030E081E090E0909319018093D9 |
:100ED000180100D000D088E491E0ADB7BEB71296FB |
:100EE0009C938E93119714963C932E93139759D0FD |
:100EF00080E00F900F900F900F90DF91CF911F9196 |
:100F00000F91089580911B0180931C0181E0DF9176 |
:100F1000CF911F910F910895C90196958795909350 |
:100F2000190180931801892BA1F6CDCF25E031E07E |
:100F30004ECF81E0B4DC81E0BADC80E0B0DC80E060 |
:100F4000B6DC72CF00D000D0EDB7FEB7319683E7A4 |
:100F500091E0ADB7BEB712969C938E931197128312 |
:100F600013821FD082E080931B0110922101109206 |
:100F700020010F900F900F900F90B9DC2E813F81D0 |
:100F80007DCFFB01DC0102C005900D924150504025 |
:100F9000D8F70895DC0101C06D9341505040E0F74F |
:100FA0000895A0E0B0E0E6EDF7E09CC2FE013596C2 |
:100FB00061917191A0914F01B091500113968C9164 |
:100FC0001397886013968C9380914F0190915001F4 |
:100FD000AF010AD0E0914F01F09150012381277FAA |
:100FE00023832096E2E09AC2ABE0B0E0E9EFF7E0BD |
:100FF00069C23C012B015A01FC01178216828381D0 |
:1010000081FD03C06FEF7FEFB9C19AE0892E1E0109 |
:101010000894211C311CF3012381F20123FD8591E9 |
:1010200023FF81912F01882309F4A5C1853239F46A |
:1010300023FD859123FF81912F01853221F490E0DA |
:10104000B301B6D1E8CF982FFF24EE249924FFE115 |
:10105000FF15D0F09B3269F09C3228F4903259F0A1 |
:10106000933291F40EC09D3249F0903369F441E01F |
:1010700024C052E0F52A84E0F82A28C098E0F92A32 |
:1010800025C0E0E1FE2A22C0F7FC29C0892F805349 |
:101090008A3070F4F6FE05C0989C902C1124980EAE |
:1010A00015C0E89CE02C1124E80EF0E2FF2A0EC0E7 |
:1010B0009E3229F4F6FC5FC140E4F42A07C09C3656 |
:1010C00019F450E8F52A02C0983649F4F20123FDDC |
:1010D000959123FF91912F01992309F0B8CF892F82 |
:1010E0008554833018F08052833038F444E050E067 |
:1010F000A40EB51E5FE359830FC0933631F09337CA |
:1011000079F0933509F052C01FC0F50180818983C1 |
:1011100042E050E0A40EB51E610101E010E011C0F4 |
:10112000F501C080D180F6FC03C06FEF7FEF02C0F5 |
:10113000692D70E042E050E0A40EB51EC6012DD12D |
:101140008C015FE7F52213C0F501C080D180F6FC69 |
:1011500003C06FEF7FEF02C0692D70E042E050E006 |
:10116000A40EB51EC6010ED18C0150E8F52AF3FE7F |
:1011700006C018C080E290E0B3011AD1EA948E2D27 |
:1011800090E008171907B0F30DC0F601F7FC859140 |
:10119000F7FE81916F0190E0B3010AD1E110EA946A |
:1011A000015010400115110581F7E2C0943611F08D |
:1011B000993661F5F7FE08C0F50120813181428141 |
:1011C000538184E090E00AC0F501808191819C0107 |
:1011D000442737FD4095542F82E090E0A80EB91EB9 |
:1011E0009FE6F92257FF09C050954095309521950B |
:1011F0003F4F4F4F5F4FE0E8FE2ACA01B901A101FE |
:101200002AE030E001D1D82ED2183FC0953729F41A |
:101210001F2D1F7E2AE030E01DC01F2D197F9F3635 |
:1012200061F0903720F4983509F0A5C00FC09037D1 |
:1012300039F0983709F09FC004C028E030E00AC0B8 |
:10124000106114FD146020E130E004C014FD16604C |
:1012500020E132E017FF08C0F501608171818281D1 |
:10126000938144E050E008C0F50180819181BC0188 |
:1012700080E090E042E050E0A40EB51EA101C4D091 |
:10128000D82ED2188FE7F82EF122F6FE0BC05EEFB3 |
:10129000F522D91438F4F4FE07C0F2FC05C08FEE35 |
:1012A000F82202C01D2D01C0192DF4FE0DC0FE0153 |
:1012B000ED0DF11D8081803319F499EEF92208C0FB |
:1012C0001F5FF2FE05C003C08F2D867809F01F5FF7 |
:1012D0000F2DF3FC13C0F0FE0EC01E1510F09D2C58 |
:1012E0000AC09D2C9E0C911A1E2D05C080E290E034 |
:1012F000B3015ED01F5F1E15C8F304C01E1510F4A5 |
:10130000E11A01C0EE2404FF0EC080E390E0B301B7 |
:101310004FD002FF1BC001FD03C088E790E00EC064 |
:1013200088E590E00BC0802F867881F001FF02C035 |
:101330008BE201C080E2F7FC8DE290E0B30138D08F |
:1013400005C080E390E0B30133D09A94D914C8F378 |
:10135000DA94F101ED0DF11D808190E0B30128D008 |
:10136000DD20B1F705C080E290E0B30121D0EA941E |
:10137000EE20C9F750CEF30166817781CB012B9621 |
:10138000E2E1BCC0FC010590615070400110D8F74B |
:10139000809590958E0F9F1F0895FC0161507040BD |
:1013A00001900110D8F7809590958E0F9F1F08959A |
:1013B0000F931F93CF93DF938C01EB018B8181FF00 |
:1013C0001BC082FF0DC02E813F818C819D8128171B |
:1013D000390764F4E881F9810193F983E88306C051 |
:1013E000E885F985802F0995892B31F48E819F81BD |
:1013F00001969F838E8302C00FEF1FEFC801DF911C |
:10140000CF911F910F910895FA01AA27283051F129 |
:10141000203181F1E8946F936E7F6E5F7F4F8F4F25 |
:101420009F4FAF4FB1E03ED0B4E03CD0670F781F84 |
:10143000891F9A1FA11D680F791F8A1F911DA11D69 |
:101440006A0F711D811D911DA11D20D009F46894A2 |
:101450003F912AE0269F11243019305D3193DEF64A |
:10146000CF010895462F4770405D4193B3E00FD000 |
:10147000C9F7F6CF462F4F70405D4A3318F0495DEB |
:1014800031FD4052419302D0A9F7EACFB4E0A695CE |
:101490009795879577956795BA95C9F700976105F0 |
:1014A000710508959B01AC010A2E06945795479546 |
:1014B00037952795BA95C9F7620F731F841F951F3B |
:1014C000A01D08952F923F924F925F926F927F924C |
:1014D0008F929F92AF92BF92CF92DF92EF92FF9244 |
:1014E0000F931F93CF93DF93CDB7DEB7CA1BDB0BF0 |
:1014F0000FB6F894DEBF0FBECDBF09942A88398895 |
:1015000048885F846E847D848C849B84AA84B9849B |
:10151000C884DF80EE80FD800C811B81AA81B981A7 |
:10152000CE0FD11D0FB6F894DEBF0FBECDBFED01BB |
:061530000895F894FFCFBE |
:10153600FF5A77720072640000000002000000008B |
:0A1546003E04000000000A0005004A |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/bin/i2c_tiny_usb_avrusb_attiny45.hex |
---|
0,0 → 1,168 |
:100000003EC0C4C157C056C055C054C053C052C0F2 |
:1000100051C050C04FC04EC04DC04CC04BC0040377 |
:1000200009041A03540069006C006C0020004800A9 |
:10003000610072006200610075006D001A036900C2 |
:10004000320063002D00740069006E0079002D00FD |
:1000500075007300620012011001FF000008030424 |
:1000600031C60501010200010902120001010080F0 |
:10007000050904000000000000000100FF8E1124AB |
:100080001FBECFE5D1E0DEBFCDBF10E0A0E6B0E0FF |
:10009000EAE5FAE002C005900D92A636B107D9F75D |
:1000A00010E0A6E6B0E001C01D92A939B107E1F762 |
:1000B00067D3D1C4A5CF85B7836085BF8BB7806474 |
:1000C0008BBF0895FF920F931F93CF93DF9360919F |
:1000D0007F00662351F180917C00CCE0D0E0C81B0A |
:1000E000D109CD57DF4F635080917B008D3279F07D |
:1000F0008091660087FD11C0CE0165D38F3F09F462 |
:100100008FC0882309F489C090E080E008C08AE5A8 |
:1001100080936100683009F4A2C090E880E0909379 |
:1001200066008093600010927F008091610084FFE0 |
:1001300026C0809160008F3F11F1182F893078F52B |
:10014000811B809360008091660080FD30C02BE4AD |
:10015000F22E8F5F8093660087FD30C0112309F077 |
:100160004FC004E080E790E0612F81D2183019F091 |
:100170008FEF80936000F0926F00009361009AE02F |
:1001800086B3857031F49150D9F7109280001092A7 |
:100190007A00DF91CF911F910F91FF90089518E0A1 |
:1001A000811B809360008091660080FFD0CF93EC2C |
:1001B000F92E8F5F8093660087FFD0CFC0917D00BE |
:1001C000D0917E0086FD32C0112399F01150DE01DE |
:1001D000E0E7F0E0412F50E01F5F9A012F583F4FBA |
:1001E0008D918193E217F307D9F74F5F5F4FC40FEB |
:1001F000D51FD0937E00C0937D00012F0C5FB2CF3E |
:1002000080E790E0612F2ED3182F893008F4A4C026 |
:100210008FEF809360000EE1AECF90E08FEF7FCF45 |
:100220008EE18093610090E08FEF79CF112309F385 |
:1002300011509E01A0E7B0E0612F70E01F5FAB019D |
:100240004F585F4FF90184918D932F5F3F4FA41753 |
:10025000B507C1F76F5F7F4FC60FD71FCACF888121 |
:10026000807629F528E730E010927800898188238C |
:1002700089F41092790030937E0020937D0090E8FD |
:1002800022E08F81882321F48E81821708F447CFE2 |
:10029000822F45CF8530B9F08630F1F0883031F1CA |
:1002A0008930A1F18A3059F190E820E0EACFCE01FF |
:1002B0002DD3282F8F3F09F04DC0888187FD09C0BD |
:1002C0008FEF90E02CCF8A818093800090E820E02F |
:1002D000D8CF8E8190E023CF8B81813031F1823075 |
:1002E000D9F0833059F190EC20E0CBCF82E890E058 |
:1002F00090937E0080937D0090E821E0C2CF309300 |
:100300007E0020937D0090E821E0BBCF8A8180931E |
:10031000820090E820E0B5CF88E690E090937E00E0 |
:1003200080937D0090EC22E1ACCF86E590E0909345 |
:100330007E0080937D0090EC22E1A3CF8A81882308 |
:1003400071F48EE190E090937E0080937D0090ECBC |
:1003500024E097CF90E895CF082F0C5F03CF813032 |
:1003600061F0823009F0BFCF8CE390E090937E0083 |
:1003700080937D0090EC2AE184CF82E290E090931C |
:100380007E0080937D0090EC2AE17BCFCF93CFB7A6 |
:10039000CF93B09BFECFB09B09C0B09B07C0B09B72 |
:1003A00005C0B09B03C0B09B01C09EC0DF93C0914D |
:1003B0007C00DD27CD57DF4FB09B02C0DF91EBCF34 |
:1003C0002F930F931F9306B32FEF00FB20F94F934A |
:1003D0003F9316B34FEF012700FB21F93BE031C0FB |
:1003E0004E7F012F16B3216028C0102F4D7F226051 |
:1003F000000006B329C04B7F2460012F000016B314 |
:100400002BC016B3477F28602AC04F7E06B32061F9 |
:100410002CC04F7D16B320622FC04F7B06B32064E3 |
:1004200032C0422706B349934FEF0000102710FB5C |
:1004300020F916B31570A9F1297F91F2012700FB6D |
:1004400021F906B3237F89F23150F0F1102710FB18 |
:1004500022F916B3277E79F2012700FB23F92F7CBE |
:1004600081F206B3102710FB24F92F7971F200C036 |
:1004700016B3012700FB25F92F7359F200C006B30C |
:10048000102710FB26F9223040F200C016B30127D6 |
:1004900000FB27F9243028F64F77206816B30000B8 |
:1004A000F9CF3B503195333010E41ABFB8F0C31B7D |
:1004B000D0400881033C41F10B3431F11981412FC7 |
:1004C0001F7720917A00121731F4093691F10D321D |
:1004D00079F0013E69F02227209381003F914F91EE |
:1004E0001F910F912F91DF91CF91CFBFCF91189591 |
:1004F000009381003F914F911F910F912F91DF91B8 |
:10050000CAB7C6FD46CFF0CF00918100002331F37A |
:1005100010917F00112349F534304AF130937F0068 |
:1005200000937B0010917C003BE0311B30937C00FA |
:100530001EC000917F000130C4F40AE530916100D3 |
:1005400034FD17C000936100CFE6D0E016C0052748 |
:1005500010E008BB1FC0052722C0052727C00527BC |
:100560002CC0052710E008BB33C04AE503C042EDAC |
:1005700001C0432FC4E1D0E032E017B31560C09A48 |
:1005800008B317BB5F9355E020E820FF052708BBA1 |
:10059000279517951C3FD8F620FF0527279508BB00 |
:1005A00017951C3FC0F620FF05272795179508BB18 |
:1005B0001C3F98F620FF0527279517951C3F08BB81 |
:1005C00070F600C0499120FF052708BB27951795B5 |
:1005D0001C3F38F620FF0527279508BB17951C3FC1 |
:1005E00038F520FF05272795179508BB1C3F10F508 |
:1005F00020FF0527279517951C3F08BBE8F4242FFB |
:100600003A9519F60A7F5F9108BB00C010918000EF |
:10061000C651D04011F010937A0010E41ABF016067 |
:1006200017B31A7F402F4A7F08BB17BB48BB56CF72 |
:100630000527D3CF0527D8CF0527DDCFA82FB92F82 |
:100640008FEF9FEF41E050EA615070F02D9138E05C |
:10065000722F782796958795269570FF02C084277C |
:1006600095273A95A9F7F0CF809590950895E6DF04 |
:100670008D939D930895882319F4B99AC19808958C |
:10068000B998C19A0895E0916400F091650031979E |
:10069000F1F7882359F0BD98C59AB59BFECF80919C |
:1006A0006200909163000197F1F70895BD9AC59893 |
:1006B000F6CF81E0E8DF80E0E6DF089580E0DBDF71 |
:1006C00081E0E1DF81E0D7DF08950F931F93CF939F |
:1006D000DF93082F10E0C7E0D0E008C081E0CBDF57 |
:1006E000E8DF21978FEFCF3FD80789F0C8010C2EA4 |
:1006F00002C0959587950A94E2F780FDEFCF80E0E0 |
:10070000BADFD7DF21978FEFCF3FD80779F781E0A6 |
:10071000B2DF81E0B8DF16B380E0B5DF1695109543 |
:10072000812F8170DF91CF911F910F910895FF92DA |
:100730000F931F93F82E81E09EDF80E0A4DF17E087 |
:1007400000E081E0A0DF000FB199016080E09BDF55 |
:100750001150B8F7FF2051F480E08DDFAADF81E06F |
:100760008ADF802F1F910F91FF90089581E083DF32 |
:10077000A0DF81E080DF802F1F910F91FF9008950F |
:100780002EE088E190E00FB6F894A89581BD0FBEE9 |
:1007900021BDB998C19ABD98C59A10926D0010926A |
:1007A0006C0088B38A7F88BB87B3856087BB80E491 |
:1007B0009CE90197F1F787B38A7F87BB7CDC78944B |
:1007C000A89580DCFDCFEF92FF920F931F93CF93FC |
:1007D000DF93E82E292FF62E80916700813091F566 |
:1007E00000916C0010916D00862F90E0081719079A |
:1007F00008F4F02EFF20A1F08E2D922F9C01E9012C |
:10080000899163DF9E012E192F15D0F301501040FE |
:10081000FA940F191109F39410936D0000936C0072 |
:1008200080916E0081FF06C080916C0090916D00F8 |
:10083000892BB1F08F2DDF91CF911F910F91FF90F8 |
:10084000EF9008958E2D60E070E04F2D50E0FCD0C9 |
:100850008F2DDF91CF911F910F91FF90EF90089511 |
:100860002DDFE8CFCF92DF92EF92FF920F931F938D |
:10087000CF93DF93C82E292FD62E80916700813029 |
:10088000E1F5E0906C00F0906D00862F90E0E816A6 |
:10089000F90608F4DE2CDD20E1F08C2D922F9C016E |
:1008A0008901E701219780E009F481E040DFF80148 |
:1008B00081938F018E2F8C198D15A0F30894E10878 |
:1008C000F108DA94ED18F108D394F0926D00E092FB |
:1008D0006C0080916E0081FF06C080916C00909149 |
:1008E0006D00892B89F08D2DDF91CF911F910F9194 |
:1008F000FF90EF90DF90CF9008958C2D60E070E036 |
:100900004D2D50E0A1D0EFCFD9DEEDCF1F93CF9387 |
:10091000DF93EC0188E690E090937E0080937D0069 |
:100920002981223009F456C0233070F1233009F4B4 |
:1009300067C0283008F03EC01C81110F8A8180FDFD |
:100940001160898180FD04C081E095DE81E09BDE3D |
:1009500080E091DE80E097DE812FB7DE882309F406 |
:100960005FC081E0809367002E813F8130936D00EE |
:1009700020936C00898180936E0081FF4DC0232BF2 |
:1009800009F447C08FEF17C02223C9F0213091F43A |
:100990006AE770E044E050E04ED084E0DF91CF9110 |
:1009A0001F910895969587959093650080936400B4 |
:1009B000892BF1F080E0DF91CF911F9108958A811A |
:1009C000809368008B818093690082E0DF91CF91F2 |
:1009D0001F9108958A819B819093630080936200A8 |
:1009E000009701F781E090E09093630080936200AC |
:1009F00081E090E0909365008093640080E0DBCF1D |
:100A0000809167008093680081E0DF91CF911F9112 |
:100A1000089554DE2E813F81232B61F28FEFCBCFDF |
:100A200082E08093670010926D0010926C0046DEA9 |
:100A30002E813F81F1CFFB01DC0102C005900D92B8 |
:100A400041505040D8F70895DC0101C06D934150EA |
:0A0A50005040E0F70895F894FFCF3E |
:060A5A00FF5A0A0005002E |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/bin/i2c_tiny_usb_usbtiny_atmega8.hex |
---|
0,0 → 1,149 |
:100000004AC086C063C062C061C060C05FC05EC0DD |
:100010005DC05CC05BC05AC059C058C057C056C014 |
:1000200055C054C053C000CDD914F13C28E5A16C93 |
:1000300078B5509D89441A03540069006C006C0027 |
:1000400020004800610072006200610075006D00D0 |
:100050001A036900320063002D00740069006E000D |
:1000600079002D0075007300620012011001FF007D |
:100070000008030431C60502010200010902120052 |
:1000800001010080050904000000FF0000000403D6 |
:1000900009040100FF8E11241FBECFE5D4E0DEBFAE |
:1000A000CDBF10E0A0E6B0E0ECE2F9E002C00590C0 |
:1000B0000D92A636B107D9F710E0A6E6B0E001C070 |
:1000C0001D92A639B107E1F7EDD22EC499CFDC011C |
:1000D0009FEF8FEF660FB9F046E2F0E0229560FFE8 |
:1000E0002D91E82FE227EF70929582958F70392F2E |
:1000F000307F832B9F70E40F3591932731709327C6 |
:1001000083276A9559F7809590958D939D930895CF |
:100110000F931F932F93DF93CF930FB70F93829972 |
:10012000FECF82990BC0829909C0829907C082993B |
:1001300005C0829903C000E40ABFA8C0C0917E0038 |
:10014000DD27C158DF4F0BE014E124E0829BE9CFAB |
:100150003F934F936F9360B330E803C060B3432B7A |
:100160004993442764712627215020B32471A9F1B3 |
:1001700037953C3FA0F56227615060B364713795B5 |
:100180003C3F98F526272150379520B324713C3FFA |
:1001900090F56227615037953C3F60B36471A0F5DC |
:1001A0002627215037953C3FC8F520B3247162279C |
:1001B000615037953C3FB0F50A9560B37AF06471B1 |
:1001C0002627215037953C3F88F520B324716227BC |
:1001D000615037953C3F10F22DC031C048C06127B7 |
:1001E00020B324713F774160C6CF3F77426060B350 |
:1001F00064712127C7CF3F774460612720B3247102 |
:10020000622761503795C8CF3F774860212731601A |
:1002100060B36471262721503795C6CF3F77406180 |
:100220006127C1CF3F7740622127C4CF3F77406429 |
:100230006127C9CF3F774068212700C08FCF30E4C6 |
:100240003ABF0B500195033090F0C01B2881233C2E |
:1002500091F12B3481F119811F774091950014178A |
:1002600031F42936D9F02D3249F0213E39F04427B6 |
:10027000409366006F914F913F9108C020936600B4 |
:100280006F914F913F910AB706FD49CF0F910FBF74 |
:10029000CF91DF912F911F910F91189500917000D0 |
:1002A0000023F1F040917D004423D1F4409370008D |
:1002B000C1E7D0E018C0209166002223C1F240912E |
:1002C0007D00442369F400937D0020937C0000911D |
:1002D0007E004BE0401B40937E00C0E6D0E002C0B1 |
:1002E000C1E6D0E001E022B32B7E206111B314619E |
:1002F00022BB11BB14E130E830FF212722BB379528 |
:1003000047954C3FC0F530FF2127379522BB4795D5 |
:100310004C3FA8F530FF21273795000022BB4795B9 |
:100320004C3F78F530FF21273795000022BB4795D9 |
:100330004C3F48F530FF2127699122BB37954795FF |
:100340004C3F18F530FF2127379522BB47954C3F8E |
:1003500000F530FF21273795479522BB4C3FD8F455 |
:1003600030FF21273795362F479522BB4C3FA8F405 |
:100370000A9512F614C02127442722BBC2CF212799 |
:10038000C5CF2127CBCF2127D1CF2127442722BB7F |
:10039000D7CF2127DACF2127DFCF2127E5CF2B7E2B |
:1003A00022BB6F914F913F9100E40ABFDF91CF9143 |
:1003B00011B3022F206122BB1B7EDFBFDF912F9183 |
:1003C000000011BB02BB1F910F91189585B7836088 |
:1003D00085BF8BB780648BBF789408951F93CF93AC |
:1003E000DF9360917D00662309F477C080917E00E1 |
:1003F000CCE0D0E0C81BD109C158DF4F81E0809329 |
:10040000670080917C008D3209F059C01E818F8178 |
:1004100081111FEF8881807609F041C0898188238E |
:1004200021F41882198292E042C0853021F48A8139 |
:1004300080936B00BAC0863039F582E08093670004 |
:100440008B81813021F492E1CAE6D0E030C0823065 |
:1004500021F492E1CCE7D0E02AC0833009F0A5C0B6 |
:100460008A81882321F494E0CEE8D0E020C0813056 |
:1004700021F49AE1C6E3D0E01AC0823009F095C0B9 |
:100480009AE1C0E5D0E013C0883019F481E0888398 |
:1004900004C08A3009F089C0188291E008C0CE01FA |
:1004A000ADD1982F8F3F19F483E08093670019171F |
:1004B00008F0192FD0936A00C093690005C06350FB |
:1004C00011F0CE0112D110E01093680083EC8093FC |
:1004D00071001092700010927D008091700088234E |
:1004E00009F053C020916700222309F44AC080918B |
:1004F000710098E889278093710010916800193085 |
:1005000010F018E002C0112379F1233031F482E7B2 |
:1005100090E0612F28D1182F22C0309169004091BE |
:100520006A00213061F4832F942FFC01A2E7B0E030 |
:1005300081918D938E2F831B8117D0F30CC0832F55 |
:10054000942FFC01A2E7B0E0849131968D938E2F19 |
:10055000831B8117C8F3F0936A00E09369008091D0 |
:100560006800811B8093680082E790E0612FAFDD17 |
:100570001D5F109370001350183038F4109267000C |
:1005800004C080916B00809395008AE002C0815086 |
:1005900019F0849BFCCF0BC0F8941092700010925D |
:1005A0007D0010926B00789402C090E082CFDF91C2 |
:1005B000CF911F910895882319F0A498AC9A0895BB |
:1005C000A49AAC980895E0916400F0916500319789 |
:1005D000F1F7882329F0A598AD9A9D9BFECF02C024 |
:1005E000A59AAD9880916200909163000197F1F710 |
:1005F000089581E0E8DF80E0E6DF089580E0DBDF5A |
:1006000081E0E1DF81E0D7DF08950F931F93CF935F |
:10061000DF93C7E0D0E0082F10E0C8010C2E02C025 |
:10062000959587950A94E2F780FF02C081E001C0AA |
:1006300080E0C1DFDEDF21978FEFCF3FD80769F77A |
:1006400081E0B9DF81E0BFDF13B380E0BCDF12954A |
:100650001F701095812F8170DF91CF911F910F91A5 |
:100660000895FF920F931F93F82E81E0A4DF80E09E |
:10067000AADF17E000E081E0A6DF000F9C9901608F |
:1006800080E0A1DF1150B8F7FF2011F081E001C038 |
:1006900080E091DFAEDF81E08EDF802F1F910F9130 |
:1006A000FF9008952EE088E190E00FB6F894A895A9 |
:1006B00081BD0FBE21BDA498AC9AA598AD9A1092A9 |
:1006C0006E0010926D0082B38B7E82BB81B3846119 |
:1006D00081BB80E49CE90197F1F781B38B7E81BBFC |
:1006E00075DE7894A8957ADEFDCFEF92FF920F9396 |
:1006F0001F93CF93DF93E82E292FF62E80916C0065 |
:10070000813021F500916D0010916E00862F90E0F0 |
:100710000817190708F4F02E8E2D922F9C01E9017D |
:1007200002C0899172DF9E012E192F15D0F3A80106 |
:100730004F19510950936E0040936D0080916F00E6 |
:1007400081FF0AC0452B41F459DF06C08E2D60E0C1 |
:1007500070E04F2D50E0E1D0DF91CF911F910F91CC |
:10076000FF90EF900895CF92DF92EF92FF920F9358 |
:100770001F93CF93DF93C82E292FD62E80916C0024 |
:10078000813061F5E0906D00F0906E00862F90E072 |
:10079000E816F90608F4DE2C8C2D922F9C018901B5 |
:1007A000E70108C080E0209709F481E05ADFF801F2 |
:1007B00081938F012197802F8C198D1598F39701C4 |
:1007C0002D19310930936E0020936D0080916F00D8 |
:1007D00081FF0AC0232B41F411DF06C08C2D60E09D |
:1007E00070E04D2D50E099D08D2DDF91CF911F916C |
:1007F0000F91FF90EF90DF90CF9008951F93CF93CC |
:10080000DF93EC0189818230E9F0833030F4882372 |
:1008100059F0813009F073C00DC0833009F46AC00B |
:10082000883008F06CC030C08A8188838B818983CE |
:1008300082E066C0CE0162E970E044E050E064D03E |
:1008400084E05EC08A819B81909363008093620004 |
:10085000892B31F481E090E09093630080936200F3 |
:1008600080916200909163009695879590936500C2 |
:1008700080936400892B09F042C081E090E090935E |
:100880006500809364003BC01C81110F8A8180FD4C |
:100890001160898180FD04C081E08DDE81E093DEFE |
:1008A00080E089DE80E08FDE812FAFDE882341F497 |
:1008B00082E080936C0010926E0010926D0010C068 |
:1008C00081E080936C002E813F8130936E002093F5 |
:1008D0006D00898180936F0081FF03C0232B09F491 |
:1008E0008DDE8A8180FF0BC08E819F81892B39F03C |
:1008F0008FEF06C080916C00888381E001C080E0AA |
:10090000DF91CF911F910895FB01DC0102C005909A |
:100910000D9241505040D8F70895DC0101C06D930D |
:0C09200041505040E0F70895F894FFCFDC |
:06092C00D25A0A0005008A |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/bin/i2c_tiny_usb_usbtiny_atmega88.hex |
---|
0,0 → 1,150 |
:1000000051C08DC06AC069C068C067C066C065C0A5 |
:1000100064C063C062C061C060C05FC05EC05DC0DC |
:100020005CC05BC05AC059C058C057C056C055C00C |
:1000300054C053C000CDD914F13C28E5A16C78B56B |
:10004000509D89441A03540069006C006C00200024 |
:100050004800610072006200610075006D001A03C3 |
:100060006900320063002D00740069006E007900A1 |
:100070002D0075007300620012011001FF000008DE |
:10008000030431C605020102000109021200010148 |
:100090000080050904000000FF00000004030904BB |
:1000A0000100FF8E11241FBECFEFD4E0DEBFCDBF15 |
:1000B00011E0A0E0B1E0EEE3F9E002C005900D929E |
:1000C000A630B107D9F711E0A6E0B1E001C01D925A |
:1000D000A633B107E1F7EDD230C492CFDC019FEF38 |
:1000E0008FEF660FB9F044E3F0E0229560FF2D91A9 |
:1000F000E82FE227EF70929582958F70392F307F2D |
:10010000832B9F70E40F35919327317093278327BA |
:100110006A9559F7809590958D939D9308950F93C7 |
:100120001F932F93DF93CF930FB70F934A99FECF6F |
:100130004A990BC04A9909C04A9907C04A9905C013 |
:100140004A9903C001E00CBBA8C0C0911E01DD2785 |
:10015000C15EDE4F0BE014E124E04A9BE9CF3F9300 |
:100160004F936F9369B130E803C069B1432B499352 |
:10017000442764712627215029B12471A9F13795AC |
:100180003C3FA0F56227615069B1647137953C3FEF |
:1001900098F526272150379529B124713C3F90F5D9 |
:1001A0006227615037953C3F69B16471A0F52627FD |
:1001B000215037953C3FC8F529B124716227615021 |
:1001C00037953C3FB0F50A9569B17AF064712627FE |
:1001D000215037953C3F88F529B124716227615041 |
:1001E00037953C3F10F22DC031C048C0612729B17E |
:1001F00024713F774160C6CF3F77426069B1647137 |
:100200002127C7CF3F774460612729B12471622736 |
:1002100061503795C8CF3F7748602127316069B179 |
:100220006471262721503795C6CF3F7740616127FB |
:10023000C1CF3F7740622127C4CF3F774064612719 |
:10024000C9CF3F774068212700C08FCF31E03CBB4A |
:100250000B500195033090F0C01B2881233C91F195 |
:100260002B3481F119811F7740913501141731F436 |
:100270002936D9F02D3249F0213E39F044274093F8 |
:1002800006016F914F913F9108C0209306016F9135 |
:100290004F913F910CB300FD49CF0F910FBFCF910C |
:1002A000DF912F911F910F9118950091100100235C |
:1002B000F1F040911D014423D1F440931001C1E1BC |
:1002C000D1E018C0209106012223C1F240911D0106 |
:1002D000442369F400931D0120931C0100911E0129 |
:1002E0004BE0401B40931E01C0E0D1E002C0C1E0E2 |
:1002F000D1E001E02BB12B7E20611AB114612BB942 |
:100300001AB914E130E830FF21272BB9379547950A |
:100310004C3FC0F530FF212737952BB947954C3F0F |
:10032000A8F530FF2127379500002BB947954C3FA2 |
:1003300078F530FF2127379500002BB947954C3FC2 |
:1003400048F530FF212769912BB9379547954C3FE8 |
:1003500018F530FF212737952BB947954C3F00F50D |
:1003600030FF2127379547952BB94C3FD8F430FF04 |
:1003700021273795362F47952BB94C3FA8F40A957E |
:1003800012F614C0212744272BB9C2CF2127C5CF8D |
:100390002127CBCF2127D1CF212744272BB9D7CF56 |
:1003A0002127DACF2127DFCF2127E5CF2B7E2BB9DD |
:1003B0006F914F913F9101E00CBBDF91CF911AB14A |
:1003C000022F20612BB91B7EDFBFDF912F91000030 |
:1003D0001AB90BB91F910F911895E9E6F0E08081E9 |
:1003E00083608083E89A789408951F93CF93DF9376 |
:1003F00060911D01662309F477C080911E01CCE055 |
:10040000D0E0C81BD109C15EDE4F81E080930701B7 |
:1004100080911C018D3209F059C01E818F8181119C |
:100420001FEF8881807609F041C08981882321F4FB |
:100430001882198292E042C0853021F48A8180932B |
:100440000B01BAC0863039F582E0809307018B81B9 |
:10045000813021F492E1C8E7D0E030C0823021F44D |
:1004600092E1CAE8D0E02AC0833009F0A5C08A81B1 |
:10047000882321F494E0CCE9D0E020C0813021F43D |
:100480009AE1C4E4D0E01AC0823009F095C09AE144 |
:10049000CEE5D0E013C0883019F481E0888304C031 |
:1004A0008A3009F089C0188291E008C0CE01AFD12E |
:1004B000982F8F3F19F483E080930701191708F0F4 |
:1004C000192FD0930A01C093090105C0635011F0A0 |
:1004D000CE0114D110E01093080183EC8093110138 |
:1004E0001092100110921D0180911001882309F0D3 |
:1004F00053C020910701222309F44AC080911101C1 |
:1005000098E889278093110110910801193010F0A3 |
:1005100018E002C0112379F1233031F482E191E037 |
:10052000612F2AD1182F22C03091090140910A0170 |
:10053000213061F4832F942FFC01A2E1B1E081917D |
:100540008D938E2F831B8117D0F30CC0832F942F94 |
:10055000FC01A2E1B1E0849131968D938E2F831B33 |
:100560008117C8F3F0930A01E09309018091080113 |
:10057000811B8093080182E191E0612FAFDD1D5F57 |
:10058000109310011350183038F41092070104C072 |
:1005900080910B01809335018AE002C0815019F0EF |
:1005A0004C9BFCCF0BC0F8941092100110921D01CF |
:1005B00010920B01789402C090E082CFDF91CF912E |
:1005C0001F910895882319F03C98449A08953C9A05 |
:1005D00044980895E0910401F09105013197F1F7F5 |
:1005E000882329F03D98459A359BFECF02C03D9A5D |
:1005F000459880910201909103010197F1F70895C8 |
:1006000081E0E8DF80E0E6DF089580E0DBDF81E085 |
:10061000E1DF81E0D7DF08950F931F93CF93DF933E |
:10062000C7E0D0E0082F10E0C8010C2E02C095955D |
:1006300087950A94E2F780FF02C081E001C080E064 |
:10064000C1DFDEDF21978FEFCF3FD80769F781E069 |
:10065000B9DF81E0BFDF16B180E0BCDF12951F700B |
:100660001095812F8170DF91CF911F910F91089587 |
:10067000FF920F931F93F82E81E0A4DF80E0AADFA2 |
:1006800017E000E081E0A6DF000F3499016080E010 |
:10069000A1DF1150B8F7FF2011F081E001C080E028 |
:1006A00091DFAEDF81E08EDF802F1F910F91FF90F1 |
:1006B00008952EE088E190E00FB6F894A895809315 |
:1006C00060000FBE209360003C98449A3D98459A84 |
:1006D00010920E0110920D018BB18B7E8BB98AB1F5 |
:1006E00084618AB980E49CE90197F1F78AB18B7E35 |
:1006F0008AB973DE7894A89578DEFDCFEF92FF92E9 |
:100700000F931F93CF93DF93E82E292FF62E80911E |
:100710000C01813021F500910D0110910E01862F01 |
:1007200090E00817190708F4F02E8E2D922F9C01E7 |
:10073000E90102C0899170DF9E012E192F15D0F3B7 |
:10074000A8014F19510950930E0140930D0180915A |
:100750000F0181FF0AC0452B41F457DF06C08E2DE3 |
:1007600060E070E04F2D50E0E1D0DF91CF911F911C |
:100770000F91FF90EF900895CF92DF92EF92FF924A |
:100780000F931F93CF93DF93C82E292FD62E8091DE |
:100790000C01813061F5E0900D01F0900E01862F83 |
:1007A00090E0E816F90608F4DE2C8C2D922F9C01BF |
:1007B0008901E70108C080E0209709F481E058DF53 |
:1007C000F80181938F012197802F8C198D1598F353 |
:1007D00097012D19310930930E0120930D0180915D |
:1007E0000F0181FF0AC0232B41F40FDF06C08C2DBF |
:1007F00060E070E04D2D50E099D08D2DDF91CF91CC |
:100800001F910F91FF90EF90DF90CF9008951F936D |
:10081000CF93DF93EC0189818230E9F0833030F4AB |
:10082000882359F0813009F073C00DC0833009F47A |
:100830006AC0883008F06CC030C08A8188838B81A0 |
:10084000898382E066C0CE0160EA70E044E050E057 |
:1008500064D084E05EC08A819B8190930301809381 |
:100860000201892B31F481E090E0909303018093A1 |
:1008700002018091020190910301969587959093D2 |
:10088000050180930401892B09F042C081E090E0CA |
:1008900090930501809304013BC01C81110F8A8154 |
:1008A00080FD1160898180FD04C081E08BDE81E0E4 |
:1008B00091DE80E087DE80E08DDE812FADDE882353 |
:1008C00041F482E080930C0110920E0110920D0110 |
:1008D00010C081E080930C012E813F8130930E0186 |
:1008E00020930D01898180930F0181FF03C0232B89 |
:1008F00009F48BDE8A8180FF0BC08E819F81892B5A |
:1009000039F08FEF06C080910C01888381E001C02F |
:1009100080E0DF91CF911F910895FB01DC0102C0BF |
:1009200005900D9241505040D8F70895DC0101C068 |
:0E0930006D9341505040E0F70895F894FFCFCA |
:06093E00D25A0A00050078 |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/bin/i2c_tiny_usb_usbtiny_attiny45.hex |
---|
0,0 → 1,149 |
:1000000046C082C05FC05EC05DC05CC05BC05AC0FD |
:1000100059C058C057C056C055C054C053C000CD79 |
:10002000D914F13C28E5A16C78B5509D89441A0398 |
:10003000540069006C006C002000480061007200F0 |
:100040006200610075006D001A03690032006300F0 |
:100050002D00740069006E0079002D00750073009A |
:10006000620012011001FF000008030431C60502FE |
:1000700001020001090212000101008005090400CB |
:100080000000FF000000040309040100FF8E11249A |
:100090001FBECFE5D1E0DEBFCDBF10E0A0E6B0E0EF |
:1000A000E2E2F9E002C005900D92A636B107D9F759 |
:1000B00010E0A6E6B0E001C01D92A639B107E1F755 |
:1000C000ECD22DC49DCFDC019FEF8FEF660FB9F00E |
:1000D0004EE1F0E0229560FF2D91E82FE227EF70CE |
:1000E000929582958F70392F307F832B9F70E40F0C |
:1000F000359193273170932783276A9559F7809517 |
:1001000090958D939D9308950F931F932F93DF9355 |
:10011000CF930FB70F93B299FECFB2990BC0B2999C |
:1001200009C0B29907C0B29905C0B29903C000E4F2 |
:100130000ABFA8C0C0917E00DD27C158DF4F0BE089 |
:1001400015E024E0B29BE9CF3F934F936F9366B3E2 |
:1001500030E803C066B3432B4993442765702627D4 |
:10016000215026B32570A9F137953C3FA0F56227B1 |
:10017000615066B3657037953C3F98F5262721504E |
:10018000379526B325703C3F90F56227615037952F |
:100190003C3F66B36570A0F52627215037953C3F5C |
:1001A000C8F526B325706227615037953C3FB0F5FE |
:1001B0000A9566B37AF065702627215037953C3F43 |
:1001C00088F526B325706227615037953C3F10F2C1 |
:1001D0002DC031C048C0612726B325703F774160EC |
:1001E000C6CF3F77426066B365702127C7CF3F77A0 |
:1001F0004460612726B32570622761503795C8CFC8 |
:100200003F7748602127316066B36570262721500B |
:100210003795C6CF3F7740616127C1CF3F774062B6 |
:100220002127C4CF3F7740646127C9CF3F7740681B |
:10023000212700C08FCF30E43ABF0B500195033027 |
:1002400090F0C01B2881233C91F12B3481F119815E |
:100250001F7740919500141731F42936D9F02D32CB |
:1002600049F0213E39F04427409366006F914F9149 |
:100270003F9108C0209366006F914F913F910AB75C |
:1002800006FD49CF0F910FBFCF91DF912F911F91A5 |
:100290000F911895009170000023F1F040917D00BE |
:1002A0004423D1F440937000C1E7D0E018C02091FE |
:1002B00066002223C1F240917D00442369F400933B |
:1002C0007D0020937C0000917E004BE0401B40931A |
:1002D0007E00C0E6D0E002C0C1E6D0E001E028B375 |
:1002E0002A7F216017B3156028BB17BB15E030E8E3 |
:1002F00030FF212728BB379547954C3FC0F530FF8D |
:100300002127379528BB47954C3FA8F530FF21277B |
:100310003795000028BB47954C3F78F530FF2127E3 |
:100320003795000028BB47954C3F48F530FF212703 |
:10033000699128BB379547954C3F18F530FF212729 |
:10034000379528BB47954C3F00F530FF212737955F |
:10035000479528BB4C3FD8F430FF21273795362FDF |
:10036000479528BB4C3FA8F40A9512F614C02127E4 |
:10037000442728BBC2CF2127C5CF2127CBCF212798 |
:10038000D1CF2127442728BBD7CF2127DACF212758 |
:10039000DFCF2127E5CF2A7F28BB6F914F913F9177 |
:1003A00000E40ABFDF91CF9117B3022F216028BB71 |
:1003B0001A7FDFBFDF912F91000017BB08BB1F9191 |
:1003C0000F91189585B7836085BF8BB780648BBF0D |
:1003D000789408951F93CF93DF9360917D006623F7 |
:1003E00009F477C080917E00CCE0D0E0C81BD10931 |
:1003F000C158DF4F81E08093670080917C008D328F |
:1004000009F059C01E818F8181111FEF888180768C |
:1004100009F041C08981882321F41882198292E071 |
:1004200042C0853021F48A8180936B00BAC0863047 |
:1004300039F582E0809367008B81813021F492E16D |
:10044000C2E6D0E030C0823021F492E1C4E7D0E0CF |
:100450002AC0833009F0A5C08A81882321F494E062 |
:10046000C6E8D0E020C0813021F49AE1CEE2D0E0AD |
:100470001AC0823009F095C09AE1C8E4D0E013C0F8 |
:10048000883019F481E0888304C08A3009F089C07B |
:10049000188291E008C0CE01ACD1982F8F3F19F49B |
:1004A00083E080936700191708F0192FD0936A0032 |
:1004B000C093690005C0635011F0CE0111D110E066 |
:1004C0001093680083EC809371001092700010927A |
:1004D0007D0080917000882309F053C0209167004F |
:1004E000222309F44AC08091710098E889278093FB |
:1004F000710010916800193010F018E002C011234B |
:1005000079F1233031F482E790E0612F27D1182F61 |
:1005100022C03091690040916A00213061F4832F3C |
:10052000942FFC01A2E7B0E081918D938E2F831B65 |
:100530008117D0F30CC0832F942FFC01A2E7B0E009 |
:10054000849131968D938E2F831B8117C8F3F0937E |
:100550006A00E093690080916800811B80936800C5 |
:1005600082E790E0612FAFDD1D5F109370001350A4 |
:10057000183038F41092670004C080916B008093AB |
:1005800095008AE002C0815019F0B09BFCCF0BC0EF |
:10059000F8941092700010927D0010926B00789485 |
:1005A00002C090E082CFDF91CF911F910895882300 |
:1005B00019F0B998C19A0895B99AC1980895E0912F |
:1005C0006400F09165003197F1F7882329F0BD9818 |
:1005D000C59AB59BFECF02C0BD9AC59880916200B6 |
:1005E000909163000197F1F7089581E0E8DF80E0E2 |
:1005F000E6DF089580E0DBDF81E0E1DF81E0D7DF47 |
:1006000008950F931F93CF93DF93C7E0D0E0082F97 |
:1006100010E0C8010C2E02C0959587950A94E2F768 |
:1006200080FF02C081E001C080E0C1DFDEDF2197F2 |
:100630008FEFCF3FD80769F781E0B9DF81E0BFDFF7 |
:1006400016B380E0BCDF16951095812F8170DF9185 |
:10065000CF911F910F910895FF920F931F93F82E42 |
:1006600081E0A5DF80E0ABDF17E000E081E0A7DFFD |
:10067000000FB199016080E0A2DF1150B8F7FF20B0 |
:1006800011F081E001C080E092DFAFDF81E08FDF19 |
:10069000802F1F910F91FF9008952EE088E190E048 |
:1006A0000FB6F894A89581BD0FBE21BDB998C19A27 |
:1006B000BD98C59A10926E0010926D0088B38A7F23 |
:1006C00088BB87B3856087BB80E49CE90197F1F71D |
:1006D00087B38A7F87BB76DE7894A8957BDEFDCFD3 |
:1006E000EF92FF920F931F93CF93DF93E82E292F62 |
:1006F000F62E80916C00813021F500916D001091F3 |
:100700006E00862F90E00817190708F4F02E8E2D42 |
:10071000922F9C01E90102C0899173DF9E012E197D |
:100720002F15D0F3A8014F19510950936E00409333 |
:100730006D0080916F0081FF0AC0452B41F45ADFA4 |
:1007400006C08E2D60E070E04F2D50E0E1D0DF91CB |
:10075000CF911F910F91FF90EF900895CF92DF926C |
:10076000EF92FF920F931F93CF93DF93C82E292F01 |
:10077000D62E80916C00813061F5E0906D00F09094 |
:100780006E00862F90E0E816F90608F4DE2C8C2D1A |
:10079000922F9C018901E70108C080E0209709F4AD |
:1007A00081E05ADFF80181938F012197802F8C1906 |
:1007B0008D1598F397012D19310930936E00209310 |
:1007C0006D0080916F0081FF0AC0232B41F412DF7E |
:1007D00006C08C2D60E070E04D2D50E099D08D2D3D |
:1007E000DF91CF911F910F91FF90EF90DF90CF900D |
:1007F00008951F93CF93DF93EC0189818230E9F054 |
:10080000833030F4882359F0813009F073C00DC073 |
:10081000833009F46AC0883008F06CC030C08A8127 |
:1008200088838B81898382E066C0CE016AE870E0AC |
:1008300044E050E064D084E05EC08A819B81909364 |
:10084000630080936200892B31F481E090E0909303 |
:10085000630080936200809162009091630096959E |
:1008600087959093650080936400892B09F042C0BE |
:1008700081E090E090936500809364003BC01C8110 |
:10088000110F8A8180FD1160898180FD04C081E0A3 |
:100890008EDE81E094DE80E08ADE80E090DE812FD3 |
:1008A000B0DE882341F482E080936C0010926E00E9 |
:1008B00010926D0010C081E080936C002E813F810A |
:1008C00030936E0020936D00898180936F0081FFCB |
:1008D00003C0232B09F48EDE8A8180FF0BC08E813A |
:1008E0009F81892B39F08FEF06C080916C0088833F |
:1008F00081E001C080E0DF91CF911F910895FB015D |
:10090000DC0102C005900D9241505040D8F7089587 |
:10091000DC0101C06D9341505040E0F70895F89418 |
:02092000FFCF07 |
:06092200D25A0A00050094 |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/!____!.txt |
---|
0,0 → 1,27 |
i2c-tiny-usb firmware customized for MLAB hardware AVRUSB01 |
http://www.mlab.cz/PermaLink/AVRUSB01 |
----------------------------------------------------- |
- original firmare from http://www.harbaum.org/till/i2c_tiny_usb/i2c_tiny_usb-2009-02-10.zip |
- the original package contains drivers as well |
- the code itself has to be modifyied so that it vas possible to reconfigure IO pins for |
different hardware (minor changes in main function and in header file, new file config.h) |
- make process was automated so that "make all" creates all configuraed target binaries |
(for ATmega8 and ATmega88) |
- binary files for MLAB hardware is in bin directory |
- hardware configuration is this: |
XTAL 12.0MHz |
USB D+ PD2/INT0 |
USB D- PD4 |
ISP_RES# PB2 |
ISP_MOSI PB3 |
ISP_MISO PB4 |
ISP_SCK PB5 |
GreenLED PC1 (active L) |
RedLedLED PC0 (active L) |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile-avrusb.atmega8 |
---|
0,0 → 1,86 |
# Name: Makefile |
# Project: USB I2C |
# Author: Christian Starkjohann, modified for I2C USB by Till Harbaum |
# Creation Date: 2005-03-20 |
# Tabsize: 4 |
# Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
# License: Proprietary, free under certain conditions. See Documentation. |
# This Revision: $Id: Makefile-avrusb.mega8,v 1.1 2006/12/03 21:28:59 harbaum Exp $ |
SERIAL = `echo /dev/tty.[Uu][Ss]*` |
UISP = uisp -dprog=stk200 |
# UISP = uisp -dprog=avr910 -dserial=$(SERIAL) -dpart=auto |
# The two lines above are for "uisp" and the AVR910 serial programmer connected |
# to a Keyspan USB to serial converter to a Mac running Mac OS X. |
# Choose your favorite programmer and interface. |
DEFINES += -DDEBUG |
DEFINES += -DDEBUG_LEVEL=1 |
COMPILE = avr-gcc -Wall -O2 -Iusbdrv -I. -mmcu=atmega8 $(DEFINES) |
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o |
# symbolic targets: |
all: firmware.hex |
.c.o: |
$(COMPILE) -c $< -o $@ |
.S.o: |
$(COMPILE) -x assembler-with-cpp -c $< -o $@ |
# "-x assembler-with-cpp" should not be necessary since this is the default |
# file type for the .S (with capital S) extension. However, upper case |
# characters are not always preserved on Windows. To ensure WinAVR |
# compatibility define the file type manually. |
.c.s: |
$(COMPILE) -S $< -o $@ |
# Fuse high byte: |
# 0xD9 = 1 1 0 1 1 0 0 1 = Factory Default Value |
# 0xC9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) |
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 |
# | | | | | +-------- BOOTSZ1 |
# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) |
# | | | +-------------- CKOPT (full output swing) |
# | | +---------------- SPIEN (allow serial programming) |
# | +------------------ WDTON (WDT not always on) |
# +-------------------- RSTDISBL (reset pin is enabled) |
# Fuse low byte: |
# 0xE1 = 1 1 1 0 0 0 0 1 = Factory Default Value |
# 0x9F = 1 0 0 1 1 1 1 1 |
# ^ ^ \ / \--+--/ |
# | | | +------- CKSEL 3..0 (external >8M crystal) |
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) |
# | +------------------ BODEN (BrownOut Detector enabled) |
# +-------------------- BODLEVEL (2.7V) |
fuse: |
$(UISP) --wr_fuse_h=0xc9 --wr_fuse_l=0x9f |
clean: |
rm -f firmware.hex firmware.lst firmware.obj firmware.cof firmware.list firmware.map firmware.eep.hex firmware.bin *.o usbdrv/*.o firmware.s usbdrv/oddebug.s usbdrv/usbdrv.s |
# file targets: |
firmware.bin: $(OBJECTS) |
$(COMPILE) -o firmware.bin $(OBJECTS) |
firmware.hex: firmware.bin |
rm -f firmware.hex firmware.eep.hex |
avr-objcopy -j .text -j .data -O ihex firmware.bin firmware.hex |
./checksize firmware.bin 8192 960 |
# do the checksize script as our last action to allow successful compilation |
# on Windows with WinAVR where the Unix commands will fail. |
program: firmware.hex |
avrdude -c usbasp -p atmega8 -U lfuse:w:0x9f:m -U hfuse:w:0xc9:m -U flash:w:firmware.hex |
program-nodep: |
avrdude -c usbasp -p atmega8 -U lfuse:w:0x9f:m -U hfuse:w:0xc9:m -U flash:w:firmware.hex |
disasm: firmware.bin |
avr-objdump -d firmware.bin |
cpp: |
$(COMPILE) -E main.c |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile-avrusb.atmega88 |
---|
0,0 → 1,91 |
# Name: Makefile |
# Project: USB I2C |
# Author: Christian Starkjohann, modified for I2C USB by Till Harbaum |
# Creation Date: 2005-03-20 |
# Tabsize: 4 |
# Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
# License: Proprietary, free under certain conditions. See Documentation. |
# This Revision: $Id: Makefile-avrusb.mega8,v 1.1 2006/12/03 21:28:59 harbaum Exp $ |
SERIAL = `echo /dev/tty.[Uu][Ss]*` |
UISP = uisp -dprog=stk200 |
# UISP = uisp -dprog=avr910 -dserial=$(SERIAL) -dpart=auto |
# The two lines above are for "uisp" and the AVR910 serial programmer connected |
# to a Keyspan USB to serial converter to a Mac running Mac OS X. |
# Choose your favorite programmer and interface. |
DEFINES += -DDEBUG |
DEFINES += -DDEBUG_LEVEL=1 |
COMPILE = avr-gcc -Wall -O2 -Iusbdrv -I. -mmcu=atmega88 $(DEFINES) |
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o |
# symbolic targets: |
all: firmware.hex |
.c.o: |
$(COMPILE) -c $< -o $@ |
.S.o: |
$(COMPILE) -x assembler-with-cpp -c $< -o $@ |
# "-x assembler-with-cpp" should not be necessary since this is the default |
# file type for the .S (with capital S) extension. However, upper case |
# characters are not always preserved on Windows. To ensure WinAVR |
# compatibility define the file type manually. |
.c.s: |
$(COMPILE) -S $< -o $@ |
# Fuse extended byte: |
# 0xF9 = 1 1 1 1 1 0 0 1 <<<----Default Value (default value is used) |
# 0xF9 = 1 1 1 1 1 0 0 1 <-- BOOTRST (select vetor) |
# \+/ |
# +----- BOOTSZ1..0 (Select Boot Size) |
# Fuse high byte: |
# 0xDF 1 1 0 1 1 1 1 1 <<<----Default Value (default value may be used) |
# 0xDE = 1 1 0 1 1 1 1 0 |
# ^ ^ ^ ^ ^ \-+-/ |
# | | | | | +------ BODLEVEL (1.7-2.0V) |
# | | | | +---------- EESAVE (don't preserve EEPROM over chip erase) |
# | | | +-------------- WDTON (WDT not always on) |
# | | +---------------- SPIEN (allow serial programming)!!! |
# | +------------------ DWEN (debug wire not enabled) |
# +-------------------- RSTDISBL (reset pin is not disabled) |
# Fuse low byte: |
# 0x62 0 1 1 0 0 0 1 0 <<<----Default Value (must be programmed to use xosc) |
# 0xD7 = 1 1 0 1 0 1 1 1 |
# ^ ^ \ / \--+--/ |
# | | | +------- CKSEL 3..0 (full swing xosc, BOD enabled) |
# | | +--------------- SUT 1..0 (startup timer - see CKSEL) |
# | +------------------ CKOUT (clock output is not enabled) |
# +-------------------- CLKDIV8 (clock divider is not enabled) |
fuse: |
$(UISP) --wr_fuse_h=0xDE --wr_fuse_l=0xD7 |
clean: |
rm -f firmware.hex firmware.lst firmware.obj firmware.cof firmware.list firmware.map firmware.eep.hex firmware.bin *.o usbdrv/*.o firmware.s usbdrv/oddebug.s usbdrv/usbdrv.s |
# file targets: |
firmware.bin: $(OBJECTS) |
$(COMPILE) -o firmware.bin $(OBJECTS) |
firmware.hex: firmware.bin |
rm -f firmware.hex firmware.eep.hex |
avr-objcopy -j .text -j .data -O ihex firmware.bin firmware.hex |
./checksize firmware.bin 8192 960 |
# do the checksize script as our last action to allow successful compilation |
# on Windows with WinAVR where the Unix commands will fail. |
program: firmware.hex |
avrdude -c usbasp -p atmega88 -U lfuse:w:0xD7:m -U hfuse:w:0xDE:m -U flash:w:firmware.hex |
program-nodep: |
avrdude -c usbasp -p atmega88 -U lfuse:w:0xD7:m -U hfuse:w:0xDE:m -U flash:w:firmware.hex |
disasm: firmware.bin |
avr-objdump -d firmware.bin |
cpp: |
$(COMPILE) -E main.c |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile-avrusb.attiny45 |
---|
0,0 → 1,75 |
# Name: Makefile |
# Project: USB I2C |
# Author: Christian Starkjohann, modified for I2C USB by Till Harbaum |
# Creation Date: 2005-03-20 |
# Tabsize: 4 |
# Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
# License: Proprietary, free under certain conditions. See Documentation. |
# This Revision: $Id: Makefile-avrusb.tiny45,v 1.3 2007/06/07 13:53:47 harbaum Exp $ |
# DEFINES += -DDEBUG |
# DEFINES += -DDEBUG_LEVEL=1 |
DEFINES += -DF_CPU=12000000 |
COMPILE = avr-gcc -Wall -O2 -Iusbdrv -I. -mmcu=attiny45 $(DEFINES) |
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o main.o |
# symbolic targets: |
all: firmware.hex |
.c.o: |
$(COMPILE) -c $< -o $@ |
.S.o: |
$(COMPILE) -x assembler-with-cpp -c $< -o $@ |
# "-x assembler-with-cpp" should not be necessary since this is the default |
# file type for the .S (with capital S) extension. However, upper case |
# characters are not always preserved on Windows. To ensure WinAVR |
# compatibility define the file type manually. |
.c.s: |
$(COMPILE) -S $< -o $@ |
# Fuse high byte: |
# 0x5f = 0 1 0 1 1 1 1 1 <-- BODLEVEL0 (Brown out trigger level bit 0) |
# ^ ^ ^ ^ ^ ^ ^------ BODLEVEL1 (Brown out trigger level bit 1) |
# | | | | | +-------- BODLEVEL2 (Brown out trigger level bit 2) |
# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) |
# | | | +-------------- WDTON (WDT not always on) |
# | | +---------------- SPIEN (allow serial programming) |
# | +------------------ DWEN (ebug wire is enabled) |
# +-------------------- RSTDISBL (reset pin is disabled) |
# Fuse low byte: |
# 0xdf = 1 1 0 1 1 1 1 1 |
# ^ ^ \ / \--+--/ |
# | | | +------- CKSEL 3..0 (external >8M crystal) |
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) |
# | +------------------ CKOUT (clock output enable) |
# +-------------------- CKDIV8 (divide clock by eight disabled) |
clean: |
# rm -f firmware.hex firmware.lst firmware.obj firmware.cof firmware.list firmware.map *.bin *.o */*.o *~ */*~ firmware.s usbdrv/oddebug.s usbdrv/usbdrv.s |
rm -f firmware.hex firmware.lst firmware.obj firmware.cof firmware.list firmware.map firmware.eep.hex firmware.bin *.o usbdrv/*.o firmware.s usbdrv/oddebug.s usbdrv/usbdrv.s |
# file targets: |
firmware.bin: $(OBJECTS) |
$(COMPILE) -o firmware.bin $(OBJECTS) |
firmware.hex: firmware.bin |
rm -f firmware.hex firmware.eep.hex |
avr-objcopy -j .text -j .data -O ihex firmware.bin firmware.hex |
./checksize firmware.bin 4096 196 |
# do the checksize script as our last action to allow successful compilation |
# on Windows with WinAVR where the Unix commands will fail. |
program: firmware.hex |
avrdude -P/dev/ttyS0 -c stk500hvsp -p attiny45 -U lfuse:w:0xdf:m -U flash:w:firmware.hex -U hfuse:w:0x5f:m |
program-usb: firmware.hex |
avrdude -P/dev/ttyUSB0 -c stk500hvsp -p attiny45 -U lfuse:w:0xdf:m -U flash:w:firmware.hex -U hfuse:w:0x5f:m |
disasm: firmware.bin |
avr-objdump -d firmware.bin |
cpp: |
$(COMPILE) -E main.c |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile-usbtiny.atmega88 |
---|
0,0 → 1,17 |
# ====================================================================== |
# Makefile for i2c-tiny-usb |
# |
# Copyright (C) 2006 Till Harbaum |
# |
# This is free software, licensed under the terms of the GNU General |
# Public License as published by the Free Software Foundation. |
# ====================================================================== |
USBTINY = ./usbtiny |
TARGET_ARCH = -DF_CPU=12000000 -DUSBTINY -mmcu=atmega88 |
OBJECTS = main.o |
FLASH_CMD = avrdude -c usbasp -p atmega88 -U lfuse:w:0xD7:m -U hfuse:w:0xDE:m -U flash:w:main.hex |
STACK = 32 |
FLASH = 8192 |
SRAM = 1024 |
include $(USBTINY)/common.mk |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/config.h |
---|
0,0 → 1,46 |
#ifndef __CONFIG_H_ |
#define __CONFIG_H_ |
// Define USB pin names |
// -------------------- |
#if! defined (__AVR_ATtiny45__) |
#define CONFIG_USB_PORT D |
#define CONFIG_USB_DPLUS 2 |
#define CONFIG_USB_DMINUS 4 |
#else |
#define CONFIG_USB_PORT B |
#define CONFIG_USB_DPLUS 2 |
#define CONFIG_USB_DMINUS 0 |
#endif |
// SPI Config |
// ---------- |
#define ENABLE_SCL_EXPAND // wait for slow target device (SCL L state hold in L state) |
// CPU Compatibility |
// ----------------- |
// ATmega88 --> ATmega8 (USART0 Registers to USART Registers) |
#ifdef UDR0 |
#define UDR UDR0 |
#endif |
#ifdef UDRE0 |
#define UDRE UDRE0 |
#endif |
#ifdef UCSR0A |
#define UCSRA UCSR0A |
#endif |
// Macros for Port (enables to easily define IO signals) |
// --------------- |
#define GLUE(A,B) A##B |
#define DDR(PORT_LETTER) GLUE(DDR, PORT_LETTER) // Makes DDRC from DDR(C) etc. |
#define PORT(PORT_LETTER) GLUE(PORT,PORT_LETTER) // Makes PORTC from PORT(C) |
#define PIN(PORT_LETTER) GLUE(PIN, PORT_LETTER) // Makes PINC from PIN(C) |
#endif |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/main.c |
---|
0,0 → 1,569 |
/* Name: main.c |
* Project: i2c-tiny-usb |
* Author: Till Harbaum |
* Tabsize: 4 |
* Copyright: (c) 2005 by Till Harbaum <till@harbaum.org> |
* License: GPL |
* This Revision: $Id: main.c,v 1.9 2007/06/07 13:53:47 harbaum Exp $ |
* |
* $Log: main.c,v $ |
* Revision 1.9 2007/06/07 13:53:47 harbaum |
* Version number fixes |
* |
* Revision 1.8 2007/05/19 12:30:11 harbaum |
* Updated USB stacks |
* |
* Revision 1.7 2007/04/22 10:34:05 harbaum |
* *** empty log message *** |
* |
* Revision 1.6 2007/01/05 19:30:58 harbaum |
* i2c clock bug fix |
* |
* Revision 1.5 2007/01/03 18:35:07 harbaum |
* usbtiny fixes and pcb layouts |
* |
* Revision 1.4 2006/12/03 21:28:59 harbaum |
* *** empty log message *** |
* |
* Revision 1.3 2006/11/22 19:12:45 harbaum |
* Added usbtiny support |
* |
* Revision 1.2 2006/11/14 19:15:13 harbaum |
* *** empty log message *** |
* |
*/ |
#include <stdio.h> |
#include <ctype.h> |
#include <string.h> |
#include <avr/io.h> |
#include <avr/interrupt.h> |
#include <avr/pgmspace.h> |
#include <avr/wdt.h> |
#include <util/delay.h> |
#include "config.h" |
// Include USB library (AVRUSB or USBTINY) |
// ------------------- |
#ifndef USBTINY |
// use avrusb library |
#include "usbdrv.h" |
#include "oddebug.h" |
#else |
// use usbtiny library |
#include "usb.h" |
#include "usbtiny.h" |
typedef byte_t uchar; |
#define usbInit() usb_init() |
#define usbPoll() usb_poll() |
#endif |
/* commands from USB, must e.g. match command ids in kernel driver */ |
#define CMD_ECHO 0 |
#define CMD_GET_FUNC 1 |
#define CMD_SET_DELAY 2 |
#define CMD_GET_STATUS 3 |
#define CMD_I2C_IO 4 |
#define CMD_I2C_BEGIN 1 // flag fo I2C_IO |
#define CMD_I2C_END 2 // flag fo I2C_IO |
/* linux kernel flags */ |
#define I2C_M_TEN 0x10 /* we have a ten bit chip address */ |
#define I2C_M_RD 0x01 |
#define I2C_M_NOSTART 0x4000 |
#define I2C_M_REV_DIR_ADDR 0x2000 |
#define I2C_M_IGNORE_NAK 0x1000 |
#define I2C_M_NO_RD_ACK 0x0800 |
/* To determine what functionality is present */ |
#define I2C_FUNC_I2C 0x00000001 |
#define I2C_FUNC_10BIT_ADDR 0x00000002 |
#define I2C_FUNC_PROTOCOL_MANGLING 0x00000004 /* I2C_M_{REV_DIR_ADDR,NOSTART,..} */ |
#define I2C_FUNC_SMBUS_HWPEC_CALC 0x00000008 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_READ_WORD_DATA_PEC 0x00000800 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_WRITE_WORD_DATA_PEC 0x00001000 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_PROC_CALL_PEC 0x00002000 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL_PEC 0x00004000 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_BLOCK_PROC_CALL 0x00008000 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_QUICK 0x00010000 |
#define I2C_FUNC_SMBUS_READ_BYTE 0x00020000 |
#define I2C_FUNC_SMBUS_WRITE_BYTE 0x00040000 |
#define I2C_FUNC_SMBUS_READ_BYTE_DATA 0x00080000 |
#define I2C_FUNC_SMBUS_WRITE_BYTE_DATA 0x00100000 |
#define I2C_FUNC_SMBUS_READ_WORD_DATA 0x00200000 |
#define I2C_FUNC_SMBUS_WRITE_WORD_DATA 0x00400000 |
#define I2C_FUNC_SMBUS_PROC_CALL 0x00800000 |
#define I2C_FUNC_SMBUS_READ_BLOCK_DATA 0x01000000 |
#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA 0x02000000 |
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK 0x04000000 /* I2C-like block xfer */ |
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK 0x08000000 /* w/ 1-byte reg. addr. */ |
#define I2C_FUNC_SMBUS_READ_I2C_BLOCK_2 0x10000000 /* I2C-like block xfer */ |
#define I2C_FUNC_SMBUS_WRITE_I2C_BLOCK_2 0x20000000 /* w/ 2-byte reg. addr. */ |
#define I2C_FUNC_SMBUS_READ_BLOCK_DATA_PEC 0x40000000 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC 0x80000000 /* SMBus 2.0 */ |
#define I2C_FUNC_SMBUS_BYTE I2C_FUNC_SMBUS_READ_BYTE | \ |
I2C_FUNC_SMBUS_WRITE_BYTE |
#define I2C_FUNC_SMBUS_BYTE_DATA I2C_FUNC_SMBUS_READ_BYTE_DATA | \ |
I2C_FUNC_SMBUS_WRITE_BYTE_DATA |
#define I2C_FUNC_SMBUS_WORD_DATA I2C_FUNC_SMBUS_READ_WORD_DATA | \ |
I2C_FUNC_SMBUS_WRITE_WORD_DATA |
#define I2C_FUNC_SMBUS_BLOCK_DATA I2C_FUNC_SMBUS_READ_BLOCK_DATA | \ |
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA |
#define I2C_FUNC_SMBUS_I2C_BLOCK I2C_FUNC_SMBUS_READ_I2C_BLOCK | \ |
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK |
#define I2C_FUNC_SMBUS_EMUL I2C_FUNC_SMBUS_QUICK | \ |
I2C_FUNC_SMBUS_BYTE | \ |
I2C_FUNC_SMBUS_BYTE_DATA | \ |
I2C_FUNC_SMBUS_WORD_DATA | \ |
I2C_FUNC_SMBUS_PROC_CALL | \ |
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA | \ |
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA_PEC | \ |
I2C_FUNC_SMBUS_I2C_BLOCK |
/* the currently support capability is quite limited */ |
const unsigned long func PROGMEM = I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; |
#ifdef DEBUG |
#define DEBUGF(format, args...) printf_P(PSTR(format), ##args) |
/* ------------------------------------------------------------------------- */ |
static int uart_putchar(char c, FILE *stream) { |
if (c == '\n') |
uart_putchar('\r', stream); |
loop_until_bit_is_set(UCSRA, UDRE); |
UDR = c; |
return 0; |
} |
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, |
_FDEV_SETUP_WRITE); |
#else |
#define DEBUGF(format, args...) |
#endif |
/* ------------------------------------------------------------------------- */ |
#define DEFAULT_DELAY 10 // default 10us (100khz) |
static unsigned short clock_delay = DEFAULT_DELAY; |
static unsigned short clock_delay2 = DEFAULT_DELAY/2; |
static unsigned short expected; |
static unsigned char saved_cmd; |
#if! defined (__AVR_ATtiny45__) |
#define I2C_PORT PORTC |
#define I2C_PIN PINC |
#define I2C_DDR DDRC |
#define I2C_SDA _BV(4) |
#define I2C_SCL _BV(5) |
#else |
#define I2C_PORT PORTB |
#define I2C_PIN PINB |
#define I2C_DDR DDRB |
#define I2C_SDA _BV(1) |
#define I2C_SCL _BV(5) |
#endif |
static void i2c_io_set_sda(uchar hi) { |
if(hi) { |
I2C_DDR &= ~I2C_SDA; // high -> input |
I2C_PORT |= I2C_SDA; // with pullup |
} else { |
I2C_DDR |= I2C_SDA; // low -> output |
I2C_PORT &= ~I2C_SDA; // drive low |
} |
} |
static uchar i2c_io_get_sda(void) { |
return(I2C_PIN & I2C_SDA); |
} |
static void i2c_io_set_scl(uchar hi) { |
#ifdef ENABLE_SCL_EXPAND |
_delay_loop_2(clock_delay2); |
if(hi) { |
I2C_DDR &= ~I2C_SCL; // port is input |
I2C_PORT |= I2C_SCL; // enable pullup |
// wait while pin is pulled low by client |
while(!(I2C_PIN & I2C_SCL)); |
} else { |
I2C_DDR |= I2C_SCL; // port is output |
I2C_PORT &= ~I2C_SCL; // drive it low |
} |
_delay_loop_2(clock_delay); |
#else |
_delay_loop_2(clock_delay2); |
if(hi) I2C_PORT |= I2C_SCL; // port is high |
else I2C_PORT &= ~I2C_SCL; // port is low |
_delay_loop_2(clock_delay); |
#endif |
} |
static void i2c_init(void) { |
/* init the sda/scl pins */ |
I2C_DDR &= ~I2C_SDA; // port is input |
I2C_PORT |= I2C_SDA; // enable pullup |
#ifdef ENABLE_SCL_EXPAND |
I2C_DDR &= ~I2C_SCL; // port is input |
I2C_PORT |= I2C_SCL; // enable pullup |
#else |
I2C_DDR |= I2C_SCL; // port is output |
#endif |
/* no bytes to be expected */ |
expected = 0; |
} |
/* clock HI, delay, then LO */ |
static void i2c_scl_toggle(void) { |
i2c_io_set_scl(1); |
i2c_io_set_scl(0); |
} |
/* i2c start condition */ |
static void i2c_start(void) { |
i2c_io_set_sda(0); |
i2c_io_set_scl(0); |
} |
/* i2c repeated start condition */ |
static void i2c_repstart(void) |
{ |
/* scl, sda may not be high */ |
i2c_io_set_sda(1); |
i2c_io_set_scl(1); |
i2c_io_set_sda(0); |
i2c_io_set_scl(0); |
} |
/* i2c stop condition */ |
void i2c_stop(void) { |
i2c_io_set_sda(0); |
i2c_io_set_scl(1); |
i2c_io_set_sda(1); |
} |
uchar i2c_put_u08(uchar b) { |
char i; |
for (i=7;i>=0;i--) { |
if ( b & (1<<i) ) i2c_io_set_sda(1); |
else i2c_io_set_sda(0); |
i2c_scl_toggle(); // clock HI, delay, then LO |
} |
i2c_io_set_sda(1); // leave SDL HI |
i2c_io_set_scl(1); // clock back up |
b = i2c_io_get_sda(); // get the ACK bit |
i2c_io_set_scl(0); // not really ?? |
return(b == 0); // return ACK value |
} |
uchar i2c_get_u08(uchar last) { |
char i; |
uchar c,b = 0; |
i2c_io_set_sda(1); // make sure pullups are activated |
i2c_io_set_scl(0); // clock LOW |
for(i=7;i>=0;i--) { |
i2c_io_set_scl(1); // clock HI |
c = i2c_io_get_sda(); |
b <<= 1; |
if(c) b |= 1; |
i2c_io_set_scl(0); // clock LO |
} |
if(last) i2c_io_set_sda(1); // set NAK |
else i2c_io_set_sda(0); // set ACK |
i2c_scl_toggle(); // clock pulse |
i2c_io_set_sda(1); // leave with SDL HI |
return b; // return received byte |
} |
#ifdef DEBUG |
void i2c_scan(void) { |
uchar i = 0; |
for(i=0;i<127;i++) { |
i2c_start(); // do start transition |
if(i2c_put_u08(i << 1)) // send DEVICE address |
DEBUGF("I2C device at address 0x%x\n", i); |
i2c_stop(); |
} |
} |
#endif |
/* ------------------------------------------------------------------------- */ |
struct i2c_cmd { |
unsigned char type; |
unsigned char cmd; |
unsigned short flags; |
unsigned short addr; |
unsigned short len; |
}; |
#define STATUS_IDLE 0 |
#define STATUS_ADDRESS_ACK 1 |
#define STATUS_ADDRESS_NAK 2 |
static uchar status = STATUS_IDLE; |
static uchar i2c_do(struct i2c_cmd *cmd) { |
uchar addr; |
DEBUGF("i2c %s at 0x%02x, len = %d\n", |
(cmd->flags&I2C_M_RD)?"rd":"wr", cmd->addr, cmd->len); |
/* normal 7bit address */ |
addr = ( cmd->addr << 1 ); |
if (cmd->flags & I2C_M_RD ) |
addr |= 1; |
if(cmd->cmd & CMD_I2C_BEGIN) |
i2c_start(); |
else |
i2c_repstart(); |
// send DEVICE address |
if(!i2c_put_u08(addr)) { |
DEBUGF("I2C read: address error @ %x\n", addr); |
status = STATUS_ADDRESS_NAK; |
expected = 0; |
i2c_stop(); |
} else { |
status = STATUS_ADDRESS_ACK; |
expected = cmd->len; |
saved_cmd = cmd->cmd; |
/* check if transfer is already done (or failed) */ |
if((cmd->cmd & CMD_I2C_END) && !expected) |
i2c_stop(); |
} |
/* more data to be expected? */ |
#ifndef USBTINY |
return(cmd->len?0xff:0x00); |
#else |
return(((cmd->flags & I2C_M_RD) && cmd->len)?0xff:0x00); |
#endif |
} |
#ifndef USBTINY |
uchar usbFunctionSetup(uchar data[8]) { |
static uchar replyBuf[4]; |
usbMsgPtr = replyBuf; |
#else |
extern byte_t usb_setup ( byte_t data[8] ) |
{ |
byte_t *replyBuf = data; |
#endif |
DEBUGF("Setup %x %x %x %x\n", data[0], data[1], data[2], data[3]); |
switch(data[1]) { |
case CMD_ECHO: // echo (for transfer reliability testing) |
replyBuf[0] = data[2]; |
replyBuf[1] = data[3]; |
return 2; |
break; |
case CMD_GET_FUNC: |
memcpy_P(replyBuf, &func, sizeof(func)); |
return sizeof(func); |
break; |
case CMD_SET_DELAY: |
/* The delay function used delays 4 system ticks per cycle. */ |
/* This gives 1/3us at 12Mhz per cycle. The delay function is */ |
/* called twice per clock edge and thus four times per full cycle. */ |
/* Thus it is called one time per edge with the full delay */ |
/* value and one time with the half one. Resulting in */ |
/* 2 * n * 1/3 + 2 * 1/2 n * 1/3 = n us. */ |
clock_delay = *(unsigned short*)(data+2); |
if(!clock_delay) clock_delay = 1; |
clock_delay2 = clock_delay/2; |
if(!clock_delay2) clock_delay2 = 1; |
DEBUGF("request for delay %dus\n", clock_delay); |
break; |
case CMD_I2C_IO: |
case CMD_I2C_IO + CMD_I2C_BEGIN: |
case CMD_I2C_IO + CMD_I2C_END: |
case CMD_I2C_IO + CMD_I2C_BEGIN + CMD_I2C_END: |
// these are only allowed as class transfers |
return i2c_do((struct i2c_cmd*)data); |
break; |
case CMD_GET_STATUS: |
replyBuf[0] = status; |
return 1; |
break; |
default: |
// must not happen ... |
break; |
} |
return 0; // reply len |
} |
/*---------------------------------------------------------------------------*/ |
/* usbFunctionRead */ |
/*---------------------------------------------------------------------------*/ |
#ifndef USBTINY |
uchar usbFunctionRead( uchar *data, uchar len ) |
#else |
extern byte_t usb_in ( byte_t* data, byte_t len ) |
#endif |
{ |
uchar i; |
DEBUGF("read %d bytes, %d exp\n", len, expected); |
if(status == STATUS_ADDRESS_ACK) { |
if(len > expected) { |
DEBUGF("exceeds!\n"); |
len = expected; |
} |
// consume bytes |
for(i=0;i<len;i++) { |
expected--; |
*data = i2c_get_u08(expected == 0); |
DEBUGF("data = %x\n", *data); |
data++; |
} |
// end transfer on last byte |
if((saved_cmd & CMD_I2C_END) && !expected) |
i2c_stop(); |
} else { |
DEBUGF("not in ack state\n"); |
memset(data, 0, len); |
} |
return len; |
} |
/*---------------------------------------------------------------------------*/ |
/* usbFunctionWrite */ |
/*---------------------------------------------------------------------------*/ |
#ifndef USBTINY |
uchar usbFunctionWrite( uchar *data, uchar len ) |
#else |
extern void usb_out ( byte_t* data, byte_t len ) |
#endif |
{ |
uchar i, err=0; |
DEBUGF("write %d bytes, %d exp\n", len, expected); |
if(status == STATUS_ADDRESS_ACK) { |
if(len > expected) { |
DEBUGF("exceeds!\n"); |
len = expected; |
} |
// consume bytes |
for(i=0;i<len;i++) { |
expected--; |
DEBUGF("data = %x\n", *data); |
if(!i2c_put_u08(*data++)) |
err = 1; |
} |
// end transfer on last byte |
if((saved_cmd & CMD_I2C_END) && !expected) |
i2c_stop(); |
if(err) { |
DEBUGF("write failed\n"); |
//TODO: set status |
} |
} else { |
DEBUGF("not in ack state\n"); |
memset(data, 0, len); |
} |
#ifndef USBTINY |
return len; |
#endif |
} |
/* ------------------------------------------------------------------------- */ |
int main(void) { |
wdt_enable(WDTO_1S); |
#if DEBUG_LEVEL > 0 |
/* let debug routines init the uart if they want to */ |
odDebugInit(); |
#else |
#ifdef DEBUG |
/* quick'n dirty uart init */ |
UCSRB |= _BV(TXEN); |
UBRRL = F_CPU / (19200 * 16L) - 1; |
#endif |
#endif |
#ifdef DEBUG |
stdout = &mystdout; |
#endif |
DEBUGF("i2c-tiny-usb - (c) 2006 by Till Harbaum\n"); |
i2c_init(); |
#ifdef DEBUG |
i2c_scan(); |
#endif |
/* clear usb ports */ |
PORT(CONFIG_USB_PORT) &= (uchar)~((1<<CONFIG_USB_DMINUS)|(1<<CONFIG_USB_DPLUS)); |
/* make usb data lines outputs */ |
DDR(CONFIG_USB_PORT) |= ((1<<CONFIG_USB_DMINUS)|(1<<CONFIG_USB_DPLUS)); |
/* USB Reset by device only required on Watchdog Reset */ |
_delay_loop_2(40000); // 10ms |
/* make usb data lines inputs */ |
DDR(CONFIG_USB_PORT) &= ~((1<<CONFIG_USB_DMINUS)|(1<<CONFIG_USB_DPLUS)); |
usbInit(); |
sei(); |
for(;;) { /* main event loop */ |
wdt_reset(); |
usbPoll(); |
} |
return 0; |
} |
/* ------------------------------------------------------------------------- */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/python |
---|
0,0 → 1,2 |
#!/bin/sh |
echo Dummy python for WinAVR compilation |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbconfig.h |
---|
0,0 → 1,117 |
/* Name: usbconfig.h |
* Project: AVR USB driver |
* Author: Christian Starkjohann, modified by Till Harbaum |
* Creation Date: 2005-04-01 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: Proprietary, free under certain conditions. See Documentation. |
* This Revision: $Id: usbconfig.h,v 1.4 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
#ifndef __usbconfig_h_included__ |
#define __usbconfig_h_included__ |
/* |
General Description: |
This file contains parts of the USB driver which can be configured and can or |
must be adapted to your hardware. |
*/ |
/* ---------------------------- Hardware Config ---------------------------- */ |
#include "config.h" |
#define USB_CFG_IOPORTNAME CONFIG_USB_PORT |
/* This is the port where the USB bus is connected. When you configure it to |
* "PORTB", the registers PORTB, PINB (=PORTB+2) and DDRB (=PORTB+1) will be |
* used. |
*/ |
#define USB_CFG_DMINUS_BIT CONFIG_USB_DMINUS |
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. |
* This MUST be bit 0. All other values will result in a compile error! |
*/ |
#define USB_CFG_DPLUS_BIT CONFIG_USB_DPLUS |
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. |
* This may be any bit in the port. Please note that D+ must also be connected |
* to interrupt pin INT0! |
*/ |
/* --------------------------- Functional Range ---------------------------- */ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0 |
/* Define this to 1 if you want to compile a version with two endpoints: The |
* default control endpoint 0 and an interrupt-in endpoint 1. |
*/ |
#define USB_CFG_INTR_POLL_INTERVAL 10 |
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll |
* interval. The value is in milliseconds and must not be less than 10 ms for |
* low speed devices. |
*/ |
#define USB_CFG_IS_SELF_POWERED 0 |
/* Define this to 1 if the device has its own power supply. Set it to 0 if the |
* device is powered from the USB bus. |
*/ |
#define USB_CFG_MAX_BUS_POWER 10 |
/* Set this variable to the maximum USB bus power consumption of your device. |
* The value is in milliamperes. [It will be divided by two since USB |
* communicates power requirements in units of 2 mA.] |
*/ |
#define USB_CFG_SAMPLE_EXACT 1 |
/* This variable affects Sampling Jitter for USB receiving. When it is 0, the |
* driver guarantees a sampling window of 1/2 bit. The USB spec requires |
* that the receiver has at most 1/4 bit sampling window. The 1/2 bit window |
* should still work reliably enough because we work at low speed. If you want |
* to meet the spec, set this value to 1. This will unroll a loop which |
* results in bigger code size. |
* If you have problems with long cables, try setting this value to 1. |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITE 1 |
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out |
* transfers. Set it to 0 if you don't need it and want to save a couple of |
* bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_READ 1 |
/* Set this to 1 if you need to send control replies which are generated |
* "on the fly" when usbFunctionRead() is called. If you only want to send |
* data from a static buffer, set it to 0 and return the data from |
* usbFunctionSetup(). This saves a couple of bytes. |
*/ |
/* -------------------------- Device Description --------------------------- */ |
#define USB_CFG_VENDOR_ID 0x03, 0x04 |
/* USB vendor ID for the device, low byte first. */ |
#define USB_CFG_DEVICE_ID 0x31, 0xc6 |
/* This is the ID of the device, low byte first. It is interpreted in the |
* scope of the vendor ID. The only requirement is that no two devices may |
* share the same product and vendor IDs. Not even if the devices are never |
* on the same bus together! |
*/ |
#define USB_CFG_DEVICE_VERSION 0x05, 0x01 |
/* Version number of the device: Minor number first, then major number. |
*/ |
#define USB_CFG_VENDOR_NAME 'T', 'i', 'l', 'l', ' ', 'H', 'a', 'r', 'b', 'a', 'u', 'm' |
#define USB_CFG_VENDOR_NAME_LEN 12 |
/* These two values define the vendor name returned by the USB device. The name |
* must be given as a list of characters under single quotes. The characters |
* are interpreted as Unicode (UTF-16) entities. |
* If you don't want a vendor name string, undefine these macros. |
*/ |
#define USB_CFG_DEVICE_NAME 'i','2','c','-','t','i','n','y','-','u','s','b' |
#define USB_CFG_DEVICE_NAME_LEN 12 |
/* Same as above for the device name. If you don't want a device name, undefine |
* the macros. |
*/ |
#define USB_CFG_DEVICE_CLASS 0xff |
#define USB_CFG_DEVICE_SUBCLASS 0 |
/* See USB specification if you want to conform to an existing device class. |
*/ |
#define USB_CFG_INTERFACE_CLASS 0 |
#define USB_CFG_INTERFACE_SUBCLASS 0 |
#define USB_CFG_INTERFACE_PROTOCOL 0 |
/* See USB specification if you want to conform to an existing device class or |
* protocol. |
*/ |
#endif /* __usbconfig_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny.h |
---|
0,0 → 1,80 |
// ====================================================================== |
// USBtiny Configuration |
// |
// Copyright (C) 2006 Dick Streefland |
// |
// This is free software, licensed under the terms of the GNU General |
// Public License as published by the Free Software Foundation. |
// ====================================================================== |
// The D+ and D- USB signals should be connected to two pins of the same |
// I/O port. The following macros define the port letter and the input |
// bit numbers: |
#include "config.h" |
#define USBTINY_PORT CONFIG_USB_PORT |
#define USBTINY_DPLUS CONFIG_USB_DPLUS |
#define USBTINY_DMINUS CONFIG_USB_DMINUS |
// The D+ signal should be connected to an interrupt input to trigger an |
// interrupt at the start of a packet. When you use the same pin for the |
// D+ USB signal and the interrupt input, only two I/O pins are needed |
// for the USB interface. The following macro defines the interrupt |
// number: |
#define USBTINY_INT 0 |
// The power requirement of the USB device in mA, or 0 when the device |
// is not bus powered: |
#define USBTINY_MAX_POWER 10 |
// The USB vendor and device IDs. These values should be unique for |
// every distinct device. You can get your own vendor ID from the USB |
// Implementers Forum (www.usb.org) if you have a spare $1500 to kill. |
// Alternatively, you can buy a small range of device IDs from |
// www.voti.nl or www.mecanique.co.uk, or be naughty and use something |
// else, like for instance product ID 0x6666, which is registered as |
// "Prototype product Vendor ID". |
#define USBTINY_VENDOR_ID 0x0403 |
#define USBTINY_DEVICE_ID 0xc631 |
// The version of the device as a 16-bit number: 256*major + minor. |
#define USBTINY_DEVICE_VERSION 0x205 |
// The following optional macros may be used as an identification of |
// your device. Undefine them when you run out of flash space. |
#define USBTINY_VENDOR_NAME "Till Harbaum" |
#define USBTINY_DEVICE_NAME "i2c-tiny-usb" |
#undef USBTINY_SERIAL |
// Define the device class, subclass and protocol. Device class 0xff |
// is "vendor specific". |
#define USBTINY_DEVICE_CLASS 0xff |
#define USBTINY_DEVICE_SUBCLASS 0 |
#define USBTINY_DEVICE_PROTOCOL 0 |
// Define the interface class, subclass and protocol. Interface class |
// 0xff is "vendor specific". |
#define USBTINY_INTERFACE_CLASS 0xff |
#define USBTINY_INTERFACE_SUBCLASS 0 |
#define USBTINY_INTERFACE_PROTOCOL 0 |
// Normally, usb_setup() should write the reply of up to 8 bytes into the |
// packet buffer, and return the reply length. When this macro is defined |
// as 1, you have the option of returning 0xff instead. In that case, the |
// USB driver will call a function usb_in() to obtain the data to send |
// back to the host. This can be used to generate the data on-the-fly. |
#define USBTINY_CALLBACK_IN 1 |
// When this macro is defined as 0, OUT packets are simply ignored. |
// When defined as 1, the function usb_out() is called for OUT packets. |
// You need this option to send data from the host to the device in |
// a control transfer. |
#define USBTINY_CALLBACK_OUT 1 |
// Set the macro USBTINY_ENDPOINT to 1 to add an additional endpoint, |
// according to the values of the three other macros. |
#define USBTINY_ENDPOINT 0 |
#define USBTINY_ENDPOINT_ADDRESS 0x81 // IN endpoint #1 |
#define USBTINY_ENDPOINT_TYPE 0x00 // control transfer type |
#define USBTINY_ENDPOINT_INTERVAL 0 // ignored |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile-usbtiny.atmega8 |
---|
0,0 → 1,17 |
# ====================================================================== |
# Makefile for i2c-tiny-usb |
# |
# Copyright (C) 2006 Till Harbaum |
# |
# This is free software, licensed under the terms of the GNU General |
# Public License as published by the Free Software Foundation. |
# ====================================================================== |
USBTINY = ./usbtiny |
TARGET_ARCH = -DF_CPU=12000000 -DUSBTINY -mmcu=atmega8 |
OBJECTS = main.o |
FLASH_CMD = avrdude -c usbasp -p atmega8 -U lfuse:w:0x9f:m -U hfuse:w:0xc9:m -U flash:w:main.hex |
STACK = 32 |
FLASH = 8192 |
SRAM = 1024 |
include $(USBTINY)/common.mk |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/Makefile-usbtiny.attiny45 |
---|
0,0 → 1,19 |
# ====================================================================== |
# Makefile for i2c-tiny-usb |
# |
# Copyright (C) 2006 Till Harbaum |
# |
# This is free software, licensed under the terms of the GNU General |
# Public License as published by the Free Software Foundation. |
# ====================================================================== |
USBTINY = ./usbtiny |
TARGET_ARCH = -DF_CPU=12000000 -DUSBTINY -mmcu=attiny45 |
OBJECTS = main.o |
TTY = /dev/ttyUSB0 |
# TTY = /dev/ttyS0 |
FLASH_CMD = avrdude -P$(TTY) -c stk500hvsp -p attiny45 -U lfuse:w:0xdf:m -U hfuse:w:0x5f:m -U flash:w:main.hex |
STACK = 32 |
FLASH = 4096 |
SRAM = 256 |
include $(USBTINY)/common.mk |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/COPYING |
---|
0,0 → 1,341 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) 19yy <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) 19yy name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/checksize |
---|
0,0 → 1,35 |
#!/bin/sh |
# Name: checksize |
# Project: AVR Make system |
# Author: Christian Starkjohann |
# Creation Date: 2004-12-29 |
# Tabsize: 4 |
# Copyright: (c) 2005 OBJECTIVE DEVELOPMENT Software GmbH. |
# Revision: $Id: checksize,v 1.1.1.1 2006/11/09 18:27:00 harbaum Exp $ |
error=0 |
codelimit=2048 # default value |
datalimit=96 # default value; leave 32 bytes for stack |
if [ $# -gt 1 ]; then |
codelimit="$2" |
fi |
if [ $# -gt 2 ]; then |
datalimit="$3" |
fi |
set -- `avr-size -d "$1" | awk '/[0-9]/ {print $1 + $2, $2 + $3, $2}'` |
if [ $1 -gt $codelimit ]; then |
echo "*** code size $1 exceeds limit of $codelimit" |
error=1 |
else |
echo "ROM: $1 bytes (data=$3)" |
fi |
if [ $2 -gt $datalimit ]; then |
echo "*** data size $2 exceeds limit of $datalimit" |
error=1 |
else |
echo "RAM: $2 bytes" |
fi |
exit $error |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/original/i2c_tiny_usb-2009-02-10.zip |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/readme.txt |
---|
0,0 → 1,38 |
i2c-tiny-usb - (c) 2006 by Till Harbaum |
--------------------------------------- |
http://www.harbaum.org/till/i2c_tiny_usb |
The firmware code itself is distributed under the GPL, but |
one of the usb codes comes under a separate license. Plase see |
the .txt files in usbdrv for details. |
The default configuration is for a attiny45. The Makefile.mega8 |
allows to compile the device for the Atmega8 cpu. This includes |
the possibility to use the atmega8 rs232 for debugging. |
The attiny45 has to be programmed in high voltage serial |
programming (hsvp) mode since this application needs the |
reset pin to be reconfigured for other use. |
This project supports two usb implementations: the avrusb and |
usbtiny. Due to this four Makefiles exist: |
Makefile-avrusb.tiny45 - build with avrusb for Attiny45 |
Makefile-avrusb.mega8 - build with avrusb for Atmega8 |
Makefile-usbtiny.tiny45 - build with usbtiny for Attiny45 |
Makefile-usbtiny.mega8 - build with usbtiny for Atmega8 |
Just type |
make -f Makefile-avrusb.xxx program |
or |
make -f Makefile-usbtiny.xxx flash |
to compile and upload the file. Please adjust e.g. programmer |
settings in the Makefile. |
If you don't want to recompile the firmware yourself you might |
use the included firmware.hex which is a prebuilt binary for the |
attiny45. Plase make sure you adjust the fuses accordingly. |
They need to be set to "external crystal > 8Mhz" and the RESET |
pin has to be disabled in order to be re-used for application |
specific purposes. See Makefile-avrusb.tiny45 for more details. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/Changelog.txt |
---|
0,0 → 1,134 |
This file documents changes in the firmware-only USB driver for atmel's AVR |
microcontrollers. New entries are always appended to the end of the file. |
Scroll down to the bottom to see the most recent changes. |
2005-04-01: |
- Implemented endpoint 1 as interrupt-in endpoint. |
- Moved all configuration options to usbconfig.h which is not part of the |
driver. |
- Changed interface for usbVendorSetup(). |
- Fixed compatibility with ATMega8 device. |
- Various minor optimizations. |
2005-04-11: |
- Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() |
and usbFunctionWrite() now. Added configuration options to choose which |
of these functions to compile in. |
- Assembler module delivers receive data non-inverted now. |
- Made register and bit names compatible with more AVR devices. |
2005-05-03: |
- Allow address of usbRxBuf on any memory page as long as the buffer does |
not cross 256 byte page boundaries. |
- Better device compatibility: works with Mega88 now. |
- Code optimization in debugging module. |
- Documentation updates. |
2006-01-02: |
- Added (free) default Vendor- and Product-IDs bought from voti.nl. |
- Added USBID-License.txt file which defines the rules for using the free |
shared VID/PID pair. |
- Added Readme.txt to the usbdrv directory which clarifies administrative |
issues. |
2006-01-25: |
- Added "configured state" to become more standards compliant. |
- Added "HALT" state for interrupt endpoint. |
- Driver passes the "USB Command Verifier" test from usb.org now. |
- Made "serial number" a configuration option. |
- Minor optimizations, we now recommend compiler option "-Os" for best |
results. |
- Added a version number to usbdrv.h |
2006-02-03: |
- New configuration variable USB_BUFFER_SECTION for the memory section where |
the USB rx buffer will go. This defaults to ".bss" if not defined. Since |
this buffer MUST NOT cross 256 byte pages (not even touch a page at the |
end), the user may want to pass a linker option similar to |
"-Wl,--section-start=.mybuffer=0x800060". |
- Provide structure for usbRequest_t. |
- New defines for USB constants. |
- Prepared for HID implementations. |
- Increased data size limit for interrupt transfers to 8 bytes. |
- New macro usbInterruptIsReady() to query interrupt buffer state. |
2006-02-18: |
- Ensure that the data token which is sent as an ack to an OUT transfer is |
always zero sized. This fixes a bug where the host reports an error after |
sending an out transfer to the device, although all data arrived at the |
device. |
- Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). |
* Release 2006-02-20 |
- Give a compiler warning when compiling with debugging turned on. |
- Added Oleg Semyonov's changes for IAR-cc compatibility. |
- Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() |
(also thanks to Oleg!). |
- Rearranged tests in usbPoll() to save a couple of instructions in the most |
likely case that no actions are pending. |
- We need a delay between the SET ADDRESS request until the new address |
becomes active. This delay was handled in usbPoll() until now. Since the |
spec says that the delay must not exceed 2ms, previous versions required |
aggressive polling during the enumeration phase. We have now moved the |
handling of the delay into the interrupt routine. |
- We must not reply with NAK to a SETUP transaction. We can only achieve this |
by making sure that the rx buffer is empty when SETUP tokens are expected. |
We therefore don't pass zero sized data packets from the status phase of |
a transfer to usbPoll(). This change MAY cause troubles if you rely on |
receiving a less than 8 bytes long packet in usbFunctionWrite() to |
identify the end of a transfer. usbFunctionWrite() will NEVER be called |
with a zero length. |
* Release 2006-03-14 |
- Improved IAR C support: tiny memory model, more devices |
- Added template usbconfig.h file under the name usbconfig-prototype.h |
* Release 2006-03-26 |
- Added provision for one more interrupt-in endpoint (endpoint 3). |
- Added provision for one interrupt-out endpoint (endpoint 1). |
- Added flowcontrol macros for USB. |
- Added provision for custom configuration descriptor. |
- Allow ANY two port bits for D+ and D-. |
- Merged (optional) receive endpoint number into global usbRxToken variable. |
- Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the |
variable name from the single port letter instead of computing the address |
of related ports from the output-port address. |
* Release 2006-06-26 |
- Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the |
new features. |
- Removed "#warning" directives because IAR does not understand them. Use |
unused static variables instead to generate a warning. |
- Do not include <avr/io.h> when compiling with IAR. |
- Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each |
USB descriptor should be handled. It is now possible to provide descriptor |
data in Flash, RAM or dynamically at runtime. |
- STALL is now a status in usbTxLen* instead of a message. We can now conform |
to the spec and leave the stall status pending until it is cleared. |
- Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the |
application code to reset data toggling on interrupt pipes. |
* Release 2006-07-18 |
- Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes |
an assembler error. |
- usbDeviceDisconnect() takes pull-up resistor to high impedance now. |
* Release 2007-02-01 |
- Merged in some code size improvements from usbtiny (thanks to Dick |
Streefland for these optimizations!) |
- Special alignment requirement for usbRxBuf not required any more. Thanks |
again to Dick Streefland for this hint! |
- Reverted to "#warning" instead of unused static variables -- new versions |
of IAR CC should handle this directive. |
- Changed Open Source license to GNU GPL v2 in order to make linking against |
other free libraries easier. We no longer require publication of the |
circuit diagrams, but we STRONGLY encourage it. If you improve the driver |
itself, PLEASE grant us a royalty free license to your changes for our |
commercial license. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/CommercialLicense.txt |
---|
0,0 → 1,155 |
AVR-USB Driver Software License Agreement |
Version 2006-07-24 |
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN |
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING |
THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. |
1 DEFINITIONS |
1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, |
Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. |
1.2 "You" shall mean the Licensee. |
1.3 "AVR-USB" shall mean the firmware-only USB device implementation for |
Atmel AVR microcontrollers distributed by OBJECTIVE DEVELOPMENT and |
consisting of the files usbdrv.c, usbdrv.h, usbdrvasm.S, oddebug.c, |
oddebug.h, usbdrvasm.asm, iarcompat.h and usbconfig-prototype.h. |
2 LICENSE GRANTS |
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source |
code of AVR-USB. |
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the |
non-exclusive right to use and distribute AVR-USB with your hardware |
product(s), restricted by the limitations in section 3 below. |
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify |
your copy of AVR-USB according to your needs. |
2.4 USB IDs. OBJECTIVE DEVELOPMENT grants you the exclusive rights to use |
USB Product ID(s) sent to you in e-mail after receiving your payment in |
conjunction with USB Vendor ID 5824. OBJECTIVE DEVELOPMENT has acquired an |
exclusive license for this pair of USB identifiers from Wouter van Ooijen |
(www.voti.nl), who has licensed the VID from the USB Implementers Forum, |
Inc. (www.usb.org). |
3 LICENSE RESTRICTIONS |
3.1 Number of Units. Only one of the following three definitions is |
applicable. Which one is determined by the amount you pay to OBJECTIVE |
DEVELOPMENT, see section 4 ("Payment") below. |
Hobby License: You may use AVR-USB according to section 2 above in no more |
than 5 hardware units. These units must not be sold for profit. |
Entry Level License: You may use AVR-USB according to section 2 above in no |
more than 150 hardware units. |
Professional License: You may use AVR-USB according to section 2 above in |
any number of hardware units, except for large scale production ("unlimited |
fair use"). Quantities below 10,000 units are not considered large scale |
production. If your reach quantities which are obviously large scale |
production, you must pay a license fee of 0.10 EUR per unit for all units |
above 10,000. |
3.2 Rental. You may not rent, lease, or lend AVR-USB or otherwise encumber |
any copy of AVR-USB, or any of the rights granted herein. |
3.3 Transfer. You may not transfer your rights under this Agreement to |
another party without OBJECTIVE DEVELOPMENT's prior written consent. If |
such consent is obtained, you may permanently transfer this License to |
another party. The recipient of such transfer must agree to all terms and |
conditions of this Agreement. |
3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not |
expressly granted. |
3.5 Non-Exclusive Rights. Your license rights under this Agreement are |
non-exclusive. |
3.6 Third Party Rights. This Agreement cannot grant you rights controlled |
by third parties. In particular, you are not allowed to use the USB logo or |
other trademarks owned by the USB Implementers Forum, Inc. without their |
consent. Since such consent depends on USB certification, it should be |
noted that AVR-USB will not pass certification because it does not |
implement checksum verification and the microcontroller ports do not meet |
the electrical specifications. |
4 PAYMENT |
The payment amount depends on the variation of this agreement (according to |
section 3.1) into which you want to enter. Concrete prices are listed on |
OBJECTIVE DEVELOPMENT's web site, usually at |
http://www.obdev.at/avrusb/license.html. You agree to pay the amount listed |
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor |
or reseller. |
5 COPYRIGHT AND OWNERSHIP |
AVR-USB is protected by copyright laws and international copyright |
treaties, as well as other intellectual property laws and treaties. AVR-USB |
is licensed, not sold. |
6 TERM AND TERMINATION |
6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE |
DEVELOPMENT may terminate this Agreement and revoke the granted license and |
USB-IDs if you fail to comply with any of its terms and conditions. |
6.2 Survival of Terms. All provisions regarding secrecy, confidentiality |
and limitation of liability shall survive termination of this agreement. |
7 DISCLAIMER OF WARRANTY AND LIABILITY |
LIMITED WARRANTY. AVR-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY |
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE |
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER |
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND |
NON-INFRINGEMENT, WITH REGARD TO AVR-USB, AND THE PROVISION OF OR FAILURE |
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL |
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO |
STATE/JURISDICTION. |
LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, |
IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY |
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER |
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, |
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY |
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE AVR-USB OR THE |
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE |
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY |
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS |
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR AVR-USB. |
8 MISCELLANEOUS TERMS |
8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing |
purposes that you entered into this agreement. |
8.2 Entire Agreement. This document represents the entire agreement between |
OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by |
an authorized representative of both, OBJECTIVE DEVELOPMENT and you. |
8.3 Severability. In case a provision of these terms and conditions should |
be or become partly or entirely invalid, ineffective, or not executable, |
the validity of all other provisions shall not be affected. |
8.4 Applicable Law. This agreement is governed by the laws of the Republic |
of Austria. |
8.5 Responsible Courts. The responsible courts in Vienna/Austria will have |
exclusive jurisdiction regarding all disputes in connection with this |
agreement. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/License.txt |
---|
0,0 → 1,359 |
OBJECTIVE DEVELOPMENT GmbH's AVR-USB driver software is distributed under the |
terms and conditions of the GNU GPL version 2, see the text below. In addition |
to the requirements in the GPL, we STRONGLY ENCOURAGE you to do the following: |
(1) Publish your entire project on a web site and drop us a note with the URL. |
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. |
(2) Adhere to minimum publication standards. Please include AT LEAST: |
- a circuit diagram in PDF, PNG or GIF format |
- full source code for the host software |
- a Readme.txt file in ASCII format which describes the purpose of the |
project and what can be found in which directories and which files |
- a reference to http://www.obdev.at/avrusb/ |
(3) If you improve the driver firmware itself, please give us a free license |
to your modifications for our commercial license offerings. |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/Readme.txt |
---|
0,0 → 1,84 |
This is the Readme file to Objective Development's firmware-only USB driver |
for Atmel AVR microcontrollers. For more information please visit |
http://www.obdev.at/avrusb/ |
This directory contains the USB firmware only. Copy it as-is to your own |
project and add your own version of "usbconfig.h". A template for your own |
"usbconfig.h" can be found in "usbconfig-prototype.h" in this directory. |
TECHNICAL DOCUMENTATION |
======================= |
The technical documentation for the firmware driver is contained in the file |
"usbdrv.h". Please read all of it carefully! |
USB IDENTIFIERS |
=============== |
Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs |
are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you |
can assign PIDs at will. |
Since an entry level cost of 1,500 USD is too high for most small companies |
and hobbyists, we provide a single VID/PID pair for free. If you want to use |
your own VID and PID instead of our's, define the macros "USB_CFG_VENDOR_ID" |
and "USB_CFG_DEVICE_ID" accordingly in "usbconfig.h". |
To use our predefined VID/PID pair, you MUST conform to a couple of |
requirements. See the file "USBID-License.txt" for details. |
Objective Development also has some offerings which include product IDs. See |
http://www.obdev.at/avrusb/ for details. |
HOST DRIVER |
=========== |
You have received this driver together with an example device implementation |
and an example host driver. The host driver is based on libusb and compiles |
on various Unix flavors (Linux, BSD, Mac OS X). It also compiles natively on |
Windows using MinGW (see www.mingw.org) and libusb-win32 (see |
libusb-win32.sourceforge.net). The "Automator" project contains a native |
Windows host driver (not based on libusb) for Human Interface Devices. |
DEVELOPMENT SYSTEM |
================== |
This driver has been developed and optimized for the GNU compiler version 3 |
(gcc 3). It does work well with gcc 4 and future versions will probably be |
optimized for gcc 4. We recommend that you use the GNU compiler suite because |
it is freely available. AVR-USB has also been ported to the IAR compiler and |
assembler. It has been tested with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 |
with the "small" and "tiny" memory model. Please note that gcc is more |
efficient for usbdrv.c because this module has been deliberately optimized |
for gcc. |
USING AVR-USB FOR FREE |
====================== |
The AVR firmware driver is published under the GNU General Public License |
Version 2 (GPL2). See the file "License.txt" for details. |
If you decide for the free GPL2, we STRONGLY ENCOURAGE you to do the following |
things IN ADDITION to the obligations from the GPL2: |
(1) Publish your entire project on a web site and drop us a note with the URL. |
Use the form at http://www.obdev.at/avrusb/feedback.html for your submission. |
(2) Adhere to minimum publication standards. Please include AT LEAST: |
- a circuit diagram in PDF, PNG or GIF format |
- full source code for the host software |
- a Readme.txt file in ASCII format which describes the purpose of the |
project and what can be found in which directories and which files |
- a reference to http://www.obdev.at/avrusb/ |
(3) If you improve the driver firmware itself, please give us a free license |
to your modifications for our commercial license offerings. |
COMMERCIAL LICENSES FOR AVR-USB |
=============================== |
If you don't want to publish your source code under the terms of the GPL2, |
you can simply pay money for AVR-USB. As an additional benefit you get |
USB PIDs for free, licensed exclusively to you. See the file |
"CommercialLicense.txt" for details. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/USBID-License.txt |
---|
0,0 → 1,143 |
Royalty-Free Non-Exclusive License USB Product-ID |
================================================= |
Version 2006-06-19 |
OBJECTIVE DEVELOPMENT Software GmbH hereby grants you the non-exclusive |
right to use three USB.org vendor-ID (VID) / product-ID (PID) pairs with |
products based on Objective Development's firmware-only USB driver for |
Atmel AVR microcontrollers: |
* VID = 5824 (=0x16c0) / PID = 1500 (=0x5dc) for devices implementing no |
USB device class (vendor-class devices with USB class = 0xff). Devices |
using this pair will be referred to as "VENDOR CLASS" devices. |
* VID = 5824 (=0x16c0) / PID = 1503 (=0x5df) for HID class devices |
(excluding mice and keyboards). Devices using this pair will be referred |
to as "HID CLASS" devices. |
* VID = 5824 (=0x16c0) / PID = 1505 (=0x5e1) for CDC class modem devices |
Devices using this pair will be referred to as "CDC-ACM CLASS" devices. |
Since the granted right is non-exclusive, the same VID/PID pairs may be |
used by many companies and individuals for different products. To avoid |
conflicts, your device and host driver software MUST adhere to the rules |
outlined below. |
OBJECTIVE DEVELOPMENT Software GmbH has licensed these VID/PID pairs from |
Wouter van Ooijen (see www.voti.nl), who has licensed the VID from the USB |
Implementers Forum, Inc. (see www.usb.org). The VID is registered for the |
company name "Van Ooijen Technische Informatica". |
RULES AND RESTRICTIONS |
====================== |
(1) The USB device MUST provide a textual representation of the |
manufacturer and product identification. The manufacturer identification |
MUST be available at least in USB language 0x0409 (English/US). |
(2) The textual manufacturer identification MUST contain either an Internet |
domain name (e.g. "mycompany.com") registered and owned by you, or an |
e-mail address under your control (e.g. "myname@gmx.net"). You can embed |
the domain name or e-mail address in any string you like, e.g. "Objective |
Development http://www.obdev.at/avrusb/". |
(3) You are responsible for retaining ownership of the domain or e-mail |
address for as long as any of your products are in use. |
(4) You may choose any string for the textual product identification, as |
long as this string is unique within the scope of your textual manufacturer |
identification. |
(5) Matching of device-specific drivers MUST be based on the textual |
manufacturer and product identification in addition to the usual VID/PID |
matching. This means that operating system features which are based on |
VID/PID matching only (e.g. Windows kernel level drivers, automatic actions |
when the device is plugged in etc) MUST NOT be used. The driver matching |
MUST be a comparison of the entire strings, NOT a sub-string match. For |
CDC-ACM CLASS devices, a generic class driver should be used and the |
matching is based on the USB device class. |
(6) The extent to which VID/PID matching is allowed for non device-specific |
drivers or features depends on the operating system and particular VID/PID |
pair used: |
* Mac OS X, Linux, FreeBSD and other Unixes: No VID/PID matching is |
required and hence no VID/PID-only matching is allowed at all. |
* Windows: The operating system performs VID/PID matching for the kernel |
level driver. You are REQUIRED to use libusb-win32 (see |
http://libusb-win32.sourceforge.net/) as the kernel level driver for |
VENDOR CLASS devices. HID CLASS devices all use the generic HID class |
driver shipped with Windows, except mice and keyboards. You therefore |
MUST NOT use any of the shared VID/PID pairs for mice or keyboards. |
CDC-ACM CLASS devices require a ".inf" file which matches on the VID/PID |
pair. This ".inf" file MUST load the "usbser" driver to configure the |
device as modem (COM-port). |
(7) OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any |
problems which are caused by the shared use of these VID/PID pairs. You |
have been warned that the sharing of VID/PID pairs may cause problems. If |
you want to avoid them, get your own VID/PID pair for exclusive use. |
HOW TO IMPLEMENT THESE RULES |
============================ |
The following rules are for VENDOR CLASS and HID CLASS devices. CDC-ACM |
CLASS devices use the operating system's class driver and don't need a |
custom driver. |
The host driver MUST iterate over all devices with the given VID/PID |
numbers in their device descriptors and query the string representation for |
the manufacturer name in USB language 0x0409 (English/US). It MUST compare |
the ENTIRE string with your textual manufacturer identification chosen in |
(2) above. A substring search for your domain or e-mail address is NOT |
acceptable. The driver MUST NOT touch the device (other than querying the |
descriptors) unless the strings match. |
For all USB devices with matching VID/PID and textual manufacturer |
identification, the host driver must query the textual product |
identification and string-compare it with the name of the product it can |
control. It may only initialize the device if the product matches exactly. |
Objective Development provides examples for these matching rules with the |
"PowerSwitch" project (using libusb) and with the "Automator" project |
(using Windows calls on Windows and libusb on Unix). |
Technical Notes: |
================ |
Sharing the same VID/PID pair among devices is possible as long as ALL |
drivers which match the VID/PID also perform matching on the textual |
identification strings. This is easy on all operating systems except |
Windows, since Windows establishes a static connection between the VID/PID |
pair and a kernel level driver. All devices with the same VID/PID pair must |
therefore use THE SAME kernel level driver. |
We therefore demand that you use libusb-win32 for VENDOR CLASS devices. |
This is a generic kernel level driver which allows all types of USB access |
for user space applications. This is only a partial solution of the |
problem, though, because different device drivers may come with different |
versions of libusb-win32 and they may not work with the libusb version of |
the respective other driver. You are therefore encouraged to test your |
driver against a broad range of libusb-win32 versions. Do not use new |
features in new versions, or check for their existence before you use them. |
When a new libusb-win32 becomes available, make sure that your driver is |
compatible with it. |
For HID CLASS devices it is necessary that all those devices bind to the |
same kernel driver: Microsoft's generic USB HID driver. This is true for |
all HID devices except those with a specialized driver. Currently, the only |
HIDs with specialized drivers are mice and keyboards. You therefore MUST |
NOT use a shared VID/PID with mouse and keyboard devices. |
Sharing the same VID/PID among different products is unusual and probably |
violates the USB specification. If you do it, you do it at your own risk. |
To avoid possible incompatibilities, we highly recommend that you get your |
own VID/PID pair if you intend to sell your product. Objective |
Development's commercial licenses for AVR-USB include a PID for |
unrestricted exclusive use. |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/iarcompat.h |
---|
0,0 → 1,70 |
/* Name: iarcompat.h |
* Project: AVR USB driver |
* Author: Christian Starkjohann |
* Creation Date: 2006-03-01 |
* Tabsize: 4 |
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: iarcompat.h,v 1.2 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
/* |
General Description: |
This header is included when we compile with the IAR C-compiler and assembler. |
It defines macros for cross compatibility between gcc and IAR-cc. |
Thanks to Oleg Semyonov for his help with the IAR tools port! |
*/ |
#ifndef __iarcompat_h_INCLUDED__ |
#define __iarcompat_h_INCLUDED__ |
#if defined __IAR_SYSTEMS_ICC__ || defined __IAR_SYSTEMS_ASM__ |
/* Enable bit definitions */ |
#ifndef ENABLE_BIT_DEFINITIONS |
# define ENABLE_BIT_DEFINITIONS 1 |
#endif |
/* Include IAR headers */ |
#include <ioavr.h> |
#ifndef __IAR_SYSTEMS_ASM__ |
# include <inavr.h> |
#endif |
#define __attribute__(arg) |
#define IAR_SECTION(section) @ section |
#ifndef USB_BUFFER_SECTION |
# define USB_BUFFER_SECTION "TINY_Z" /* if user has not selected a named section */ |
#endif |
#ifdef __IAR_SYSTEMS_ASM__ |
# define __ASSEMBLER__ |
#endif |
#ifdef __HAS_ELPM__ |
# define PROGMEM __farflash |
#else |
# define PROGMEM __flash |
#endif |
#define PRG_RDB(addr) (*(PROGMEM char *)(addr)) |
/* The following definitions are not needed by the driver, but may be of some |
* help if you port a gcc based project to IAR. |
*/ |
#define cli() __disable_interrupt() |
#define sei() __enable_interrupt() |
#define wdt_reset() __watchdog_reset() |
/* Depending on the device you use, you may get problems with the way usbdrv.h |
* handles the differences between devices. Since IAR does not use #defines |
* for MCU registers, we can't check for the existence of a particular |
* register with an #ifdef. If the autodetection mechanism fails, include |
* definitions for the required USB_INTR_* macros in your usbconfig.h. See |
* usbconfig-prototype.h and usbdrv.h for details. |
*/ |
#endif /* defined __IAR_SYSTEMS_ICC__ || defined __IAR_SYSTEMS_ASM__ */ |
#endif /* __iarcompat_h_INCLUDED__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/oddebug.c |
---|
0,0 → 1,50 |
/* Name: oddebug.c |
* Project: AVR library |
* Author: Christian Starkjohann |
* Creation Date: 2005-01-16 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: oddebug.c,v 1.2 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
#include "oddebug.h" |
#if DEBUG_LEVEL > 0 |
#warning "Never compile production devices with debugging enabled" |
static void uartPutc(char c) |
{ |
while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ |
ODDBG_UDR = c; |
} |
static uchar hexAscii(uchar h) |
{ |
h &= 0xf; |
if(h >= 10) |
h += 'a' - (uchar)10 - '0'; |
h += '0'; |
return h; |
} |
static void printHex(uchar c) |
{ |
uartPutc(hexAscii(c >> 4)); |
uartPutc(hexAscii(c)); |
} |
void odDebug(uchar prefix, uchar *data, uchar len) |
{ |
printHex(prefix); |
uartPutc(':'); |
while(len--){ |
uartPutc(' '); |
printHex(*data++); |
} |
uartPutc('\r'); |
uartPutc('\n'); |
} |
#endif |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/oddebug.h |
---|
0,0 → 1,126 |
/* Name: oddebug.h |
* Project: AVR library |
* Author: Christian Starkjohann |
* Creation Date: 2005-01-16 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: oddebug.h,v 1.2 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
#ifndef __oddebug_h_included__ |
#define __oddebug_h_included__ |
/* |
General Description: |
This module implements a function for debug logs on the serial line of the |
AVR microcontroller. Debugging can be configured with the define |
'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging |
calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is |
2, DBG1 and DBG2 logs will be printed. |
A debug log consists of a label ('prefix') to indicate which debug log created |
the output and a memory block to dump in hex ('data' and 'len'). |
*/ |
#ifndef F_CPU |
# define F_CPU 12000000 /* 12 MHz */ |
#endif |
/* make sure we have the UART defines: */ |
#include "iarcompat.h" |
#ifndef __IAR_SYSTEMS_ICC__ |
# include <avr/io.h> |
#endif |
#ifndef uchar |
# define uchar unsigned char |
#endif |
#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ |
# warning "Debugging disabled because device has no UART" |
# undef DEBUG_LEVEL |
#endif |
#ifndef DEBUG_LEVEL |
# define DEBUG_LEVEL 0 |
#endif |
/* ------------------------------------------------------------------------- */ |
#if DEBUG_LEVEL > 0 |
# define DBG1(prefix, data, len) odDebug(prefix, data, len) |
#else |
# define DBG1(prefix, data, len) |
#endif |
#if DEBUG_LEVEL > 1 |
# define DBG2(prefix, data, len) odDebug(prefix, data, len) |
#else |
# define DBG2(prefix, data, len) |
#endif |
/* ------------------------------------------------------------------------- */ |
#if DEBUG_LEVEL > 0 |
extern void odDebug(uchar prefix, uchar *data, uchar len); |
/* Try to find our control registers; ATMEL likes to rename these */ |
#if defined UBRR |
# define ODDBG_UBRR UBRR |
#elif defined UBRRL |
# define ODDBG_UBRR UBRRL |
#elif defined UBRR0 |
# define ODDBG_UBRR UBRR0 |
#elif defined UBRR0L |
# define ODDBG_UBRR UBRR0L |
#endif |
#if defined UCR |
# define ODDBG_UCR UCR |
#elif defined UCSRB |
# define ODDBG_UCR UCSRB |
#elif defined UCSR0B |
# define ODDBG_UCR UCSR0B |
#endif |
#if defined TXEN |
# define ODDBG_TXEN TXEN |
#else |
# define ODDBG_TXEN TXEN0 |
#endif |
#if defined USR |
# define ODDBG_USR USR |
#elif defined UCSRA |
# define ODDBG_USR UCSRA |
#elif defined UCSR0A |
# define ODDBG_USR UCSR0A |
#endif |
#if defined UDRE |
# define ODDBG_UDRE UDRE |
#else |
# define ODDBG_UDRE UDRE0 |
#endif |
#if defined UDR |
# define ODDBG_UDR UDR |
#elif defined UDR0 |
# define ODDBG_UDR UDR0 |
#endif |
static inline void odDebugInit(void) |
{ |
ODDBG_UCR |= (1<<ODDBG_TXEN); |
ODDBG_UBRR = F_CPU / (19200 * 16L) - 1; |
} |
#else |
# define odDebugInit() |
#endif |
/* ------------------------------------------------------------------------- */ |
#endif /* __oddebug_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/usbconfig-prototype.h |
---|
0,0 → 1,246 |
/* Name: usbconfig.h |
* Project: AVR USB driver |
* Author: Christian Starkjohann |
* Creation Date: 2005-04-01 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbconfig-prototype.h 275 2007-03-20 09:58:28Z cs $ |
*/ |
#ifndef __usbconfig_h_included__ |
#define __usbconfig_h_included__ |
/* |
General Description: |
This file is an example configuration (with inline documentation) for the USB |
driver. It configures AVR-USB for an ATMega8 with USB D+ connected to Port D |
bit 2 (which is also hardware interrupt 0) and USB D- to Port D bit 0. You may |
wire the lines to any other port, as long as D+ is also wired to INT0. |
To create your own usbconfig.h file, copy this file to the directory |
containing "usbdrv" (that is your project firmware source directory) and |
rename it to "usbconfig.h". Then edit it accordingly. |
*/ |
/* ---------------------------- Hardware Config ---------------------------- */ |
#define USB_CFG_IOPORTNAME D |
/* This is the port where the USB bus is connected. When you configure it to |
* "B", the registers PORTB, PINB and DDRB will be used. |
*/ |
#define USB_CFG_DMINUS_BIT 0 |
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. |
* This may be any bit in the port. |
*/ |
#define USB_CFG_DPLUS_BIT 2 |
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. |
* This may be any bit in the port. Please note that D+ must also be connected |
* to interrupt pin INT0! |
*/ |
/* ----------------------- Optional Hardware Config ------------------------ */ |
/* #define USB_CFG_PULLUP_IOPORTNAME D */ |
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of |
* V+, you can connect and disconnect the device from firmware by calling |
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). |
* This constant defines the port on which the pullup resistor is connected. |
*/ |
/* #define USB_CFG_PULLUP_BIT 4 */ |
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined |
* above) where the 1.5k pullup resistor is connected. See description |
* above for details. |
*/ |
/* --------------------------- Functional Range ---------------------------- */ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT 1 |
/* Define this to 1 if you want to compile a version with two endpoints: The |
* default control endpoint 0 and an interrupt-in endpoint 1. |
*/ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 |
/* Define this to 1 if you want to compile a version with three endpoints: The |
* default control endpoint 0, an interrupt-in endpoint 1 and an interrupt-in |
* endpoint 3. You must also enable endpoint 1 above. |
*/ |
#define USB_CFG_IMPLEMENT_HALT 0 |
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature |
* for endpoint 1 (interrupt endpoint). Although you may not need this feature, |
* it is required by the standard. We have made it a config option because it |
* bloats the code considerably. |
*/ |
#define USB_CFG_INTR_POLL_INTERVAL 20 |
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll |
* interval. The value is in milliseconds and must not be less than 10 ms for |
* low speed devices. |
*/ |
#define USB_CFG_IS_SELF_POWERED 0 |
/* Define this to 1 if the device has its own power supply. Set it to 0 if the |
* device is powered from the USB bus. |
*/ |
#define USB_CFG_MAX_BUS_POWER 100 |
/* Set this variable to the maximum USB bus power consumption of your device. |
* The value is in milliamperes. [It will be divided by two since USB |
* communicates power requirements in units of 2 mA.] |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITE 0 |
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out |
* transfers. Set it to 0 if you don't need it and want to save a couple of |
* bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_READ 0 |
/* Set this to 1 if you need to send control replies which are generated |
* "on the fly" when usbFunctionRead() is called. If you only want to send |
* data from a static buffer, set it to 0 and return the data from |
* usbFunctionSetup(). This saves a couple of bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 |
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoint 1. |
* You must implement the function usbFunctionWriteOut() which receives all |
* interrupt/bulk data sent to endpoint 1. |
*/ |
#define USB_CFG_HAVE_FLOWCONTROL 0 |
/* Define this to 1 if you want flowcontrol over USB data. See the definition |
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in |
* usbdrv.h. |
*/ |
/* -------------------------- Device Description --------------------------- */ |
#define USB_CFG_VENDOR_ID 0xc0, 0x16 |
/* USB vendor ID for the device, low byte first. If you have registered your |
* own Vendor ID, define it here. Otherwise you use obdev's free shared |
* VID/PID pair. Be sure to read USBID-License.txt for rules! |
* This template uses obdev's shared VID/PID pair for HIDs: 0x16c0/0x5df. |
* Use this VID/PID pair ONLY if you understand the implications! |
*/ |
#define USB_CFG_DEVICE_ID 0xdf, 0x05 |
/* This is the ID of the product, low byte first. It is interpreted in the |
* scope of the vendor ID. If you have registered your own VID with usb.org |
* or if you have licensed a PID from somebody else, define it here. Otherwise |
* you use obdev's free shared VID/PID pair. Be sure to read the rules in |
* USBID-License.txt! |
* This template uses obdev's shared VID/PID pair for HIDs: 0x16c0/0x5df. |
* Use this VID/PID pair ONLY if you understand the implications! |
*/ |
#define USB_CFG_DEVICE_VERSION 0x00, 0x01 |
/* Version number of the device: Minor number first, then major number. |
*/ |
#define USB_CFG_VENDOR_NAME 'w', 'w', 'w', '.', 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' |
#define USB_CFG_VENDOR_NAME_LEN 12 |
/* These two values define the vendor name returned by the USB device. The name |
* must be given as a list of characters under single quotes. The characters |
* are interpreted as Unicode (UTF-16) entities. |
* If you don't want a vendor name string, undefine these macros. |
* ALWAYS define a vendor name containing your Internet domain name if you use |
* obdev's free shared VID/PID pair. See the file USBID-License.txt for |
* details. |
*/ |
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e' |
#define USB_CFG_DEVICE_NAME_LEN 8 |
/* Same as above for the device name. If you don't want a device name, undefine |
* the macros. See the file USBID-License.txt before you assign a name if you |
* use a shared VID/PID. |
*/ |
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ |
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ |
/* Same as above for the serial number. If you don't want a serial number, |
* undefine the macros. |
* It may be useful to provide the serial number through other means than at |
* compile time. See the section about descriptor properties below for how |
* to fine tune control over USB descriptors such as the string descriptor |
* for the serial number. |
*/ |
#define USB_CFG_DEVICE_CLASS 0 |
#define USB_CFG_DEVICE_SUBCLASS 0 |
/* See USB specification if you want to conform to an existing device class. |
*/ |
#define USB_CFG_INTERFACE_CLASS 3 /* HID */ |
#define USB_CFG_INTERFACE_SUBCLASS 0 |
#define USB_CFG_INTERFACE_PROTOCOL 0 |
/* See USB specification if you want to conform to an existing device class or |
* protocol. |
* This template defines a HID class device. If you implement a vendor class |
* device, set USB_CFG_INTERFACE_CLASS to 0 and USB_CFG_DEVICE_CLASS to 0xff. |
*/ |
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 /* total length of report descriptor */ |
/* Define this to the length of the HID report descriptor, if you implement |
* an HID device. Otherwise don't define it or define it to 0. |
* Since this template defines a HID device, it must also specify a HID |
* report descriptor length. You must add a PROGMEM character array named |
* "usbHidReportDescriptor" to your code which contains the report descriptor. |
* Don't forget to keep the array and this define in sync! |
*/ |
/* ------------------- Fine Control over USB Descriptors ------------------- */ |
/* If you don't want to use the driver's default USB descriptors, you can |
* provide our own. These can be provided as (1) fixed length static data in |
* flash memory, (2) fixed length static data in RAM or (3) dynamically at |
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more |
* information about this function. |
* Descriptor handling is configured through the descriptor's properties. If |
* no properties are defined or if they are 0, the default descriptor is used. |
* Possible properties are: |
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched |
* at runtime via usbFunctionDescriptor(). |
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found |
* in static memory is in RAM, not in flash memory. |
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), |
* the driver must know the descriptor's length. The descriptor itself is |
* found at the address of a well known identifier (see below). |
* List of static descriptor names (must be declared PROGMEM if in flash): |
* char usbDescriptorDevice[]; |
* char usbDescriptorConfiguration[]; |
* char usbDescriptorHidReport[]; |
* char usbDescriptorString0[]; |
* int usbDescriptorStringVendor[]; |
* int usbDescriptorStringDevice[]; |
* int usbDescriptorStringSerialNumber[]; |
* Other descriptors can't be provided statically, they must be provided |
* dynamically at runtime. |
* |
* Descriptor properties are or-ed or added together, e.g.: |
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) |
* |
* The following descriptors are defined: |
* USB_CFG_DESCR_PROPS_DEVICE |
* USB_CFG_DESCR_PROPS_CONFIGURATION |
* USB_CFG_DESCR_PROPS_STRINGS |
* USB_CFG_DESCR_PROPS_STRING_0 |
* USB_CFG_DESCR_PROPS_STRING_VENDOR |
* USB_CFG_DESCR_PROPS_STRING_PRODUCT |
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
* USB_CFG_DESCR_PROPS_HID |
* USB_CFG_DESCR_PROPS_HID_REPORT |
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) |
* |
*/ |
#define USB_CFG_DESCR_PROPS_DEVICE 0 |
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 |
#define USB_CFG_DESCR_PROPS_STRINGS 0 |
#define USB_CFG_DESCR_PROPS_STRING_0 0 |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 |
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 |
#define USB_CFG_DESCR_PROPS_HID 0 |
#define USB_CFG_DESCR_PROPS_HID_REPORT 0 |
#define USB_CFG_DESCR_PROPS_UNKNOWN 0 |
/* ----------------------- Optional MCU Description ------------------------ */ |
/* The following configurations have working defaults in usbdrv.h. You |
* usually don't need to set them explicitly. Only if you want to run |
* the driver on a device which is not yet supported or with a compiler |
* which is not fully supported (such as IAR C) or if you use a differnt |
* interrupt than INT0, you may have to define some of these. |
*/ |
/* #define USB_INTR_CFG MCUCR */ |
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ |
/* #define USB_INTR_CFG_CLR 0 */ |
/* #define USB_INTR_ENABLE GIMSK */ |
/* #define USB_INTR_ENABLE_BIT INT0 */ |
/* #define USB_INTR_PENDING GIFR */ |
/* #define USB_INTR_PENDING_BIT INTF0 */ |
#endif /* __usbconfig_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/usbdrv.c |
---|
0,0 → 1,551 |
/* Name: usbdrv.c |
* Project: AVR USB driver |
* Author: Christian Starkjohann |
* Creation Date: 2004-12-29 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrv.c,v 1.3 2007/06/07 13:53:47 harbaum Exp $ |
*/ |
#include "iarcompat.h" |
#ifndef __IAR_SYSTEMS_ICC__ |
# include <avr/io.h> |
# include <avr/pgmspace.h> |
#endif |
#include "usbdrv.h" |
#include "oddebug.h" |
/* |
General Description: |
This module implements the C-part of the USB driver. See usbdrv.h for a |
documentation of the entire driver. |
*/ |
#ifndef IAR_SECTION |
#define IAR_SECTION(arg) |
#define __no_init |
#endif |
/* The macro IAR_SECTION is a hack to allow IAR-cc compatibility. On gcc, it |
* is defined to nothing. __no_init is required on IAR. |
*/ |
/* ------------------------------------------------------------------------- */ |
/* raw USB registers / interface to assembler code: */ |
uchar usbRxBuf[2*USB_BUFSIZE]; /* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */ |
uchar usbInputBufOffset; /* offset in usbRxBuf used for low level receiving */ |
uchar usbDeviceAddr; /* assigned during enumeration, defaults to 0 */ |
uchar usbNewDeviceAddr; /* device ID which should be set after status phase */ |
uchar usbConfiguration; /* currently selected configuration. Administered by driver, but not used */ |
volatile schar usbRxLen; /* = 0; number of bytes in usbRxBuf; 0 means free, -1 for flow control */ |
uchar usbCurrentTok; /* last token received, if more than 1 rx endpoint: MSb=endpoint */ |
uchar usbRxToken; /* token for data we received; if more than 1 rx endpoint: MSb=endpoint */ |
uchar usbMsgLen = 0xff; /* remaining number of bytes, no msg to send if -1 (see usbMsgPtr) */ |
volatile uchar usbTxLen = USBPID_NAK; /* number of bytes to transmit with next IN token or handshake token */ |
uchar usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbTxLen contains handshake token */ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
volatile uchar usbTxLen1 = USBPID_NAK; /* TX count for endpoint 1 */ |
uchar usbTxBuf1[USB_BUFSIZE]; /* TX data for endpoint 1 */ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
volatile uchar usbTxLen3 = USBPID_NAK; /* TX count for endpoint 1 */ |
uchar usbTxBuf3[USB_BUFSIZE]; /* TX data for endpoint 1 */ |
#endif |
#endif |
/* USB status registers / not shared with asm code */ |
uchar *usbMsgPtr; /* data to transmit next -- ROM or RAM address */ |
static uchar usbMsgFlags; /* flag values see below */ |
#define USB_FLG_TX_PACKET (1<<0) |
/* Leave free 6 bits after TX_PACKET. This way we can increment usbMsgFlags to toggle TX_PACKET */ |
#define USB_FLG_MSGPTR_IS_ROM (1<<6) |
#define USB_FLG_USE_DEFAULT_RW (1<<7) |
/* |
optimizing hints: |
- do not post/pre inc/dec integer values in operations |
- assign value of PRG_RDB() to register variables and don't use side effects in arg |
- use narrow scope for variables which should be in X/Y/Z register |
- assign char sized expressions to variables to force 8 bit arithmetics |
*/ |
/* ------------------------------------------------------------------------- */ |
#if USB_CFG_DESCR_PROPS_STRINGS == 0 |
#if USB_CFG_DESCR_PROPS_STRING_0 == 0 |
#undef USB_CFG_DESCR_PROPS_STRING_0 |
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0) |
PROGMEM char usbDescriptorString0[] = { /* language descriptor */ |
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */ |
3, /* descriptor type */ |
0x09, 0x04, /* language index (0x0409 = US-English) */ |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN |
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor) |
PROGMEM int usbDescriptorStringVendor[] = { |
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN), |
USB_CFG_VENDOR_NAME |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_STRING_DEVICE == 0 && USB_CFG_DEVICE_NAME_LEN |
#undef USB_CFG_DESCR_PROPS_STRING_DEVICE |
#define USB_CFG_DESCR_PROPS_STRING_DEVICE sizeof(usbDescriptorStringDevice) |
PROGMEM int usbDescriptorStringDevice[] = { |
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN), |
USB_CFG_DEVICE_NAME |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN |
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber) |
PROGMEM int usbDescriptorStringSerialNumber[] = { |
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN), |
USB_CFG_SERIAL_NUMBER |
}; |
#endif |
#endif /* USB_CFG_DESCR_PROPS_STRINGS == 0 */ |
#if USB_CFG_DESCR_PROPS_DEVICE == 0 |
#undef USB_CFG_DESCR_PROPS_DEVICE |
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice) |
PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */ |
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */ |
USBDESCR_DEVICE, /* descriptor type */ |
0x10, 0x01, /* USB version supported */ |
USB_CFG_DEVICE_CLASS, |
USB_CFG_DEVICE_SUBCLASS, |
0, /* protocol */ |
8, /* max packet size */ |
USB_CFG_VENDOR_ID, /* 2 bytes */ |
USB_CFG_DEVICE_ID, /* 2 bytes */ |
USB_CFG_DEVICE_VERSION, /* 2 bytes */ |
USB_CFG_DESCR_PROPS_STRING_VENDOR != 0 ? 1 : 0, /* manufacturer string index */ |
USB_CFG_DESCR_PROPS_STRING_DEVICE != 0 ? 2 : 0, /* product string index */ |
USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER != 0 ? 3 : 0, /* serial number string index */ |
1, /* number of configurations */ |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_HID_REPORT != 0 && USB_CFG_DESCR_PROPS_HID == 0 |
#undef USB_CFG_DESCR_PROPS_HID |
#define USB_CFG_DESCR_PROPS_HID 9 /* length of HID descriptor in config descriptor below */ |
#endif |
#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0 |
#undef USB_CFG_DESCR_PROPS_CONFIGURATION |
#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration) |
PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */ |
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ |
USBDESCR_CONFIG, /* descriptor type */ |
18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + (USB_CFG_DESCR_PROPS_HID & 0xff), 0, |
/* total length of data returned (including inlined descriptors) */ |
1, /* number of interfaces in this configuration */ |
1, /* index of this configuration */ |
0, /* configuration name string index */ |
#if USB_CFG_IS_SELF_POWERED |
USBATTR_SELFPOWER, /* attributes */ |
#else |
USBATTR_BUSPOWER, /* attributes */ |
#endif |
USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */ |
/* interface descriptor follows inline: */ |
9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ |
USBDESCR_INTERFACE, /* descriptor type */ |
0, /* index of this interface */ |
0, /* alternate setting for this interface */ |
USB_CFG_HAVE_INTRIN_ENDPOINT, /* endpoints excl 0: number of endpoint descriptors to follow */ |
USB_CFG_INTERFACE_CLASS, |
USB_CFG_INTERFACE_SUBCLASS, |
USB_CFG_INTERFACE_PROTOCOL, |
0, /* string index for interface */ |
#if (USB_CFG_DESCR_PROPS_HID & 0xff) /* HID descriptor */ |
9, /* sizeof(usbDescrHID): length of descriptor in bytes */ |
USBDESCR_HID, /* descriptor type: HID */ |
0x01, 0x01, /* BCD representation of HID version */ |
0x00, /* target country code */ |
0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */ |
0x22, /* descriptor type: report */ |
USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0, /* total length of report descriptor */ |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */ |
7, /* sizeof(usbDescrEndpoint) */ |
USBDESCR_ENDPOINT, /* descriptor type = endpoint */ |
0x81, /* IN endpoint number 1 */ |
0x03, /* attrib: Interrupt endpoint */ |
8, 0, /* maximum packet size */ |
USB_CFG_INTR_POLL_INTERVAL, /* in ms */ |
#endif |
}; |
#endif |
/* We don't use prog_int or prog_int16_t for compatibility with various libc |
* versions. Here's an other compatibility hack: |
*/ |
#ifndef PRG_RDB |
#define PRG_RDB(addr) pgm_read_byte(addr) |
#endif |
typedef union{ |
unsigned word; |
uchar *ptr; |
uchar bytes[2]; |
}converter_t; |
/* We use this union to do type conversions. This is better optimized than |
* type casts in gcc 3.4.3 and much better than using bit shifts to build |
* ints from chars. Byte ordering is not a problem on an 8 bit platform. |
*/ |
/* ------------------------------------------------------------------------- */ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
void usbSetInterrupt(uchar *data, uchar len) |
{ |
uchar *p, i; |
#if USB_CFG_IMPLEMENT_HALT |
if(usbTxLen1 == USBPID_STALL) |
return; |
#endif |
#if 0 /* No runtime checks! Caller is responsible for valid data! */ |
if(len > 8) /* interrupt transfers are limited to 8 bytes */ |
len = 8; |
#endif |
if(usbTxLen1 & 0x10){ /* packet buffer was empty */ |
usbTxBuf1[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */ |
}else{ |
usbTxLen1 = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */ |
} |
p = usbTxBuf1 + 1; |
for(i=len;i--;) |
*p++ = *data++; |
usbCrc16Append(&usbTxBuf1[1], len); |
usbTxLen1 = len + 4; /* len must be given including sync byte */ |
DBG2(0x21, usbTxBuf1, len + 3); |
} |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
void usbSetInterrupt3(uchar *data, uchar len) |
{ |
uchar *p, i; |
if(usbTxLen3 & 0x10){ /* packet buffer was empty */ |
usbTxBuf3[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */ |
}else{ |
usbTxLen3 = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */ |
} |
p = usbTxBuf3 + 1; |
for(i=len;i--;) |
*p++ = *data++; |
usbCrc16Append(&usbTxBuf3[1], len); |
usbTxLen3 = len + 4; /* len must be given including sync byte */ |
DBG2(0x23, usbTxBuf3, len + 3); |
} |
#endif |
static uchar usbRead(uchar *data, uchar len) |
{ |
#if USB_CFG_IMPLEMENT_FN_READ |
if(usbMsgFlags & USB_FLG_USE_DEFAULT_RW){ |
#endif |
uchar i = len, *r = usbMsgPtr; |
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */ |
while(i--){ |
uchar c = PRG_RDB(r); /* assign to char size variable to enforce byte ops */ |
*data++ = c; |
r++; |
} |
}else{ /* RAM data */ |
while(i--) |
*data++ = *r++; |
} |
usbMsgPtr = r; |
return len; |
#if USB_CFG_IMPLEMENT_FN_READ |
}else{ |
if(len != 0) /* don't bother app with 0 sized reads */ |
return usbFunctionRead(data, len); |
return 0; |
} |
#endif |
} |
#define GET_DESCRIPTOR(cfgProp, staticName) \ |
if(cfgProp){ \ |
if((cfgProp) & USB_PROP_IS_RAM) \ |
flags &= ~USB_FLG_MSGPTR_IS_ROM; \ |
if((cfgProp) & USB_PROP_IS_DYNAMIC){ \ |
replyLen = usbFunctionDescriptor(rq); \ |
}else{ \ |
replyData = (uchar *)(staticName); \ |
SET_REPLY_LEN((cfgProp) & 0xff); \ |
} \ |
} |
/* We use if() instead of #if in the macro above because #if can't be used |
* in macros and the compiler optimizes constant conditions anyway. |
*/ |
/* Don't make this function static to avoid inlining. |
* The entire function would become too large and exceed the range of |
* relative jumps. |
* 2006-02-25: Either gcc 3.4.3 is better than the gcc used when the comment |
* above was written, or other parts of the code have changed. We now get |
* better results with an inlined function. Test condition: PowerSwitch code. |
*/ |
static void usbProcessRx(uchar *data, uchar len) |
{ |
usbRequest_t *rq = (void *)data; |
uchar replyLen = 0, flags = USB_FLG_USE_DEFAULT_RW; |
/* We use if() cascades because the compare is done byte-wise while switch() |
* is int-based. The if() cascades are therefore more efficient. |
*/ |
/* usbRxToken can be: |
* 0x2d 00101101 (USBPID_SETUP for endpoint 0) |
* 0xe1 11100001 (USBPID_OUT for endpoint 0) |
* 0xff 11111111 (USBPID_OUT for endpoint 1) |
*/ |
DBG2(0x10 + ((usbRxToken >> 1) & 3), data, len); /* SETUP0=12; OUT0=10; OUT1=13 */ |
#if USB_CFG_IMPLEMENT_FN_WRITEOUT |
if(usbRxToken == 0xff){ |
usbFunctionWriteOut(data, len); |
return; /* no reply expected, hence no usbMsgPtr, usbMsgFlags, usbMsgLen set */ |
} |
#endif |
if(usbRxToken == (uchar)USBPID_SETUP){ |
usbTxLen = USBPID_NAK; /* abort pending transmit */ |
if(len == 8){ /* Setup size must be always 8 bytes. Ignore otherwise. */ |
uchar type = rq->bmRequestType & USBRQ_TYPE_MASK; |
if(type == USBRQ_TYPE_STANDARD){ |
#define SET_REPLY_LEN(len) replyLen = (len); usbMsgPtr = replyData |
/* This macro ensures that replyLen and usbMsgPtr are always set in the same way. |
* That allows optimization of common code in if() branches */ |
uchar *replyData = usbTxBuf + 9; /* there is 3 bytes free space at the end of the buffer */ |
replyData[0] = 0; /* common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */ |
if(rq->bRequest == USBRQ_GET_STATUS){ /* 0 */ |
uchar __attribute__((__unused__)) recipient = rq->bmRequestType & USBRQ_RCPT_MASK; /* assign arith ops to variables to enforce byte size */ |
#if USB_CFG_IS_SELF_POWERED |
if(recipient == USBRQ_RCPT_DEVICE) |
replyData[0] = USB_CFG_IS_SELF_POWERED; |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_IMPLEMENT_HALT |
if(recipient == USBRQ_RCPT_ENDPOINT && rq->wIndex.bytes[0] == 0x81) /* request status for endpoint 1 */ |
replyData[0] = usbTxLen1 == USBPID_STALL; |
#endif |
replyData[1] = 0; |
SET_REPLY_LEN(2); |
}else if(rq->bRequest == USBRQ_SET_ADDRESS){ /* 5 */ |
usbNewDeviceAddr = rq->wValue.bytes[0]; |
}else if(rq->bRequest == USBRQ_GET_DESCRIPTOR){ /* 6 */ |
flags = USB_FLG_MSGPTR_IS_ROM | USB_FLG_USE_DEFAULT_RW; |
if(rq->wValue.bytes[1] == USBDESCR_DEVICE){ /* 1 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice) |
}else if(rq->wValue.bytes[1] == USBDESCR_CONFIG){ /* 2 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration) |
}else if(rq->wValue.bytes[1] == USBDESCR_STRING){ /* 3 */ |
#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC |
if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM) |
flags &= ~USB_FLG_MSGPTR_IS_ROM; |
replyLen = usbFunctionDescriptor(rq); |
#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ |
if(rq->wValue.bytes[0] == 0){ /* descriptor index */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0) |
}else if(rq->wValue.bytes[0] == 1){ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor) |
}else if(rq->wValue.bytes[0] == 2){ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_DEVICE, usbDescriptorStringDevice) |
}else if(rq->wValue.bytes[0] == 3){ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber) |
}else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ |
replyLen = usbFunctionDescriptor(rq); |
} |
#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ |
}else if(rq->wValue.bytes[1] == USBDESCR_HID){ /* 0x21 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18) |
}else if(rq->wValue.bytes[1] == USBDESCR_HID_REPORT){ /* 0x22 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport) |
}else if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ |
replyLen = usbFunctionDescriptor(rq); |
} |
}else if(rq->bRequest == USBRQ_GET_CONFIGURATION){ /* 8 */ |
replyData = &usbConfiguration; /* send current configuration value */ |
SET_REPLY_LEN(1); |
}else if(rq->bRequest == USBRQ_SET_CONFIGURATION){ /* 9 */ |
usbConfiguration = rq->wValue.bytes[0]; |
#if USB_CFG_IMPLEMENT_HALT |
usbTxLen1 = USBPID_NAK; |
#endif |
}else if(rq->bRequest == USBRQ_GET_INTERFACE){ /* 10 */ |
SET_REPLY_LEN(1); |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
}else if(rq->bRequest == USBRQ_SET_INTERFACE){ /* 11 */ |
USB_SET_DATATOKEN1(USBPID_DATA0); /* reset data toggling for interrupt endpoint */ |
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
USB_SET_DATATOKEN3(USBPID_DATA0); /* reset data toggling for interrupt endpoint */ |
# endif |
# if USB_CFG_IMPLEMENT_HALT |
usbTxLen1 = USBPID_NAK; |
}else if(rq->bRequest == USBRQ_CLEAR_FEATURE || rq->bRequest == USBRQ_SET_FEATURE){ /* 1|3 */ |
if(rq->wValue.bytes[0] == 0 && rq->wIndex.bytes[0] == 0x81){ /* feature 0 == HALT for endpoint == 1 */ |
usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL; |
USB_SET_DATATOKEN1(USBPID_DATA0); /* reset data toggling for interrupt endpoint */ |
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
USB_SET_DATATOKEN3(USBPID_DATA0); /* reset data toggling for interrupt endpoint */ |
# endif |
} |
# endif |
#endif |
}else{ |
/* the following requests can be ignored, send default reply */ |
/* 1: CLEAR_FEATURE, 3: SET_FEATURE, 7: SET_DESCRIPTOR */ |
/* 12: SYNCH_FRAME */ |
} |
#undef SET_REPLY_LEN |
}else{ /* not a standard request -- must be vendor or class request */ |
replyLen = usbFunctionSetup(data); |
} |
#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE |
if(replyLen == 0xff){ /* use user-supplied read/write function */ |
if((rq->bmRequestType & USBRQ_DIR_MASK) == USBRQ_DIR_DEVICE_TO_HOST){ |
replyLen = rq->wLength.bytes[0]; /* IN transfers only */ |
} |
flags &= ~USB_FLG_USE_DEFAULT_RW; /* we have no valid msg, use user supplied read/write functions */ |
}else /* The 'else' prevents that we limit a replyLen of 0xff to the maximum transfer len. */ |
#endif |
if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */ |
replyLen = rq->wLength.bytes[0]; |
} |
/* make sure that data packets which are sent as ACK to an OUT transfer are always zero sized */ |
}else{ /* DATA packet from out request */ |
#if USB_CFG_IMPLEMENT_FN_WRITE |
if(!(usbMsgFlags & USB_FLG_USE_DEFAULT_RW)){ |
uchar rval = usbFunctionWrite(data, len); |
replyLen = 0xff; |
if(rval == 0xff){ /* an error occurred */ |
usbMsgLen = 0xff; /* cancel potentially pending data packet for ACK */ |
usbTxLen = USBPID_STALL; |
}else if(rval != 0){ /* This was the final package */ |
replyLen = 0; /* answer with a zero-sized data packet */ |
} |
flags = 0; /* start with a DATA1 package, stay with user supplied write() function */ |
} |
#endif |
} |
usbMsgFlags = flags; |
usbMsgLen = replyLen; |
} |
/* ------------------------------------------------------------------------- */ |
static void usbBuildTxBlock(void) |
{ |
uchar wantLen, len, txLen, token; |
wantLen = usbMsgLen; |
if(wantLen > 8) |
wantLen = 8; |
usbMsgLen -= wantLen; |
token = USBPID_DATA1; |
if(usbMsgFlags & USB_FLG_TX_PACKET) |
token = USBPID_DATA0; |
usbMsgFlags++; |
len = usbRead(usbTxBuf + 1, wantLen); |
if(len <= 8){ /* valid data packet */ |
usbCrc16Append(&usbTxBuf[1], len); |
txLen = len + 4; /* length including sync byte */ |
if(len < 8) /* a partial package identifies end of message */ |
usbMsgLen = 0xff; |
}else{ |
txLen = USBPID_STALL; /* stall the endpoint */ |
usbMsgLen = 0xff; |
} |
usbTxBuf[0] = token; |
usbTxLen = txLen; |
DBG2(0x20, usbTxBuf, txLen-1); |
} |
static inline uchar isNotSE0(void) |
{ |
uchar rval; |
/* We want to do |
* return (USBIN & USBMASK); |
* here, but the compiler does int-expansion acrobatics. |
* We can avoid this by assigning to a char-sized variable. |
*/ |
rval = USBIN & USBMASK; |
return rval; |
} |
/* ------------------------------------------------------------------------- */ |
void usbPoll(void) |
{ |
uchar len, i; |
if((len = usbRxLen) > 0){ |
/* We could check CRC16 here -- but ACK has already been sent anyway. If you |
* need data integrity checks with this driver, check the CRC in your app |
* code and report errors back to the host. Since the ACK was already sent, |
* retries must be handled on application level. |
* unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3); |
*/ |
usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len - 3); |
#if USB_CFG_HAVE_FLOWCONTROL |
if(usbRxLen > 0) /* only mark as available if not inactivated */ |
usbRxLen = 0; |
#else |
usbRxLen = 0; /* mark rx buffer as available */ |
#endif |
} |
if(usbTxLen & 0x10){ /* transmit system idle */ |
if(usbMsgLen != 0xff){ /* transmit data pending? */ |
usbBuildTxBlock(); |
} |
} |
for(i = 10; i > 0; i--){ |
if(isNotSE0()) |
break; |
} |
if(i == 0){ /* RESET condition, called multiple times during reset */ |
usbNewDeviceAddr = 0; |
usbDeviceAddr = 0; |
#if USB_CFG_IMPLEMENT_HALT |
usbTxLen1 = USBPID_NAK; |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
usbTxLen3 = USBPID_NAK; |
#endif |
#endif |
DBG1(0xff, 0, 0); |
} |
} |
/* ------------------------------------------------------------------------- */ |
void usbInit(void) |
{ |
#if USB_INTR_CFG_SET != 0 |
USB_INTR_CFG |= USB_INTR_CFG_SET; |
#endif |
#if USB_INTR_CFG_CLR != 0 |
USB_INTR_CFG &= ~(USB_INTR_CFG_CLR); |
#endif |
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
USB_SET_DATATOKEN1(USBPID_DATA0); /* reset data toggling for interrupt endpoint */ |
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
USB_SET_DATATOKEN3(USBPID_DATA0); /* reset data toggling for interrupt endpoint */ |
# endif |
#endif |
} |
/* ------------------------------------------------------------------------- */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/usbdrv.h |
---|
0,0 → 1,633 |
/* Name: usbdrv.h |
* Project: AVR USB driver |
* Author: Christian Starkjohann |
* Creation Date: 2004-12-29 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrv.h,v 1.2 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
#ifndef __usbdrv_h_included__ |
#define __usbdrv_h_included__ |
#include "usbconfig.h" |
#include "iarcompat.h" |
/* |
Hardware Prerequisites: |
======================= |
USB lines D+ and D- MUST be wired to the same I/O port. D+ must (also) be |
connected to INT0. D- requires a pullup of 1.5k to +3.5V (and the device |
must be powered at 3.5V) to identify as low-speed USB device. A pullup of |
1M SHOULD be connected from D+ to +3.5V to prevent interference when no USB |
master is connected. We use D+ as interrupt source and not D- because it |
does not trigger on keep-alive and RESET states. |
As a compile time option, the 1.5k pullup resistor on D- can be made |
switchable to allow the device to disconnect at will. See the definition of |
usbDeviceConnect() and usbDeviceDisconnect() further down in this file. |
Please adapt the values in usbconfig.h according to your hardware! |
The device MUST be clocked at 12 MHz. This is more than the 10 MHz allowed by |
an AT90S2313 powered at 4.5V. However, if the supply voltage to maximum clock |
relation is interpolated linearly, an ATtiny2313 meets the requirement by |
specification. In practice, the AT90S2313 can be overclocked and works well. |
Limitations: |
============ |
Robustness with respect to communication errors: |
The driver assumes error-free communication. It DOES check for errors in |
the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte, |
token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due |
to timing constraints: We must start sending a reply within 7 bit times. |
Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU |
performance does not permit that. The driver does not check Data0/Data1 |
toggling, but application software can implement the check. |
Input characteristics: |
Since no differential receiver circuit is used, electrical interference |
robustness may suffer. The driver samples only one of the data lines with |
an ordinary I/O pin's input characteristics. However, since this is only a |
low speed USB implementation and the specification allows for 8 times the |
bit rate over the same hardware, we should be on the safe side. Even the spec |
requires detection of asymmetric states at high bit rate for SE0 detection. |
Number of endpoints: |
The driver supports up to four endpoints: One control endpoint (endpoint 0), |
two interrupt-in (or bulk-in) endpoints (endpoint 1 and 3) and one |
interrupt-out (or bulk-out) endpoint (endpoint 1). Please note that the USB |
standard forbids bulk endpoints for low speed devices! Most operating systems |
allow them anyway, but the AVR will spend 90% of the CPU time in the USB |
interrupt polling for bulk data. |
By default, only the control endpoint 0 is enabled. To get the other endpoints, |
define USB_CFG_HAVE_INTRIN_ENDPOINT, USB_CFG_HAVE_INTRIN_ENDPOINT3 and/or |
USB_CFG_IMPLEMENT_FN_WRITEOUT respectively (see usbconfig-prototype.h for |
details). |
Maximum data payload: |
Data payload of control in and out transfers may be up to 254 bytes. In order |
to accept payload data of out transfers, you need to implement |
'usbFunctionWrite()'. |
USB Suspend Mode supply current: |
The USB standard limits power consumption to 500uA when the bus is in suspend |
mode. This is not a problem for self-powered devices since they don't need |
bus power anyway. Bus-powered devices can achieve this only by putting the |
CPU in sleep mode. The driver does not implement suspend handling by itself. |
However, the application may implement activity monitoring and wakeup from |
sleep. The host sends regular SE0 states on the bus to keep it active. These |
SE0 states can be detected by wiring the INT1 pin to D-. It is not necessary |
to enable the interrupt, checking the interrupt pending flag should suffice. |
Before entering sleep mode, the application should enable INT1 for a wakeup |
on the next bus activity. |
Operation without an USB master: |
The driver behaves neutral without connection to an USB master if D- reads |
as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M) |
pullup resistor on D+. If D- becomes statically 0, the driver may block in |
the interrupt routine. |
Interrupt latency: |
The application must ensure that the USB interrupt is not disabled for more |
than 20 cycles. This implies that all interrupt routines must either be |
declared as "INTERRUPT" instead of "SIGNAL" (see "avr/signal.h") or that they |
are written in assembler with "sei" as the first instruction. |
Maximum interrupt duration / CPU cycle consumption: |
The driver handles all USB communication during the interrupt service |
routine. The routine will not return before an entire USB message is received |
and the reply is sent. This may be up to ca. 1200 cycles = 100us if the host |
conforms to the standard. The driver will consume CPU cycles for all USB |
messages, even if they address another (low-speed) device on the same bus. |
*/ |
/* ------------------------------------------------------------------------- */ |
/* --------------------------- Module Interface ---------------------------- */ |
/* ------------------------------------------------------------------------- */ |
#define USBDRV_VERSION 20070319 |
/* This define uniquely identifies a driver version. It is a decimal number |
* constructed from the driver's release date in the form YYYYMMDD. If the |
* driver's behavior or interface changes, you can use this constant to |
* distinguish versions. If it is not defined, the driver's release date is |
* older than 2006-01-25. |
*/ |
#ifndef __ASSEMBLER__ |
#ifndef uchar |
#define uchar unsigned char |
#endif |
#ifndef schar |
#define schar signed char |
#endif |
/* shortcuts for well defined 8 bit integer types */ |
struct usbRequest; /* forward declaration */ |
extern void usbInit(void); |
/* This function must be called before interrupts are enabled and the main |
* loop is entered. |
*/ |
extern void usbPoll(void); |
/* This function must be called at regular intervals from the main loop. |
* Maximum delay between calls is somewhat less than 50ms (USB timeout for |
* accepting a Setup message). Otherwise the device will not be recognized. |
* Please note that debug outputs through the UART take ~ 0.5ms per byte |
* at 19200 bps. |
*/ |
extern uchar *usbMsgPtr; |
/* This variable may be used to pass transmit data to the driver from the |
* implementation of usbFunctionWrite(). It is also used internally by the |
* driver for standard control requests. |
*/ |
extern uchar usbFunctionSetup(uchar data[8]); |
/* This function is called when the driver receives a SETUP transaction from |
* the host which is not answered by the driver itself (in practice: class and |
* vendor requests). All control transfers start with a SETUP transaction where |
* the host communicates the parameters of the following (optional) data |
* transfer. The SETUP data is available in the 'data' parameter which can |
* (and should) be casted to 'usbRequest_t *' for a more user-friendly access |
* to parameters. |
* |
* If the SETUP indicates a control-in transfer, you should provide the |
* requested data to the driver. There are two ways to transfer this data: |
* (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data |
* block and return the length of the data in 'usbFunctionSetup()'. The driver |
* will handle the rest. Or (2) return 0xff in 'usbFunctionSetup()'. The driver |
* will then call 'usbFunctionRead()' when data is needed. See the |
* documentation for usbFunctionRead() for details. |
* |
* If the SETUP indicates a control-out transfer, the only way to receive the |
* data from the host is through the 'usbFunctionWrite()' call. If you |
* implement this function, you must return 0xff in 'usbFunctionSetup()' to |
* indicate that 'usbFunctionWrite()' should be used. See the documentation of |
* this function for more information. If you just want to ignore the data sent |
* by the host, return 0 in 'usbFunctionSetup()'. |
* |
* Note that calls to the functions usbFunctionRead() and usbFunctionWrite() |
* are only done if enabled by the configuration in usbconfig.h. |
*/ |
extern uchar usbFunctionDescriptor(struct usbRequest *rq); |
/* You need to implement this function ONLY if you provide USB descriptors at |
* runtime (which is an expert feature). It is very similar to |
* usbFunctionSetup() above, but it is called only to request USB descriptor |
* data. See the documentation of usbFunctionSetup() above for more info. |
*/ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
void usbSetInterrupt(uchar *data, uchar len); |
/* This function sets the message which will be sent during the next interrupt |
* IN transfer. The message is copied to an internal buffer and must not exceed |
* a length of 8 bytes. The message may be 0 bytes long just to indicate the |
* interrupt status to the host. |
* If you need to transfer more bytes, use a control read after the interrupt. |
*/ |
extern volatile uchar usbTxLen1; |
#define usbInterruptIsReady() (usbTxLen1 & 0x10) |
/* This macro indicates whether the last interrupt message has already been |
* sent. If you set a new interrupt message before the old was sent, the |
* message already buffered will be lost. |
*/ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
void usbSetInterrupt3(uchar *data, uchar len); |
extern volatile uchar usbTxLen3; |
#define usbInterruptIsReady3() (usbTxLen3 & 0x10) |
/* Same as above for endpoint 3 */ |
#endif |
#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */ |
#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */ |
#define usbHidReportDescriptor usbDescriptorHidReport |
/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */ |
/* If you implement an HID device, you need to provide a report descriptor. |
* The HID report descriptor syntax is a bit complex. If you understand how |
* report descriptors are constructed, we recommend that you use the HID |
* Descriptor Tool from usb.org, see http://www.usb.org/developers/hidpage/. |
* Otherwise you should probably start with a working example. |
*/ |
#endif /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */ |
#if USB_CFG_IMPLEMENT_FN_WRITE |
extern uchar usbFunctionWrite(uchar *data, uchar len); |
/* This function is called by the driver to provide a control transfer's |
* payload data (control-out). It is called in chunks of up to 8 bytes. The |
* total count provided in the current control transfer can be obtained from |
* the 'length' property in the setup data. If an error occurred during |
* processing, return 0xff (== -1). The driver will answer the entire transfer |
* with a STALL token in this case. If you have received the entire payload |
* successfully, return 1. If you expect more data, return 0. If you don't |
* know whether the host will send more data (you should know, the total is |
* provided in the usbFunctionSetup() call!), return 1. |
* NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called |
* for the remaining data. You must continue to return 0xff for STALL in these |
* calls. |
* In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE |
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. |
*/ |
#endif /* USB_CFG_IMPLEMENT_FN_WRITE */ |
#if USB_CFG_IMPLEMENT_FN_READ |
extern uchar usbFunctionRead(uchar *data, uchar len); |
/* This function is called by the driver to ask the application for a control |
* transfer's payload data (control-in). It is called in chunks of up to 8 |
* bytes each. You should copy the data to the location given by 'data' and |
* return the actual number of bytes copied. If you return less than requested, |
* the control-in transfer is terminated. If you return 0xff, the driver aborts |
* the transfer with a STALL token. |
* In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ |
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. |
*/ |
#endif /* USB_CFG_IMPLEMENT_FN_READ */ |
#if USB_CFG_IMPLEMENT_FN_WRITEOUT |
extern void usbFunctionWriteOut(uchar *data, uchar len); |
/* This function is called by the driver when data on interrupt-out or bulk- |
* out endpoint 1 is received. You must define USB_CFG_IMPLEMENT_FN_WRITEOUT |
* to 1 in usbconfig.h to get this function called. |
*/ |
#endif /* USB_CFG_IMPLEMENT_FN_WRITEOUT */ |
#ifdef USB_CFG_PULLUP_IOPORTNAME |
#define usbDeviceConnect() ((USB_PULLUP_DDR |= (1<<USB_CFG_PULLUP_BIT)), \ |
(USB_PULLUP_OUT |= (1<<USB_CFG_PULLUP_BIT))) |
/* This macro (intended to look like a function) connects the device to the |
* USB bus. It is only available if you have defined the constants |
* USB_CFG_PULLUP_IOPORT and USB_CFG_PULLUP_BIT in usbconfig.h. |
*/ |
#define usbDeviceDisconnect() ((USB_PULLUP_DDR &= ~(1<<USB_CFG_PULLUP_BIT)), \ |
(USB_PULLUP_OUT &= ~(1<<USB_CFG_PULLUP_BIT))) |
/* This macro (intended to look like a function) disconnects the device from |
* the USB bus. It is only available if you have defined the constants |
* USB_CFG_PULLUP_IOPORT and USB_CFG_PULLUP_BIT in usbconfig.h. |
*/ |
#endif /* USB_CFG_PULLUP_IOPORT */ |
extern unsigned usbCrc16(unsigned data, uchar len); |
#define usbCrc16(data, len) usbCrc16((unsigned)(data), len) |
/* This function calculates the binary complement of the data CRC used in |
* USB data packets. The value is used to build raw transmit packets. |
* You may want to use this function for data checksums or to verify received |
* data. We enforce 16 bit calling conventions for compatibility with IAR's |
* tiny memory model. |
*/ |
extern unsigned usbCrc16Append(unsigned data, uchar len); |
#define usbCrc16Append(data, len) usbCrc16Append((unsigned)(data), len) |
/* This function is equivalent to usbCrc16() above, except that it appends |
* the 2 bytes CRC (lowbyte first) in the 'data' buffer after reading 'len' |
* bytes. |
*/ |
extern uchar usbConfiguration; |
/* This value contains the current configuration set by the host. The driver |
* allows setting and querying of this variable with the USB SET_CONFIGURATION |
* and GET_CONFIGURATION requests, but does not use it otherwise. |
* You may want to reflect the "configured" status with a LED on the device or |
* switch on high power parts of the circuit only if the device is configured. |
*/ |
#define USB_STRING_DESCRIPTOR_HEADER(stringLength) ((2*(stringLength)+2) | (3<<8)) |
/* This macro builds a descriptor header for a string descriptor given the |
* string's length. See usbdrv.c for an example how to use it. |
*/ |
#if USB_CFG_HAVE_FLOWCONTROL |
extern volatile schar usbRxLen; |
#define usbDisableAllRequests() usbRxLen = -1 |
/* Must be called from usbFunctionWrite(). This macro disables all data input |
* from the USB interface. Requests from the host are answered with a NAK |
* while they are disabled. |
*/ |
#define usbEnableAllRequests() usbRxLen = 0 |
/* May only be called if requests are disabled. This macro enables input from |
* the USB interface after it has been disabled with usbDisableAllRequests(). |
*/ |
#define usbAllRequestsAreDisabled() (usbRxLen < 0) |
/* Use this macro to find out whether requests are disabled. It may be needed |
* to ensure that usbEnableAllRequests() is never called when requests are |
* enabled. |
*/ |
#endif |
#define USB_SET_DATATOKEN1(token) usbTxBuf1[0] = token |
#define USB_SET_DATATOKEN3(token) usbTxBuf3[0] = token |
/* These two macros can be used by application software to reset data toggling |
* for interrupt-in endpoints 1 and 3. |
*/ |
#endif /* __ASSEMBLER__ */ |
/* ------------------------------------------------------------------------- */ |
/* ----------------- Definitions for Descriptor Properties ----------------- */ |
/* ------------------------------------------------------------------------- */ |
/* This is advanced stuff. See usbconfig-prototype.h for more information |
* about the various methods to define USB descriptors. If you do nothing, |
* the default descriptors will be used. |
*/ |
#define USB_PROP_IS_DYNAMIC (1 << 8) |
/* If this property is set for a descriptor, usbFunctionDescriptor() will be |
* used to obtain the particular descriptor. |
*/ |
#define USB_PROP_IS_RAM (1 << 9) |
/* If this property is set for a descriptor, the data is read from RAM |
* memory instead of Flash. The property is used for all methods to provide |
* external descriptors. |
*/ |
#define USB_PROP_LENGTH(len) ((len) & 0xff) |
/* If a static external descriptor is used, this is the total length of the |
* descriptor in bytes. |
*/ |
/* all descriptors which may have properties: */ |
#ifndef USB_CFG_DESCR_PROPS_DEVICE |
#define USB_CFG_DESCR_PROPS_DEVICE 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_CONFIGURATION |
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRINGS |
#define USB_CFG_DESCR_PROPS_STRINGS 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_0 |
#define USB_CFG_DESCR_PROPS_STRING_0 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_VENDOR |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_DEVICE |
#define USB_CFG_DESCR_PROPS_STRING_DEVICE 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_HID |
#define USB_CFG_DESCR_PROPS_HID 0 |
#endif |
#if !(USB_CFG_DESCR_PROPS_HID_REPORT) |
# undef USB_CFG_DESCR_PROPS_HID_REPORT |
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* do some backward compatibility tricks */ |
# define USB_CFG_DESCR_PROPS_HID_REPORT USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH |
# else |
# define USB_CFG_DESCR_PROPS_HID_REPORT 0 |
# endif |
#endif |
#ifndef USB_CFG_DESCR_PROPS_UNKNOWN |
#define USB_CFG_DESCR_PROPS_UNKNOWN 0 |
#endif |
/* ------------------ forward declaration of descriptors ------------------- */ |
/* If you use external static descriptors, they must be stored in global |
* arrays as declared below: |
*/ |
#ifndef __ASSEMBLER__ |
extern |
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorDevice[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorConfiguration[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorHidReport[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorString0[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
int usbDescriptorStringVendor[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
int usbDescriptorStringDevice[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
int usbDescriptorStringSerialNumber[]; |
#endif /* __ASSEMBLER__ */ |
/* ------------------------------------------------------------------------- */ |
/* ------------------------ General Purpose Macros ------------------------- */ |
/* ------------------------------------------------------------------------- */ |
#define USB_CONCAT(a, b) a ## b |
#define USB_CONCAT_EXPANDED(a, b) USB_CONCAT(a, b) |
#define USB_OUTPORT(name) USB_CONCAT(PORT, name) |
#define USB_INPORT(name) USB_CONCAT(PIN, name) |
#define USB_DDRPORT(name) USB_CONCAT(DDR, name) |
/* The double-define trick above lets us concatenate strings which are |
* defined by macros. |
*/ |
/* ------------------------------------------------------------------------- */ |
/* ------------------------- Constant definitions -------------------------- */ |
/* ------------------------------------------------------------------------- */ |
#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID) |
#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h" |
/* If the user has not defined IDs, we default to obdev's free IDs. |
* See USBID-License.txt for details. |
*/ |
#endif |
/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */ |
#ifndef USB_CFG_VENDOR_ID |
# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* 5824 in dec, stands for VOTI */ |
#endif |
#ifndef USB_CFG_DEVICE_ID |
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH |
# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* 1503 in dec, shared PID for HIDs */ |
# elif USB_CFG_INTERFACE_CLASS == 2 |
# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* 1505 in dec, shared PID for CDC Modems */ |
# else |
# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* 1500 in dec, obdev's free PID */ |
# endif |
#endif |
/* Derive Output, Input and DataDirection ports from port names */ |
#ifndef USB_CFG_IOPORTNAME |
#error "You must define USB_CFG_IOPORTNAME in usbconfig.h, see usbconfig-prototype.h" |
#endif |
#define USBOUT USB_OUTPORT(USB_CFG_IOPORTNAME) |
#define USB_PULLUP_OUT USB_OUTPORT(USB_CFG_PULLUP_IOPORTNAME) |
#define USBIN USB_INPORT(USB_CFG_IOPORTNAME) |
#define USBDDR USB_DDRPORT(USB_CFG_IOPORTNAME) |
#define USB_PULLUP_DDR USB_DDRPORT(USB_CFG_PULLUP_IOPORTNAME) |
#define USBMINUS USB_CFG_DMINUS_BIT |
#define USBPLUS USB_CFG_DPLUS_BIT |
#define USBIDLE (1<<USB_CFG_DMINUS_BIT) /* value representing J state */ |
#define USBMASK ((1<<USB_CFG_DPLUS_BIT) | (1<<USB_CFG_DMINUS_BIT)) /* mask for USB I/O bits */ |
/* defines for backward compatibility with older driver versions: */ |
#define USB_CFG_IOPORT USB_OUTPORT(USB_CFG_IOPORTNAME) |
#ifdef USB_CFG_PULLUP_IOPORTNAME |
#define USB_CFG_PULLUP_IOPORT USB_OUTPORT(USB_CFG_PULLUP_IOPORTNAME) |
#endif |
#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */ |
/* ----- Try to find registers and bits responsible for ext interrupt 0 ----- */ |
#ifndef USB_INTR_CFG /* allow user to override our default */ |
# if defined EICRA |
# define USB_INTR_CFG EICRA |
# else |
# define USB_INTR_CFG MCUCR |
# endif |
#endif |
#ifndef USB_INTR_CFG_SET /* allow user to override our default */ |
# define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) /* cfg for rising edge */ |
#endif |
#ifndef USB_INTR_CFG_CLR /* allow user to override our default */ |
# define USB_INTR_CFG_CLR 0 /* no bits to clear */ |
#endif |
#ifndef USB_INTR_ENABLE /* allow user to override our default */ |
# if defined GIMSK |
# define USB_INTR_ENABLE GIMSK |
# elif defined EIMSK |
# define USB_INTR_ENABLE EIMSK |
# else |
# define USB_INTR_ENABLE GICR |
# endif |
#endif |
#ifndef USB_INTR_ENABLE_BIT /* allow user to override our default */ |
# define USB_INTR_ENABLE_BIT INT0 |
#endif |
#ifndef USB_INTR_PENDING /* allow user to override our default */ |
# if defined EIFR |
# define USB_INTR_PENDING EIFR |
# else |
# define USB_INTR_PENDING GIFR |
# endif |
#endif |
#ifndef USB_INTR_PENDING_BIT /* allow user to override our default */ |
# define USB_INTR_PENDING_BIT INTF0 |
#endif |
/* |
The defines above don't work for the following chips |
at90c8534: no ISC0?, no PORTB, can't find a data sheet |
at86rf401: no PORTB, no MCUCR etc, low clock rate |
atmega103: no ISC0? (maybe omission in header, can't find data sheet) |
atmega603: not defined in avr-libc |
at43usb320, at43usb355, at76c711: have USB anyway |
at94k: is different... |
at90s1200, attiny11, attiny12, attiny15, attiny28: these have no RAM |
*/ |
/* ------------------------------------------------------------------------- */ |
/* ----------------- USB Specification Constants and Types ----------------- */ |
/* ------------------------------------------------------------------------- */ |
/* USB Token values */ |
#define USBPID_SETUP 0x2d |
#define USBPID_OUT 0xe1 |
#define USBPID_IN 0x69 |
#define USBPID_DATA0 0xc3 |
#define USBPID_DATA1 0x4b |
#define USBPID_ACK 0xd2 |
#define USBPID_NAK 0x5a |
#define USBPID_STALL 0x1e |
#ifndef __ASSEMBLER__ |
extern uchar usbTxBuf1[USB_BUFSIZE], usbTxBuf3[USB_BUFSIZE]; |
typedef union usbWord{ |
unsigned word; |
uchar bytes[2]; |
}usbWord_t; |
typedef struct usbRequest{ |
uchar bmRequestType; |
uchar bRequest; |
usbWord_t wValue; |
usbWord_t wIndex; |
usbWord_t wLength; |
}usbRequest_t; |
/* This structure matches the 8 byte setup request */ |
#endif |
/* bmRequestType field in USB setup: |
* d t t r r r r r, where |
* d ..... direction: 0=host->device, 1=device->host |
* t ..... type: 0=standard, 1=class, 2=vendor, 3=reserved |
* r ..... recipient: 0=device, 1=interface, 2=endpoint, 3=other |
*/ |
/* USB setup recipient values */ |
#define USBRQ_RCPT_MASK 0x1f |
#define USBRQ_RCPT_DEVICE 0 |
#define USBRQ_RCPT_INTERFACE 1 |
#define USBRQ_RCPT_ENDPOINT 2 |
/* USB request type values */ |
#define USBRQ_TYPE_MASK 0x60 |
#define USBRQ_TYPE_STANDARD (0<<5) |
#define USBRQ_TYPE_CLASS (1<<5) |
#define USBRQ_TYPE_VENDOR (2<<5) |
/* USB direction values: */ |
#define USBRQ_DIR_MASK 0x80 |
#define USBRQ_DIR_HOST_TO_DEVICE (0<<7) |
#define USBRQ_DIR_DEVICE_TO_HOST (1<<7) |
/* USB Standard Requests */ |
#define USBRQ_GET_STATUS 0 |
#define USBRQ_CLEAR_FEATURE 1 |
#define USBRQ_SET_FEATURE 3 |
#define USBRQ_SET_ADDRESS 5 |
#define USBRQ_GET_DESCRIPTOR 6 |
#define USBRQ_SET_DESCRIPTOR 7 |
#define USBRQ_GET_CONFIGURATION 8 |
#define USBRQ_SET_CONFIGURATION 9 |
#define USBRQ_GET_INTERFACE 10 |
#define USBRQ_SET_INTERFACE 11 |
#define USBRQ_SYNCH_FRAME 12 |
/* USB descriptor constants */ |
#define USBDESCR_DEVICE 1 |
#define USBDESCR_CONFIG 2 |
#define USBDESCR_STRING 3 |
#define USBDESCR_INTERFACE 4 |
#define USBDESCR_ENDPOINT 5 |
#define USBDESCR_HID 0x21 |
#define USBDESCR_HID_REPORT 0x22 |
#define USBDESCR_HID_PHYS 0x23 |
#define USBATTR_BUSPOWER 0x80 |
#define USBATTR_SELFPOWER 0x40 |
#define USBATTR_REMOTEWAKE 0x20 |
/* USB HID Requests */ |
#define USBRQ_HID_GET_REPORT 0x01 |
#define USBRQ_HID_GET_IDLE 0x02 |
#define USBRQ_HID_GET_PROTOCOL 0x03 |
#define USBRQ_HID_SET_REPORT 0x09 |
#define USBRQ_HID_SET_IDLE 0x0a |
#define USBRQ_HID_SET_PROTOCOL 0x0b |
/* ------------------------------------------------------------------------- */ |
#endif /* __usbdrv_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/usbdrvasm.S |
---|
0,0 → 1,710 |
/* Name: usbdrvasm.S |
* Project: AVR USB driver |
* Author: Christian Starkjohann |
* Creation Date: 2004-12-29 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrvasm.S,v 1.2 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
/* |
General Description: |
This module implements the assembler part of the USB driver. See usbdrv.h |
for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
Timing constraints according to spec (in bit times): |
timing subject min max CPUcycles |
--------------------------------------------------------------------------- |
EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128 |
EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60 |
DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60 |
*/ |
#include "iarcompat.h" |
#ifndef __IAR_SYSTEMS_ASM__ |
/* configs for io.h */ |
# define __SFR_OFFSET 0 |
# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ |
# include <avr/io.h> /* for CPU I/O register definitions and vectors */ |
#endif /* __IAR_SYSTEMS_ASM__ */ |
#include "usbdrv.h" /* for common defs */ |
/* register names */ |
#define x1 r16 |
#define x2 r17 |
#define shift r18 |
#define cnt r19 |
#define x3 r20 |
#define x4 r21 |
/* Some assembler dependent definitions and declarations: */ |
#ifdef __IAR_SYSTEMS_ASM__ |
# define nop2 rjmp $+2 /* jump to next instruction */ |
# define XL r26 |
# define XH r27 |
# define YL r28 |
# define YH r29 |
# define ZL r30 |
# define ZH r31 |
# define lo8(x) LOW(x) |
# define hi8(x) ((x)>>8) /* not HIGH to allow XLINK to make a proper range check */ |
extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset |
extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen |
extern usbTxBuf, usbMsgLen, usbTxLen1, usbTxBuf1, usbTxLen3, usbTxBuf3 |
public usbCrc16 |
public usbCrc16Append |
COMMON INTVEC |
ORG INT0_vect |
rjmp SIG_INTERRUPT0 |
RSEG CODE |
#else /* __IAR_SYSTEMS_ASM__ */ |
# define nop2 rjmp .+0 /* jump to next instruction */ |
.text |
.global SIG_INTERRUPT0 |
.type SIG_INTERRUPT0, @function |
.global usbCrc16 |
.global usbCrc16Append |
#endif /* __IAR_SYSTEMS_ASM__ */ |
;Software-receiver engine. Strict timing! Don't change unless you can preserve timing! |
;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled |
;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable |
;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes |
;Numbers in brackets are maximum cycles since SOF. |
SIG_INTERRUPT0: |
;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt |
push YL ;2 [35] push only what is necessary to sync with edge ASAP |
in YL, SREG ;1 [37] |
push YL ;2 [39] |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;first part has no timeout because it waits for IDLE or SE1 (== disconnected) |
waitForJ: |
sbis USBIN, USBMINUS ;1 [40] wait for D- == 1 |
rjmp waitForJ ;2 |
waitForK: |
;The following code results in a sampling window of 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
rjmp sofError |
foundK: |
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] |
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push YH ;2 [2] |
lds YL, usbInputBufOffset;2 [4] |
clr YH ;1 [5] |
subi YL, lo8(-(usbRxBuf));1 [6] |
sbci YH, hi8(-(usbRxBuf));1 [7] |
sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] |
rjmp haveTwoBitsK ;2 [10] |
pop YH ; undo the push from before |
rjmp waitForK ; this was not the end of sync, retry |
haveTwoBitsK: |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
push shift ;2 [16] |
push x1 ;2 [12] |
push x2 ;2 [14] |
in x1, USBIN ;1 [17] <-- sample bit 0 |
ldi shift, 0xff ;1 [18] |
bst x1, USBMINUS ;1 [19] |
bld shift, 0 ;1 [20] |
push x3 ;2 [22] |
push cnt ;2 [24] |
in x2, USBIN ;1 [25] <-- sample bit 1 |
ser x3 ;1 [26] [inserted init instruction] |
eor x1, x2 ;1 [27] |
bst x1, USBMINUS ;1 [28] |
bld shift, 1 ;1 [29] |
ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] |
rjmp rxbit2 ;2 [32] |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
unstuff0: ;1 (branch taken) |
andi x3, ~0x01 ;1 [15] |
mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit |
in x2, USBIN ;1 [17] <-- sample bit 1 again |
ori shift, 0x01 ;1 [18] |
rjmp didUnstuff0 ;2 [20] |
unstuff1: ;1 (branch taken) |
mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit |
andi x3, ~0x02 ;1 [22] |
ori shift, 0x02 ;1 [23] |
nop ;1 [24] |
in x1, USBIN ;1 [25] <-- sample bit 2 again |
rjmp didUnstuff1 ;2 [27] |
unstuff2: ;1 (branch taken) |
andi x3, ~0x04 ;1 [29] |
ori shift, 0x04 ;1 [30] |
mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit |
nop ;1 [32] |
in x2, USBIN ;1 [33] <-- sample bit 3 |
rjmp didUnstuff2 ;2 [35] |
unstuff3: ;1 (branch taken) |
in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] |
andi x3, ~0x08 ;1 [35] |
ori shift, 0x08 ;1 [36] |
rjmp didUnstuff3 ;2 [38] |
unstuff4: ;1 (branch taken) |
andi x3, ~0x10 ;1 [40] |
in x1, USBIN ;1 [41] <-- sample stuffed bit 4 |
ori shift, 0x10 ;1 [42] |
rjmp didUnstuff4 ;2 [44] |
unstuff5: ;1 (branch taken) |
andi x3, ~0x20 ;1 [48] |
in x2, USBIN ;1 [49] <-- sample stuffed bit 5 |
ori shift, 0x20 ;1 [50] |
rjmp didUnstuff5 ;2 [52] |
unstuff6: ;1 (branch taken) |
andi x3, ~0x40 ;1 [56] |
in x1, USBIN ;1 [57] <-- sample stuffed bit 6 |
ori shift, 0x40 ;1 [58] |
rjmp didUnstuff6 ;2 [60] |
; extra jobs done during bit interval: |
; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] |
; bit 1: se0 check |
; bit 2: overflow check |
; bit 3: recovery from delay [bit 0 tasks took too long] |
; bit 4: none |
; bit 5: none |
; bit 6: none |
; bit 7: jump, eor |
rxLoop: |
eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others |
in x1, USBIN ;1 [1] <-- sample bit 0 |
st y+, x3 ;2 [3] store data |
ser x3 ;1 [4] |
nop ;1 [5] |
eor x2, x1 ;1 [6] |
bst x2, USBMINUS;1 [7] |
bld shift, 0 ;1 [8] |
in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) |
andi x2, USBMASK ;1 [10] |
breq se0 ;1 [11] SE0 check for bit 1 |
andi shift, 0xf9 ;1 [12] |
didUnstuff0: |
breq unstuff0 ;1 [13] |
eor x1, x2 ;1 [14] |
bst x1, USBMINUS;1 [15] |
bld shift, 1 ;1 [16] |
rxbit2: |
in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) |
andi shift, 0xf3 ;1 [18] |
breq unstuff1 ;1 [19] do remaining work for bit 1 |
didUnstuff1: |
subi cnt, 1 ;1 [20] |
brcs overflow ;1 [21] loop control |
eor x2, x1 ;1 [22] |
bst x2, USBMINUS;1 [23] |
bld shift, 2 ;1 [24] |
in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) |
andi shift, 0xe7 ;1 [26] |
breq unstuff2 ;1 [27] |
didUnstuff2: |
eor x1, x2 ;1 [28] |
bst x1, USBMINUS;1 [29] |
bld shift, 3 ;1 [30] |
didUnstuff3: |
andi shift, 0xcf ;1 [31] |
breq unstuff3 ;1 [32] |
in x1, USBIN ;1 [33] <-- sample bit 4 |
eor x2, x1 ;1 [34] |
bst x2, USBMINUS;1 [35] |
bld shift, 4 ;1 [36] |
didUnstuff4: |
andi shift, 0x9f ;1 [37] |
breq unstuff4 ;1 [38] |
nop2 ;2 [40] |
in x2, USBIN ;1 [41] <-- sample bit 5 |
eor x1, x2 ;1 [42] |
bst x1, USBMINUS;1 [43] |
bld shift, 5 ;1 [44] |
didUnstuff5: |
andi shift, 0x3f ;1 [45] |
breq unstuff5 ;1 [46] |
nop2 ;2 [48] |
in x1, USBIN ;1 [49] <-- sample bit 6 |
eor x2, x1 ;1 [50] |
bst x2, USBMINUS;1 [51] |
bld shift, 6 ;1 [52] |
didUnstuff6: |
cpi shift, 0x02 ;1 [53] |
brlo unstuff6 ;1 [54] |
nop2 ;2 [56] |
in x2, USBIN ;1 [57] <-- sample bit 7 |
eor x1, x2 ;1 [58] |
bst x1, USBMINUS;1 [59] |
bld shift, 7 ;1 [60] |
didUnstuff7: |
cpi shift, 0x04 ;1 [61] |
brsh rxLoop ;2 [63] loop control |
unstuff7: |
andi x3, ~0x80 ;1 [63] |
ori shift, 0x80 ;1 [64] |
in x2, USBIN ;1 [65] <-- sample stuffed bit 7 |
nop ;1 [66] |
rjmp didUnstuff7 ;2 [68] |
;---------------------------------------------------------------------------- |
; Processing of received packet (numbers in brackets are cycles after end of SE0) |
;---------------------------------------------------------------------------- |
;This is the only non-error exit point for the software receiver loop |
;we don't check any CRCs here because there is no time left. |
#define token x1 |
se0: ; [0] |
subi cnt, USB_BUFSIZE ;1 [1] |
neg cnt ;1 [2] |
cpi cnt, 3 ;1 [3] |
ldi x2, 1<<USB_INTR_PENDING_BIT ;1 [4] |
out USB_INTR_PENDING, x2;1 [5] clear pending intr and check flag later. SE0 should be over. |
brlo doReturn ;1 [6] this is probably an ACK, NAK or similar packet |
sub YL, cnt ;1 [7] |
sbci YH, 0 ;1 [8] |
ld token, y ;2 [10] |
cpi token, USBPID_DATA0 ;1 [11] |
breq handleData ;1 [12] |
cpi token, USBPID_DATA1 ;1 [13] |
breq handleData ;1 [14] |
ldd x2, y+1 ;2 [16] ADDR and 1 bit endpoint number |
mov x3, x2 ;1 [17] store for endpoint number |
andi x2, 0x7f ;1 [18] x2 is now ADDR |
lds shift, usbDeviceAddr;2 [20] |
cp x2, shift ;1 [21] |
overflow: ; This is a hack: brcs overflow will never have Z flag set |
brne ignorePacket ;1 [22] packet for different address |
cpi token, USBPID_IN ;1 [23] |
breq handleIn ;1 [24] |
cpi token, USBPID_SETUP ;1 [25] |
breq handleSetupOrOut ;1 [26] |
cpi token, USBPID_OUT ;1 [27] |
breq handleSetupOrOut ;1 [28] |
; rjmp ignorePacket ;fallthrough, should not happen anyway. |
ignorePacket: |
clr shift |
sts usbCurrentTok, shift |
doReturn: |
pop cnt |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop YH |
sofError: |
pop YL |
out SREG, YL |
pop YL |
reti |
#if USB_CFG_HAVE_INTRIN_ENDPOINT && USB_CFG_HAVE_INTRIN_ENDPOINT3 |
handleIn3: ;1 [38] (branch taken) |
lds cnt, usbTxLen3 ;2 [40] |
sbrc cnt, 4 ;2 [42] |
rjmp sendCntAndReti ;0 43 + 17 = 60 until SOP |
sts usbTxLen3, x1 ;2 [44] x1 == USBPID_NAK from above |
ldi YL, lo8(usbTxBuf3) ;1 [45] |
ldi YH, hi8(usbTxBuf3) ;1 [46] |
rjmp usbSendAndReti ;2 [48] + 13 = 61 until SOP (violates the spec by 1 cycle) |
#endif |
;Setup and Out are followed by a data packet two bit times (16 cycles) after |
;the end of SE0. The sync code allows up to 40 cycles delay from the start of |
;the sync pattern until the first bit is sampled. That's a total of 56 cycles. |
handleSetupOrOut: ;1 [29] (branch taken) |
#if USB_CFG_IMPLEMENT_FN_WRITEOUT /* if we have data for second OUT endpoint, set usbCurrentTok to -1 */ |
sbrc x3, 7 ;1 [30] skip if endpoint 0 |
ldi token, -1 ;1 [31] indicate that this is endpoint 1 OUT |
#endif |
sts usbCurrentTok, token;2 [33] |
pop cnt ;2 [35] |
pop x3 ;2 [37] |
pop x2 ;2 [39] |
pop x1 ;2 [41] |
pop shift ;2 [43] |
pop YH ;2 [45] |
in YL, USB_INTR_PENDING;1 [46] |
sbrc YL, USB_INTR_PENDING_BIT;1 [47] check whether data is already arriving |
rjmp waitForJ ;2 [49] save the pops and pushes -- a new interrupt is aready pending |
rjmp sofError ;2 not an error, but it does the pops and reti we want |
handleData: ;1 [15] (branch taken) |
lds token, usbCurrentTok;2 [17] |
tst token ;1 [18] |
breq doReturn ;1 [19] |
lds x2, usbRxLen ;2 [21] |
tst x2 ;1 [22] |
brne sendNakAndReti ;1 [23] |
; 2006-03-11: The following two lines fix a problem where the device was not |
; recognized if usbPoll() was called less frequently than once every 4 ms. |
cpi cnt, 4 ;1 [24] zero sized data packets are status phase only -- ignore and ack |
brmi sendAckAndReti ;1 [25] keep rx buffer clean -- we must not NAK next SETUP |
sts usbRxLen, cnt ;2 [27] store received data, swap buffers |
sts usbRxToken, token ;2 [29] |
lds x2, usbInputBufOffset;2 [31] swap buffers |
ldi cnt, USB_BUFSIZE ;1 [32] |
sub cnt, x2 ;1 [33] |
sts usbInputBufOffset, cnt;2 [35] buffers now swapped |
rjmp sendAckAndReti ;2 [37] + 19 = 56 until SOP |
handleIn: ;1 [25] (branch taken) |
;We don't send any data as long as the C code has not processed the current |
;input data and potentially updated the output data. That's more efficient |
;in terms of code size than clearing the tx buffers when a packet is received. |
lds x1, usbRxLen ;2 [27] |
cpi x1, 1 ;1 [28] negative values are flow control, 0 means "buffer free" |
brge sendNakAndReti ;1 [29] unprocessed input packet? |
ldi x1, USBPID_NAK ;1 [30] prepare value for usbTxLen |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
sbrc x3, 7 ;2 [33] x3 contains addr + endpoint |
rjmp handleIn1 ;0 |
#endif |
lds cnt, usbTxLen ;2 [34] |
sbrc cnt, 4 ;2 [36] all handshake tokens have bit 4 set |
rjmp sendCntAndReti ;0 37 + 17 = 54 until SOP |
sts usbTxLen, x1 ;2 [38] x1 == USBPID_NAK from above |
ldi YL, lo8(usbTxBuf) ;1 [39] |
ldi YH, hi8(usbTxBuf) ;1 [40] |
rjmp usbSendAndReti ;2 [42] + 14 = 56 until SOP |
; Comment about when to set usbTxLen to USBPID_NAK: |
; We should set it back when we receive the ACK from the host. This would |
; be simple to implement: One static variable which stores whether the last |
; tx was for endpoint 0 or 1 and a compare in the receiver to distinguish the |
; ACK. However, we set it back immediately when we send the package, |
; assuming that no error occurs and the host sends an ACK. We save one byte |
; RAM this way and avoid potential problems with endless retries. The rest of |
; the driver assumes error-free transfers anyway. |
#if USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump range */ |
handleIn1: ;1 [33] (branch taken) |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint |
ldd x2, y+2 ;2 [35] |
sbrc x2, 0 ;2 [37] |
rjmp handleIn3 ;0 |
#endif |
lds cnt, usbTxLen1 ;2 [39] |
sbrc cnt, 4 ;2 [41] all handshake tokens have bit 4 set |
rjmp sendCntAndReti ;0 42 + 17 = 59 until SOP |
sts usbTxLen1, x1 ;2 [43] x1 == USBPID_NAK from above |
ldi YL, lo8(usbTxBuf1) ;1 [44] |
ldi YH, hi8(usbTxBuf1) ;1 [45] |
rjmp usbSendAndReti ;2 [47] + 13 = 60 until SOP |
#endif |
;---------------------------------------------------------------------------- |
; Transmitting data |
;---------------------------------------------------------------------------- |
bitstuff0: ;1 (for branch taken) |
eor x1, x4 ;1 |
ldi x2, 0 ;1 |
out USBOUT, x1 ;1 <-- out |
rjmp didStuff0 ;2 branch back 2 cycles earlier |
bitstuff1: ;1 (for branch taken) |
eor x1, x4 ;1 |
rjmp didStuff1 ;2 we know that C is clear, jump back to do OUT and ror 0 into x2 |
bitstuff2: ;1 (for branch taken) |
eor x1, x4 ;1 |
rjmp didStuff2 ;2 jump back 4 cycles earlier and do out and ror 0 into x2 |
bitstuff3: ;1 (for branch taken) |
eor x1, x4 ;1 |
rjmp didStuff3 ;2 jump back earlier and ror 0 into x2 |
bitstuff4: ;1 (for branch taken) |
eor x1, x4 ;1 |
ldi x2, 0 ;1 |
out USBOUT, x1 ;1 <-- out |
rjmp didStuff4 ;2 jump back 2 cycles earlier |
sendNakAndReti: ;0 [-19] 19 cycles until SOP |
ldi x3, USBPID_NAK ;1 [-18] |
rjmp usbSendX3 ;2 [-16] |
sendAckAndReti: ;0 [-19] 19 cycles until SOP |
ldi x3, USBPID_ACK ;1 [-18] |
rjmp usbSendX3 ;2 [-16] |
sendCntAndReti: ;0 [-17] 17 cycles until SOP |
mov x3, cnt ;1 [-16] |
usbSendX3: ;0 [-16] |
ldi YL, 20 ;1 [-15] 'x3' is R20 |
ldi YH, 0 ;1 [-14] |
ldi cnt, 2 ;1 [-13] |
; rjmp usbSendAndReti fallthrough |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 |
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 |
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte |
;uses: x1...x4, shift, cnt, Y |
;Numbers in brackets are time since first bit of sync pattern is sent |
usbSendAndReti: ;0 [-13] timing: 13 cycles until SOP |
in x2, USBDDR ;1 [-12] |
ori x2, USBMASK ;1 [-11] |
sbi USBOUT, USBMINUS;2 [-9] prepare idle state; D+ and D- must have been 0 (no pullups) |
in x1, USBOUT ;1 [-8] port mirror for tx loop |
out USBDDR, x2 ;1 [-7] <- acquire bus |
; need not init x2 (bitstuff history) because sync starts with 0 |
push x4 ;2 [-5] |
ldi x4, USBMASK ;1 [-4] exor mask |
ldi shift, 0x80 ;1 [-3] sync byte is first byte sent |
txLoop: ; [62] |
sbrs shift, 0 ;1 [-2] [62] |
eor x1, x4 ;1 [-1] [63] |
out USBOUT, x1 ;1 [0] <-- out bit 0 |
ror shift ;1 [1] |
ror x2 ;1 [2] |
didStuff0: |
cpi x2, 0xfc ;1 [3] |
brsh bitstuff0 ;1 [4] |
sbrs shift, 0 ;1 [5] |
eor x1, x4 ;1 [6] |
ror shift ;1 [7] |
didStuff1: |
out USBOUT, x1 ;1 [8] <-- out bit 1 |
ror x2 ;1 [9] |
cpi x2, 0xfc ;1 [10] |
brsh bitstuff1 ;1 [11] |
sbrs shift, 0 ;1 [12] |
eor x1, x4 ;1 [13] |
ror shift ;1 [14] |
didStuff2: |
ror x2 ;1 [15] |
out USBOUT, x1 ;1 [16] <-- out bit 2 |
cpi x2, 0xfc ;1 [17] |
brsh bitstuff2 ;1 [18] |
sbrs shift, 0 ;1 [19] |
eor x1, x4 ;1 [20] |
ror shift ;1 [21] |
didStuff3: |
ror x2 ;1 [22] |
cpi x2, 0xfc ;1 [23] |
out USBOUT, x1 ;1 [24] <-- out bit 3 |
brsh bitstuff3 ;1 [25] |
nop2 ;2 [27] |
ld x3, y+ ;2 [29] |
sbrs shift, 0 ;1 [30] |
eor x1, x4 ;1 [31] |
out USBOUT, x1 ;1 [32] <-- out bit 4 |
ror shift ;1 [33] |
ror x2 ;1 [34] |
didStuff4: |
cpi x2, 0xfc ;1 [35] |
brsh bitstuff4 ;1 [36] |
sbrs shift, 0 ;1 [37] |
eor x1, x4 ;1 [38] |
ror shift ;1 [39] |
didStuff5: |
out USBOUT, x1 ;1 [40] <-- out bit 5 |
ror x2 ;1 [41] |
cpi x2, 0xfc ;1 [42] |
brsh bitstuff5 ;1 [43] |
sbrs shift, 0 ;1 [44] |
eor x1, x4 ;1 [45] |
ror shift ;1 [46] |
didStuff6: |
ror x2 ;1 [47] |
out USBOUT, x1 ;1 [48] <-- out bit 6 |
cpi x2, 0xfc ;1 [49] |
brsh bitstuff6 ;1 [50] |
sbrs shift, 0 ;1 [51] |
eor x1, x4 ;1 [52] |
ror shift ;1 [53] |
didStuff7: |
ror x2 ;1 [54] |
cpi x2, 0xfc ;1 [55] |
out USBOUT, x1 ;1 [56] <-- out bit 7 |
brsh bitstuff7 ;1 [57] |
mov shift, x3 ;1 [58] |
dec cnt ;1 [59] |
brne txLoop ;1/2 [60/61] |
;make SE0: |
cbr x1, USBMASK ;1 [61] prepare SE0 [spec says EOP may be 15 to 18 cycles] |
pop x4 ;2 [63] |
;brackets are cycles from start of SE0 now |
out USBOUT, x1 ;1 [0] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle |
nop2 ;2 [2] |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
lds x2, usbNewDeviceAddr;2 [4] |
subi YL, 20 + 2 ;1 [5] |
sbci YH, 0 ;1 [6] |
breq skipAddrAssign ;2 [8] |
sts usbDeviceAddr, x2;0 if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;1 [9] int0 occurred during TX -- clear pending flag |
out USB_INTR_PENDING, x2;1 [10] |
ori x1, USBIDLE ;1 [11] |
in x2, USBDDR ;1 [12] |
cbr x2, USBMASK ;1 [13] set both pins to input |
mov x3, x1 ;1 [14] |
cbr x3, USBMASK ;1 [15] configure no pullup on both pins |
out USBOUT, x1 ;1 [16] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;1 [17] <-- release bus now |
out USBOUT, x3 ;1 [18] <-- ensure no pull-up resistors are active |
rjmp doReturn |
bitstuff5: ;1 (for branch taken) |
eor x1, x4 ;1 |
rjmp didStuff5 ;2 same trick as above... |
bitstuff6: ;1 (for branch taken) |
eor x1, x4 ;1 |
rjmp didStuff6 ;2 same trick as above... |
bitstuff7: ;1 (for branch taken) |
eor x1, x4 ;1 |
rjmp didStuff7 ;2 same trick as above... |
;---------------------------------------------------------------------------- |
; Utility functions |
;---------------------------------------------------------------------------- |
#ifdef __IAR_SYSTEMS_ASM__ |
/* Register assignments for usbCrc16 on IAR cc */ |
/* Calling conventions on IAR: |
* First parameter passed in r16/r17, second in r18/r19 and so on. |
* Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) |
* Result is passed in r16/r17 |
* In case of the "tiny" memory model, pointers are only 8 bit with no |
* padding. We therefore pass argument 1 as "16 bit unsigned". |
*/ |
RTMODEL "__rt_version", "3" |
/* The line above will generate an error if cc calling conventions change. |
* The value "3" above is valid for IAR 4.10B/W32 |
*/ |
# define argLen r18 /* argument 2 */ |
# define argPtrL r16 /* argument 1 */ |
# define argPtrH r17 /* argument 1 */ |
# define resCrcL r16 /* result */ |
# define resCrcH r17 /* result */ |
# define ptrL ZL |
# define ptrH ZH |
# define ptr Z |
# define byte r22 |
# define bitCnt r19 |
# define polyL r20 |
# define polyH r21 |
# define scratch r23 |
#else /* __IAR_SYSTEMS_ASM__ */ |
/* Register assignments for usbCrc16 on gcc */ |
/* Calling conventions on gcc: |
* First parameter passed in r24/r25, second in r22/23 and so on. |
* Callee must preserve r1-r17, r28/r29 |
* Result is passed in r24/r25 |
*/ |
# define argLen r22 /* argument 2 */ |
# define argPtrL r24 /* argument 1 */ |
# define argPtrH r25 /* argument 1 */ |
# define resCrcL r24 /* result */ |
# define resCrcH r25 /* result */ |
# define ptrL XL |
# define ptrH XH |
# define ptr x |
# define byte r18 |
# define bitCnt r19 |
# define polyL r20 |
# define polyH r21 |
# define scratch r23 |
#endif |
; extern unsigned usbCrc16(unsigned char *data, unsigned char len); |
; data: r24/25 |
; len: r22 |
; temp variables: |
; r18: data byte |
; r19: bit counter |
; r20/21: polynomial |
; r23: scratch |
; r24/25: crc-sum |
; r26/27=X: ptr |
usbCrc16: |
mov ptrL, argPtrL |
mov ptrH, argPtrH |
ldi resCrcL, 0xff |
ldi resCrcH, 0xff |
ldi polyL, lo8(0xa001) |
ldi polyH, hi8(0xa001) |
crcByteLoop: |
subi argLen, 1 |
brcs crcReady |
ld byte, ptr+ |
ldi bitCnt, 8 |
crcBitLoop: |
mov scratch, byte |
eor scratch, resCrcL |
lsr resCrcH |
ror resCrcL |
lsr byte |
sbrs scratch, 0 |
rjmp crcNoXor |
eor resCrcL, polyL |
eor resCrcH, polyH |
crcNoXor: |
dec bitCnt |
brne crcBitLoop |
rjmp crcByteLoop |
crcReady: |
com resCrcL |
com resCrcH |
ret |
; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len); |
usbCrc16Append: |
rcall usbCrc16 |
st ptr+, resCrcL |
st ptr+, resCrcH |
ret |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbdrv/usbdrvasm.asm |
---|
0,0 → 1,21 |
/* Name: usbdrvasm.asm |
* Project: AVR USB driver |
* Author: Christian Starkjohann |
* Creation Date: 2006-03-01 |
* Tabsize: 4 |
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrvasm.asm,v 1.2 2007/05/19 12:30:11 harbaum Exp $ |
*/ |
/* |
General Description: |
The IAR compiler/assembler system prefers assembler files with file extension |
".asm". We simply provide this file as an alias for usbdrvasm.S. |
Thanks to Oleg Semyonov for his help with the IAR tools port! |
*/ |
#include "usbdrvasm.S" |
end |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny/common.mk |
---|
0,0 → 1,61 |
# ====================================================================== |
# Common Makefile for USBtiny applications |
# |
# Macros to be defined before including this file: |
# |
# USBTINY - the location of this directory |
# TARGET_ARCH - gcc -mmcu= option with AVR device type |
# OBJECTS - the objects in addition to the USBtiny objects |
# FLASH_CMD - command to upload main.hex to flash |
# STACK - maximum stack size (optional) |
# FLASH - flash size (optional) |
# SRAM - SRAM size (optional) |
# SCHEM - Postscript version of the schematic to be generated |
# |
# Copyright (C) 2006 Dick Streefland |
# |
# This is free software, licensed under the terms of the GNU General |
# Public License as published by the Free Software Foundation. |
# ====================================================================== |
CC = avr-gcc |
CFLAGS = -Os -g -Wall -I. -I$(USBTINY) |
ASFLAGS = -Os -g -Wall -I. |
LDFLAGS = -g |
MODULES = crc.o int.o usb.o $(OBJECTS) |
UTIL = $(USBTINY)/../util |
main.hex: |
all: main.hex $(SCHEM) |
clean: |
rm -f main.elf *.o tags *.sch~ gschem.log |
clobber: clean |
rm -f main.hex $(SCHEM) |
main.elf: $(MODULES) |
$(LINK.o) -o $@ $(MODULES) |
main.hex: main.elf $(UTIL)/check.py |
@python $(UTIL)/check.py main.elf $(STACK) $(FLASH) $(SRAM) |
avr-objcopy -j .text -j .data -O ihex main.elf main.hex |
disasm: main.elf |
avr-objdump -S main.elf |
flash: main.hex |
$(FLASH_CMD) |
crc.o: $(USBTINY)/crc.S $(USBTINY)/def.h usbtiny.h |
$(COMPILE.c) $(USBTINY)/crc.S |
int.o: $(USBTINY)/int.S $(USBTINY)/def.h usbtiny.h |
$(COMPILE.c) $(USBTINY)/int.S |
usb.o: $(USBTINY)/usb.c $(USBTINY)/def.h $(USBTINY)/usb.h usbtiny.h |
$(COMPILE.c) $(USBTINY)/usb.c |
main.o: $(USBTINY)/usb.h |
%.ps: %.sch $(UTIL)/sch2ps |
$(UTIL)/sch2ps $< |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny/crc.S |
---|
0,0 → 1,123 |
; ====================================================================== |
; Calculate and append CRC |
; |
; The CRC is calculated 4 bits at a time, using a precomputed table of |
; 16 values. Each value is 16 bits, but only the 8 significant bits are |
; stored. The table should not cross a 256-byte page. The check.py script |
; will check for this. |
; |
; A bitwise algorithm would be a little smaller, but takes more time. |
; In fact, it takes too much time for the USB controller in my laptop. |
; The poll frequently is so high, that a lot of time is spent in the |
; interrupt handler, sending NAK packets, leaving little time for the |
; actual checksum calculation. An 8 bit algoritm would be even faster, |
; but requires a lookup table of 512 bytes. |
; |
; Copyright (C) 2006 Dick Streefland |
; |
; This is free software, licensed under the terms of the GNU General |
; Public License as published by the Free Software Foundation. |
; ====================================================================== |
#include "def.h" |
; ---------------------------------------------------------------------- |
; void crc(unsigned char *data, unsigned char len); |
; ---------------------------------------------------------------------- |
#define data r24 |
#define len r22 |
#define b r18 |
#define tmp r19 |
#define zl r20 |
#define crc_l r24 |
#define crc_h r25 |
.text |
.global crc |
.type crc, @function |
crc: |
; crc = 0xffff |
movw XL, r24 |
ldi crc_h, 0xff |
ldi crc_l, 0xff |
lsl len |
breq done |
ldi zl, lo8(crc4tab) |
ldi ZH, hi8(crc4tab) |
next_nibble: |
; b = (len & 1 ? b >> 4 : *data++) |
swap b |
sbrs len, 0 |
ld b, X+ |
; index = (crc ^ b) & 0x0f |
mov ZL, crc_l |
eor ZL, b |
andi ZL, 0x0f |
; crc >>= 4 |
swap crc_h |
swap crc_l |
andi crc_l, 0x0f |
mov tmp, crc_h |
andi tmp, 0xf0 |
or crc_l, tmp |
andi crc_h, 0x0f |
; crc ^= crc4tab[index] |
add ZL, zl |
lpm tmp, Z+ |
eor crc_h, tmp |
andi tmp, 1 |
eor crc_h, tmp |
eor crc_l, tmp |
; next nibble |
dec len |
brne next_nibble |
done: |
; crc ^= 0xffff |
com crc_l |
com crc_h |
; append crc to buffer |
st X+, crc_l |
st X+, crc_h |
ret |
; ---------------------------------------------------------------------- |
; CRC table. As bits 1..8 are always zero, omit them. |
; ---------------------------------------------------------------------- |
.section .progmem.crc,"a",@progbits |
;;; .align 4 ; avoid crossing a page boundary |
crc4tab: |
.byte 0x00+0x00 |
.byte 0xcc+0x01 |
.byte 0xd8+0x01 |
.byte 0x14+0x00 |
.byte 0xf0+0x01 |
.byte 0x3c+0x00 |
.byte 0x28+0x00 |
.byte 0xe4+0x01 |
.byte 0xa0+0x01 |
.byte 0x6c+0x00 |
.byte 0x78+0x00 |
.byte 0xb4+0x01 |
.byte 0x50+0x00 |
.byte 0x9c+0x01 |
.byte 0x88+0x01 |
.byte 0x44+0x00 |
/* ---------------------------------------------------------------------- *\ |
#!/usr/bin/python |
for crc in range(16): |
for bit in range(4): |
xor = crc & 1 |
crc >>= 1 |
if xor: |
crc ^= 0xA001 # X^16 + X^15 + X^2 + 1 (reversed) |
print "\t.byte\t0x%02x+0x%02x" % (crc >> 8, crc & 0xff) |
\* ---------------------------------------------------------------------- */ |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny/def.h |
---|
0,0 → 1,74 |
// ====================================================================== |
// Common definitions for the USB driver |
// |
// Copyright (C) 2006 Dick Streefland |
// |
// This is free software, licensed under the terms of the GNU General |
// Public License as published by the Free Software Foundation. |
// ====================================================================== |
#ifdef __ASSEMBLER__ |
#define __SFR_OFFSET 0 |
#endif |
#include <avr/io.h> |
#include "usbtiny.h" |
// Preprocessor magic |
#define CAT2(a,b) CAT2EXP(a, b) |
#define CAT2EXP(a,b) a ## b |
#define CAT3(a,b,c) CAT3EXP(a, b, c) |
#define CAT3EXP(a,b,c) a ## b ## c |
// I/O Ports |
#define USB_IN CAT2(PIN, USBTINY_PORT) |
#define USB_OUT CAT2(PORT, USBTINY_PORT) |
#define USB_DDR CAT2(DDR, USBTINY_PORT) |
// I/O bit masks |
#define USB_MASK_DMINUS (1 << (USBTINY_DMINUS)) |
#define USB_MASK_DPLUS (1 << (USBTINY_DPLUS)) |
#define USB_MASK (USB_MASK_DMINUS | USB_MASK_DPLUS) |
// Interrupt configuration |
#if defined EICRA |
# define USB_INT_CONFIG EICRA |
#else |
# define USB_INT_CONFIG MCUCR |
#endif |
#define USB_INT_CONFIG_SET ((1 << CAT3(ISC,USBTINY_INT,1)) | (1 << CAT3(ISC,USBTINY_INT,0))) |
#if defined SIG_INT0 |
# define USB_INT_VECTOR CAT2(SIG_INT, USBTINY_INT) |
#else |
# define USB_INT_VECTOR CAT2(SIG_INTERRUPT, USBTINY_INT) |
#endif |
// Interrupt enable |
#if defined GIMSK |
# define USB_INT_ENABLE GIMSK |
#elif defined EIMSK |
# define USB_INT_ENABLE EIMSK |
#else |
# define USB_INT_ENABLE GICR |
#endif |
#define USB_INT_ENABLE_BIT CAT2(INT,USBTINY_INT) |
// Interrupt pending bit |
#if defined EIFR |
# define USB_INT_PENDING EIFR |
#else |
# define USB_INT_PENDING GIFR |
#endif |
#define USB_INT_PENDING_BIT CAT2(INTF,USBTINY_INT) |
// USB PID values |
#define USB_PID_SETUP 0x2d |
#define USB_PID_OUT 0xe1 |
#define USB_PID_IN 0x69 |
#define USB_PID_DATA0 0xc3 |
#define USB_PID_DATA1 0x4b |
#define USB_PID_ACK 0xd2 |
#define USB_PID_NAK 0x5a |
#define USB_PID_STALL 0x1e |
// Various constants |
#define USB_BUFSIZE 11 // PID + data + CRC |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny/int.S |
---|
0,0 → 1,562 |
; ====================================================================== |
; USB interrupt handler |
; |
; This is the handler for the interrupt caused by the initial rising edge |
; on the D+ USB signal. The NRZI encoding and bit stuffing are removed, |
; and the packet is saved in one of the two input buffers. In some cases, |
; a reply packet is sent right away. |
; |
; When a DATA0/DATA1 packet directly follows a SETUP or OUT packet, while |
; this interrupt handler is not yet finished, there would be no time to |
; return and take another interrupt. In that case, the second packet is |
; decoded directly in the same invocation. |
; |
; This code is *extremely* time critical. For instance, there is not a |
; single spare cycle in the receiver loop, and only two in the transmitter |
; loop. In addition, the various code paths are laid out in such a way that |
; the various USB timeouts are not violated, in particular the maximum time |
; between the reception of a packet and the reply, which is 6.5 bit times |
; for a detachable cable (TRSPIPD1), and 7.5 bit times for a captive cable |
; (TRSPIPD2). The worst-case delay here is 51 cycles, which is just below |
; the 52 cycles for a detachable cable. |
; |
; The interrupt handler must be reached within 34 cycles after D+ goes high |
; for the first time, so the interrupts should not be disabled for longer |
; than 34-4-2=28 cycles. |
; |
; The end-of-packet (EOP) is sampled in the second bit, because the USB |
; standard allows the EOP to be delayed by up to one bit. As the EOP |
; duration is two bits, this is not a problem. |
; |
; Stack usage including the return address: 11 bytes. |
; |
; Copyright (C) 2006 Dick Streefland |
; |
; This is free software, licensed under the terms of the GNU General |
; Public License as published by the Free Software Foundation. |
; ====================================================================== |
#include "def.h" |
; ---------------------------------------------------------------------- |
; local data |
; ---------------------------------------------------------------------- |
.data |
tx_ack: .byte USB_PID_ACK ; ACK packet |
tx_nak: .byte USB_PID_NAK ; NAK packet |
.lcomm token_pid, 1 ; PID of most recent token packet |
; ---------------------------------------------------------------------- |
; register definitions |
; ---------------------------------------------------------------------- |
// receiver: |
#define count r16 |
#define usbmask r17 |
#define odd r18 |
#define byte r19 |
#define fixup r20 |
#define even r22 |
// transmitter: |
#define output odd |
#define done fixup |
#define next even |
// control: |
#define pid odd |
#define addr usbmask |
#define tmp fixup |
#define nop2 rjmp .+0 // not .+2 for some strange reason |
; ---------------------------------------------------------------------- |
; interrupt handler |
; ---------------------------------------------------------------------- |
.text |
.global USB_INT_VECTOR |
.type USB_INT_VECTOR, @function |
; ---------------------------------------------------------------------- |
; This handler must be reached no later than 34 cycles after D+ goes high |
; for the first time. |
; ---------------------------------------------------------------------- |
USB_INT_VECTOR: |
; save registers |
push count |
push usbmask |
push odd |
push YH |
push YL |
in count, SREG |
push count |
; ---------------------------------------------------------------------- |
; Synchronize to the pattern 10101011 on D+. This code must be reached |
; no later than 47 cycles after D+ goes high for the first time. |
; ---------------------------------------------------------------------- |
sync: |
; wait until D+ == 0 |
sbic USB_IN, USBTINY_DPLUS |
rjmp sync ; jump if D+ == 1 |
resync: |
; sync on 0-->1 transition on D+ with a 2 cycle resolution |
sbic USB_IN, USBTINY_DPLUS |
rjmp sync6 ; jump if D+ == 1 |
sbic USB_IN, USBTINY_DPLUS |
rjmp sync6 ; jump if D+ == 1 |
sbic USB_IN, USBTINY_DPLUS |
rjmp sync6 ; jump if D+ == 1 |
sbic USB_IN, USBTINY_DPLUS |
rjmp sync6 ; jump if D+ == 1 |
sbic USB_IN, USBTINY_DPLUS |
rjmp sync6 ; jump if D+ == 1 |
ldi count, 1<<USB_INT_PENDING_BIT |
out USB_INT_PENDING, count |
rjmp return ; ==> false start, bail out |
sync6: |
; we are now between -1 and +1 cycle from the center of the bit |
; following the 0-->1 transition |
lds YL, usb_rx_off |
clr YH |
subi YL, lo8(-(usb_rx_buf)) ; Y = & usb_rx_buf[usb_rx_off] |
sbci YH, hi8(-(usb_rx_buf)) |
ldi count, USB_BUFSIZE ; limit on number of bytes to receive |
ldi usbmask, USB_MASK ; why is there no eori instruction? |
ldi odd, USB_MASK_DPLUS |
sync7: |
; the last sync bit should also be 1 |
sbis USB_IN, USBTINY_DPLUS ; bit 7 of sync byte? |
rjmp resync ; no, wait for next transition |
push byte |
push fixup |
push even |
; ---------------------------------------------------------------------- |
; receiver loop |
; ---------------------------------------------------------------------- |
in even, USB_IN ; sample bit 0 |
ldi byte, 0x80 ; load sync byte for correct unstuffing |
rjmp rxentry ; 2 cycles |
rxloop: |
in even, USB_IN ; sample bit 0 |
or fixup, byte |
st Y+, fixup ; 2 cycles |
rxentry: |
clr fixup |
andi even, USB_MASK |
eor odd, even |
subi odd, 1 |
in odd, USB_IN ; sample bit 1 |
andi odd, USB_MASK |
breq eop ; ==> EOP detected |
ror byte |
cpi byte, 0xfc |
brcc skip0 |
skipped0: |
eor even, odd |
subi even, 1 |
in even, USB_IN ; sample bit 2 |
andi even, USB_MASK |
ror byte |
cpi byte, 0xfc |
brcc skip1 |
skipped1: |
eor odd, even |
subi odd, 1 |
ror byte |
in odd, USB_IN ; sample bit 3 |
andi odd, USB_MASK |
cpi byte, 0xfc |
brcc skip2 |
eor even, odd |
subi even, 1 |
ror byte |
skipped2: |
cpi byte, 0xfc |
in even, USB_IN ; sample bit 4 |
andi even, USB_MASK |
brcc skip3 |
eor odd, even |
subi odd, 1 |
ror byte |
skipped4: |
cpi byte, 0xfc |
skipped3: |
brcc skip4 |
in odd, USB_IN ; sample bit 5 |
andi odd, USB_MASK |
eor even, odd |
subi even, 1 |
ror byte |
skipped5: |
cpi byte, 0xfc |
brcc skip5 |
dec count |
in even, USB_IN ; sample bit 6 |
brmi overflow ; ==> overflow |
andi even, USB_MASK |
eor odd, even |
subi odd, 1 |
ror byte |
skipped6: |
cpi byte, 0xfc |
brcc skip6 |
in odd, USB_IN ; sample bit 7 |
andi odd, USB_MASK |
eor even, odd |
subi even, 1 |
ror byte |
cpi byte, 0xfc |
brcs rxloop ; 2 cycles |
rjmp skip7 |
eop: |
rjmp eop2 |
overflow: |
rjmp ignore |
; ---------------------------------------------------------------------- |
; out-of-line code to skip stuffing bits |
; ---------------------------------------------------------------------- |
skip0: ; 1+6 cycles |
eor even, usbmask |
in odd, USB_IN ; resample bit 1 |
andi odd, USB_MASK |
cbr byte, (1<<7) |
sbr fixup, (1<<0) |
rjmp skipped0 |
skip1: ; 2+5 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<1) |
in even, USB_IN ; resample bit 2 |
andi even, USB_MASK |
eor odd, usbmask |
rjmp skipped1 |
skip2: ; 3+7 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<2) |
eor even, usbmask |
in odd, USB_IN ; resample bit 3 |
andi odd, USB_MASK |
eor even, odd |
subi even, 1 |
ror byte |
rjmp skipped2 |
skip3: ; 4+7 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<3) |
eor odd, usbmask |
ori byte, 1 |
in even, USB_IN ; resample bit 4 |
andi even, USB_MASK |
eor odd, even |
subi odd, 1 |
ror byte |
rjmp skipped3 |
skip4: ; 5 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<4) |
eor even, usbmask |
rjmp skipped4 |
skip5: ; 5 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<5) |
eor odd, usbmask |
rjmp skipped5 |
skip6: ; 5 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<6) |
eor even, usbmask |
rjmp skipped6 |
skip7: ; 7 cycles |
cbr byte, (1<<7) |
sbr fixup, (1<<7) |
eor odd, usbmask |
nop2 |
rjmp rxloop |
; ---------------------------------------------------------------------- |
; end-of-packet detected (worst-case: 3 cycles after end of SE0) |
; ---------------------------------------------------------------------- |
eop2: |
; clear pending interrupt (SE0+3) |
ldi byte, 1<<USB_INT_PENDING_BIT |
out USB_INT_PENDING, byte ; clear pending bit at end of packet |
; ignore packets shorter than 3 bytes |
subi count, USB_BUFSIZE |
neg count ; count = packet length |
cpi count, 3 |
brlo ignore |
; get PID |
sub YL, count |
ld pid, Y |
; check for DATA0/DATA1 first, as this is the critical path (SE0+12) |
cpi pid, USB_PID_DATA0 |
breq is_data ; handle DATA0 packet |
cpi pid, USB_PID_DATA1 |
breq is_data ; handle DATA1 packet |
; check ADDR (SE0+16) |
ldd addr, Y+1 |
andi addr, 0x7f |
lds tmp, usb_address |
cp addr, tmp ; is this packet for me? |
brne ignore ; no, ignore |
; check for other PIDs (SE0+23) |
cpi pid, USB_PID_IN |
breq is_in ; handle IN packet |
cpi pid, USB_PID_SETUP |
breq is_setup_out ; handle SETUP packet |
cpi pid, USB_PID_OUT |
breq is_setup_out ; handle OUT packet |
; ---------------------------------------------------------------------- |
; exit point for ignored packets |
; ---------------------------------------------------------------------- |
ignore: |
clr tmp |
sts token_pid, tmp |
pop even |
pop fixup |
pop byte |
rjmp return |
; ---------------------------------------------------------------------- |
; Handle SETUP/OUT (SE0+30) |
; ---------------------------------------------------------------------- |
is_setup_out: |
sts token_pid, pid ; save PID of token packet |
pop even |
pop fixup |
pop byte |
in count, USB_INT_PENDING ; next packet already started? |
sbrc count, USB_INT_PENDING_BIT |
rjmp sync ; yes, get it right away (SE0+42) |
; ---------------------------------------------------------------------- |
; restore registers and return from interrupt |
; ---------------------------------------------------------------------- |
return: |
pop count |
out SREG, count |
pop YL |
pop YH |
pop odd |
pop usbmask |
pop count |
reti |
; ---------------------------------------------------------------------- |
; Handle IN (SE0+26) |
; ---------------------------------------------------------------------- |
is_in: |
lds count, usb_tx_len |
tst count ; data ready? |
breq nak ; no, reply with NAK |
lds tmp, usb_rx_len |
tst tmp ; unprocessed input packet? |
brne nak ; yes, don't send old data for new packet |
sts usb_tx_len, tmp ; buffer is available again (after reti) |
ldi YL, lo8(usb_tx_buf) |
ldi YH, hi8(usb_tx_buf) |
rjmp send_packet ; SE0+40, SE0 --> SOP <= 51 |
; ---------------------------------------------------------------------- |
; Handle DATA0/DATA1 (SE0+17) |
; ---------------------------------------------------------------------- |
is_data: |
lds pid, token_pid |
tst pid ; data following our SETUP/OUT |
breq ignore ; no, ignore |
lds tmp, usb_rx_len |
tst tmp ; buffer free? |
brne nak ; no, reply with NAK |
sts usb_rx_len, count ; pass buffer length |
sts usb_rx_token, pid ; pass PID of token (SETUP or OUT) |
lds count, usb_rx_off ; switch to other input buffer |
ldi tmp, USB_BUFSIZE |
sub tmp, count |
sts usb_rx_off, tmp |
; ---------------------------------------------------------------------- |
; send ACK packet (SE0+35) |
; ---------------------------------------------------------------------- |
ack: |
ldi YL, lo8(tx_ack) |
ldi YH, hi8(tx_ack) |
rjmp send_token |
; ---------------------------------------------------------------------- |
; send NAK packet (SE0+36) |
; ---------------------------------------------------------------------- |
nak: |
ldi YL, lo8(tx_nak) |
ldi YH, hi8(tx_nak) |
send_token: |
ldi count, 1 ; SE0+40, SE0 --> SOP <= 51 |
; ---------------------------------------------------------------------- |
; acquire the bus and send a packet (11 cycles to SOP) |
; ---------------------------------------------------------------------- |
send_packet: |
in output, USB_OUT |
cbr output, USB_MASK |
ori output, USB_MASK_DMINUS |
in usbmask, USB_DDR |
ori usbmask, USB_MASK |
out USB_OUT, output ; idle state |
out USB_DDR, usbmask ; acquire bus |
ldi usbmask, USB_MASK |
ldi byte, 0x80 ; start with sync byte |
; ---------------------------------------------------------------------- |
; transmitter loop |
; ---------------------------------------------------------------------- |
txloop: |
sbrs byte, 0 |
eor output, usbmask |
out USB_OUT, output ; output bit 0 |
ror byte |
ror done |
stuffed0: |
cpi done, 0xfc |
brcc stuff0 |
sbrs byte, 0 |
eor output, usbmask |
ror byte |
stuffed1: |
out USB_OUT, output ; output bit 1 |
ror done |
cpi done, 0xfc |
brcc stuff1 |
sbrs byte, 0 |
eor output, usbmask |
ror byte |
nop |
stuffed2: |
out USB_OUT, output ; output bit 2 |
ror done |
cpi done, 0xfc |
brcc stuff2 |
sbrs byte, 0 |
eor output, usbmask |
ror byte |
nop |
stuffed3: |
out USB_OUT, output ; output bit 3 |
ror done |
cpi done, 0xfc |
brcc stuff3 |
sbrs byte, 0 |
eor output, usbmask |
ld next, Y+ ; 2 cycles |
out USB_OUT, output ; output bit 4 |
ror byte |
ror done |
stuffed4: |
cpi done, 0xfc |
brcc stuff4 |
sbrs byte, 0 |
eor output, usbmask |
ror byte |
stuffed5: |
out USB_OUT, output ; output bit 5 |
ror done |
cpi done, 0xfc |
brcc stuff5 |
sbrs byte, 0 |
eor output, usbmask |
ror byte |
stuffed6: |
ror done |
out USB_OUT, output ; output bit 6 |
cpi done, 0xfc |
brcc stuff6 |
sbrs byte, 0 |
eor output, usbmask |
ror byte |
mov byte, next |
stuffed7: |
ror done |
out USB_OUT, output ; output bit 7 |
cpi done, 0xfc |
brcc stuff7 |
dec count |
brpl txloop ; 2 cycles |
rjmp gen_eop |
; ---------------------------------------------------------------------- |
; out-of-line code to insert stuffing bits |
; ---------------------------------------------------------------------- |
stuff0: ; 2+3 |
eor output, usbmask |
clr done |
out USB_OUT, output |
rjmp stuffed0 |
stuff1: ; 3 |
eor output, usbmask |
rjmp stuffed1 |
stuff2: ; 3 |
eor output, usbmask |
rjmp stuffed2 |
stuff3: ; 3 |
eor output, usbmask |
rjmp stuffed3 |
stuff4: ; 2+3 |
eor output, usbmask |
clr done |
out USB_OUT, output |
rjmp stuffed4 |
stuff5: ; 3 |
eor output, usbmask |
rjmp stuffed5 |
stuff6: ; 3 |
eor output, usbmask |
rjmp stuffed6 |
stuff7: ; 3 |
eor output, usbmask |
rjmp stuffed7 |
; ---------------------------------------------------------------------- |
; generate EOP, release the bus, and return from interrupt |
; ---------------------------------------------------------------------- |
gen_eop: |
cbr output, USB_MASK |
out USB_OUT, output ; output SE0 for 2 bit times |
pop even |
pop fixup |
pop byte |
ldi count, 1<<USB_INT_PENDING_BIT |
out USB_INT_PENDING, count ; interrupt was triggered by transmit |
pop YH ; this is the saved SREG |
pop YL |
in usbmask, USB_DDR |
mov count, output |
ori output, USB_MASK_DMINUS |
out USB_OUT, output ; output J state for 1 bit time |
cbr usbmask, USB_MASK |
out SREG, YH |
pop YH |
pop odd ; is the same register as output! |
nop |
out USB_DDR, usbmask ; release bus |
out USB_OUT, count ; disable D- pullup |
pop usbmask |
pop count |
reti |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny/usb.c |
---|
0,0 → 1,418 |
// ====================================================================== |
// USB driver |
// |
// Entry points: |
// usb_init() - enable the USB interrupt |
// usb_poll() - poll for incoming packets and process them |
// |
// This code communicates with the interrupt handler through a number of |
// global variables, including two input buffers and one output buffer. |
// Packets are queued for transmission by copying them into the output |
// buffer. The interrupt handler will transmit such a packet on the |
// reception of an IN packet. |
// |
// Standard SETUP packets are handled here. Non-standard SETUP packets |
// are forwarded to the application code by calling usb_setup(). The |
// macros USBTINY_CALLBACK_IN and USBTINY_CALLBACK_OUT control whether |
// the callback functions usb_in() and usb_out() will be called for IN |
// and OUT transfers. |
// |
// Maximum stack usage (gcc 3.4.3 & 4.1.0) of usb_poll(): 5 bytes plus |
// possible additional stack usage in usb_setup(), usb_in() or usb_out(). |
// |
// Copyright (C) 2006 Dick Streefland |
// |
// This is free software, licensed under the terms of the GNU General |
// Public License as published by the Free Software Foundation. |
// ====================================================================== |
#include <avr/pgmspace.h> |
#include <avr/interrupt.h> |
#include "def.h" |
#include "usb.h" |
#define LE(word) (word) & 0xff, (word) >> 8 |
// ---------------------------------------------------------------------- |
// USB constants |
// ---------------------------------------------------------------------- |
enum |
{ |
DESCRIPTOR_TYPE_DEVICE = 1, |
DESCRIPTOR_TYPE_CONFIGURATION, |
DESCRIPTOR_TYPE_STRING, |
DESCRIPTOR_TYPE_INTERFACE, |
DESCRIPTOR_TYPE_ENDPOINT, |
}; |
// ---------------------------------------------------------------------- |
// Interrupt handler interface |
// ---------------------------------------------------------------------- |
byte_t usb_rx_buf[2*USB_BUFSIZE]; // two input buffers |
byte_t usb_rx_off; // buffer offset: 0 or USB_BUFSIZE |
byte_t usb_rx_len; // buffer size, 0 means empty |
byte_t usb_rx_token; // PID of token packet: SETUP or OUT |
byte_t usb_tx_buf[USB_BUFSIZE]; // output buffer |
byte_t usb_tx_len; // output buffer size, 0 means empty |
byte_t usb_address; // assigned USB address |
// ---------------------------------------------------------------------- |
// Local data |
// ---------------------------------------------------------------------- |
enum |
{ |
TX_STATE_IDLE = 0, // transmitter idle |
TX_STATE_RAM, // usb_tx_data is a RAM address |
TX_STATE_ROM, // usb_tx_data is a ROM address |
TX_STATE_CALLBACK, // call usb_in() to obtain transmit data |
}; |
static byte_t usb_tx_state; // TX_STATE_*, see enum above |
static byte_t usb_tx_total; // total transmit size |
static byte_t* usb_tx_data; // pointer to data to transmit |
static byte_t new_address; // new device address |
#if defined USBTINY_VENDOR_NAME |
struct |
{ |
byte_t length; |
byte_t type; |
int string[sizeof(USBTINY_VENDOR_NAME)-1]; |
} string_vendor PROGMEM = |
{ |
2 * sizeof(USBTINY_VENDOR_NAME), |
DESCRIPTOR_TYPE_STRING, |
{ CAT2(L, USBTINY_VENDOR_NAME) } |
}; |
# define VENDOR_NAME_ID 1 |
#else |
# define VENDOR_NAME_ID 0 |
#endif |
#if defined USBTINY_DEVICE_NAME |
struct |
{ |
byte_t length; |
byte_t type; |
int string[sizeof(USBTINY_DEVICE_NAME)-1]; |
} string_device PROGMEM = |
{ |
2 * sizeof(USBTINY_DEVICE_NAME), |
DESCRIPTOR_TYPE_STRING, |
{ CAT2(L, USBTINY_DEVICE_NAME) } |
}; |
# define DEVICE_NAME_ID 2 |
#else |
# define DEVICE_NAME_ID 0 |
#endif |
#if defined USBTINY_SERIAL |
struct |
{ |
byte_t length; |
byte_t type; |
int string[sizeof(USBTINY_SERIAL)-1]; |
} string_serial PROGMEM = |
{ |
2 * sizeof(USBTINY_SERIAL), |
DESCRIPTOR_TYPE_STRING, |
{ CAT2(L, USBTINY_SERIAL) } |
}; |
# define SERIAL_ID 3 |
#else |
# define SERIAL_ID 0 |
#endif |
#if VENDOR_NAME_ID || DEVICE_NAME_ID || SERIAL_ID |
static byte_t string_langid [] PROGMEM = |
{ |
4, // bLength |
DESCRIPTOR_TYPE_STRING, // bDescriptorType (string) |
LE(0x0409), // wLANGID[0] (American English) |
}; |
#endif |
// Device Descriptor |
static byte_t descr_device [18] PROGMEM = |
{ |
18, // bLength |
DESCRIPTOR_TYPE_DEVICE, // bDescriptorType |
LE(0x0110), // bcdUSB |
USBTINY_DEVICE_CLASS, // bDeviceClass |
USBTINY_DEVICE_SUBCLASS, // bDeviceSubClass |
USBTINY_DEVICE_PROTOCOL, // bDeviceProtocol |
8, // bMaxPacketSize0 |
LE(USBTINY_VENDOR_ID), // idVendor |
LE(USBTINY_DEVICE_ID), // idProduct |
LE(USBTINY_DEVICE_VERSION), // bcdDevice |
VENDOR_NAME_ID, // iManufacturer |
DEVICE_NAME_ID, // iProduct |
SERIAL_ID, // iSerialNumber |
1, // bNumConfigurations |
}; |
// Configuration Descriptor |
static byte_t descr_config [] PROGMEM = |
{ |
9, // bLength |
DESCRIPTOR_TYPE_CONFIGURATION, // bDescriptorType |
LE(9+9+7*USBTINY_ENDPOINT), // wTotalLength |
1, // bNumInterfaces |
1, // bConfigurationValue |
0, // iConfiguration |
(USBTINY_MAX_POWER ? 0x80 : 0xc0), // bmAttributes |
(USBTINY_MAX_POWER + 1) / 2, // MaxPower |
// Standard Interface Descriptor |
9, // bLength |
DESCRIPTOR_TYPE_INTERFACE, // bDescriptorType |
0, // bInterfaceNumber |
0, // bAlternateSetting |
USBTINY_ENDPOINT, // bNumEndpoints |
USBTINY_INTERFACE_CLASS, // bInterfaceClass |
USBTINY_INTERFACE_SUBCLASS, // bInterfaceSubClass |
USBTINY_INTERFACE_PROTOCOL, // bInterfaceProtocol |
0, // iInterface |
#if USBTINY_ENDPOINT |
// Additional Endpoint |
7, // bLength |
DESCRIPTOR_TYPE_ENDPOINT, // bDescriptorType |
USBTINY_ENDPOINT_ADDRESS, // bEndpointAddress |
USBTINY_ENDPOINT_TYPE, // bmAttributes |
LE(8), // wMaxPacketSize |
USBTINY_ENDPOINT_INTERVAL, // bInterval |
#endif |
}; |
// ---------------------------------------------------------------------- |
// Inspect an incoming packet. |
// ---------------------------------------------------------------------- |
static void usb_receive ( byte_t* data, byte_t rx_len ) |
{ |
byte_t len; |
byte_t type; |
byte_t limit; |
usb_tx_state = TX_STATE_RAM; |
len = 0; |
if ( usb_rx_token == USB_PID_SETUP ) |
{ |
limit = data[6]; |
if ( data[7] ) |
{ |
limit = 255; |
} |
type = data[0] & 0x60; |
if ( type == 0x00 ) |
{ // Standard request |
if ( data[1] == 0 ) // GET_STATUS |
{ |
len = 2; |
#if USBTINY_MAX_POWER == 0 |
data[0] = (data[0] == 0x80); |
#else |
data[0] = 0; |
#endif |
data[1] = 0; |
} |
else if ( data[1] == 5 ) // SET_ADDRESS |
{ |
new_address = data[2]; |
} |
else if ( data[1] == 6 ) // GET_DESCRIPTOR |
{ |
usb_tx_state = TX_STATE_ROM; |
if ( data[3] == 1 ) |
{ // DEVICE |
data = (byte_t*) &descr_device; |
len = sizeof(descr_device); |
} |
else if ( data[3] == 2 ) |
{ // CONFIGURATION |
data = (byte_t*) &descr_config; |
len = sizeof(descr_config); |
} |
#if VENDOR_NAME_ID || DEVICE_NAME_ID || SERIAL_ID |
else if ( data[3] == 3 ) |
{ // STRING |
if ( data[2] == 0 ) |
{ |
data = (byte_t*) &string_langid; |
len = sizeof(string_langid); |
} |
#if VENDOR_NAME_ID |
else if ( data[2] == VENDOR_NAME_ID ) |
{ |
data = (byte_t*) &string_vendor; |
len = sizeof(string_vendor); |
} |
#endif |
#if DEVICE_NAME_ID |
else if ( data[2] == DEVICE_NAME_ID ) |
{ |
data = (byte_t*) &string_device; |
len = sizeof(string_device); |
} |
#endif |
#if SERIAL_ID |
else if ( data[2] == SERIAL_ID ) |
{ |
data = (byte_t*) &string_serial; |
len = sizeof(string_serial); |
} |
#endif |
} |
#endif |
} |
else if ( data[1] == 8 ) // GET_CONFIGURATION |
{ |
data[0] = 1; // return bConfigurationValue |
len = 1; |
} |
else if ( data[1] == 10 ) // GET_INTERFACE |
{ |
data[0] = 0; |
len = 1; |
} |
} |
else |
{ // Class or Vendor request |
len = usb_setup( data ); |
#if USBTINY_CALLBACK_IN |
if ( len == 0xff ) |
{ |
usb_tx_state = TX_STATE_CALLBACK; |
} |
#endif |
} |
if ( len > limit ) |
{ |
len = limit; |
} |
usb_tx_data = data; |
} |
#if USBTINY_CALLBACK_OUT |
else if ( rx_len > 0 ) |
{ // usb_rx_token == USB_PID_OUT |
usb_out( data, rx_len ); |
} |
#endif |
usb_tx_total = len; |
usb_tx_buf[0] = USB_PID_DATA0; // next data packet will be DATA1 |
} |
// ---------------------------------------------------------------------- |
// Load the transmit buffer with the next packet. |
// ---------------------------------------------------------------------- |
static void usb_transmit ( void ) |
{ |
byte_t len; |
byte_t* src; |
byte_t* dst; |
byte_t i; |
byte_t b; |
usb_tx_buf[0] ^= (USB_PID_DATA0 ^ USB_PID_DATA1); |
len = usb_tx_total; |
if ( len > 8 ) |
{ |
len = 8; |
} |
dst = usb_tx_buf + 1; |
if ( len > 0 ) |
{ |
#if USBTINY_CALLBACK_IN |
if ( usb_tx_state == TX_STATE_CALLBACK ) |
{ |
len = usb_in( dst, len ); |
} |
else |
#endif |
{ |
src = usb_tx_data; |
if ( usb_tx_state == TX_STATE_RAM ) |
{ |
for ( i = 0; i < len; i++ ) |
{ |
*dst++ = *src++; |
} |
} |
else // usb_tx_state == TX_STATE_ROM |
{ |
for ( i = 0; i < len; i++ ) |
{ |
b = pgm_read_byte( src ); |
src++; |
*dst++ = b; |
} |
} |
usb_tx_data = src; |
} |
usb_tx_total -= len; |
} |
crc( usb_tx_buf + 1, len ); |
usb_tx_len = len + 3; |
if ( len < 8 ) |
{ // this is the last packet |
usb_tx_state = TX_STATE_IDLE; |
} |
} |
// ---------------------------------------------------------------------- |
// Initialize the low-level USB driver. |
// ---------------------------------------------------------------------- |
extern void usb_init ( void ) |
{ |
USB_INT_CONFIG |= USB_INT_CONFIG_SET; |
USB_INT_ENABLE |= (1 << USB_INT_ENABLE_BIT); |
sei(); |
} |
// ---------------------------------------------------------------------- |
// Poll USB driver: |
// - check for incoming USB packets |
// - refill an empty transmit buffer |
// - check for USB bus reset |
// ---------------------------------------------------------------------- |
extern void usb_poll ( void ) |
{ |
byte_t i; |
// check for incoming USB packets |
if ( usb_rx_len != 0 ) |
{ |
usb_receive( usb_rx_buf + USB_BUFSIZE - usb_rx_off + 1, usb_rx_len - 3 ); |
usb_tx_len = 0; // abort pending transmission |
usb_rx_len = 0; // accept next packet |
} |
// refill an empty transmit buffer, when the transmitter is active |
if ( usb_tx_len == 0 ) |
{ |
if ( usb_tx_state != TX_STATE_IDLE ) |
{ |
usb_transmit(); |
} |
else |
{ // change the USB address at the end of a transfer |
usb_address = new_address; |
} |
} |
// check for USB bus reset |
for ( i = 10; i > 0 && ! (USB_IN & USB_MASK_DMINUS); i-- ) |
{ |
} |
if ( i == 0 ) |
{ // SE0 for more than 2.5uS is a reset |
cli(); |
usb_tx_len=0; |
usb_rx_len=0; |
new_address = 0; |
sei(); |
} |
} |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/usbtiny/usb.h |
---|
0,0 → 1,28 |
// ====================================================================== |
// Public interface of the USB driver |
// |
// Copyright (C) 2006 Dick Streefland |
// |
// This is free software, licensed under the terms of the GNU General |
// Public License as published by the Free Software Foundation. |
// ====================================================================== |
#ifndef USB_H |
#define USB_H |
typedef unsigned char byte_t; |
typedef unsigned int uint_t; |
// usb.c |
extern void usb_init ( void ); |
extern void usb_poll ( void ); |
// crc.S |
extern void crc ( byte_t* data, byte_t len ); |
// application callback functions |
extern byte_t usb_setup ( byte_t data[8] ); |
extern void usb_out ( byte_t* data, byte_t len ); |
extern byte_t usb_in ( byte_t* data, byte_t len ); |
#endif // USB_H |
/Modules/AVR/AVRUSB01A/SW/fw_i2c_tiny_usb/util/check.py |
---|
0,0 → 1,51 |
#!/usr/bin/python |
# ====================================================================== |
# check.py - Check section sizes and other constraints |
# |
# Copyright (C) 2006 Dick Streefland |
# |
# This is free software, licensed under the terms of the GNU General |
# Public License as published by the Free Software Foundation. |
# ====================================================================== |
import os, sys |
stacksize = 32 |
flashsize = 2048 |
ramsize = 128 |
if len(sys.argv) > 2: |
stacksize = int(sys.argv[2]) |
if len(sys.argv) > 3: |
flashsize = int(sys.argv[3]) |
if len(sys.argv) > 4: |
ramsize = int(sys.argv[4]) |
max_sram = ramsize - stacksize |
for line in os.popen('avr-objdump -ht ' + sys.argv[1]).readlines(): |
a = line.split() |
if len(a) == 7: |
if a[1] == '.text': |
text = int(a[2], 16) |
if a[1] == '.data': |
data = int(a[2], 16) |
if a[1] == '.bss': |
bss = int(a[2], 16) |
if len(a) == 5 and a[4] == 'crc4tab': |
crc4tab = int(a[0], 16) |
print 'text: %d, data: %d, bss: %d' % (text, data, bss) |
status = 0 |
overflow = text + data - flashsize |
if overflow > 0: |
print 'ERROR: Flash size limit exceeded by %d bytes.' % overflow |
status = 1 |
overflow = bss + data - max_sram |
if overflow > 0: |
print 'ERROR: SRAM size limit exceeded by %d bytes.' % overflow |
status = 1 |
if (crc4tab & 0xff) > 0xf0: |
print 'ERROR: The table crc4tab should not cross a page boundary.' |
status = 1 |
sys.exit(status) |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/!____!.txt |
---|
0,0 → 1,30 |
USBasp firmware customized for MLAB hardware AVRUSB01 |
http://www.mlab.cz/PermaLink/AVRUSB01 |
----------------------------------------------------- |
- original firmare from http://www.fischl.de/usbasp/usbasp.2011-05-28.tar.gz |
- the original package contains drivers as well, please use them |
- hardware supports Green LED (always on) |
- hardware supports Red LED (busy indicator) |
- hardware supports jumper for slowing down SPI clocks (just install jumper on J6 to position RX-GND) |
- the code itself has to be modifyied so that it vas possible to reconfigure IO pins for |
different hardware (minor changes in main function and in header file) |
- make process was automated so that "make all" creates all configured target binaries |
(for ATmega8 and ATmega88) |
- binary files for MLAB hardware is in bin directory |
- hardware configuration is this: |
XTAL 12.0MHz |
USB D+ PD2/INT0 |
USB D- PD4 |
ISP_RES# PB2 |
ISP_MOSI PB3 |
ISP_MISO PB4 |
ISP_SCK PB5 |
GreenLED PC1 (active L) |
RedLedLED PC0 (active L) |
Slow SPI CLK PD0 (to GND) |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/Makefile |
---|
0,0 → 1,180 |
# |
# Makefile for usbasp |
# 20061119 Thomas Fischl original |
# 20061120 Hanns-Konrad Unger help: and TARGET=atmega48 added |
# 20140209 Milan Horkel added automatic built for more targets |
ALL_TARGETS=atmega8 atmega88 |
# Default target |
# -------------- |
ifndef $(TARGET) |
TARGET=atmega88 |
endif |
# Define target dependent constants |
# --------------------------------- |
ifeq ($(TARGET), atmega8) |
HFUSE=0xC9 |
LFUSE=0x9F |
endif |
ifeq ($(TARGET), atmega88) |
EFUSE=0xF9 |
HFUSE=0xDE |
LFUSE=0xD7 |
endif |
# ISP=bsd PORT=/dev/parport0 |
# ISP=ponyser PORT=/dev/ttyS1 |
# ISP=stk500 PORT=/dev/ttyS1 |
# ISP=usbasp PORT=/dev/usb/ttyUSB0 |
# ISP=stk500v2 PORT=/dev/ttyUSB0 |
ISP=usbasp |
PORT=/dev/usb/ttyUSB0 |
help: |
@echo "Usage: make same as make help" |
@echo " make help same as make" |
@echo " make all build HEX for all target CPUs" |
@echo " make hex create HEX for default target CPU" |
@echo " make clean remove redundant data" |
@echo " make disasm create listing" |
@echo " make flash upload HEX into flash (for default target CPU)" |
@echo " make fuses program fuses (for default target CPU)" |
@echo " make avrdude test avrdude" |
@echo "Current values:" |
@echo " TARGET=${TARGET}" |
@echo " LFUSE=${LFUSE}" |
@echo " HFUSE=${HFUSE}" |
@echo " CLOCK=12000000" |
@echo " ISP=${ISP}" |
@echo " PORT=${PORT}" |
COMPILE = avr-gcc -Wall -O2 -Iusbdrv -I. -mmcu=$(TARGET) # -DDEBUG_LEVEL=2 |
OBJECTS = usbdrv/usbdrv.o usbdrv/usbdrvasm.o usbdrv/oddebug.o isp.o clock.o tpi.o main.o |
.c.o: |
$(COMPILE) -c $< -o $@ |
#-Wa,-ahlms=$<.lst |
.S.o: |
$(COMPILE) -x assembler-with-cpp -c $< -o $@ |
# "-x assembler-with-cpp" should not be necessary since this is the default |
# file type for the .S (with capital S) extension. However, upper case |
# characters are not always preserved on Windows. To ensure WinAVR |
# compatibility define the file type manually. |
.c.s: |
$(COMPILE) -S $< -o $@ |
cleantmp: |
rm -f usbasp.lst usbasp.obj usbasp.cof usbasp.list usbasp.map usbasp.bin *.o main.s usbdrv/*.o |
clean: cleantmp |
rm -f usbasp_$(TARGET).hex usbasp_$(TARGET).eep.hex |
# file targets: |
usbasp.bin: $(OBJECTS) |
$(COMPILE) -o usbasp.bin $(OBJECTS) -Wl,-Map,usbasp.map |
usbasp.hex: usbasp_$(TARGET).hex |
usbasp_$(TARGET).hex: usbasp.bin |
rm -f usbasp_$(TARGET).hex usbasp_$(TARGET).eep.hex |
avr-objcopy -j .text -j .data -O ihex usbasp.bin $@ |
# ./checksize usbasp.bin |
# do the checksize script as our last action to allow successful compilation |
# on Windows with WinAVR where the Unix commands will fail. |
disasm: usbasp.bin |
avr-objdump -d usbasp.bin |
cpp: |
$(COMPILE) -E main.c |
flash: |
avrdude -c ${ISP} -p ${TARGET} -P ${PORT} -U flash:w:usbasp.hex |
fuses: |
avrdude -c ${ISP} -p ${TARGET} -P ${PORT} -u -U hfuse:w:$(HFUSE):m -U lfuse:w:$(LFUSE):m |
avrdude: |
avrdude -c ${ISP} -p ${TARGET} -P ${PORT} -v |
# Fuse atmega8 |
# ------------ |
# Fuse atmega8 high byte HFUSE: |
# 0xD9 = 1 1 0 1 1 0 0 1 = Factory Default Value |
# 0xC9 = 1 1 0 0 1 0 0 1 <-- BOOTRST (boot reset vector at 0x0000) |
# ^ ^ ^ ^ ^ ^ ^------ BOOTSZ0 |
# | | | | | +-------- BOOTSZ1 |
# | | | | + --------- EESAVE (don't preserve EEPROM over chip erase) |
# | | | +-------------- CKOPT (full output swing) |
# | | +---------------- SPIEN (allow serial programming) |
# | +------------------ WDTON (WDT not always on) |
# +-------------------- RSTDISBL (reset pin is enabled) |
# Fuse atmega8 low byte LFUSE: |
# 0xE1 = 1 1 1 0 0 0 0 1 = Factory Default Value |
# 0x9F = 1 0 0 1 1 1 1 1 |
# ^ ^ \ / \--+--/ |
# | | | +------- CKSEL 3..0 (external >8M crystal) |
# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) |
# | +------------------ BODEN (BrownOut Detector enabled) |
# +-------------------- BODLEVEL (2.7V) |
# |
# Fuse atmega88 |
# ------------- |
# Fuse atmega88 extended byte: |
# 0xF9 = 1 1 1 1 1 0 0 1 = Factory Default Value (default value is used) |
# 0xF9 = 1 1 1 1 1 0 0 1 <-- BOOTRST (select vetor) |
# \+/ |
# +----- BOOTSZ1..0 (Select Boot Size) |
# Fuse high byte: |
# 0xDF 1 1 0 1 1 1 1 1 = Factory Default Value (default value may be used) |
# 0xDE = 1 1 0 1 1 1 1 0 |
# ^ ^ ^ ^ ^ \-+-/ |
# | | | | | +------ BODLEVEL (1.7-2.0V) |
# | | | | +---------- EESAVE (don't preserve EEPROM over chip erase) |
# | | | +-------------- WDTON (WDT not always on) |
# | | +---------------- SPIEN (allow serial programming)!!! |
# | +------------------ DWEN (debug wire not enabled) |
# +-------------------- RSTDISBL (reset pin is not disabled) |
# Fuse low byte: |
# 0x62 0 1 1 0 0 0 1 0 = Factory Default Value (must be programmed to use xosc) |
# 0xD7 = 1 1 0 1 0 1 1 1 |
# ^ ^ \ / \--+--/ |
# | | | +------- CKSEL 3..0 (full swing xosc, BOD enabled) |
# | | +--------------- SUT 1..0 (startup timer - see CKSEL) |
# | +------------------ CKOUT (clock output is not enabled) |
# +-------------------- CLKDIV8 (clock divider is not enabled) |
SERIAL = `echo /dev/tty.USA19QI*` |
UISP = uisp -dprog=$S -dserial=$(SERIAL) -dpart=auto |
# The two lines above are for "uisp" and the AVR910 serial programmer connected |
# to a Keyspan USB to serial converter to a Mac running Mac OS X. |
# Choose your favorite programmer and interface. |
uisp: all |
$(UISP) --erase |
$(UISP) --upload --verify if=usbasp_$(TARGET).hex |
# Execute these steps for each target CPU |
# Do not remove empty line in this definition! |
define EXEC |
rm -f usbasp_$(1).hex |
make TARGET=$(1) cleantmp |
make TARGET=$(1) usbasp_$(1).hex |
endef |
all: |
@$(foreach III,$(ALL_TARGETS),$(call EXEC,$(III))) |
@make cleantmp |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/bin/test_firmware.bat |
---|
0,0 → 1,8 |
rem Test if programmer is working |
rem |
rem Fuses: |
rem CPU EFUSE HFUSE LFUSE |
rem ATmega8 C9 9F |
rem ATmega88 F9 DE D7 |
rem |
avrdude -c usbasp -p atmega88 -F |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/bin/usbasp_atmega8.hex |
---|
0,0 → 1,297 |
:100000003BC0A6C154C053C052C051C050C04FC025 |
:100010004EC04DC04CC04BC04AC049C048C047C08C |
:1000200046C045C044C0040309041C0377007700A0 |
:1000300077002E00660069007300630068006C00A2 |
:100040002E00640065000E0355005300420061005D |
:100050007300700012011001FF000008C016DC05DB |
:1000600004010102000109021200010100801909C6 |
:10007000040000000000000011241FBECFE5D4E002 |
:10008000DEBFCDBF10E0A0E6B0E0E8E6F2E102C0DE |
:1000900005900D92A236B107D9F710E0A2E6B0E0C4 |
:1000A00001C01D92AA3AB107E1F766D5DBC8A8CF17 |
:1000B00085B7826085BF8BB780648BBF08951F931F |
:1000C000CF93DF9360918800635067FD13C08091E8 |
:1000D0008500CCE0D0E0C81BD109C457DF4F809128 |
:1000E00084008D3209F462C08091620087FD84C073 |
:1000F000109288008091600084FF4AC06091610086 |
:100100006F3F09F445C0693070F168506093610039 |
:100110008091780098E889278093780068E0809142 |
:10012000620087FD8BC0209186003091870086FF9A |
:100130006DC0A9E7B0E080E090E0F901E80FF91F99 |
:10014000E491ED9301966817C1F76150862F90E016 |
:100150006F5F0196820F931F9093870080938600B4 |
:10016000162F1C5F0BC0109261008091780098E8F8 |
:10017000892780937800662391F614E089E790E060 |
:10018000E3D01C3019F08FEF809361001093600072 |
:1001900094E180B3847131F49150D9F710928900C1 |
:1001A00010928300DF91CF911F910895683009F07C |
:1001B0009FCF83EC809378008AE580936000109253 |
:1001C00062008881807659F59A8110928100898138 |
:1001D000882309F043C01092820022E081E890E079 |
:1001E00090938700809386008F81882319F49E81E5 |
:1001F000921708F1922F1FC0CE01D6D48F3F51F134 |
:10020000882309F475CF1092610072CF962FD9011F |
:10021000E9E7F0E08D9181939150E1F796CFCE011F |
:100220000BD6282F8F3F01F7888187FD25C09FEFD0 |
:1002300080E880936200909361005ACF89E790E054 |
:1002400089D5682F893008F453C08FEF80936100FF |
:100250001EE19CCF8EE1809360004ACF853071F023 |
:10026000863091F0883031F1893061F18A3031F196 |
:1002700020E081E890E0B4CF9E81DACF90938900AE |
:1002800020E081E890E0ACCF8B81813049F1823071 |
:10029000F9F0833029F020E080E480936200A4CF5D |
:1002A000992349F586E290E0909387008093860039 |
:1002B00024E0F2CF21E08BE890E092CF21E081E8CA |
:1002C00090E08ECF90938B0020E081E890E088CF83 |
:1002D00086E690E0909387008093860022E1DCCF51 |
:1002E00084E590E0909387008093860022E1D4CF4C |
:1002F000182F1C5F43CF913051F0923061F686E4A5 |
:1003000090E090938700809386002EE0C5CF8AE22C |
:1003100090E090938700809386002CE1BDCFA82FBA |
:10032000B92F80E090E041E050EA609530E009C0EC |
:100330002D9182279795879510F084279527305E19 |
:10034000C8F36F5FA8F30895EADF8D939D93089536 |
:10035000CF93CFB7CF93C395849BE9F7849B09C014 |
:10036000849B07C0849B05C0849B03C0849B01C001 |
:10037000A1C0DF93C0918500DD27C457DF4F849B68 |
:1003800002C0DF91EBCF2F930F931F9300B32FEF9A |
:1003900004FB20F94F933F9310B34FEF012704FB69 |
:1003A00021F93BE031C04E7F012F10B3216028C0FE |
:1003B000102F4D7F2260000000B329C04B7F2460C6 |
:1003C000012F000010B32BC010B3477F28602AC054 |
:1003D0004F7E00B320612CC04F7D10B320622FC030 |
:1003E0004F7B00B3206432C0422700B349934FEFE4 |
:1003F0000000102714FB20F910B31471C9F1297FF4 |
:1004000091F2012704FB21F900B3237F89F23150D7 |
:1004100058F1102714FB22F910B3277E79F2012737 |
:1004200004FB23F92F7C81F200B3102714FB24F97D |
:100430002F7971F200C010B3012704FB25F92F7347 |
:1004400059F200C000B3102714FB26F9223040F205 |
:1004500000C010B3012704FB27F9243028F64F779A |
:10046000206810B30000F9CF10E41ABF002717C0AE |
:100470003B503195C31BD04010E41ABF0881033CA8 |
:10048000E9F00B34D9F0209183001981110F121378 |
:10049000EDCF093641F10D3211F0013E39F70093ED |
:1004A0008A003F914F911F910F912F91DF91CAB711 |
:1004B000C6FD51CFCF91CFBFCF91189520918A0023 |
:1004C000222379F310918800112311F5343012F1B1 |
:1004D0003093880020938400109185003BE0311B0D |
:1004E0003093850017C00091880001308CF40AE534 |
:1004F0003091600034FD10C000936000C8E7D0E088 |
:100500000FC02795A8F45150A9F4220F0000F9CF8D |
:100510004AE503C042ED01C0432FC4E1D0E032E020 |
:1005200011B31461949A11BB02B320E414E15F93F8 |
:10053000012756E002BB279520F4515021F4220FE9 |
:10054000F9CF012756E000003B5A02BBD0F22795B5 |
:1005500028F4515029F4220F0000F9CF012756E06A |
:10056000279502BB20F4515021F4220FF9CF012727 |
:1005700056E02991332302BB21F60B7E10918900AE |
:10058000110FC651D04002BB11F01093830010E44C |
:100590001ABF006111B31B7E402F4B7E5F9100C0DC |
:1005A00000C002BB11BB42BB7CCF8091A5008DB9BE |
:1005B0008091A2008EB90895282F8823A1F0883059 |
:1005C00008F042C08EE793E09093A4008093A300CC |
:1005D000243019F12530B8F0263099F1263068F131 |
:1005E0002730F9F008958FE993E09093A400809369 |
:1005F000A30081E08093A70082E58093A50081E0BD |
:100600008093A20008952230A1F0233070F42130AD |
:1006100049F780EC8093A700089588E18093A700B4 |
:10062000089583E08093A700089580E38093A70056 |
:10063000089580E68093A70008958CE08093A7003A |
:1006400008952093A70008958FE993E09093A40064 |
:100650008093A3001092A20081E08093A70029302C |
:1006600041F02A3050F4283039F683E58093A50014 |
:10067000089582E58093A50008952B3029F02C3051 |
:1006800009F0BACF8093A20081E58093A500089578 |
:1006900022B79091A70082B7821B8917E0F30895D3 |
:1006A00087B38C6287BBC298C59892B72091A70088 |
:1006B00082B7891B8217E0F3C29A92B782B7891B6F |
:1006C0008217E0F3C2988091A3009091A4008F5903 |
:1006D000934019F01092A60008958091A5008DB95D |
:1006E0008091A2008EB91092A600089587B3837DF1 |
:1006F00087BB88B3837D88BB1DB80895582F209190 |
:10070000A70040E030E057FD16C0C398440FB499ED |
:100710004F5FC59A92B782B7891B8217E0F3C598DD |
:1007200092B782B7891B8217E0F33F5F383029F018 |
:10073000550F57FFEACFC39AE9CF842F08958FB999 |
:10074000779BFECF8FB108950F931F930FE1E09138 |
:10075000A300F091A4008CEA0995E091A300F09128 |
:10076000A40083E50995E091A300F091A40080E046 |
:100770000995182FE091A300F091A40080E009955D |
:10078000133561F11DB822B79091A70082B7821B83 |
:100790008917E0F3C29A22B782B7821B8917E0F368 |
:1007A000C29822B782B7821B8917E0F3E091A300B9 |
:1007B000F091A40083E0EF39F80721F0002351F015 |
:1007C0000150C9CF8091A5008DB98091A2008EB94A |
:1007D0000023B1F781E01F910F91089580E01F91F0 |
:1007E0000F9108959B01AC0181E15695479537958E |
:1007F00027958A95D1F78091A6008217D9F020938A |
:10080000A600E091A300F091A4008DE40995E09189 |
:10081000A300F091A40080E00995E091A300F0917D |
:10082000A4008091A6000995E091A300F091A40096 |
:1008300080E009950895EF92FF920F931F937B013B |
:100840008C01D0DF8E2D8170880F880F880FE0918A |
:10085000A300F091A40080620995D801C70129E0A6 |
:10086000B695A795979587952A95D1F7E091A3001E |
:10087000F091A400099516950795F794E794E091F7 |
:10088000A300F091A4008E2D0995E091A300F091B2 |
:10089000A40080E009951F910F91FF90EF900895BB |
:1008A0000F931F938C01E091A300F091A40080EAC4 |
:1008B0000995E091A300F091A400812F0995E091A2 |
:1008C000A300F091A400802F0995E091A300F0917E |
:1008D000A40080E009951F910F910895FF920F9356 |
:1008E0001F938C01F62EE091A300F091A40080EC00 |
:1008F0000995E091A300F091A400812F0995E09162 |
:10090000A300F091A400802F0995E091A300F0913D |
:10091000A4008F2D09958EE1B9D080E01F910F9131 |
:10092000FF900895CF92DF92EF92FF920F931F9363 |
:100930006B017C01142F56DFE091A300F091A4001D |
:100940008CE40995D701C60149E0B695A79597951E |
:1009500087954A95D1F7E091A300F091A4000995FD |
:10096000D701C601B695A79597958795E091A30005 |
:10097000F091A4000995E091A300F091A40080E01B |
:1009800009951F3FF1F012B70EE1C701B60153DF21 |
:100990008F3F79F482B7811B8D33B8F312B70150C2 |
:1009A000A1F781E01F910F91FF90EF90DF90CF9022 |
:1009B000089580E01F910F91FF90EF90DF90CF900E |
:1009C00008958FE063D080E01F910F91FF90EF902A |
:1009D000DF90CF900895CF92DF92EF92FF920F9326 |
:1009E0001F936B017C01042F122FFCDE8C2D817074 |
:1009F000880F880F880FE091A300F091A400806415 |
:100A00000995D701C60169E0B695A7959795879591 |
:100A10006A95D1F7E091A300F091A4000995D70160 |
:100A2000C601B695A79597958795E091A300F0919B |
:100A3000A4000995E091A300F091A400802F0995EE |
:100A40001123C1F00F37F1F012B70EE1C701B60163 |
:100A5000F2DE8F3779F482B7811B8D33B8F312B78A |
:100A60000150A1F781E01F910F91FF90EF90DF906F |
:100A7000CF90089580E01F910F91FF90EF90DF904D |
:100A8000CF9008958FE002D080E0F5CF382F8823F3 |
:100A900049F020E092B782B7891B8C33E0F32F5FD7 |
:100AA0002317C0F30895BD9ABB98C39A50E217D09C |
:100AB0005A95E9F70895AC0188E605D0842F03D054 |
:100AC00089E601D0852F0FD028E030E0382780FB61 |
:100AD000869506D02A95D1F730FB02D000D06894D5 |
:100AE000BB98C39A16F0C398BB9AE091A800F09106 |
:100AF000A9003197F0F7C59AE6B3E3FBE091A800AF |
:100B0000F091A9003197F0F7C598089520ECE7DF40 |
:100B100046F42A95E1F780E02AE1E5DF2A95E9F736 |
:100B2000DECF28E030E0DBDF869587F938272A958D |
:100B3000D1F7D5DF27F9322772F3D1DFD0CFDB0130 |
:100B4000742FB9DF84E2BFDFE1DF8D937A95D1F7AF |
:100B50000895DB01742FAFDF83EFB5DF8DE1B3DFE5 |
:100B600084E6B1DF8D91AFDF82E7ADDFCFDF807844 |
:100B7000D9F77A9589F7089593E098BB8CE385BB04 |
:100B80008AEE82BBA09AA19AA998A89A8898909A6E |
:100B900081B3846181BB81B38B7E81BB93BF88DAD3 |
:100BA00078948DDA8CDAFDCFFF920F931F93CF9359 |
:100BB000DF93082F792FF62E40916300413069F0C2 |
:100BC000443059F0463009F492C01FEF812FDF9175 |
:100BD000CF911F910F91FF900895FF2009F4B2C0AB |
:100BE000802F972F9C01E90110E053C08091740081 |
:100BF00090917500892B09F058C060917000709138 |
:100C000071008091720090917300488121E0E3DED1 |
:100C100080916400909165000197909365008093A6 |
:100C20006400892BD9F4109263008091760081FFD3 |
:100C30003AC08091770090E0209174003091750067 |
:100C40008217930781F1609170007091710080911B |
:100C5000720090917300488165DE11E08091700010 |
:100C600090917100A0917200B09173000196A11D46 |
:100C7000B11D8093700090937100A0937200B093A7 |
:100C8000730021969E01201B2F1508F09FCF4091E5 |
:100C90006300413009F4AACF8091700090917100F7 |
:100CA00068811CDEB5CF11E0D9CF609170007091E2 |
:100CB00071008091720090917300488120E08BDE7A |
:100CC00080917700815080937700882309F0A0CF2E |
:100CD000609170007091710080917200909173002A |
:100CE000488120DE809174008093770091CF8091BD |
:100CF000700090917100602F4F2D2BDF809170005C |
:100D000090917100A0917200B09173008F0D911DB0 |
:100D1000A11DB11D8093700090937100A09372008B |
:100D2000B093730080916400909165008F199109D0 |
:100D30009093650080936400892B21F410926300E6 |
:100D400011E044CF10E0812FDF91CF911F910F91DF |
:100D5000FF9008950F931F93CF93DF93082F792F60 |
:100D6000162F40916300842F8250823050F045301E |
:100D700009F446C01FEF812FDF91CF911F910F9192 |
:100D800008954530E9F1662399F1802F9C01E9012E |
:100D900020C0809170009091710082DD88838091E5 |
:100DA000700090917100A0917200B0917300019653 |
:100DB000A11DB11D8093700090937100A0937200EB |
:100DC000B093730021969E01201B211778F4409167 |
:100DD00063004230F1F66091700070917100809173 |
:100DE00072009091730027DD8883D9CF183018F6F0 |
:100DF00010926300812FDF91CF911F910F91089581 |
:100E00008091700090917100602F412F98DE809149 |
:100E1000700090917100A0917200B0917300810FE9 |
:100E2000911DA11DB11D8093700090937100A0933E |
:100E30007200B09373009FCF0F931F93CF93DF93F4 |
:100E40008C01DC0111968C91813009F44EC0823006 |
:100E500009F4E7C0833009F455C0843009F4B5C003 |
:100E6000873009F486C0853009F45AC1863009F408 |
:100E700010C1883009F4DBC0893009F458C18A30C8 |
:100E800009F469C18B3009F49CC18C3009F4B7C1F5 |
:100E90008D3009F4CBC18E3009F4CFC18F3009F009 |
:100EA00065C1F801938180E0228130E0822B932B91 |
:100EB000AA2797FDA095BA2F809370009093710098 |
:100EC000A0937200B0937300978180E0268130E098 |
:100ED000822B932B909365008093640085E0809330 |
:100EE00063008FEFC8E6D0E038C0809B3FC08091A0 |
:100EF000660062DB10926700A898D2DB80E0C8E64B |
:100F0000D0E02BC0E091A300F091A400D80112968C |
:100F10008C910995C8E6D0E080936800E091A30029 |
:100F2000F091A400D80113968C91099580936900E3 |
:100F3000E091A300F091A400D80114968C9109953A |
:100F400080936A00E091A300F091A400D801159667 |
:100F50008C91099580936B0084E0D0938700C093B7 |
:100F60008600DF91CF911F910F91089585E024DBDA |
:100F7000C1CF80916700882399F4F801938180E0C4 |
:100F8000228130E0822B932BAA2797FDA095BA2FC0 |
:100F90008093700090937100A0937200B0937300DF |
:100FA000D80117969C91179780E016962C9130E007 |
:100FB000822B932B909365008093640083E0809351 |
:100FC00063008FEFC8E6D0E0C8CF80916700882328 |
:100FD00099F4F801938180E0228130E0822B932BF9 |
:100FE000AA2797FDA095BA2F809370009093710067 |
:100FF000A0937200B0937300D80117969C91179735 |
:1010000080E016962C9130E0822B932B9093650014 |
:101010008093640082E0809363008FEFC8E6D0E0A5 |
:101020009CCF64DBA89A80E0C8E6D0E096CF8091A0 |
:1010300067008823B1F4D80113969C91139780E040 |
:1010400012962C9130E0822B932BAA2797FDA09526 |
:10105000BA2F8093700090937100A0937200B093A8 |
:101060007300109275001092740010927600F801CF |
:10107000978180E0268130E0822B932B909365004E |
:101080008093640084E0809363008FEFC8E6D0E033 |
:1010900064CF80916700882399F4F801938180E000 |
:1010A000228130E0822B932BAA2797FDA095BA2F9F |
:1010B0008093700090937100A0937200B0937300BE |
:1010C000D80114968C91149715969C91292F2F7006 |
:1010D00020937600492F50E0407F50704295529502 |
:1010E000507F5427407F5427480F511D509375005F |
:1010F0004093740020FF02C040937700F80197816D |
:1011000080E0268130E0822B932B909365008093C2 |
:10111000640081E0809363008FEFC8E6D0E01DCFCC |
:1011200013DBC8E6D0E08093680081E016CF81E051 |
:1011300080936700F80182819381A481B5818093B7 |
:10114000700090937100A0937200B093730080E0E0 |
:10115000C8E6D0E002CFD80112968C918093660049 |
:10116000C8E6D0E01092680081E0F7CE803109F047 |
:1011700040C0D80113969C91139780E012962C9151 |
:1011800030E0822B932BAA2797FDA095BA2F80934E |
:10119000700090937100A0937200B0937300F801F7 |
:1011A000978180E0268130E0822B932B909365001D |
:1011B0008093640086E0809363008FEFC8E6D0E000 |
:1011C000CCCEF801938180E0228130E0822B932BFA |
:1011D0009093A9008093A800C29ABA9A83E056DC43 |
:1011E000C298A89880E152DC5EDC80E0C8E6D0E0DE |
:1011F000B4CE8F3751F180E0C8E6D0E0AECE80ECBF |
:1012000062DC80E060DC8AE041DCC29A85E03EDCA2 |
:10121000C29885E03BDC87B3837D87BB88B3837D41 |
:1012200088BBA89A80E0C8E6D0E097CE6FDCC8E61D |
:10123000D0E08093680081E090CED80112968C9126 |
:1012400042DC80E0C8E6D0E088CEC8E6D0E081E0AD |
:10125000809368001092690010926A0010926B00EF |
:0812600084E07BCEF894FFCF7F |
:021268005AFF2B |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/bin/usbasp_atmega88.hex |
---|
0,0 → 1,298 |
:1000000042C0ADC15BC05AC059C058C057C056C0ED |
:1000100055C054C053C052C051C050C04FC04EC054 |
:100020004DC04CC04BC04AC049C048C047C046C084 |
:1000300045C044C0040309041C037700770077001F |
:100040002E00660069007300630068006C002E00DB |
:10005000640065000E035500530042006100730008 |
:10006000700012011001FF000008C016DC05040139 |
:1000700001020001090212000101008019090400B7 |
:1000800000000000000011241FBECFEFD4E0DEBF4F |
:10009000CDBF11E0A0E0B1E0E8E7F2E102C00590D9 |
:1000A0000D92A230B107D9F711E0A2E0B1E001C092 |
:1000B0001D92AA34B107E1F767D5DCC8A1CFE9E604 |
:1000C000F0E0808182608083E89A08951F93CF9347 |
:1000D000DF9360912801635067FD13C08091250173 |
:1000E000CCE0D0E0C81BD109C45DDE4F8091240173 |
:1000F0008D3209F462C08091020187FD84C01092A4 |
:1001000028018091000184FF4AC0609101016F3F86 |
:1001100009F445C0693070F1685060930101809125 |
:10012000180198E889278093180168E080910201FE |
:1001300087FD8BC0209126013091270186FF6DC07D |
:10014000A9E1B1E080E090E0F901E80FF91FE49146 |
:10015000ED9301966817C1F76150862F90E06F5FAD |
:100160000196820F931F9093270180932601162FEB |
:100170001C5F0BC0109201018091180198E889273B |
:1001800080931801662391F614E089E191E0E3D0B1 |
:100190001C3019F08FEF809301011093000194E15E |
:1001A00089B1847131F49150D9F7109229011092DC |
:1001B0002301DF91CF911F910895683009F09FCFFF |
:1001C00083EC809318018AE580930001109202016C |
:1001D0008881807659F59A8110922101898188233E |
:1001E00009F043C01092220122E081E291E0909355 |
:1001F0002701809326018F81882319F49E8192170D |
:1002000008F1922F1FC0CE01D7D48F3F51F1882320 |
:1002100009F475CF1092010172CFD901962FE9E14F |
:10022000F1E08D9181939150E1F796CFCE010CD6FC |
:10023000282F8F3F01F7888187FD25C09FEF80E839 |
:1002400080930201909301015ACF89E191E08AD510 |
:10025000682F893008F453C08FEF809301011EE1AD |
:100260009CCF8EE1809300014ACF853071F08630BB |
:1002700091F0883031F1893061F18A3031F120E03C |
:1002800081E291E0B4CF9E81DACF9093290120E002 |
:1002900081E291E0ACCF8B81813049F18230F9F07D |
:1002A000833029F020E080E480930201A4CF9923D9 |
:1002B00049F584E390E0909327018093260124E0A0 |
:1002C000F2CF21E08BE291E092CF21E081E291E058 |
:1002D0008ECF90932B0120E081E291E088CF84E7DC |
:1002E00090E0909327018093260122E1DCCF82E603 |
:1002F00090E0909327018093260122E1D4CF182F1C |
:100300001C5F43CF913051F0923061F684E590E06C |
:1003100090932701809326012EE0C5CF88E390E0DB |
:1003200090932701809326012CE1BDCFA82FB92FF0 |
:1003300080E090E041E050EA609530E009C02D9106 |
:1003400082279795879510F084279527305EC8F30C |
:100350006F5FA8F30895EADF8D939D930895CF937F |
:10036000CFB7CF93C3954C9BE9F74C9B09C04C9BEF |
:1003700007C04C9B05C04C9B03C04C9B01C0A1C057 |
:10038000DF93C0912501DD27C45DDE4F4C9B02C089 |
:10039000DF91EBCF2F930F931F9309B12FEF04FB46 |
:1003A00020F94F933F9319B14FEF012704FB21F937 |
:1003B0003BE031C04E7F012F19B1216028C0102FC2 |
:1003C0004D7F2260000009B129C04B7F2460012FBE |
:1003D000000019B12BC019B1477F28602AC04F7E99 |
:1003E00009B120612CC04F7D19B120622FC04F7B15 |
:1003F00009B1206432C0422709B149934FEF000090 |
:10040000102714FB20F919B11471C9F1297F91F259 |
:10041000012704FB21F909B1237F89F2315058F1FA |
:10042000102714FB22F919B1277E79F2012704FB6A |
:1004300023F92F7C81F209B1102714FB24F92F79BD |
:1004400071F200C019B1012704FB25F92F7359F28D |
:1004500000C009B1102714FB26F9223040F200C079 |
:1004600019B1012704FB27F9243028F64F772068BB |
:1004700019B10000F9CF11E01CBB002717C03B5099 |
:100480003195C31BD04011E01CBB0881033CE9F04F |
:100490000B34D9F0209123011981110F1213EDCFE4 |
:1004A000093641F10D3211F0013E39F700932A016E |
:1004B0003F914F911F910F912F91DF91CCB3C0FDD0 |
:1004C00051CFCF91CFBFCF91189520912A012223F0 |
:1004D00079F310912801112311F5343012F1309382 |
:1004E000280120932401109125013BE0311B30931A |
:1004F000250117C00091280101308CF40AE53091E4 |
:10050000000134FD10C000930001C8E1D1E00FC02C |
:100510002795A8F45150A9F4220F0000F9CF4AE51D |
:1005200003C042ED01C0432FC4E1D0E032E01AB174 |
:1005300014615C9A1AB90BB120E414E15F930127AE |
:1005400056E00BB9279520F4515021F4220FF9CF32 |
:10055000012756E000003B5A0BB9D0F2279528F44A |
:10056000515029F4220F0000F9CF012756E02795BA |
:100570000BB920F4515021F4220FF9CF012756E096 |
:10058000299133230BB921F60B7E10912901110F0C |
:10059000C651D0400BB911F01093230111E01CBBE0 |
:1005A00000611AB11B7E402F4B7E5F9100C000C0DE |
:1005B0000BB91AB94BB97CCF809145018CBD8091A4 |
:1005C00042018DBD0895282F8823A1F0883008F0BE |
:1005D00042C085E893E09093440180934301243026 |
:1005E00019F12530B8F0263099F1263068F127301E |
:1005F000F9F0089586EA93E09093440180934301D3 |
:1006000081E08093470182E58093450181E08093FA |
:10061000420108952230A1F0233070F4213049F7CF |
:1006200080EC80934701089588E180934701089505 |
:1006300083E080934701089580E380934701089504 |
:1006400080E68093470108958CE0809347010895E8 |
:1006500020934701089586EA93E0909344018093A4 |
:1006600043011092420181E080934701293041F01B |
:100670002A3050F4283039F683E5809345010895F7 |
:1006800082E58093450108952B3029F02C3009F044 |
:10069000BACF8093420181E580934501089526B544 |
:1006A0009091470186B5821B8917E0F3089584B1C4 |
:1006B0008C6284B92A982D9896B52091470186B509 |
:1006C000891B8217E0F32A9A96B586B5891B821793 |
:1006D000E0F32A988091430190914401865A934017 |
:1006E00019F0109246010895809145018CBD8091CA |
:1006F00042018DBD10924601089584B1837D84B975 |
:1007000085B1837D85B91CBC0895582F2091470180 |
:1007100040E030E057FD16C02B98440F1C994F5F06 |
:100720002D9A96B586B5891B8217E0F32D9896B55C |
:1007300086B5891B8217E0F33F5F383029F0550FEB |
:1007400057FFEACF2B9AE9CF842F08958EBD0DB4C1 |
:1007500007FEFDCF8EB508950F931F930FE1E09133 |
:100760004301F09144018CEA0995E0914301F09135 |
:10077000440183E50995E0914301F091440180E053 |
:100780000995182FE0914301F091440180E009950B |
:10079000133561F11CBC26B59091470186B5821BCB |
:1007A0008917E0F32A9A26B586B5821B8917E0F3EC |
:1007B0002A9826B586B5821B8917E0F3E09143019C |
:1007C000F091440183E0E63AF80721F0002351F06C |
:1007D0000150C9CF809145018CBD809142018DBDF2 |
:1007E0000023B1F781E01F910F91089580E01F91E0 |
:1007F0000F9108959B01AC0181E15695479537957E |
:1008000027958A95D1F7809146018217D9F02093D8 |
:100810004601E0914301F09144018DE40995E09196 |
:100820004301F091440180E00995E0914301F0918A |
:100830004401809146010995E0914301F091440102 |
:1008400080E009950895EF92FF920F931F937B012B |
:100850008C01D0DF8E2D8170880F880F880FE0917A |
:100860004301F091440180620995D801C70129E054 |
:10087000B695A795979587952A95D1F7E09143016D |
:10088000F0914401099516950795F794E794E09146 |
:100890004301F09144018E2D0995E0914301F091BF |
:1008A000440180E009951F910F91FF90EF9008950A |
:1008B0000F931F938C01E0914301F091440180EA72 |
:1008C0000995E0914301F0914401812F0995E09150 |
:1008D0004301F0914401802F0995E0914301F0918B |
:1008E000440180E009951F910F910895FF920F93A5 |
:1008F0001F938C01F62EE0914301F091440180ECAE |
:100900000995E0914301F0914401812F0995E0910F |
:100910004301F0914401802F0995E0914301F0914A |
:1009200044018F2D09958EE1B9D080E01F910F9180 |
:10093000FF900895CF92DF92EF92FF920F931F9353 |
:100940006B017C01142F56DFE0914301F0914401CB |
:100950008CE40995D701C60149E0B695A79597950E |
:1009600087954A95D1F7E0914301F09144010995AB |
:10097000D701C601B695A79597958795E091430154 |
:10098000F09144010995E0914301F091440180E028 |
:1009900009951F3FF1F016B50EE1C701B60153DF0F |
:1009A0008F3F79F486B5811B8D33B8F316B50150AE |
:1009B000A1F781E01F910F91FF90EF90DF90CF9012 |
:1009C000089580E01F910F91FF90EF90DF90CF90FE |
:1009D00008958FE063D080E01F910F91FF90EF901A |
:1009E000DF90CF900895CF92DF92EF92FF920F9316 |
:1009F0001F936B017C01042F122FFCDE8C2D817064 |
:100A0000880F880F880FE0914301F09144018064C2 |
:100A10000995D701C60169E0B695A7959795879581 |
:100A20006A95D1F7E0914301F09144010995D7010E |
:100A3000C601B695A79597958795E0914301F091EA |
:100A400044010995E0914301F0914401802F0995FB |
:100A50001123C1F00F37F1F016B50EE1C701B60151 |
:100A6000F2DE8F3779F486B5811B8D33B8F316B576 |
:100A70000150A1F781E01F910F91FF90EF90DF905F |
:100A8000CF90089580E01F910F91FF90EF90DF903D |
:100A9000CF9008958FE002D080E0F5CF382F8823E3 |
:100AA00049F020E096B586B5891B8C33E0F32F5FC3 |
:100AB0002317C0F30895259A23982B9A50E217D054 |
:100AC0005A95E9F70895AC0188E605D0842F03D044 |
:100AD00089E601D0852F0FD028E030E0382780FB51 |
:100AE000869506D02A95D1F730FB02D000D06894C5 |
:100AF00023982B9A16F02B98239AE0914801F091B5 |
:100B000049013197F0F72D9AE3B1E3FBE0914801F9 |
:100B1000F09149013197F0F72D98089520ECE7DF27 |
:100B200046F42A95E1F780E02AE1E5DF2A95E9F726 |
:100B3000DECF28E030E0DBDF869587F938272A957D |
:100B4000D1F7D5DF27F9322772F3D1DFD0CFDB0120 |
:100B5000742FB9DF84E2BFDFE1DF8D937A95D1F79F |
:100B60000895DB01742FAFDF83EFB5DF8DE1B3DFD5 |
:100B700084E6B1DF8D91AFDF82E7ADDFCFDF807834 |
:100B8000D9F77A9589F7089593E095B98CE388B9F8 |
:100B90008AEE8BB9389A399A4198409A5098589A67 |
:100BA0008AB184618AB98AB18B7E8AB995BD87DAA8 |
:100BB00078948CDA8BDAFDCFFF920F931F93CF934B |
:100BC000DF93082F792FF62E40910301413069F011 |
:100BD000443059F0463009F492C01FEF812FDF9165 |
:100BE000CF911F910F91FF900895FF2009F4B2C09B |
:100BF000802F972F9C01E90110E053C080911401D0 |
:100C000090911501892B09F058C0609110017091E5 |
:100C100011018091120190911301488121E0E3DEDE |
:100C200080910401909105010197909305018093B3 |
:100C30000401892BD9F4109203018091160181FFE0 |
:100C40003AC08091170190E0209114013091150174 |
:100C50008217930781F160911001709111018091C9 |
:100C6000120190911301488165DE11E0809110011D |
:100C700090911101A0911201B09113010196A11D53 |
:100C8000B11D8093100190931101A0931201B093B4 |
:100C9000130121969E01201B2F1508F09FCF409134 |
:100CA0000301413009F4AACF809110019091110104 |
:100CB00068811CDEB5CF11E0D9CF60911001709131 |
:100CC00011018091120190911301488120E08BDE87 |
:100CD00080911701815080931701882309F0A0CFDC |
:100CE0006091100170911101809112019091130196 |
:100CF000488120DE809114018093170191CF80916B |
:100D0000100190911101602F4F2D2BDF8091100168 |
:100D100090911101A0911201B09113018F0D911DBD |
:100D2000A11DB11D8093100190931101A093120198 |
:100D3000B093130180910401909105018F199109DD |
:100D40009093050180930401892B21F410920301F3 |
:100D500011E044CF10E0812FDF91CF911F910F91CF |
:100D6000FF9008950F931F93CF93DF93082F792F50 |
:100D7000162F40910301842F8250823050F045306D |
:100D800009F446C01FEF812FDF91CF911F910F9182 |
:100D900008954530E9F1662399F1802F9C01E9011E |
:100DA00020C0809110019091110182DD8883809193 |
:100DB000100190911101A0911201B09113010196BF |
:100DC000A11DB11D8093100190931101A0931201F8 |
:100DD000B093130121969E01201B211778F44091B6 |
:100DE00003014230F1F66091100170911101809180 |
:100DF00012019091130127DD8883D9CF183018F69E |
:100E000010920301812FDF91CF911F910F910895CF |
:100E10008091100190911101602F412F98DE8091F7 |
:100E2000100190911101A0911201B0911301810F55 |
:100E3000911DA11DB11D8093100190931101A093EC |
:100E40001201B09313019FCF0F931F93CF93DF93A2 |
:100E50008C01DC0111968C91813009F44EC08230F6 |
:100E600009F4E7C0833009F455C0843009F4B5C0F3 |
:100E7000873009F486C0853009F45AC1863009F4F8 |
:100E800010C1883009F4DBC0893009F458C18A30B8 |
:100E900009F469C18B3009F49CC18C3009F4B7C1E5 |
:100EA0008D3009F4CBC18E3009F4CFC18F3009F0F9 |
:100EB00065C1F801938180E0228130E0822B932B81 |
:100EC000AA2797FDA095BA2F809310019093110146 |
:100ED000A0931201B0931301978180E0268130E046 |
:100EE000822B932B909305018093040185E08093DE |
:100EF00003018FEFC8E0D1E038C0489B3FC080912C |
:100F0000060161DB109207014098D1DB80E0C8E068 |
:100F1000D1E02BC0E0914301F0914401D801129639 |
:100F20008C910995C8E0D1E080930801E0914301DC |
:100F3000F0914401D80113968C9109958093090191 |
:100F4000E0914301F0914401D80114968C910995E8 |
:100F500080930A01E0914301F0914401D801159674 |
:100F60008C91099580930B0184E0D0932701C09365 |
:100F70002601DF91CF911F910F91089585E023DB2A |
:100F8000C1CF80910701882399F4F801938180E013 |
:100F9000228130E0822B932BAA2797FDA095BA2FB0 |
:100FA0008093100190931101A0931201B09313014B |
:100FB000D80117969C91179780E016962C9130E0F7 |
:100FC000822B932B909305018093040183E08093FF |
:100FD00003018FEFC8E0D1E0C8CF809107018823DB |
:100FE00099F4F801938180E0228130E0822B932BE9 |
:100FF000AA2797FDA095BA2F809310019093110115 |
:10100000A0931201B0931301D80117969C911797E2 |
:1010100080E016962C9130E0822B932B9093050163 |
:101020008093040182E0809303018FEFC8E0D1E058 |
:101030009CCF63DB409A80E0C8E0D1E096CF8091FE |
:1010400007018823B1F4D80113969C91139780E08F |
:1010500012962C9130E0822B932BAA2797FDA09516 |
:10106000BA2F8093100190931101A0931201B093B5 |
:101070001301109215011092140110921601F8013B |
:10108000978180E0268130E0822B932B909305019D |
:101090008093040184E0809303018FEFC8E0D1E0E6 |
:1010A00064CF80910701882399F4F801938180E04F |
:1010B000228130E0822B932BAA2797FDA095BA2F8F |
:1010C0008093100190931101A0931201B09313012A |
:1010D000D80114968C91149715969C91292F2F70F6 |
:1010E00020931601492F50E0407F50704295529551 |
:1010F000507F5427407F5427480F511D50931501AE |
:101100004093140120FF02C040931701F80197811A |
:1011100080E0268130E0822B932B90930501809311 |
:10112000040181E0809303018FEFC8E0D1E01DCF7F |
:1011300013DBC8E0D1E08093080181E016CF81E0A5 |
:1011400080930701F80182819381A481B581809306 |
:10115000100190931101A0931201B093130180E04C |
:10116000C8E0D1E002CFD80112968C91809306019D |
:10117000C8E0D1E01092080181E0F7CE803109F09B |
:1011800040C0D80113969C91139780E012962C9141 |
:1011900030E0822B932BAA2797FDA095BA2F80933E |
:1011A000100190931101A0931201B0931301F80163 |
:1011B000978180E0268130E0822B932B909305016C |
:1011C0008093040186E0809303018FEFC8E0D1E0B3 |
:1011D000CCCEF801938180E0228130E0822B932BEA |
:1011E00090934901809348012A9A229A83E056DC21 |
:1011F0002A98409880E152DC5EDC80E0C8E0D1E0D3 |
:10120000B4CE8F3751F180E0C8E0D1E0AECE80ECB3 |
:1012100062DC80E060DC8AE041DC2A9A85E03EDC2A |
:101220002A9885E03BDC84B1837D84B985B1837DD8 |
:1012300085B9409A80E0C8E0D1E097CE6FDCC8E085 |
:10124000D1E08093080181E090CED80112968C9174 |
:1012500042DC80E0C8E0D1E088CEC8E0D1E081E0A7 |
:10126000809308011092090110920A0110920B015B |
:0812700084E07BCEF894FFCF6F |
:021278005AFF1B |
:00000001FF |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/original/usbasp.2011-05-28.tar.gz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/main.c |
---|
0,0 → 1,347 |
/* |
* USBasp - USB in-circuit programmer for Atmel AVR controllers |
* |
* Thomas Fischl <tfischl@gmx.de> |
* |
* License........: GNU GPL v2 (see Readme.txt) |
* Target.........: ATMega8 at 12 MHz |
* Creation Date..: 2005-02-20 |
* Last change....: 2009-02-28 |
* |
* PC2 SCK speed option. |
* GND -> slow (8khz SCK), |
* open -> software set speed (default is 375kHz SCK) |
* |
* 2014_02_09 miho@mlab.cz - cleaned code and defined IO port better, automatic compile prodcess for more target CPUs |
* |
*/ |
#include <avr/io.h> |
#include <avr/interrupt.h> |
#include <avr/pgmspace.h> |
#include <avr/wdt.h> |
#include "usbasp.h" |
#include "usbdrv.h" |
#include "isp.h" |
#include "clock.h" |
#include "tpi.h" |
#include "tpi_defs.h" |
static uchar replyBuffer[8]; |
static uchar prog_state = PROG_STATE_IDLE; |
static uchar prog_sck = USBASP_ISP_SCK_AUTO; |
static uchar prog_address_newmode = 0; |
static unsigned long prog_address; |
static unsigned int prog_nbytes = 0; |
static unsigned int prog_pagesize; |
static uchar prog_blockflags; |
static uchar prog_pagecounter; |
uchar usbFunctionSetup(uchar data[8]) { |
uchar len = 0; |
if (data[1] == USBASP_FUNC_CONNECT) { |
/* set SCK speed */ |
if ((PIN(CLKSW_PORT) & (1 << CLKSW_BIT)) == 0) { |
ispSetSCKOption(USBASP_ISP_SCK_8); |
} else { |
ispSetSCKOption(prog_sck); |
} |
/* set compatibility mode of address delivering */ |
prog_address_newmode = 0; |
ledRedOn(); |
ispConnect(); |
} else if (data[1] == USBASP_FUNC_DISCONNECT) { |
ispDisconnect(); |
ledRedOff(); |
} else if (data[1] == USBASP_FUNC_TRANSMIT) { |
replyBuffer[0] = ispTransmit(data[2]); |
replyBuffer[1] = ispTransmit(data[3]); |
replyBuffer[2] = ispTransmit(data[4]); |
replyBuffer[3] = ispTransmit(data[5]); |
len = 4; |
} else if (data[1] == USBASP_FUNC_READFLASH) { |
if (!prog_address_newmode) |
prog_address = (data[3] << 8) | data[2]; |
prog_nbytes = (data[7] << 8) | data[6]; |
prog_state = PROG_STATE_READFLASH; |
len = 0xff; /* multiple in */ |
} else if (data[1] == USBASP_FUNC_READEEPROM) { |
if (!prog_address_newmode) |
prog_address = (data[3] << 8) | data[2]; |
prog_nbytes = (data[7] << 8) | data[6]; |
prog_state = PROG_STATE_READEEPROM; |
len = 0xff; /* multiple in */ |
} else if (data[1] == USBASP_FUNC_ENABLEPROG) { |
replyBuffer[0] = ispEnterProgrammingMode(); |
len = 1; |
} else if (data[1] == USBASP_FUNC_WRITEFLASH) { |
if (!prog_address_newmode) |
prog_address = (data[3] << 8) | data[2]; |
prog_pagesize = data[4]; |
prog_blockflags = data[5] & 0x0F; |
prog_pagesize += (((unsigned int) data[5] & 0xF0) << 4); |
if (prog_blockflags & PROG_BLOCKFLAG_FIRST) { |
prog_pagecounter = prog_pagesize; |
} |
prog_nbytes = (data[7] << 8) | data[6]; |
prog_state = PROG_STATE_WRITEFLASH; |
len = 0xff; /* multiple out */ |
} else if (data[1] == USBASP_FUNC_WRITEEEPROM) { |
if (!prog_address_newmode) |
prog_address = (data[3] << 8) | data[2]; |
prog_pagesize = 0; |
prog_blockflags = 0; |
prog_nbytes = (data[7] << 8) | data[6]; |
prog_state = PROG_STATE_WRITEEEPROM; |
len = 0xff; /* multiple out */ |
} else if (data[1] == USBASP_FUNC_SETLONGADDRESS) { |
/* set new mode of address delivering (ignore address delivered in commands) */ |
prog_address_newmode = 1; |
/* set new address */ |
prog_address = *((unsigned long*) &data[2]); |
} else if (data[1] == USBASP_FUNC_SETISPSCK) { |
/* set sck option */ |
prog_sck = data[2]; |
replyBuffer[0] = 0; |
len = 1; |
} else if (data[1] == USBASP_FUNC_TPI_CONNECT) { |
tpi_dly_cnt = data[2] | (data[3] << 8); |
/* RST high */ |
ISP_OUT |= (1 << ISP_RST); |
ISP_DDR |= (1 << ISP_RST); |
clockWait(3); |
/* RST low */ |
ISP_OUT &= ~(1 << ISP_RST); |
ledRedOn(); |
clockWait(16); |
tpi_init(); |
} else if (data[1] == USBASP_FUNC_TPI_DISCONNECT) { |
tpi_send_byte(TPI_OP_SSTCS(TPISR)); |
tpi_send_byte(0); |
clockWait(10); |
/* pulse RST */ |
ISP_OUT |= (1 << ISP_RST); |
clockWait(5); |
ISP_OUT &= ~(1 << ISP_RST); |
clockWait(5); |
/* set all ISP pins inputs */ |
ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
/* switch pullups off */ |
ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
ledRedOff(); |
} else if (data[1] == USBASP_FUNC_TPI_RAWREAD) { |
replyBuffer[0] = tpi_recv_byte(); |
len = 1; |
} else if (data[1] == USBASP_FUNC_TPI_RAWWRITE) { |
tpi_send_byte(data[2]); |
} else if (data[1] == USBASP_FUNC_TPI_READBLOCK) { |
prog_address = (data[3] << 8) | data[2]; |
prog_nbytes = (data[7] << 8) | data[6]; |
prog_state = PROG_STATE_TPI_READ; |
len = 0xff; /* multiple in */ |
} else if (data[1] == USBASP_FUNC_TPI_WRITEBLOCK) { |
prog_address = (data[3] << 8) | data[2]; |
prog_nbytes = (data[7] << 8) | data[6]; |
prog_state = PROG_STATE_TPI_WRITE; |
len = 0xff; /* multiple out */ |
} else if (data[1] == USBASP_FUNC_GETCAPABILITIES) { |
replyBuffer[0] = USBASP_CAP_0_TPI; |
replyBuffer[1] = 0; |
replyBuffer[2] = 0; |
replyBuffer[3] = 0; |
len = 4; |
} |
usbMsgPtr = replyBuffer; |
return len; |
} |
uchar usbFunctionRead(uchar *data, uchar len) { |
uchar i; |
/* check if programmer is in correct read state */ |
if ((prog_state != PROG_STATE_READFLASH) && (prog_state |
!= PROG_STATE_READEEPROM) && (prog_state != PROG_STATE_TPI_READ)) { |
return 0xff; |
} |
/* fill packet TPI mode */ |
if(prog_state == PROG_STATE_TPI_READ) |
{ |
tpi_read_block(prog_address, data, len); |
prog_address += len; |
return len; |
} |
/* fill packet ISP mode */ |
for (i = 0; i < len; i++) { |
if (prog_state == PROG_STATE_READFLASH) { |
data[i] = ispReadFlash(prog_address); |
} else { |
data[i] = ispReadEEPROM(prog_address); |
} |
prog_address++; |
} |
/* last packet? */ |
if (len < 8) { |
prog_state = PROG_STATE_IDLE; |
} |
return len; |
} |
uchar usbFunctionWrite(uchar *data, uchar len) { |
uchar retVal = 0; |
uchar i; |
/* check if programmer is in correct write state */ |
if ((prog_state != PROG_STATE_WRITEFLASH) && (prog_state |
!= PROG_STATE_WRITEEEPROM) && (prog_state != PROG_STATE_TPI_WRITE)) { |
return 0xff; |
} |
if (prog_state == PROG_STATE_TPI_WRITE) |
{ |
tpi_write_block(prog_address, data, len); |
prog_address += len; |
prog_nbytes -= len; |
if(prog_nbytes <= 0) |
{ |
prog_state = PROG_STATE_IDLE; |
return 1; |
} |
return 0; |
} |
for (i = 0; i < len; i++) { |
if (prog_state == PROG_STATE_WRITEFLASH) { |
/* Flash */ |
if (prog_pagesize == 0) { |
/* not paged */ |
ispWriteFlash(prog_address, data[i], 1); |
} else { |
/* paged */ |
ispWriteFlash(prog_address, data[i], 0); |
prog_pagecounter--; |
if (prog_pagecounter == 0) { |
ispFlushPage(prog_address, data[i]); |
prog_pagecounter = prog_pagesize; |
} |
} |
} else { |
/* EEPROM */ |
ispWriteEEPROM(prog_address, data[i]); |
} |
prog_nbytes--; |
if (prog_nbytes == 0) { |
prog_state = PROG_STATE_IDLE; |
if ((prog_blockflags & PROG_BLOCKFLAG_LAST) && (prog_pagecounter |
!= prog_pagesize)) { |
/* last block and page flush pending, so flush it now */ |
ispFlushPage(prog_address, data[i]); |
} |
retVal = 1; // Need to return 1 when no more data is to be received |
} |
prog_address++; |
} |
return retVal; |
} |
int main(void) { |
uchar i, j; |
/* unused pins with pullups */ |
PORTB = PORTB_UNUSED_MASK; |
PORTC = PORTC_UNUSED_MASK; |
PORTD = PORTD_UNUSED_MASK; |
/* LED ports as output */ |
ledInit(); |
ledGreenOn(); |
ledRedOff(); |
/* CLKSW input with PullUp (external jumper to GND) */ |
clkswInit(); |
/* output SE0 for USB reset */ |
DDR(USB_CFG_IOPORTNAME) |= (1 << USB_CFG_DPLUS_BIT | 1<<USB_CFG_DMINUS_BIT); |
/* USB Reset by device only required on Watchdog Reset */ |
j = 0; |
while (--j) { |
i = 0; |
/* delay >10ms for USB reset */ |
while (--i) |
; |
} |
/* all USB and ISP pins inputs */ |
DDR(USB_CFG_IOPORTNAME) &= ~(1 << USB_CFG_DPLUS_BIT | 1<<USB_CFG_DMINUS_BIT); |
/* init timer */ |
clockInit(); |
/* main event loop */ |
usbInit(); |
sei(); |
for (;;) { |
usbPoll(); |
} |
return 0; |
} |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbasp.h |
---|
0,0 → 1,91 |
/* |
* usbasp.c - part of USBasp |
* |
* Autor..........: Thomas Fischl <tfischl@gmx.de> |
* Description....: Definitions and macros for usbasp |
* Licence........: GNU GPL v2 (see Readme.txt) |
* Creation Date..: 2009-02-28 |
* Last change....: 2009-02-28 |
*/ |
#ifndef USBASP_H_ |
#define USBASP_H_ |
/* PORTS Definitions */ |
#define LED_RED_PORT C |
#define LED_RED_BIT 0 |
#define LED_GREEN_PORT C |
#define LED_GREEN_BIT 1 |
#define CLKSW_PORT D |
#define CLKSW_BIT 0 |
#define PORTB_UNUSED_MASK (1<<PB1 | 1<<PB0) |
#define PORTC_UNUSED_MASK (1<<PC5 | 1<<PC4 | 1<<PC3 | 1<<PC2) |
#define PORTD_UNUSED_MASK (1<<PD7 | 1<<PD6 | 1<<PD5 | 1<<PD3 | 1<<PD1) |
/* USB function call identifiers */ |
#define USBASP_FUNC_CONNECT 1 |
#define USBASP_FUNC_DISCONNECT 2 |
#define USBASP_FUNC_TRANSMIT 3 |
#define USBASP_FUNC_READFLASH 4 |
#define USBASP_FUNC_ENABLEPROG 5 |
#define USBASP_FUNC_WRITEFLASH 6 |
#define USBASP_FUNC_READEEPROM 7 |
#define USBASP_FUNC_WRITEEEPROM 8 |
#define USBASP_FUNC_SETLONGADDRESS 9 |
#define USBASP_FUNC_SETISPSCK 10 |
#define USBASP_FUNC_TPI_CONNECT 11 |
#define USBASP_FUNC_TPI_DISCONNECT 12 |
#define USBASP_FUNC_TPI_RAWREAD 13 |
#define USBASP_FUNC_TPI_RAWWRITE 14 |
#define USBASP_FUNC_TPI_READBLOCK 15 |
#define USBASP_FUNC_TPI_WRITEBLOCK 16 |
#define USBASP_FUNC_GETCAPABILITIES 127 |
/* USBASP capabilities */ |
#define USBASP_CAP_0_TPI 0x01 |
/* programming state */ |
#define PROG_STATE_IDLE 0 |
#define PROG_STATE_WRITEFLASH 1 |
#define PROG_STATE_READFLASH 2 |
#define PROG_STATE_READEEPROM 3 |
#define PROG_STATE_WRITEEEPROM 4 |
#define PROG_STATE_TPI_READ 5 |
#define PROG_STATE_TPI_WRITE 6 |
/* Block mode flags */ |
#define PROG_BLOCKFLAG_FIRST 1 |
#define PROG_BLOCKFLAG_LAST 2 |
/* ISP SCK speed identifiers */ |
#define USBASP_ISP_SCK_AUTO 0 |
#define USBASP_ISP_SCK_0_5 1 /* 500 Hz */ |
#define USBASP_ISP_SCK_1 2 /* 1 kHz */ |
#define USBASP_ISP_SCK_2 3 /* 2 kHz */ |
#define USBASP_ISP_SCK_4 4 /* 4 kHz */ |
#define USBASP_ISP_SCK_8 5 /* 8 kHz */ |
#define USBASP_ISP_SCK_16 6 /* 16 kHz */ |
#define USBASP_ISP_SCK_32 7 /* 32 kHz */ |
#define USBASP_ISP_SCK_93_75 8 /* 93.75 kHz */ |
#define USBASP_ISP_SCK_187_5 9 /* 187.5 kHz */ |
#define USBASP_ISP_SCK_375 10 /* 375 kHz */ |
#define USBASP_ISP_SCK_750 11 /* 750 kHz */ |
#define USBASP_ISP_SCK_1500 12 /* 1.5 MHz */ |
/* Macros for Port (enables to easily define IO signals) */ |
#define GLUE(A,B) A##B |
#define DDR(PORT_LETTER) GLUE(DDR, PORT_LETTER) // Makes DDRC from DDR(C) etc. |
#define PORT(PORT_LETTER) GLUE(PORT,PORT_LETTER) // Makes PORTC from PORT(C) |
#define PIN(PORT_LETTER) GLUE(PIN, PORT_LETTER) // Makes PINC from PIN(C) |
/* macros for gpio functions */ |
#define ledRedOn() PORT(LED_RED_PORT) &= ~(1 << LED_RED_BIT) // Active L |
#define ledRedOff() PORT(LED_RED_PORT) |= (1 << LED_RED_BIT) |
#define ledGreenOn() PORT(LED_GREEN_PORT) &= ~(1 << LED_GREEN_BIT) // Active L |
#define ledGreenOff() PORT(LED_GREEN_PORT) |= (1 << LED_GREEN_BIT) |
#define ledInit() DDR(LED_RED_PORT) |= (1 << LED_RED_BIT),\ |
DDR(LED_GREEN_PORT) |= (1 << LED_GREEN_BIT) // Outputs |
#define clkswInit() DDR(CLKSW_PORT) &= ~(1 << CLKSW_BIT),\ |
PORT(CLKSW_PORT) |= (1 << CLKSW_BIT) // Input with PullUp |
#endif /* USBASP_H_ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbconfig.h |
---|
0,0 → 1,244 |
/* Name: usbconfig.h |
* Project: AVR USB driver |
* Author: Christian Starkjohann, Thomas Fischl |
* Creation Date: 2005-04-01 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt) or proprietary (CommercialLicense.txt) |
*/ |
#ifndef __usbconfig_h_included__ |
#define __usbconfig_h_included__ |
/* |
General Description: |
This file contains parts of the USB driver which can be configured and can or |
must be adapted to your hardware. |
Please note that the usbdrv contains a usbconfig-prototype.h file now. We |
recommend that you use that file as a template because it will always list |
the newest features and options. |
*/ |
/* ---------------------------- Hardware Config ---------------------------- */ |
#define USB_COUNT_SOF 0 |
/* Define this to 1 if interrupt is conected to D- signal |
*/ |
#define USB_CFG_IOPORTNAME D |
/* This is the port where the USB bus is connected. When you configure it to |
* "B", the registers PORTB, PINB and DDRB will be used. |
*/ |
#define USB_CFG_DMINUS_BIT 4 |
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. |
* This may be any bit in the port. |
*/ |
#define USB_CFG_DPLUS_BIT 2 |
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. |
* This may be any bit in the port. Please note that D+ must also be connected |
* to interrupt pin INT0! |
*/ |
#define USB_CFG_CLOCK_KHZ 12000 |
/* Clock rate of the AVR in MHz. Legal values are 12000, 16000 or 16500. |
* The 16.5 MHz version of the code requires no crystal, it tolerates +/- 1% |
* deviation from the nominal frequency. All other rates require a precision |
* of 2000 ppm and thus a crystal! |
* Default if not specified: 12 MHz |
*/ |
/* ----------------------- Optional Hardware Config ------------------------ */ |
/* #define USB_CFG_PULLUP_IOPORTNAME D */ |
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of |
* V+, you can connect and disconnect the device from firmware by calling |
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). |
* This constant defines the port on which the pullup resistor is connected. |
*/ |
/* #define USB_CFG_PULLUP_BIT 4 */ |
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined |
* above) where the 1.5k pullup resistor is connected. See description |
* above for details. |
*/ |
/* --------------------------- Functional Range ---------------------------- */ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0 |
/* Define this to 1 if you want to compile a version with two endpoints: The |
* default control endpoint 0 and an interrupt-in endpoint 1. |
*/ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 |
/* Define this to 1 if you want to compile a version with three endpoints: The |
* default control endpoint 0, an interrupt-in endpoint 1 and an interrupt-in |
* endpoint 3. You must also enable endpoint 1 above. |
*/ |
#define USB_CFG_IMPLEMENT_HALT 0 |
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature |
* for endpoint 1 (interrupt endpoint). Although you may not need this feature, |
* it is required by the standard. We have made it a config option because it |
* bloats the code considerably. |
*/ |
#define USB_CFG_INTR_POLL_INTERVAL 10 |
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll |
* interval. The value is in milliseconds and must not be less than 10 ms for |
* low speed devices. |
*/ |
#define USB_CFG_IS_SELF_POWERED 0 |
/* Define this to 1 if the device has its own power supply. Set it to 0 if the |
* device is powered from the USB bus. |
*/ |
#define USB_CFG_MAX_BUS_POWER 50 |
/* Set this variable to the maximum USB bus power consumption of your device. |
* The value is in milliamperes. [It will be divided by two since USB |
* communicates power requirements in units of 2 mA.] |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITE 1 |
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out |
* transfers. Set it to 0 if you don't need it and want to save a couple of |
* bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_READ 1 |
/* Set this to 1 if you need to send control replies which are generated |
* "on the fly" when usbFunctionRead() is called. If you only want to send |
* data from a static buffer, set it to 0 and return the data from |
* usbFunctionSetup(). This saves a couple of bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 |
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoint 1. |
* You must implement the function usbFunctionWriteOut() which receives all |
* interrupt/bulk data sent to endpoint 1. |
*/ |
#define USB_CFG_HAVE_FLOWCONTROL 0 |
/* Define this to 1 if you want flowcontrol over USB data. See the definition |
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in |
* usbdrv.h. |
*/ |
/* -------------------------- Device Description --------------------------- */ |
#define USB_CFG_VENDOR_ID 0xc0, 0x16 /* 5824 in dec, stands for VOTI */ |
/* USB vendor ID for the device, low byte first. If you have registered your |
* own Vendor ID, define it here. Otherwise you use obdev's free shared |
* VID/PID pair. Be sure to read USBID-License.txt for rules! |
*/ |
#define USB_CFG_DEVICE_ID 0xdc, 0x05 /* 1500 in dec, obdev's free PID */ |
/* This is the ID of the product, low byte first. It is interpreted in the |
* scope of the vendor ID. If you have registered your own VID with usb.org |
* or if you have licensed a PID from somebody else, define it here. Otherwise |
* you use obdev's free shared VID/PID pair. Be sure to read the rules in |
* USBID-License.txt! |
*/ |
#define USB_CFG_DEVICE_VERSION 0x04, 0x01 |
/* Version number of the device: Minor number first, then major number. |
*/ |
#define USB_CFG_VENDOR_NAME 'w', 'w', 'w', '.', 'f', 'i', 's', 'c', 'h', 'l', '.', 'd', 'e' |
#define USB_CFG_VENDOR_NAME_LEN 13 |
/* These two values define the vendor name returned by the USB device. The name |
* must be given as a list of characters under single quotes. The characters |
* are interpreted as Unicode (UTF-16) entities. |
* If you don't want a vendor name string, undefine these macros. |
* ALWAYS define a vendor name containing your Internet domain name if you use |
* obdev's free shared VID/PID pair. See the file USBID-License.txt for |
* details. |
*/ |
#define USB_CFG_DEVICE_NAME 'U', 'S', 'B', 'a', 's', 'p' |
#define USB_CFG_DEVICE_NAME_LEN 6 |
/* Same as above for the device name. If you don't want a device name, undefine |
* the macros. See the file USBID-License.txt before you assign a name. |
*/ |
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ |
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ |
/* Same as above for the serial number. If you don't want a serial number, |
* undefine the macros. |
* It may be useful to provide the serial number through other means than at |
* compile time. See the section about descriptor properties below for how |
* to fine tune control over USB descriptors such as the string descriptor |
* for the serial number. |
*/ |
#define USB_CFG_DEVICE_CLASS 0xff |
#define USB_CFG_DEVICE_SUBCLASS 0 |
/* See USB specification if you want to conform to an existing device class. |
*/ |
#define USB_CFG_INTERFACE_CLASS 0 |
#define USB_CFG_INTERFACE_SUBCLASS 0 |
#define USB_CFG_INTERFACE_PROTOCOL 0 |
/* See USB specification if you want to conform to an existing device class or |
* protocol. |
*/ |
#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 0 /* total length of report descriptor */ |
/* Define this to the length of the HID report descriptor, if you implement |
* an HID device. Otherwise don't define it or define it to 0. |
*/ |
/* ------------------- Fine Control over USB Descriptors ------------------- */ |
/* If you don't want to use the driver's default USB descriptors, you can |
* provide our own. These can be provided as (1) fixed length static data in |
* flash memory, (2) fixed length static data in RAM or (3) dynamically at |
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more |
* information about this function. |
* Descriptor handling is configured through the descriptor's properties. If |
* no properties are defined or if they are 0, the default descriptor is used. |
* Possible properties are: |
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched |
* at runtime via usbFunctionDescriptor(). |
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found |
* in static memory is in RAM, not in flash memory. |
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), |
* the driver must know the descriptor's length. The descriptor itself is |
* found at the address of a well known identifier (see below). |
* List of static descriptor names (must be declared PROGMEM if in flash): |
* char usbDescriptorDevice[]; |
* char usbDescriptorConfiguration[]; |
* char usbDescriptorHidReport[]; |
* char usbDescriptorString0[]; |
* int usbDescriptorStringVendor[]; |
* int usbDescriptorStringDevice[]; |
* int usbDescriptorStringSerialNumber[]; |
* Other descriptors can't be provided statically, they must be provided |
* dynamically at runtime. |
* |
* Descriptor properties are or-ed or added together, e.g.: |
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) |
* |
* The following descriptors are defined: |
* USB_CFG_DESCR_PROPS_DEVICE |
* USB_CFG_DESCR_PROPS_CONFIGURATION |
* USB_CFG_DESCR_PROPS_STRINGS |
* USB_CFG_DESCR_PROPS_STRING_0 |
* USB_CFG_DESCR_PROPS_STRING_VENDOR |
* USB_CFG_DESCR_PROPS_STRING_PRODUCT |
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
* USB_CFG_DESCR_PROPS_HID |
* USB_CFG_DESCR_PROPS_HID_REPORT |
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) |
* |
*/ |
#define USB_CFG_DESCR_PROPS_DEVICE 0 |
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 |
#define USB_CFG_DESCR_PROPS_STRINGS 0 |
#define USB_CFG_DESCR_PROPS_STRING_0 0 |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 |
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 |
#define USB_CFG_DESCR_PROPS_HID 0 |
#define USB_CFG_DESCR_PROPS_HID_REPORT 0 |
#define USB_CFG_DESCR_PROPS_UNKNOWN 0 |
/* ----------------------- Optional MCU Description ------------------------ */ |
/* The following configurations have working defaults in usbdrv.h. You |
* usually don't need to set them explicitly. Only if you want to run |
* the driver on a device which is not yet supported or with a compiler |
* which is not fully supported (such as IAR C) or if you use a differnt |
* interrupt than INT0, you may have to define some of these. |
*/ |
/* #define USB_INTR_CFG MCUCR */ |
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ |
/* #define USB_INTR_CFG_CLR 0 */ |
/* #define USB_INTR_ENABLE GIMSK */ |
/* #define USB_INTR_ENABLE_BIT INT0 */ |
/* #define USB_INTR_PENDING GIFR */ |
/* #define USB_INTR_PENDING_BIT INTF0 */ |
#endif /* __usbconfig_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/clock.c |
---|
0,0 → 1,24 |
/* |
* clock.c - part of USBasp |
* |
* Autor..........: Thomas Fischl <tfischl@gmx.de> |
* Description....: Provides functions for timing/waiting |
* Licence........: GNU GPL v2 (see Readme.txt) |
* Creation Date..: 2005-02-23 |
* Last change....: 2005-04-20 |
*/ |
#include <inttypes.h> |
#include <avr/io.h> |
#include "clock.h" |
/* wait time * 320 us */ |
void clockWait(uint8_t time) { |
uint8_t i; |
for (i = 0; i < time; i++) { |
uint8_t starttime = TIMERVALUE; |
while ((uint8_t) (TIMERVALUE - starttime) < CLOCK_T_320us) { |
} |
} |
} |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/clock.h |
---|
0,0 → 1,28 |
/* |
* clock.h - part of USBasp |
* |
* Autor..........: Thomas Fischl <tfischl@gmx.de> |
* Description....: Provides functions for timing/waiting |
* Licence........: GNU GPL v2 (see Readme.txt) |
* Creation Date..: 2005-02-23 |
* Last change....: 2006-11-16 |
*/ |
#ifndef __clock_h_included__ |
#define __clock_h_included__ |
#define F_CPU 12000000L /* 12MHz */ |
#define TIMERVALUE TCNT0 |
#define CLOCK_T_320us 60 |
#ifdef __AVR_ATmega8__ |
#define TCCR0B TCCR0 |
#endif |
/* set prescaler to 64 */ |
#define clockInit() TCCR0B = (1 << CS01) | (1 << CS00); |
/* wait time * 320 us */ |
void clockWait(uint8_t time); |
#endif /* __clock_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/isp.c |
---|
0,0 → 1,336 |
/* |
* isp.c - part of USBasp |
* |
* Autor..........: Thomas Fischl <tfischl@gmx.de> |
* Description....: Provides functions for communication/programming |
* over ISP interface |
* Licence........: GNU GPL v2 (see Readme.txt) |
* Creation Date..: 2005-02-23 |
* Last change....: 2010-01-19 |
*/ |
#include <avr/io.h> |
#include "isp.h" |
#include "clock.h" |
#include "usbasp.h" |
#define spiHWdisable() SPCR = 0 |
uchar sck_sw_delay; |
uchar sck_spcr; |
uchar sck_spsr; |
uchar isp_hiaddr; |
void spiHWenable() { |
SPCR = sck_spcr; |
SPSR = sck_spsr; |
} |
void ispSetSCKOption(uchar option) { |
if (option == USBASP_ISP_SCK_AUTO) |
option = USBASP_ISP_SCK_375; |
if (option >= USBASP_ISP_SCK_93_75) { |
ispTransmit = ispTransmit_hw; |
sck_spsr = 0; |
sck_sw_delay = 1; /* force RST#/SCK pulse for 320us */ |
switch (option) { |
case USBASP_ISP_SCK_1500: |
/* enable SPI, master, 1.5MHz, XTAL/8 */ |
sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); |
sck_spsr = (1 << SPI2X); |
case USBASP_ISP_SCK_750: |
/* enable SPI, master, 750kHz, XTAL/16 */ |
sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR0); |
break; |
case USBASP_ISP_SCK_375: |
default: |
/* enable SPI, master, 375kHz, XTAL/32 (default) */ |
sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); |
sck_spsr = (1 << SPI2X); |
break; |
case USBASP_ISP_SCK_187_5: |
/* enable SPI, master, 187.5kHz XTAL/64 */ |
sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1); |
break; |
case USBASP_ISP_SCK_93_75: |
/* enable SPI, master, 93.75kHz XTAL/128 */ |
sck_spcr = (1 << SPE) | (1 << MSTR) | (1 << SPR1) | (1 << SPR0); |
break; |
} |
} else { |
ispTransmit = ispTransmit_sw; |
switch (option) { |
case USBASP_ISP_SCK_32: |
sck_sw_delay = 3; |
break; |
case USBASP_ISP_SCK_16: |
sck_sw_delay = 6; |
break; |
case USBASP_ISP_SCK_8: |
sck_sw_delay = 12; |
break; |
case USBASP_ISP_SCK_4: |
sck_sw_delay = 24; |
break; |
case USBASP_ISP_SCK_2: |
sck_sw_delay = 48; |
break; |
case USBASP_ISP_SCK_1: |
sck_sw_delay = 96; |
break; |
case USBASP_ISP_SCK_0_5: |
sck_sw_delay = 192; |
break; |
} |
} |
} |
void ispDelay() { |
uint8_t starttime = TIMERVALUE; |
while ((uint8_t) (TIMERVALUE - starttime) < sck_sw_delay) { |
} |
} |
void ispConnect() { |
/* all ISP pins are inputs before */ |
/* now set output pins */ |
ISP_DDR |= (1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI); |
/* reset device */ |
ISP_OUT &= ~(1 << ISP_RST); /* RST low */ |
ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */ |
/* positive reset pulse > 2 SCK (target) */ |
ispDelay(); |
ISP_OUT |= (1 << ISP_RST); /* RST high */ |
ispDelay(); |
ISP_OUT &= ~(1 << ISP_RST); /* RST low */ |
if (ispTransmit == ispTransmit_hw) { |
spiHWenable(); |
} |
/* Initial extended address value */ |
isp_hiaddr = 0; |
} |
void ispDisconnect() { |
/* set all ISP pins inputs */ |
ISP_DDR &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
/* switch pullups off */ |
ISP_OUT &= ~((1 << ISP_RST) | (1 << ISP_SCK) | (1 << ISP_MOSI)); |
/* disable hardware SPI */ |
spiHWdisable(); |
} |
uchar ispTransmit_sw(uchar send_byte) { |
uchar rec_byte = 0; |
uchar i; |
for (i = 0; i < 8; i++) { |
/* set MSB to MOSI-pin */ |
if ((send_byte & 0x80) != 0) { |
ISP_OUT |= (1 << ISP_MOSI); /* MOSI high */ |
} else { |
ISP_OUT &= ~(1 << ISP_MOSI); /* MOSI low */ |
} |
/* shift to next bit */ |
send_byte = send_byte << 1; |
/* receive data */ |
rec_byte = rec_byte << 1; |
if ((ISP_IN & (1 << ISP_MISO)) != 0) { |
rec_byte++; |
} |
/* pulse SCK */ |
ISP_OUT |= (1 << ISP_SCK); /* SCK high */ |
ispDelay(); |
ISP_OUT &= ~(1 << ISP_SCK); /* SCK low */ |
ispDelay(); |
} |
return rec_byte; |
} |
uchar ispTransmit_hw(uchar send_byte) { |
SPDR = send_byte; |
while (!(SPSR & (1 << SPIF))) |
; |
return SPDR; |
} |
uchar ispEnterProgrammingMode() { |
uchar check; |
uchar count = 32; |
while (count--) { |
ispTransmit(0xAC); |
ispTransmit(0x53); |
check = ispTransmit(0); |
ispTransmit(0); |
if (check == 0x53) { |
return 0; |
} |
spiHWdisable(); |
/* pulse RST */ |
ispDelay(); |
ISP_OUT |= (1 << ISP_RST); /* RST high */ |
ispDelay(); |
ISP_OUT &= ~(1 << ISP_RST); /* RST low */ |
ispDelay(); |
if (ispTransmit == ispTransmit_hw) { |
spiHWenable(); |
} |
} |
return 1; /* error: device dosn't answer */ |
} |
static void ispUpdateExtended(unsigned long address) |
{ |
uchar curr_hiaddr; |
curr_hiaddr = (address >> 17); |
/* check if extended address byte is changed */ |
if(isp_hiaddr != curr_hiaddr) |
{ |
isp_hiaddr = curr_hiaddr; |
/* Load Extended Address byte */ |
ispTransmit(0x4D); |
ispTransmit(0x00); |
ispTransmit(isp_hiaddr); |
ispTransmit(0x00); |
} |
} |
uchar ispReadFlash(unsigned long address) { |
ispUpdateExtended(address); |
ispTransmit(0x20 | ((address & 1) << 3)); |
ispTransmit(address >> 9); |
ispTransmit(address >> 1); |
return ispTransmit(0); |
} |
uchar ispWriteFlash(unsigned long address, uchar data, uchar pollmode) { |
/* 0xFF is value after chip erase, so skip programming |
if (data == 0xFF) { |
return 0; |
} |
*/ |
ispUpdateExtended(address); |
ispTransmit(0x40 | ((address & 1) << 3)); |
ispTransmit(address >> 9); |
ispTransmit(address >> 1); |
ispTransmit(data); |
if (pollmode == 0) |
return 0; |
if (data == 0x7F) { |
clockWait(15); /* wait 4,8 ms */ |
return 0; |
} else { |
/* polling flash */ |
uchar retries = 30; |
uint8_t starttime = TIMERVALUE; |
while (retries != 0) { |
if (ispReadFlash(address) != 0x7F) { |
return 0; |
}; |
if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) { |
starttime = TIMERVALUE; |
retries--; |
} |
} |
return 1; /* error */ |
} |
} |
uchar ispFlushPage(unsigned long address, uchar pollvalue) { |
ispUpdateExtended(address); |
ispTransmit(0x4C); |
ispTransmit(address >> 9); |
ispTransmit(address >> 1); |
ispTransmit(0); |
if (pollvalue == 0xFF) { |
clockWait(15); |
return 0; |
} else { |
/* polling flash */ |
uchar retries = 30; |
uint8_t starttime = TIMERVALUE; |
while (retries != 0) { |
if (ispReadFlash(address) != 0xFF) { |
return 0; |
}; |
if ((uint8_t) (TIMERVALUE - starttime) > CLOCK_T_320us) { |
starttime = TIMERVALUE; |
retries--; |
} |
} |
return 1; /* error */ |
} |
} |
uchar ispReadEEPROM(unsigned int address) { |
ispTransmit(0xA0); |
ispTransmit(address >> 8); |
ispTransmit(address); |
return ispTransmit(0); |
} |
uchar ispWriteEEPROM(unsigned int address, uchar data) { |
ispTransmit(0xC0); |
ispTransmit(address >> 8); |
ispTransmit(address); |
ispTransmit(data); |
clockWait(30); // wait 9,6 ms |
return 0; |
} |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/isp.h |
---|
0,0 → 1,65 |
/* |
* isp.h - part of USBasp |
* |
* Autor..........: Thomas Fischl <tfischl@gmx.de> |
* Description....: Provides functions for communication/programming |
* over ISP interface |
* Licence........: GNU GPL v2 (see Readme.txt) |
* Creation Date..: 2005-02-23 |
* Last change....: 2009-02-28 |
*/ |
#ifndef __isp_h_included__ |
#define __isp_h_included__ |
#ifndef uchar |
#define uchar unsigned char |
#endif |
#define ISP_OUT PORTB |
#define ISP_IN PINB |
#define ISP_DDR DDRB |
#define ISP_RST PB2 |
#define ISP_MOSI PB3 |
#define ISP_MISO PB4 |
#define ISP_SCK PB5 |
/* Prepare connection to target device */ |
void ispConnect(); |
/* Close connection to target device */ |
void ispDisconnect(); |
/* read an write a byte from isp using software (slow) */ |
uchar ispTransmit_sw(uchar send_byte); |
/* read an write a byte from isp using hardware (fast) */ |
uchar ispTransmit_hw(uchar send_byte); |
/* enter programming mode */ |
uchar ispEnterProgrammingMode(); |
/* read byte from eeprom at given address */ |
uchar ispReadEEPROM(unsigned int address); |
/* write byte to flash at given address */ |
uchar ispWriteFlash(unsigned long address, uchar data, uchar pollmode); |
uchar ispFlushPage(unsigned long address, uchar pollvalue); |
/* read byte from flash at given address */ |
uchar ispReadFlash(unsigned long address); |
/* write byte to eeprom at given address */ |
uchar ispWriteEEPROM(unsigned int address, uchar data); |
/* pointer to sw or hw transmit function */ |
uchar (*ispTransmit)(uchar); |
/* set SCK speed. call before ispConnect! */ |
void ispSetSCKOption(uchar sckoption); |
/* load extended address byte */ |
void ispLoadExtendedAddressByte(unsigned long address); |
#endif /* __isp_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/tpi.S |
---|
0,0 → 1,258 |
/** |
* \brief Size-optimized code for TPI |
* \file tpi.s |
* \author S³awomir Fra |
*/ |
#include <avr/io.h> |
#include "tpi_defs.h" |
#define TPI_CLK_PORT PORTB |
#define TPI_CLK_DDR DDRB |
#define TPI_CLK_BIT 5 |
#define TPI_DATAOUT_PORT PORTB |
#define TPI_DATAOUT_DDR DDRB |
#define TPI_DATAOUT_BIT 3 |
#ifdef TPI_WITH_OPTO |
# define TPI_DATAIN_PIN PINB |
# define TPI_DATAIN_DDR DDRB |
# define TPI_DATAIN_BIT 4 |
#else |
# define TPI_DATAIN_PIN PINB |
# define TPI_DATAIN_BIT 3 |
#endif |
.comm tpi_dly_cnt, 2 |
/** |
* TPI init |
*/ |
.global tpi_init |
tpi_init: |
/* CLK <= out */ |
sbi _SFR_IO_ADDR(TPI_CLK_DDR), TPI_CLK_BIT |
#ifdef TPI_WITH_OPTO |
/* DATAIN <= pull-up */ |
cbi _SFR_IO_ADDR(TPI_DATAIN_DDR), TPI_DATAIN_BIT |
sbi _SFR_IO_ADDR(TPI_DATAIN_PORT), TPI_DATAIN_BIT |
/* DATAOUT <= high */ |
sbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT |
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT |
#else |
/* DATA <= pull-up */ |
cbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT |
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT |
#endif |
/* 32 bits */ |
ldi r21, 32 |
1: |
rcall tpi_bit_h |
dec r21 |
brne 1b |
ret |
/** |
* Update PR |
* in: r25:r24 <= PR |
* lost: r18-r21,r24,r30-r31 |
*/ |
tpi_pr_update: |
movw r20, r24 |
ldi r24, TPI_OP_SSTPR(0) |
rcall tpi_send_byte |
mov r24, r20 |
rcall tpi_send_byte |
ldi r24, TPI_OP_SSTPR(1) |
rcall tpi_send_byte |
mov r24, r21 |
// rjmp tpi_send_byte |
/** |
* Send one byte |
* in: r24 <= byte |
* lost: r18-r19,r30-r31 |
*/ |
.global tpi_send_byte |
tpi_send_byte: |
/* start bit */ |
rcall tpi_bit_l |
/* 8 data bits */ |
ldi r18, 8 |
ldi r19, 0 |
1: |
// parity |
eor r19, r24 |
// get bit, shift |
bst r24, 0 |
lsr r24 |
// send |
rcall tpi_bit |
dec r18 |
brne 1b |
/* parity bit */ |
bst r19, 0 |
rcall tpi_bit |
/* 2 stop bits */ |
rcall tpi_bit_h |
// rjmp tpi_bit_h |
/** |
* Exchange of one bit |
* in: T <= bit_in |
* out: T => bit_out |
* lost: r30-r31 |
*/ |
tpi_bit_h: |
set |
tpi_bit: |
/* TPIDATA = T */ |
#ifdef TPI_WITH_OPTO |
// DATAOUT = high (opto should allow TPIDATA to be pulled low by external device) |
// if(T == 0) |
// DATAOUT = low |
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT |
brts 1f |
tpi_bit_l: |
cbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT |
1: |
#else |
// DATAOUT = pull-up |
// if(T == 0) |
// DATAOUT = low |
cbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT |
sbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT |
brts 1f |
tpi_bit_l: |
cbi _SFR_IO_ADDR(TPI_DATAOUT_PORT), TPI_DATAOUT_BIT |
sbi _SFR_IO_ADDR(TPI_DATAOUT_DDR), TPI_DATAOUT_BIT |
1: |
#endif |
/* delay(); */ |
lds r30, tpi_dly_cnt |
lds r31, tpi_dly_cnt+1 |
1: |
sbiw r30, 1 |
brsh 1b |
/* TPICLK = 1 */ |
sbi _SFR_IO_ADDR(TPI_CLK_PORT), TPI_CLK_BIT |
/* T = TPIDATA */ |
in r30, _SFR_IO_ADDR(TPI_DATAIN_PIN) |
bst r30, TPI_DATAIN_BIT |
/* delay(); */ |
lds r30, tpi_dly_cnt |
lds r31, tpi_dly_cnt+1 |
1: |
sbiw r30, 1 |
brsh 1b |
/* TPICLK = 0 */ |
cbi _SFR_IO_ADDR(TPI_CLK_PORT), TPI_CLK_BIT |
ret |
/** |
* Receive one byte |
* out: r24 => byte |
* lost: r18-r19,r30-r31 |
*/ |
.global tpi_recv_byte |
tpi_recv_byte: |
/* waitfor(start_bit, 192); */ |
ldi r18, 192 |
1: |
rcall tpi_bit_h |
brtc .tpi_recv_found_start |
dec r18 |
brne 1b |
/* no start bit: set return value */ |
.tpi_break_ret0: |
ldi r24, 0 |
/* send 2 breaks (24++ bits) */ |
ldi r18, 26 |
1: |
rcall tpi_bit_l |
dec r18 |
brne 1b |
/* send hi */ |
rjmp tpi_bit_h |
// ---- |
.tpi_recv_found_start: |
/* recv 8bits(+calc.parity) */ |
ldi r18, 8 |
ldi r19, 0 |
1: |
rcall tpi_bit_h |
lsr r24 |
bld r24, 7 |
eor r19, r24 |
dec r18 |
brne 1b |
/* recv parity */ |
rcall tpi_bit_h |
bld r18, 7 |
eor r19, r18 |
brmi .tpi_break_ret0 |
/* recv stop bits */ |
rcall tpi_bit_h |
rjmp tpi_bit_h |
/** |
* Read Block |
*/ |
.global tpi_read_block |
tpi_read_block: |
// X <= dptr |
movw XL, r22 |
// r23 <= len |
mov r23, r20 |
/* set PR */ |
rcall tpi_pr_update |
/* read data */ |
.tpi_read_loop: |
ldi r24, TPI_OP_SLD_INC |
rcall tpi_send_byte |
rcall tpi_recv_byte |
st X+, r24 |
dec r23 |
brne .tpi_read_loop |
ret |
/** |
* Write block |
*/ |
.global tpi_write_block |
tpi_write_block: |
// X <= sptr |
movw XL, r22 |
// r23 <= len |
mov r23, r20 |
/* set PR */ |
rcall tpi_pr_update |
/* write data */ |
.tpi_write_loop: |
ldi r24, TPI_OP_SOUT(NVMCMD) |
rcall tpi_send_byte |
ldi r24, NVMCMD_WORD_WRITE |
rcall tpi_send_byte |
ldi r24, TPI_OP_SST_INC |
rcall tpi_send_byte |
ld r24, X+ |
rcall tpi_send_byte |
.tpi_nvmbsy_wait: |
ldi r24, TPI_OP_SIN(NVMCSR) |
rcall tpi_send_byte |
rcall tpi_recv_byte |
andi r24, NVMCSR_BSY |
brne .tpi_nvmbsy_wait |
dec r23 |
brne .tpi_write_loop |
ret |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/tpi.h |
---|
0,0 → 1,47 |
/** |
* \brief Header for tpi |
* \file tpi.h |
* \author S³awomir Fra |
*/ |
#ifndef __TPI_H__ |
#define __TPI_H__ |
#include <stdint.h> |
/* Globals */ |
/** Number of iterations in tpi_delay loop */ |
extern uint16_t tpi_dly_cnt; |
/* Functions */ |
/** |
* TPI init |
*/ |
void tpi_init(void); |
/** |
* Send raw byte by TPI |
* \param b Byte to send |
*/ |
void tpi_send_byte(uint8_t b); |
/** |
* Receive one raw byte from TPI |
* \return Received byte |
*/ |
uint8_t tpi_recv_byte(void); |
/** |
* Read block |
* \param addr Address of block |
* \param dptr Pointer to dest memory block |
* \param len Length of read |
*/ |
void tpi_read_block(uint16_t addr, uint8_t* dptr, uint8_t len); |
/** |
* Write block |
* \param addr Address to program |
* \param sptr Pointer to source block |
* \param len Length of write |
*/ |
void tpi_write_block(uint16_t addr, const uint8_t* sptr, uint8_t len); |
#endif /*__TPI_H__*/ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/tpi_defs.h |
---|
0,0 → 1,59 |
/** |
* \brief Internal defs for tpi |
* \file tpi_defs.h |
* \author S³awomir Fra |
*/ |
#ifndef __TPI_DEFS_H__ |
#define __TPI_DEFS_H__ |
/* TPI instructions */ |
#define TPI_OP_SLD 0x20 |
#define TPI_OP_SLD_INC 0x24 |
#define TPI_OP_SST 0x60 |
#define TPI_OP_SST_INC 0x64 |
#define TPI_OP_SSTPR(a) (0x68 | (a)) |
#define TPI_OP_SIN(a) (0x10 | (((a)<<1)&0x60) | ((a)&0x0F) ) |
#define TPI_OP_SOUT(a) (0x90 | (((a)<<1)&0x60) | ((a)&0x0F) ) |
#define TPI_OP_SLDCS(a) (0x80 | ((a)&0x0F) ) |
#define TPI_OP_SSTCS(a) (0xC0 | ((a)&0x0F) ) |
#define TPI_OP_SKEY 0xE0 |
/* TPI control/status registers */ |
#define TPIIR 0xF |
#define TPIPCR 0x2 |
#define TPISR 0x0 |
// TPIPCR bits |
#define TPIPCR_GT_2 0x04 |
#define TPIPCR_GT_1 0x02 |
#define TPIPCR_GT_0 0x01 |
#define TPIPCR_GT_128b 0x00 |
#define TPIPCR_GT_64b 0x01 |
#define TPIPCR_GT_32b 0x02 |
#define TPIPCR_GT_16b 0x03 |
#define TPIPCR_GT_8b 0x04 |
#define TPIPCR_GT_4b 0x05 |
#define TPIPCR_GT_2b 0x06 |
#define TPIPCR_GT_0b 0x07 |
// TPISR bits |
#define TPISR_NVMEN 0x02 |
/* NVM registers */ |
#define NVMCSR 0x32 |
#define NVMCMD 0x33 |
// NVMCSR bits |
#define NVMCSR_BSY 0x80 |
// NVMCMD values |
#define NVMCMD_NOP 0x00 |
#define NVMCMD_CHIP_ERASE 0x10 |
#define NVMCMD_SECTION_ERASE 0x14 |
#define NVMCMD_WORD_WRITE 0x1D |
#endif /*__TPI_DEFS_H__*/ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/Changelog.txt |
---|
0,0 → 1,308 |
This file documents changes in the firmware-only USB driver for atmel's AVR |
microcontrollers. New entries are always appended to the end of the file. |
Scroll down to the bottom to see the most recent changes. |
2005-04-01: |
- Implemented endpoint 1 as interrupt-in endpoint. |
- Moved all configuration options to usbconfig.h which is not part of the |
driver. |
- Changed interface for usbVendorSetup(). |
- Fixed compatibility with ATMega8 device. |
- Various minor optimizations. |
2005-04-11: |
- Changed interface to application: Use usbFunctionSetup(), usbFunctionRead() |
and usbFunctionWrite() now. Added configuration options to choose which |
of these functions to compile in. |
- Assembler module delivers receive data non-inverted now. |
- Made register and bit names compatible with more AVR devices. |
2005-05-03: |
- Allow address of usbRxBuf on any memory page as long as the buffer does |
not cross 256 byte page boundaries. |
- Better device compatibility: works with Mega88 now. |
- Code optimization in debugging module. |
- Documentation updates. |
2006-01-02: |
- Added (free) default Vendor- and Product-IDs bought from voti.nl. |
- Added USBID-License.txt file which defines the rules for using the free |
shared VID/PID pair. |
- Added Readme.txt to the usbdrv directory which clarifies administrative |
issues. |
2006-01-25: |
- Added "configured state" to become more standards compliant. |
- Added "HALT" state for interrupt endpoint. |
- Driver passes the "USB Command Verifier" test from usb.org now. |
- Made "serial number" a configuration option. |
- Minor optimizations, we now recommend compiler option "-Os" for best |
results. |
- Added a version number to usbdrv.h |
2006-02-03: |
- New configuration variable USB_BUFFER_SECTION for the memory section where |
the USB rx buffer will go. This defaults to ".bss" if not defined. Since |
this buffer MUST NOT cross 256 byte pages (not even touch a page at the |
end), the user may want to pass a linker option similar to |
"-Wl,--section-start=.mybuffer=0x800060". |
- Provide structure for usbRequest_t. |
- New defines for USB constants. |
- Prepared for HID implementations. |
- Increased data size limit for interrupt transfers to 8 bytes. |
- New macro usbInterruptIsReady() to query interrupt buffer state. |
2006-02-18: |
- Ensure that the data token which is sent as an ack to an OUT transfer is |
always zero sized. This fixes a bug where the host reports an error after |
sending an out transfer to the device, although all data arrived at the |
device. |
- Updated docs in usbdrv.h to reflect changed API in usbFunctionWrite(). |
* Release 2006-02-20 |
- Give a compiler warning when compiling with debugging turned on. |
- Added Oleg Semyonov's changes for IAR-cc compatibility. |
- Added new (optional) functions usbDeviceConnect() and usbDeviceDisconnect() |
(also thanks to Oleg!). |
- Rearranged tests in usbPoll() to save a couple of instructions in the most |
likely case that no actions are pending. |
- We need a delay between the SET ADDRESS request until the new address |
becomes active. This delay was handled in usbPoll() until now. Since the |
spec says that the delay must not exceed 2ms, previous versions required |
aggressive polling during the enumeration phase. We have now moved the |
handling of the delay into the interrupt routine. |
- We must not reply with NAK to a SETUP transaction. We can only achieve this |
by making sure that the rx buffer is empty when SETUP tokens are expected. |
We therefore don't pass zero sized data packets from the status phase of |
a transfer to usbPoll(). This change MAY cause troubles if you rely on |
receiving a less than 8 bytes long packet in usbFunctionWrite() to |
identify the end of a transfer. usbFunctionWrite() will NEVER be called |
with a zero length. |
* Release 2006-03-14 |
- Improved IAR C support: tiny memory model, more devices |
- Added template usbconfig.h file under the name usbconfig-prototype.h |
* Release 2006-03-26 |
- Added provision for one more interrupt-in endpoint (endpoint 3). |
- Added provision for one interrupt-out endpoint (endpoint 1). |
- Added flowcontrol macros for USB. |
- Added provision for custom configuration descriptor. |
- Allow ANY two port bits for D+ and D-. |
- Merged (optional) receive endpoint number into global usbRxToken variable. |
- Use USB_CFG_IOPORTNAME instead of USB_CFG_IOPORT. We now construct the |
variable name from the single port letter instead of computing the address |
of related ports from the output-port address. |
* Release 2006-06-26 |
- Updated documentation in usbdrv.h and usbconfig-prototype.h to reflect the |
new features. |
- Removed "#warning" directives because IAR does not understand them. Use |
unused static variables instead to generate a warning. |
- Do not include <avr/io.h> when compiling with IAR. |
- Introduced USB_CFG_DESCR_PROPS_* in usbconfig.h to configure how each |
USB descriptor should be handled. It is now possible to provide descriptor |
data in Flash, RAM or dynamically at runtime. |
- STALL is now a status in usbTxLen* instead of a message. We can now conform |
to the spec and leave the stall status pending until it is cleared. |
- Made usbTxPacketCnt1 and usbTxPacketCnt3 public. This allows the |
application code to reset data toggling on interrupt pipes. |
* Release 2006-07-18 |
- Added an #if !defined __ASSEMBLER__ to the warning in usbdrv.h. This fixes |
an assembler error. |
- usbDeviceDisconnect() takes pull-up resistor to high impedance now. |
* Release 2007-02-01 |
- Merged in some code size improvements from usbtiny (thanks to Dick |
Streefland for these optimizations!) |
- Special alignment requirement for usbRxBuf not required any more. Thanks |
again to Dick Streefland for this hint! |
- Reverted to "#warning" instead of unused static variables -- new versions |
of IAR CC should handle this directive. |
- Changed Open Source license to GNU GPL v2 in order to make linking against |
other free libraries easier. We no longer require publication of the |
circuit diagrams, but we STRONGLY encourage it. If you improve the driver |
itself, PLEASE grant us a royalty free license to your changes for our |
commercial license. |
* Release 2007-03-29 |
- New configuration option "USB_PUBLIC" in usbconfig.h. |
- Set USB version number to 1.10 instead of 1.01. |
- Code used USB_CFG_DESCR_PROPS_STRING_DEVICE and |
USB_CFG_DESCR_PROPS_STRING_PRODUCT inconsistently. Changed all occurrences |
to USB_CFG_DESCR_PROPS_STRING_PRODUCT. |
- New assembler module for 16.5 MHz RC oscillator clock with PLL in receiver |
code. |
- New assembler module for 16 MHz crystal. |
- usbdrvasm.S contains common code only, clock-specific parts have been moved |
to usbdrvasm12.S, usbdrvasm16.S and usbdrvasm165.S respectively. |
* Release 2007-06-25 |
- 16 MHz module: Do SE0 check in stuffed bits as well. |
* Release 2007-07-07 |
- Define hi8(x) for IAR compiler to limit result to 8 bits. This is necessary |
for negative values. |
- Added 15 MHz module contributed by V. Bosch. |
- Interrupt vector name can now be configured. This is useful if somebody |
wants to use a different hardware interrupt than INT0. |
* Release 2007-08-07 |
- Moved handleIn3 routine in usbdrvasm16.S so that relative jump range is |
not exceeded. |
- More config options: USB_RX_USER_HOOK(), USB_INITIAL_DATATOKEN, |
USB_COUNT_SOF |
- USB_INTR_PENDING can now be a memory address, not just I/O |
* Release 2007-09-19 |
- Split out common parts of assembler modules into separate include file |
- Made endpoint numbers configurable so that given interface definitions |
can be matched. See USB_CFG_EP3_NUMBER in usbconfig-prototype.h. |
- Store endpoint number for interrupt/bulk-out so that usbFunctionWriteOut() |
can handle any number of endpoints. |
- Define usbDeviceConnect() and usbDeviceDisconnect() even if no |
USB_CFG_PULLUP_IOPORTNAME is defined. Directly set D+ and D- to 0 in this |
case. |
* Release 2007-12-01 |
- Optimize usbDeviceConnect() and usbDeviceDisconnect() for less code size |
when USB_CFG_PULLUP_IOPORTNAME is not defined. |
* Release 2007-12-13 |
- Renamed all include-only assembler modules from *.S to *.inc so that |
people don't add them to their project sources. |
- Distribute leap bits in tx loop more evenly for 16 MHz module. |
- Use "macro" and "endm" instead of ".macro" and ".endm" for IAR |
- Avoid compiler warnings for constant expr range by casting some values in |
USB descriptors. |
* Release 2008-01-21 |
- Fixed bug in 15 and 16 MHz module where the new address set with |
SET_ADDRESS was already accepted at the next NAK or ACK we send, not at |
the next data packet we send. This caused problems when the host polled |
too fast. Thanks to Alexander Neumann for his help and patience debugging |
this issue! |
* Release 2008-02-05 |
- Fixed bug in 16.5 MHz module where a register was used in the interrupt |
handler before it was pushed. This bug was introduced with version |
2007-09-19 when common parts were moved to a separate file. |
- Optimized CRC routine (thanks to Reimar Doeffinger). |
* Release 2008-02-16 |
- Removed outdated IAR compatibility stuff (code sections). |
- Added hook macros for USB_RESET_HOOK() and USB_SET_ADDRESS_HOOK(). |
- Added optional routine usbMeasureFrameLength() for calibration of the |
internal RC oscillator. |
* Release 2008-02-28 |
- USB_INITIAL_DATATOKEN defaults to USBPID_DATA1 now, which means that we |
start with sending USBPID_DATA0. |
- Changed defaults in usbconfig-prototype.h |
- Added free USB VID/PID pair for MIDI class devices |
- Restructured AVR-USB as separate package, not part of PowerSwitch any more. |
* Release 2008-04-18 |
- Restructured usbdrv.c so that it is easier to read and understand. |
- Better code optimization with gcc 4. |
- If a second interrupt in endpoint is enabled, also add it to config |
descriptor. |
- Added config option for long transfers (above 254 bytes), see |
USB_CFG_LONG_TRANSFERS in usbconfig.h. |
- Added 20 MHz module contributed by Jeroen Benschop. |
* Release 2008-05-13 |
- Fixed bug in libs-host/hiddata.c function usbhidGetReport(): length |
was not incremented, pointer to length was incremented instead. |
- Added code to command line tool(s) which claims an interface. This code |
is disabled by default, but may be necessary on newer Linux kernels. |
- Added usbconfig.h option "USB_CFG_CHECK_DATA_TOGGLING". |
- New header "usbportability.h" prepares ports to other development |
environments. |
- Long transfers (above 254 bytes) did not work when usbFunctionRead() was |
used to supply the data. Fixed this bug. [Thanks to Alexander Neumann!] |
- In hiddata.c (example code for sending/receiving data over HID), use |
USB_RECIP_DEVICE instead of USB_RECIP_INTERFACE for control transfers so |
that we need not claim the interface. |
- in usbPoll() loop 20 times polling for RESET state instead of 10 times. |
This accounts for the higher clock rates we now support. |
- Added a module for 12.8 MHz RC oscillator with PLL in receiver loop. |
- Added hook to SOF code so that oscillator can be tuned to USB frame clock. |
- Added timeout to waitForJ loop. Helps preventing unexpected hangs. |
- Added example code for oscillator tuning to libs-device (thanks to |
Henrik Haftmann for the idea to this routine). |
- Implemented option USB_CFG_SUPPRESS_INTR_CODE. |
* Release 2008-10-22 |
- Fixed libs-device/osctune.h: OSCCAL is memory address on ATMega88 and |
similar, not offset of 0x20 needs to be added. |
- Allow distribution under GPLv3 for those who have to link against other |
code distributed under GPLv3. |
* Release 2008-11-26 |
- Removed libusb-win32 dependency for hid-data example in Makefile.windows. |
It was never required and confused many people. |
- Added extern uchar usbRxToken to usbdrv.h. |
- Integrated a module with CRC checks at 18 MHz by Lukas Schrittwieser. |
* Release 2009-03-23 |
- Hid-mouse example used settings from hid-data example, fixed that. |
- Renamed project to V-USB due to a trademark issue with Atmel(r). |
- Changed CommercialLicense.txt and USBID-License.txt to make the |
background of USB ID registration clearer. |
* Release 2009-04-15 |
- Changed CommercialLicense.txt to reflect the new range of PIDs from |
Jason Kotzin. |
- Removed USBID-License.txt in favor of USB-IDs-for-free.txt and |
USB-ID-FAQ.txt |
- Fixed a bug in the 12.8 MHz module: End Of Packet decection was made in |
the center between bit 0 and 1 of each byte. This is where the data lines |
are expected to change and the sampled data may therefore be nonsense. |
We therefore check EOP ONLY if bits 0 AND 1 have both been read as 0 on D-. |
- Fixed a bitstuffing problem in the 16 MHz module: If bit 6 was stuffed, |
the unstuffing code in the receiver routine was 1 cycle too long. If |
multiple bytes had the unstuffing in bit 6, the error summed up until the |
receiver was out of sync. |
- Included option for faster CRC routine. |
Thanks to Slawomir Fras (BoskiDialer) for this code! |
- Updated bits in Configuration Descriptor's bmAttributes according to |
USB 1.1 (in particular bit 7, it is a must-be-set bit now). |
* Release 2009-08-22 |
- Moved first DBG1() after odDebugInit() in all examples. |
- Use vector INT0_vect instead of SIG_INTERRUPT0 if defined. This makes |
V-USB compatible with the new "p" suffix devices (e.g. ATMega328p). |
- USB_CFG_CLOCK_KHZ setting is now required in usbconfig.h (no default any |
more). |
- New option USB_CFG_DRIVER_FLASH_PAGE allows boot loaders on devices with |
more than 64 kB flash. |
- Built-in configuration descriptor allows custom definition for second |
endpoint now. |
* Release 2010-07-15 |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/CommercialLicense.txt |
---|
0,0 → 1,166 |
V-USB Driver Software License Agreement |
Version 2009-08-03 |
THIS LICENSE AGREEMENT GRANTS YOU CERTAIN RIGHTS IN A SOFTWARE. YOU CAN |
ENTER INTO THIS AGREEMENT AND ACQUIRE THE RIGHTS OUTLINED BELOW BY PAYING |
THE AMOUNT ACCORDING TO SECTION 4 ("PAYMENT") TO OBJECTIVE DEVELOPMENT. |
1 DEFINITIONS |
1.1 "OBJECTIVE DEVELOPMENT" shall mean OBJECTIVE DEVELOPMENT Software GmbH, |
Grosse Schiffgasse 1A/7, 1020 Wien, AUSTRIA. |
1.2 "You" shall mean the Licensee. |
1.3 "V-USB" shall mean all files included in the package distributed under |
the name "vusb" by OBJECTIVE DEVELOPMENT (http://www.obdev.at/vusb/) |
unless otherwise noted. This includes the firmware-only USB device |
implementation for Atmel AVR microcontrollers, some simple device examples |
and host side software examples and libraries. |
2 LICENSE GRANTS |
2.1 Source Code. OBJECTIVE DEVELOPMENT shall furnish you with the source |
code of V-USB. |
2.2 Distribution and Use. OBJECTIVE DEVELOPMENT grants you the |
non-exclusive right to use, copy and distribute V-USB with your hardware |
product(s), restricted by the limitations in section 3 below. |
2.3 Modifications. OBJECTIVE DEVELOPMENT grants you the right to modify |
the source code and your copy of V-USB according to your needs. |
2.4 USB IDs. OBJECTIVE DEVELOPMENT furnishes you with one or two USB |
Product ID(s), sent to you in e-mail. These Product IDs are reserved |
exclusively for you. OBJECTIVE DEVELOPMENT has obtained USB Product ID |
ranges under the Vendor ID 5824 from Wouter van Ooijen (Van Ooijen |
Technische Informatica, www.voti.nl) and under the Vendor ID 8352 from |
Jason Kotzin (Clay Logic, www.claylogic.com). Both owners of the Vendor IDs |
have obtained these IDs from the USB Implementers Forum, Inc. |
(www.usb.org). OBJECTIVE DEVELOPMENT disclaims all liability which might |
arise from the assignment of USB IDs. |
2.5 USB Certification. Although not part of this agreement, we want to make |
it clear that you cannot become USB certified when you use V-USB or a USB |
Product ID assigned by OBJECTIVE DEVELOPMENT. AVR microcontrollers don't |
meet the electrical specifications required by the USB specification and |
the USB Implementers Forum certifies only members who bought a Vendor ID of |
their own. |
3 LICENSE RESTRICTIONS |
3.1 Number of Units. Only one of the following three definitions is |
applicable. Which one is determined by the amount you pay to OBJECTIVE |
DEVELOPMENT, see section 4 ("Payment") below. |
Hobby License: You may use V-USB according to section 2 above in no more |
than 5 hardware units. These units must not be sold for profit. |
Entry Level License: You may use V-USB according to section 2 above in no |
more than 150 hardware units. |
Professional License: You may use V-USB according to section 2 above in |
any number of hardware units, except for large scale production ("unlimited |
fair use"). Quantities below 10,000 units are not considered large scale |
production. If your reach quantities which are obviously large scale |
production, you must pay a license fee of 0.10 EUR per unit for all units |
above 10,000. |
3.2 Rental. You may not rent, lease, or lend V-USB or otherwise encumber |
any copy of V-USB, or any of the rights granted herein. |
3.3 Transfer. You may not transfer your rights under this Agreement to |
another party without OBJECTIVE DEVELOPMENT's prior written consent. If |
such consent is obtained, you may permanently transfer this License to |
another party. The recipient of such transfer must agree to all terms and |
conditions of this Agreement. |
3.4 Reservation of Rights. OBJECTIVE DEVELOPMENT retains all rights not |
expressly granted. |
3.5 Non-Exclusive Rights. Your license rights under this Agreement are |
non-exclusive. |
3.6 Third Party Rights. This Agreement cannot grant you rights controlled |
by third parties. In particular, you are not allowed to use the USB logo or |
other trademarks owned by the USB Implementers Forum, Inc. without their |
consent. Since such consent depends on USB certification, it should be |
noted that V-USB will not pass certification because it does not |
implement checksum verification and the microcontroller ports do not meet |
the electrical specifications. |
4 PAYMENT |
The payment amount depends on the variation of this agreement (according to |
section 3.1) into which you want to enter. Concrete prices are listed on |
OBJECTIVE DEVELOPMENT's web site, usually at |
http://www.obdev.at/vusb/license.html. You agree to pay the amount listed |
there to OBJECTIVE DEVELOPMENT or OBJECTIVE DEVELOPMENT's payment processor |
or reseller. |
5 COPYRIGHT AND OWNERSHIP |
V-USB is protected by copyright laws and international copyright |
treaties, as well as other intellectual property laws and treaties. V-USB |
is licensed, not sold. |
6 TERM AND TERMINATION |
6.1 Term. This Agreement shall continue indefinitely. However, OBJECTIVE |
DEVELOPMENT may terminate this Agreement and revoke the granted license and |
USB-IDs if you fail to comply with any of its terms and conditions. |
6.2 Survival of Terms. All provisions regarding secrecy, confidentiality |
and limitation of liability shall survive termination of this agreement. |
7 DISCLAIMER OF WARRANTY AND LIABILITY |
LIMITED WARRANTY. V-USB IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY |
KIND. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, OBJECTIVE |
DEVELOPMENT AND ITS SUPPLIERS HEREBY DISCLAIM ALL WARRANTIES, EITHER |
EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE, AND |
NON-INFRINGEMENT, WITH REGARD TO V-USB, AND THE PROVISION OF OR FAILURE |
TO PROVIDE SUPPORT SERVICES. THIS LIMITED WARRANTY GIVES YOU SPECIFIC LEGAL |
RIGHTS. YOU MAY HAVE OTHERS, WHICH VARY FROM STATE/JURISDICTION TO |
STATE/JURISDICTION. |
LIMITATION OF LIABILITY. TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, |
IN NO EVENT SHALL OBJECTIVE DEVELOPMENT OR ITS SUPPLIERS BE LIABLE FOR ANY |
SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER |
(INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, |
BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY |
LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE V-USB OR THE |
PROVISION OF OR FAILURE TO PROVIDE SUPPORT SERVICES, EVEN IF OBJECTIVE |
DEVELOPMENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IN ANY |
CASE, OBJECTIVE DEVELOPMENT'S ENTIRE LIABILITY UNDER ANY PROVISION OF THIS |
AGREEMENT SHALL BE LIMITED TO THE AMOUNT ACTUALLY PAID BY YOU FOR V-USB. |
8 MISCELLANEOUS TERMS |
8.1 Marketing. OBJECTIVE DEVELOPMENT has the right to mention for marketing |
purposes that you entered into this agreement. |
8.2 Entire Agreement. This document represents the entire agreement between |
OBJECTIVE DEVELOPMENT and you. It may only be modified in writing signed by |
an authorized representative of both, OBJECTIVE DEVELOPMENT and you. |
8.3 Severability. In case a provision of these terms and conditions should |
be or become partly or entirely invalid, ineffective, or not executable, |
the validity of all other provisions shall not be affected. |
8.4 Applicable Law. This agreement is governed by the laws of the Republic |
of Austria. |
8.5 Responsible Courts. The responsible courts in Vienna/Austria will have |
exclusive jurisdiction regarding all disputes in connection with this |
agreement. |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/License.txt |
---|
0,0 → 1,361 |
OBJECTIVE DEVELOPMENT GmbH's V-USB driver software is distributed under the |
terms and conditions of the GNU GPL version 2 or the GNU GPL version 3. It is |
your choice whether you apply the terms of version 2 or version 3. The full |
text of GPLv2 is included below. In addition to the requirements in the GPL, |
we STRONGLY ENCOURAGE you to do the following: |
(1) Publish your entire project on a web site and drop us a note with the URL. |
Use the form at http://www.obdev.at/vusb/feedback.html for your submission. |
(2) Adhere to minimum publication standards. Please include AT LEAST: |
- a circuit diagram in PDF, PNG or GIF format |
- full source code for the host software |
- a Readme.txt file in ASCII format which describes the purpose of the |
project and what can be found in which directories and which files |
- a reference to http://www.obdev.at/vusb/ |
(3) If you improve the driver firmware itself, please give us a free license |
to your modifications for our commercial license offerings. |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/Readme.txt |
---|
0,0 → 1,172 |
This is the Readme file to Objective Development's firmware-only USB driver |
for Atmel AVR microcontrollers. For more information please visit |
http://www.obdev.at/vusb/ |
This directory contains the USB firmware only. Copy it as-is to your own |
project and add all .c and .S files to your project (these files are marked |
with an asterisk in the list below). Then copy usbconfig-prototype.h as |
usbconfig.h to your project and edit it according to your configuration. |
TECHNICAL DOCUMENTATION |
======================= |
The technical documentation (API) for the firmware driver is contained in the |
file "usbdrv.h". Please read all of it carefully! Configuration options are |
documented in "usbconfig-prototype.h". |
The driver consists of the following files: |
Readme.txt ............. The file you are currently reading. |
Changelog.txt .......... Release notes for all versions of the driver. |
usbdrv.h ............... Driver interface definitions and technical docs. |
* usbdrv.c ............... High level language part of the driver. Link this |
module to your code! |
* usbdrvasm.S ............ Assembler part of the driver. This module is mostly |
a stub and includes one of the usbdrvasm*.S files |
depending on processor clock. Link this module to |
your code! |
usbdrvasm*.inc ......... Assembler routines for particular clock frequencies. |
Included by usbdrvasm.S, don't link it directly! |
asmcommon.inc .......... Common assembler routines. Included by |
usbdrvasm*.inc, don't link it directly! |
usbconfig-prototype.h .. Prototype for your own usbdrv.h file. |
* oddebug.c .............. Debug functions. Only used when DEBUG_LEVEL is |
defined to a value greater than 0. Link this module |
to your code! |
oddebug.h .............. Interface definitions of the debug module. |
usbportability.h ....... Header with compiler-dependent stuff. |
usbdrvasm.asm .......... Compatibility stub for IAR-C-compiler. Use this |
module instead of usbdrvasm.S when you assembler |
with IAR's tools. |
License.txt ............ Open Source license for this driver. |
CommercialLicense.txt .. Optional commercial license for this driver. |
USB-ID-FAQ.txt ......... General infos about USB Product- and Vendor-IDs. |
USB-IDs-for-free.txt ... List and terms of use for free shared PIDs. |
(*) ... These files should be linked to your project. |
CPU CORE CLOCK FREQUENCY |
======================== |
We supply assembler modules for clock frequencies of 12 MHz, 12.8 MHz, 15 MHz, |
16 MHz, 16.5 MHz 18 MHz and 20 MHz. Other clock rates are not supported. The |
actual clock rate must be configured in usbconfig.h. |
12 MHz Clock |
This is the traditional clock rate of V-USB because it's the lowest clock |
rate where the timing constraints of the USB spec can be met. |
15 MHz Clock |
Similar to 12 MHz, but some NOPs inserted. On the other hand, the higher clock |
rate allows for some loops which make the resulting code size somewhat smaller |
than the 12 MHz version. |
16 MHz Clock |
This clock rate has been added for users of the Arduino board and other |
ready-made boards which come with a fixed 16 MHz crystal. It's also an option |
if you need the slightly higher clock rate for performance reasons. Since |
16 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code |
is somewhat tricky and has to insert a leap cycle every third byte. |
12.8 MHz and 16.5 MHz Clock |
The assembler modules for these clock rates differ from the other modules |
because they have been built for an RC oscillator with only 1% precision. The |
receiver code inserts leap cycles to compensate for clock deviations. 1% is |
also the precision which can be achieved by calibrating the internal RC |
oscillator of the AVR. Please note that only AVRs with internal 64 MHz PLL |
oscillator can reach 16.5 MHz with the RC oscillator. This includes the very |
popular ATTiny25, ATTiny45, ATTiny85 series as well as the ATTiny26. Almost |
all AVRs can reach 12.8 MHz, although this is outside the specified range. |
See the EasyLogger example at http://www.obdev.at/vusb/easylogger.html for |
code which calibrates the RC oscillator based on the USB frame clock. |
18 MHz Clock |
This module is closer to the USB specification because it performs an on the |
fly CRC check for incoming packets. Packets with invalid checksum are |
discarded as required by the spec. If you also implement checks for data |
PID toggling on application level (see option USB_CFG_CHECK_DATA_TOGGLING |
in usbconfig.h for more info), this ensures data integrity. Due to the CRC |
tables and alignment requirements, this code is bigger than modules for other |
clock rates. To activate this module, you must define USB_CFG_CHECK_CRC to 1 |
and USB_CFG_CLOCK_KHZ to 18000 in usbconfig.h. |
20 MHz Clock |
This module is for people who won't do it with less than the maximum. Since |
20 MHz is not divisible by the USB low speed bit clock of 1.5 MHz, the code |
uses similar tricks as the 16 MHz module to insert leap cycles. |
USB IDENTIFIERS |
=============== |
Every USB device needs a vendor- and a product-identifier (VID and PID). VIDs |
are obtained from usb.org for a price of 1,500 USD. Once you have a VID, you |
can assign PIDs at will. |
Since an entry level cost of 1,500 USD is too high for most small companies |
and hobbyists, we provide some VID/PID pairs for free. See the file |
USB-IDs-for-free.txt for details. |
Objective Development also has some license offerings which include product |
IDs. See http://www.obdev.at/vusb/ for details. |
DEVELOPMENT SYSTEM |
================== |
This driver has been developed and optimized for the GNU compiler version 3 |
and 4. We recommend that you use the GNU compiler suite because it is freely |
available. V-USB has also been ported to the IAR compiler and assembler. It |
has been tested with IAR 4.10B/W32 and 4.12A/W32 on an ATmega8 with the |
"small" and "tiny" memory model. Not every release is tested with IAR CC and |
the driver may therefore fail to compile with IAR. Please note that gcc is |
more efficient for usbdrv.c because this module has been deliberately |
optimized for gcc. |
Gcc version 3 produces smaller code than version 4 due to new optimizing |
capabilities which don't always improve things on 8 bit CPUs. The code size |
generated by gcc 4 can be reduced with the compiler options |
-fno-move-loop-invariants, -fno-tree-scev-cprop and |
-fno-inline-small-functions in addition to -Os. On devices with more than |
8k of flash memory, we also recommend the linker option --relax (written as |
-Wl,--relax for gcc) to convert absolute calls into relative where possible. |
For more information about optimizing options see: |
http://www.tty1.net/blog/2008-04-29-avr-gcc-optimisations_en.html |
These optimizations are good for gcc 4.x. Version 3.x of gcc does not support |
most of these options and produces good code anyway. |
USING V-USB FOR FREE |
==================== |
The AVR firmware driver is published under the GNU General Public License |
Version 2 (GPL2) and the GNU General Public License Version 3 (GPL3). It is |
your choice whether you apply the terms of version 2 or version 3. |
If you decide for the free GPL2 or GPL3, we STRONGLY ENCOURAGE you to do the |
following things IN ADDITION to the obligations from the GPL: |
(1) Publish your entire project on a web site and drop us a note with the URL. |
Use the form at http://www.obdev.at/vusb/feedback.html for your submission. |
If you don't have a web site, you can publish the project in obdev's |
documentation wiki at |
http://www.obdev.at/goto.php?t=vusb-wiki&p=hosted-projects. |
(2) Adhere to minimum publication standards. Please include AT LEAST: |
- a circuit diagram in PDF, PNG or GIF format |
- full source code for the host software |
- a Readme.txt file in ASCII format which describes the purpose of the |
project and what can be found in which directories and which files |
- a reference to http://www.obdev.at/vusb/ |
(3) If you improve the driver firmware itself, please give us a free license |
to your modifications for our commercial license offerings. |
COMMERCIAL LICENSES FOR V-USB |
============================= |
If you don't want to publish your source code under the terms of the GPL, |
you can simply pay money for V-USB. As an additional benefit you get |
USB PIDs for free, reserved exclusively to you. See the file |
"CommercialLicense.txt" for details. |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/USB-ID-FAQ.txt |
---|
0,0 → 1,149 |
Version 2009-08-22 |
========================== |
WHY DO WE NEED THESE IDs? |
========================== |
USB is more than a low level protocol for data transport. It also defines a |
common set of requests which must be understood by all devices. And as part |
of these common requests, the specification defines data structures, the |
USB Descriptors, which are used to describe the properties of the device. |
From the perspective of an operating system, it is therefore possible to find |
out basic properties of a device (such as e.g. the manufacturer and the name |
of the device) without a device-specific driver. This is essential because |
the operating system can choose a driver to load based on this information |
(Plug-And-Play). |
Among the most important properties in the Device Descriptor are the USB |
Vendor- and Product-ID. Both are 16 bit integers. The most simple form of |
driver matching is based on these IDs. The driver announces the Vendor- and |
Product-IDs of the devices it can handle and the operating system loads the |
appropriate driver when the device is connected. |
It is obvious that this technique only works if the pair Vendor- plus |
Product-ID is unique: Only devices which require the same driver can have the |
same pair of IDs. |
===================================================== |
HOW DOES THE USB STANDARD ENSURE THAT IDs ARE UNIQUE? |
===================================================== |
Since it is so important that USB IDs are unique, the USB Implementers Forum, |
Inc. (usb.org) needs a way to enforce this legally. It is not forbidden by |
law to build a device and assign it any random numbers as IDs. Usb.org |
therefore needs an agreement to regulate the use of USB IDs. The agreement |
binds only parties who agreed to it, of course. Everybody else is free to use |
any numbers for their IDs. |
So how can usb.org ensure that every manufacturer of USB devices enters into |
an agreement with them? They do it via trademark licensing. Usb.org has |
registered the trademark "USB", all associated logos and related terms. If |
you want to put an USB logo on your product or claim that it is USB |
compliant, you must license these trademarks from usb.org. And this is where |
you enter into an agreement. See the "USB-IF Trademark License Agreement and |
Usage Guidelines for the USB-IF Logo" at |
http://www.usb.org/developers/logo_license/. |
Licensing the USB trademarks requires that you buy a USB Vendor-ID from |
usb.org (one-time fee of ca. 2,000 USD), that you become a member of usb.org |
(yearly fee of ca. 4,000 USD) and that you meet all the technical |
specifications from the USB spec. |
This means that most hobbyists and small companies will never be able to |
become USB compliant, just because membership is so expensive. And you can't |
be compliant with a driver based on V-USB anyway, because the AVR's port pins |
don't meet the electrical specifications for USB. So, in principle, all |
hobbyists and small companies are free to choose any random numbers for their |
IDs. They have nothing to lose... |
There is one exception worth noting, though: If you use a sub-component which |
implements USB, the vendor of the sub-components may guarantee USB |
compliance. This might apply to some or all of FTDI's solutions. |
======================================================================= |
WHY SHOULD YOU OBTAIN USB IDs EVEN IF YOU DON'T LICENSE USB TRADEMARKS? |
======================================================================= |
You have learned in the previous section that you are free to choose any |
numbers for your IDs anyway. So why not do exactly this? There is still the |
technical issue. If you choose IDs which are already in use by somebody else, |
operating systems will load the wrong drivers and your device won't work. |
Even if you choose IDs which are not currently in use, they may be in use in |
the next version of the operating system or even after an automatic update. |
So what you need is a pair of Vendor- and Product-IDs for which you have the |
guarantee that no USB compliant product uses them. This implies that no |
operating system will ever ship with drivers responsible for these IDs. |
============================================== |
HOW DOES OBJECTIVE DEVELOPMENT HANDLE USB IDs? |
============================================== |
Objective Development gives away pairs of USB-IDs with their V-USB licenses. |
In order to ensure that these IDs are unique, Objective Development has an |
agreement with the company/person who has bought the USB Vendor-ID from |
usb.org. This agreement ensures that a range of USB Product-IDs is reserved |
for assignment by Objective Development and that the owner of the Vendor-ID |
won't give it to anybody else. |
This means that you have to trust three parties to ensure uniqueness of |
your IDs: |
- Objective Development, that they don't give the same PID to more than |
one person. |
- The owner of the Vendor-ID that they don't assign PIDs from the range |
assigned to Objective Development to anybody else. |
- Usb.org that they don't assign the same Vendor-ID a second time. |
================================== |
WHO IS THE OWNER OF THE VENDOR-ID? |
================================== |
Objective Development has obtained ranges of USB Product-IDs under two |
Vendor-IDs: Under Vendor-ID 5824 from Wouter van Ooijen (Van Ooijen |
Technische Informatica, www.voti.nl) and under Vendor-ID 8352 from Jason |
Kotzin (Clay Logic, www.claylogic.com). Both VID owners have received their |
Vendor-ID directly from usb.org. |
========================================================================= |
CAN I USE USB-IDs FROM OBJECTIVE DEVELOPMENT WITH OTHER DRIVERS/HARDWARE? |
========================================================================= |
The short answer is: Yes. All you get is a guarantee that the IDs are never |
assigned to anybody else. What more do you need? |
============================ |
WHAT ABOUT SHARED ID PAIRS? |
============================ |
Objective Development has reserved some PID/VID pairs for shared use. You |
have no guarantee of uniqueness for them, except that no USB compliant device |
uses them. In order to avoid technical problems, we must ensure that all |
devices with the same pair of IDs use the same driver on kernel level. For |
details, see the file USB-IDs-for-free.txt. |
====================================================== |
I HAVE HEARD THAT SUB-LICENSING OF USB-IDs IS ILLEGAL? |
====================================================== |
A 16 bit integer number cannot be protected by copyright laws. It is not |
sufficiently complex. And since none of the parties involved entered into the |
USB-IF Trademark License Agreement, we are not bound by this agreement. So |
there is no reason why it should be illegal to sub-license USB-IDs. |
============================================= |
WHO IS LIABLE IF THERE ARE INCOMPATIBILITIES? |
============================================= |
Objective Development disclaims all liabilities which might arise from the |
assignment of IDs. If you guarantee product features to your customers |
without proper disclaimer, YOU are liable for that. |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/USB-IDs-for-free.txt |
---|
0,0 → 1,148 |
Version 2009-08-22 |
=========================== |
FREE USB-IDs FOR SHARED USE |
=========================== |
Objective Development has reserved a set of USB Product-IDs for use according |
to the guidelines outlined below. For more information about the concept of |
USB IDs please see the file USB-ID-FAQ.txt. Objective Development guarantees |
that the IDs listed below are not used by any USB compliant devices. |
==================== |
MECHANISM OF SHARING |
==================== |
From a technical point of view, two different devices can share the same USB |
Vendor- and Product-ID if they require the same driver on operating system |
level. We make use of this fact by assigning separate IDs for various device |
classes. On application layer, devices must be distinguished by their textual |
name or serial number. We offer separate sets of IDs for discrimination by |
textual name and for serial number. |
Examples for shared use of USB IDs are included with V-USB in the "examples" |
subdirectory. |
====================================== |
IDs FOR DISCRIMINATION BY TEXTUAL NAME |
====================================== |
If you use one of the IDs listed below, your device and host-side software |
must conform to these rules: |
(1) The USB device MUST provide a textual representation of the manufacturer |
and product identification. The manufacturer identification MUST be available |
at least in USB language 0x0409 (English/US). |
(2) The textual manufacturer identification MUST contain either an Internet |
domain name (e.g. "mycompany.com") registered and owned by you, or an e-mail |
address under your control (e.g. "myname@gmx.net"). You can embed the domain |
name or e-mail address in any string you like, e.g. "Objective Development |
http://www.obdev.at/vusb/". |
(3) You are responsible for retaining ownership of the domain or e-mail |
address for as long as any of your products are in use. |
(4) You may choose any string for the textual product identification, as long |
as this string is unique within the scope of your textual manufacturer |
identification. |
(5) Application side device look-up MUST be based on the textual manufacturer |
and product identification in addition to VID/PID matching. The driver |
matching MUST be a comparison of the entire strings, NOT a sub-string match. |
(6) For devices which implement a particular USB device class (e.g. HID), the |
operating system's default class driver MUST be used. If an operating system |
driver for Vendor Class devices is needed, this driver must be libusb or |
libusb-win32 (see http://libusb.org/ and |
http://libusb-win32.sourceforge.net/). |
Table if IDs for discrimination by textual name: |
PID dec (hex) | VID dec (hex) | Description of use |
==============+===============+============================================ |
1500 (0x05dc) | 5824 (0x16c0) | For Vendor Class devices with libusb |
--------------+---------------+-------------------------------------------- |
1503 (0x05df) | 5824 (0x16c0) | For generic HID class devices (which are |
| | NOT mice, keyboards or joysticks) |
--------------+---------------+-------------------------------------------- |
1505 (0x05e1) | 5824 (0x16c0) | For CDC-ACM class devices (modems) |
--------------+---------------+-------------------------------------------- |
1508 (0x05e4) | 5824 (0x16c0) | For MIDI class devices |
--------------+---------------+-------------------------------------------- |
Note that Windows caches the textual product- and vendor-description for |
mice, keyboards and joysticks. Name-bsed discrimination is therefore not |
recommended for these device classes. |
======================================= |
IDs FOR DISCRIMINATION BY SERIAL NUMBER |
======================================= |
If you use one of the IDs listed below, your device and host-side software |
must conform to these rules: |
(1) The USB device MUST provide a textual representation of the serial |
number. The serial number string MUST be available at least in USB language |
0x0409 (English/US). |
(2) The serial number MUST start with either an Internet domain name (e.g. |
"mycompany.com") registered and owned by you, or an e-mail address under your |
control (e.g. "myname@gmx.net"), both terminated with a colon (":") character. |
You MAY append any string you like for further discrimination of your devices. |
(3) You are responsible for retaining ownership of the domain or e-mail |
address for as long as any of your products are in use. |
(5) Application side device look-up MUST be based on the serial number string |
in addition to VID/PID matching. The matching must start at the first |
character of the serial number string and include the colon character |
terminating your domain or e-mail address. It MAY stop anywhere after that. |
(6) For devices which implement a particular USB device class (e.g. HID), the |
operating system's default class driver MUST be used. If an operating system |
driver for Vendor Class devices is needed, this driver must be libusb or |
libusb-win32 (see http://libusb.org/ and |
http://libusb-win32.sourceforge.net/). |
Table if IDs for discrimination by serial number string: |
PID dec (hex) | VID dec (hex) | Description of use |
===============+===============+=========================================== |
10200 (0x27d8) | 5824 (0x16c0) | For Vendor Class devices with libusb |
---------------+---------------+------------------------------------------- |
10201 (0x27d9) | 5824 (0x16c0) | For generic HID class devices (which are |
| | NOT mice, keyboards or joysticks) |
---------------+---------------+------------------------------------------- |
10202 (0x27da) | 5824 (0x16c0) | For USB Mice |
---------------+---------------+------------------------------------------- |
10203 (0x27db) | 5824 (0x16c0) | For USB Keyboards |
---------------+---------------+------------------------------------------- |
10204 (0x27db) | 5824 (0x16c0) | For USB Joysticks |
---------------+---------------+------------------------------------------- |
10205 (0x27dc) | 5824 (0x16c0) | For CDC-ACM class devices (modems) |
---------------+---------------+------------------------------------------- |
10206 (0x27dd) | 5824 (0x16c0) | For MIDI class devices |
---------------+---------------+------------------------------------------- |
================= |
ORIGIN OF USB-IDs |
================= |
OBJECTIVE DEVELOPMENT Software GmbH has obtained all VID/PID pairs listed |
here from Wouter van Ooijen (see www.voti.nl) for exclusive disposition. |
Wouter van Ooijen has obtained the VID from the USB Implementers Forum, Inc. |
(see www.usb.org). The VID is registered for the company name "Van Ooijen |
Technische Informatica". |
========== |
DISCLAIMER |
========== |
OBJECTIVE DEVELOPMENT Software GmbH disclaims all liability for any |
problems which are caused by the shared use of these VID/PID pairs. |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/asmcommon.inc |
---|
0,0 → 1,188 |
/* Name: asmcommon.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2007-11-05 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id$ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file contains assembler code which is shared among the USB driver |
implementations for different CPU cocks. Since the code must be inserted |
in the middle of the module, it's split out into this file and #included. |
Jump destinations called from outside: |
sofError: Called when no start sequence was found. |
se0: Called when a package has been successfully received. |
overflow: Called when receive buffer overflows. |
doReturn: Called after sending data. |
Outside jump destinations used by this module: |
waitForJ: Called to receive an already arriving packet. |
sendAckAndReti: |
sendNakAndReti: |
sendCntAndReti: |
usbSendAndReti: |
The following macros must be defined before this file is included: |
.macro POP_STANDARD |
.endm |
.macro POP_RETI |
.endm |
*/ |
#define token x1 |
overflow: |
ldi x2, 1<<USB_INTR_PENDING_BIT |
USB_STORE_PENDING(x2) ; clear any pending interrupts |
ignorePacket: |
clr token |
rjmp storeTokenAndReturn |
;---------------------------------------------------------------------------- |
; Processing of received packet (numbers in brackets are cycles after center of SE0) |
;---------------------------------------------------------------------------- |
;This is the only non-error exit point for the software receiver loop |
;we don't check any CRCs here because there is no time left. |
se0: |
subi cnt, USB_BUFSIZE ;[5] |
neg cnt ;[6] |
sub YL, cnt ;[7] |
sbci YH, 0 ;[8] |
ldi x2, 1<<USB_INTR_PENDING_BIT ;[9] |
USB_STORE_PENDING(x2) ;[10] clear pending intr and check flag later. SE0 should be over. |
ld token, y ;[11] |
cpi token, USBPID_DATA0 ;[13] |
breq handleData ;[14] |
cpi token, USBPID_DATA1 ;[15] |
breq handleData ;[16] |
lds shift, usbDeviceAddr;[17] |
ldd x2, y+1 ;[19] ADDR and 1 bit endpoint number |
lsl x2 ;[21] shift out 1 bit endpoint number |
cpse x2, shift ;[22] |
rjmp ignorePacket ;[23] |
/* only compute endpoint number in x3 if required later */ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT || USB_CFG_IMPLEMENT_FN_WRITEOUT |
ldd x3, y+2 ;[24] endpoint number + crc |
rol x3 ;[26] shift in LSB of endpoint |
#endif |
cpi token, USBPID_IN ;[27] |
breq handleIn ;[28] |
cpi token, USBPID_SETUP ;[29] |
breq handleSetupOrOut ;[30] |
cpi token, USBPID_OUT ;[31] |
brne ignorePacket ;[32] must be ack, nak or whatever |
; rjmp handleSetupOrOut ; fallthrough |
;Setup and Out are followed by a data packet two bit times (16 cycles) after |
;the end of SE0. The sync code allows up to 40 cycles delay from the start of |
;the sync pattern until the first bit is sampled. That's a total of 56 cycles. |
handleSetupOrOut: ;[32] |
#if USB_CFG_IMPLEMENT_FN_WRITEOUT /* if we have data for endpoint != 0, set usbCurrentTok to address */ |
andi x3, 0xf ;[32] |
breq storeTokenAndReturn ;[33] |
mov token, x3 ;[34] indicate that this is endpoint x OUT |
#endif |
storeTokenAndReturn: |
sts usbCurrentTok, token;[35] |
doReturn: |
POP_STANDARD ;[37] 12...16 cycles |
USB_LOAD_PENDING(YL) ;[49] |
sbrc YL, USB_INTR_PENDING_BIT;[50] check whether data is already arriving |
rjmp waitForJ ;[51] save the pops and pushes -- a new interrupt is already pending |
sofError: |
POP_RETI ;macro call |
reti |
handleData: |
#if USB_CFG_CHECK_CRC |
CRC_CLEANUP_AND_CHECK ; jumps to ignorePacket if CRC error |
#endif |
lds shift, usbCurrentTok;[18] |
tst shift ;[20] |
breq doReturn ;[21] |
lds x2, usbRxLen ;[22] |
tst x2 ;[24] |
brne sendNakAndReti ;[25] |
; 2006-03-11: The following two lines fix a problem where the device was not |
; recognized if usbPoll() was called less frequently than once every 4 ms. |
cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and ack |
brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP |
#if USB_CFG_CHECK_DATA_TOGGLING |
sts usbCurrentDataToken, token ; store for checking by C code |
#endif |
sts usbRxLen, cnt ;[28] store received data, swap buffers |
sts usbRxToken, shift ;[30] |
lds x2, usbInputBufOffset;[32] swap buffers |
ldi cnt, USB_BUFSIZE ;[34] |
sub cnt, x2 ;[35] |
sts usbInputBufOffset, cnt;[36] buffers now swapped |
rjmp sendAckAndReti ;[38] 40 + 17 = 57 until SOP |
handleIn: |
;We don't send any data as long as the C code has not processed the current |
;input data and potentially updated the output data. That's more efficient |
;in terms of code size than clearing the tx buffers when a packet is received. |
lds x1, usbRxLen ;[30] |
cpi x1, 1 ;[32] negative values are flow control, 0 means "buffer free" |
brge sendNakAndReti ;[33] unprocessed input packet? |
ldi x1, USBPID_NAK ;[34] prepare value for usbTxLen |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
andi x3, 0xf ;[35] x3 contains endpoint |
#if USB_CFG_SUPPRESS_INTR_CODE |
brne sendNakAndReti ;[36] |
#else |
brne handleIn1 ;[36] |
#endif |
#endif |
lds cnt, usbTxLen ;[37] |
sbrc cnt, 4 ;[39] all handshake tokens have bit 4 set |
rjmp sendCntAndReti ;[40] 42 + 16 = 58 until SOP |
sts usbTxLen, x1 ;[41] x1 == USBPID_NAK from above |
ldi YL, lo8(usbTxBuf) ;[43] |
ldi YH, hi8(usbTxBuf) ;[44] |
rjmp usbSendAndReti ;[45] 57 + 12 = 59 until SOP |
; Comment about when to set usbTxLen to USBPID_NAK: |
; We should set it back when we receive the ACK from the host. This would |
; be simple to implement: One static variable which stores whether the last |
; tx was for endpoint 0 or 1 and a compare in the receiver to distinguish the |
; ACK. However, we set it back immediately when we send the package, |
; assuming that no error occurs and the host sends an ACK. We save one byte |
; RAM this way and avoid potential problems with endless retries. The rest of |
; the driver assumes error-free transfers anyway. |
#if !USB_CFG_SUPPRESS_INTR_CODE && USB_CFG_HAVE_INTRIN_ENDPOINT /* placed here due to relative jump range */ |
handleIn1: ;[38] |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
; 2006-06-10 as suggested by O.Tamura: support second INTR IN / BULK IN endpoint |
cpi x3, USB_CFG_EP3_NUMBER;[38] |
breq handleIn3 ;[39] |
#endif |
lds cnt, usbTxLen1 ;[40] |
sbrc cnt, 4 ;[42] all handshake tokens have bit 4 set |
rjmp sendCntAndReti ;[43] 47 + 16 = 63 until SOP |
sts usbTxLen1, x1 ;[44] x1 == USBPID_NAK from above |
ldi YL, lo8(usbTxBuf1) ;[46] |
ldi YH, hi8(usbTxBuf1) ;[47] |
rjmp usbSendAndReti ;[48] 50 + 12 = 62 until SOP |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
handleIn3: |
lds cnt, usbTxLen3 ;[41] |
sbrc cnt, 4 ;[43] |
rjmp sendCntAndReti ;[44] 49 + 16 = 65 until SOP |
sts usbTxLen3, x1 ;[45] x1 == USBPID_NAK from above |
ldi YL, lo8(usbTxBuf3) ;[47] |
ldi YH, hi8(usbTxBuf3) ;[48] |
rjmp usbSendAndReti ;[49] 51 + 12 = 63 until SOP |
#endif |
#endif |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/oddebug.c |
---|
0,0 → 1,50 |
/* Name: oddebug.c |
* Project: AVR library |
* Author: Christian Starkjohann |
* Creation Date: 2005-01-16 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: oddebug.c 692 2008-11-07 15:07:40Z cs $ |
*/ |
#include "oddebug.h" |
#if DEBUG_LEVEL > 0 |
#warning "Never compile production devices with debugging enabled" |
static void uartPutc(char c) |
{ |
while(!(ODDBG_USR & (1 << ODDBG_UDRE))); /* wait for data register empty */ |
ODDBG_UDR = c; |
} |
static uchar hexAscii(uchar h) |
{ |
h &= 0xf; |
if(h >= 10) |
h += 'a' - (uchar)10 - '0'; |
h += '0'; |
return h; |
} |
static void printHex(uchar c) |
{ |
uartPutc(hexAscii(c >> 4)); |
uartPutc(hexAscii(c)); |
} |
void odDebug(uchar prefix, uchar *data, uchar len) |
{ |
printHex(prefix); |
uartPutc(':'); |
while(len--){ |
uartPutc(' '); |
printHex(*data++); |
} |
uartPutc('\r'); |
uartPutc('\n'); |
} |
#endif |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/oddebug.h |
---|
0,0 → 1,123 |
/* Name: oddebug.h |
* Project: AVR library |
* Author: Christian Starkjohann |
* Creation Date: 2005-01-16 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: oddebug.h 692 2008-11-07 15:07:40Z cs $ |
*/ |
#ifndef __oddebug_h_included__ |
#define __oddebug_h_included__ |
/* |
General Description: |
This module implements a function for debug logs on the serial line of the |
AVR microcontroller. Debugging can be configured with the define |
'DEBUG_LEVEL'. If this macro is not defined or defined to 0, all debugging |
calls are no-ops. If it is 1, DBG1 logs will appear, but not DBG2. If it is |
2, DBG1 and DBG2 logs will be printed. |
A debug log consists of a label ('prefix') to indicate which debug log created |
the output and a memory block to dump in hex ('data' and 'len'). |
*/ |
#ifndef F_CPU |
# define F_CPU 12000000 /* 12 MHz */ |
#endif |
/* make sure we have the UART defines: */ |
#include "usbportability.h" |
#ifndef uchar |
# define uchar unsigned char |
#endif |
#if DEBUG_LEVEL > 0 && !(defined TXEN || defined TXEN0) /* no UART in device */ |
# warning "Debugging disabled because device has no UART" |
# undef DEBUG_LEVEL |
#endif |
#ifndef DEBUG_LEVEL |
# define DEBUG_LEVEL 0 |
#endif |
/* ------------------------------------------------------------------------- */ |
#if DEBUG_LEVEL > 0 |
# define DBG1(prefix, data, len) odDebug(prefix, data, len) |
#else |
# define DBG1(prefix, data, len) |
#endif |
#if DEBUG_LEVEL > 1 |
# define DBG2(prefix, data, len) odDebug(prefix, data, len) |
#else |
# define DBG2(prefix, data, len) |
#endif |
/* ------------------------------------------------------------------------- */ |
#if DEBUG_LEVEL > 0 |
extern void odDebug(uchar prefix, uchar *data, uchar len); |
/* Try to find our control registers; ATMEL likes to rename these */ |
#if defined UBRR |
# define ODDBG_UBRR UBRR |
#elif defined UBRRL |
# define ODDBG_UBRR UBRRL |
#elif defined UBRR0 |
# define ODDBG_UBRR UBRR0 |
#elif defined UBRR0L |
# define ODDBG_UBRR UBRR0L |
#endif |
#if defined UCR |
# define ODDBG_UCR UCR |
#elif defined UCSRB |
# define ODDBG_UCR UCSRB |
#elif defined UCSR0B |
# define ODDBG_UCR UCSR0B |
#endif |
#if defined TXEN |
# define ODDBG_TXEN TXEN |
#else |
# define ODDBG_TXEN TXEN0 |
#endif |
#if defined USR |
# define ODDBG_USR USR |
#elif defined UCSRA |
# define ODDBG_USR UCSRA |
#elif defined UCSR0A |
# define ODDBG_USR UCSR0A |
#endif |
#if defined UDRE |
# define ODDBG_UDRE UDRE |
#else |
# define ODDBG_UDRE UDRE0 |
#endif |
#if defined UDR |
# define ODDBG_UDR UDR |
#elif defined UDR0 |
# define ODDBG_UDR UDR0 |
#endif |
static inline void odDebugInit(void) |
{ |
ODDBG_UCR |= (1<<ODDBG_TXEN); |
ODDBG_UBRR = F_CPU / (19200 * 16L) - 1; |
} |
#else |
# define odDebugInit() |
#endif |
/* ------------------------------------------------------------------------- */ |
#endif /* __oddebug_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbconfig-prototype.h |
---|
0,0 → 1,376 |
/* Name: usbconfig.h |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2005-04-01 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbconfig-prototype.h 785 2010-05-30 17:57:07Z cs $ |
*/ |
#ifndef __usbconfig_h_included__ |
#define __usbconfig_h_included__ |
/* |
General Description: |
This file is an example configuration (with inline documentation) for the USB |
driver. It configures V-USB for USB D+ connected to Port D bit 2 (which is |
also hardware interrupt 0 on many devices) and USB D- to Port D bit 4. You may |
wire the lines to any other port, as long as D+ is also wired to INT0 (or any |
other hardware interrupt, as long as it is the highest level interrupt, see |
section at the end of this file). |
+ To create your own usbconfig.h file, copy this file to your project's |
+ firmware source directory) and rename it to "usbconfig.h". |
+ Then edit it accordingly. |
*/ |
/* ---------------------------- Hardware Config ---------------------------- */ |
#define USB_CFG_IOPORTNAME D |
/* This is the port where the USB bus is connected. When you configure it to |
* "B", the registers PORTB, PINB and DDRB will be used. |
*/ |
#define USB_CFG_DMINUS_BIT 4 |
/* This is the bit number in USB_CFG_IOPORT where the USB D- line is connected. |
* This may be any bit in the port. |
*/ |
#define USB_CFG_DPLUS_BIT 2 |
/* This is the bit number in USB_CFG_IOPORT where the USB D+ line is connected. |
* This may be any bit in the port. Please note that D+ must also be connected |
* to interrupt pin INT0! [You can also use other interrupts, see section |
* "Optional MCU Description" below, or you can connect D- to the interrupt, as |
* it is required if you use the USB_COUNT_SOF feature. If you use D- for the |
* interrupt, the USB interrupt will also be triggered at Start-Of-Frame |
* markers every millisecond.] |
*/ |
#define USB_CFG_CLOCK_KHZ (F_CPU/1000) |
/* Clock rate of the AVR in kHz. Legal values are 12000, 12800, 15000, 16000, |
* 16500, 18000 and 20000. The 12.8 MHz and 16.5 MHz versions of the code |
* require no crystal, they tolerate +/- 1% deviation from the nominal |
* frequency. All other rates require a precision of 2000 ppm and thus a |
* crystal! |
* Since F_CPU should be defined to your actual clock rate anyway, you should |
* not need to modify this setting. |
*/ |
#define USB_CFG_CHECK_CRC 0 |
/* Define this to 1 if you want that the driver checks integrity of incoming |
* data packets (CRC checks). CRC checks cost quite a bit of code size and are |
* currently only available for 18 MHz crystal clock. You must choose |
* USB_CFG_CLOCK_KHZ = 18000 if you enable this option. |
*/ |
/* ----------------------- Optional Hardware Config ------------------------ */ |
/* #define USB_CFG_PULLUP_IOPORTNAME D */ |
/* If you connect the 1.5k pullup resistor from D- to a port pin instead of |
* V+, you can connect and disconnect the device from firmware by calling |
* the macros usbDeviceConnect() and usbDeviceDisconnect() (see usbdrv.h). |
* This constant defines the port on which the pullup resistor is connected. |
*/ |
/* #define USB_CFG_PULLUP_BIT 4 */ |
/* This constant defines the bit number in USB_CFG_PULLUP_IOPORT (defined |
* above) where the 1.5k pullup resistor is connected. See description |
* above for details. |
*/ |
/* --------------------------- Functional Range ---------------------------- */ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT 0 |
/* Define this to 1 if you want to compile a version with two endpoints: The |
* default control endpoint 0 and an interrupt-in endpoint (any other endpoint |
* number). |
*/ |
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 |
/* Define this to 1 if you want to compile a version with three endpoints: The |
* default control endpoint 0, an interrupt-in endpoint 3 (or the number |
* configured below) and a catch-all default interrupt-in endpoint as above. |
* You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature. |
*/ |
#define USB_CFG_EP3_NUMBER 3 |
/* If the so-called endpoint 3 is used, it can now be configured to any other |
* endpoint number (except 0) with this macro. Default if undefined is 3. |
*/ |
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */ |
/* The above macro defines the startup condition for data toggling on the |
* interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1. |
* Since the token is toggled BEFORE sending any data, the first packet is |
* sent with the oposite value of this configuration! |
*/ |
#define USB_CFG_IMPLEMENT_HALT 0 |
/* Define this to 1 if you also want to implement the ENDPOINT_HALT feature |
* for endpoint 1 (interrupt endpoint). Although you may not need this feature, |
* it is required by the standard. We have made it a config option because it |
* bloats the code considerably. |
*/ |
#define USB_CFG_SUPPRESS_INTR_CODE 0 |
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't |
* want to send any data over them. If this macro is defined to 1, functions |
* usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if |
* you need the interrupt-in endpoints in order to comply to an interface |
* (e.g. HID), but never want to send any data. This option saves a couple |
* of bytes in flash memory and the transmit buffers in RAM. |
*/ |
#define USB_CFG_INTR_POLL_INTERVAL 10 |
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll |
* interval. The value is in milliseconds and must not be less than 10 ms for |
* low speed devices. |
*/ |
#define USB_CFG_IS_SELF_POWERED 0 |
/* Define this to 1 if the device has its own power supply. Set it to 0 if the |
* device is powered from the USB bus. |
*/ |
#define USB_CFG_MAX_BUS_POWER 100 |
/* Set this variable to the maximum USB bus power consumption of your device. |
* The value is in milliamperes. [It will be divided by two since USB |
* communicates power requirements in units of 2 mA.] |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITE 0 |
/* Set this to 1 if you want usbFunctionWrite() to be called for control-out |
* transfers. Set it to 0 if you don't need it and want to save a couple of |
* bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_READ 0 |
/* Set this to 1 if you need to send control replies which are generated |
* "on the fly" when usbFunctionRead() is called. If you only want to send |
* data from a static buffer, set it to 0 and return the data from |
* usbFunctionSetup(). This saves a couple of bytes. |
*/ |
#define USB_CFG_IMPLEMENT_FN_WRITEOUT 0 |
/* Define this to 1 if you want to use interrupt-out (or bulk out) endpoints. |
* You must implement the function usbFunctionWriteOut() which receives all |
* interrupt/bulk data sent to any endpoint other than 0. The endpoint number |
* can be found in 'usbRxToken'. |
*/ |
#define USB_CFG_HAVE_FLOWCONTROL 0 |
/* Define this to 1 if you want flowcontrol over USB data. See the definition |
* of the macros usbDisableAllRequests() and usbEnableAllRequests() in |
* usbdrv.h. |
*/ |
#define USB_CFG_DRIVER_FLASH_PAGE 0 |
/* If the device has more than 64 kBytes of flash, define this to the 64 k page |
* where the driver's constants (descriptors) are located. Or in other words: |
* Define this to 1 for boot loaders on the ATMega128. |
*/ |
#define USB_CFG_LONG_TRANSFERS 0 |
/* Define this to 1 if you want to send/receive blocks of more than 254 bytes |
* in a single control-in or control-out transfer. Note that the capability |
* for long transfers increases the driver size. |
*/ |
/* #define USB_RX_USER_HOOK(data, len) if(usbRxToken == (uchar)USBPID_SETUP) blinkLED(); */ |
/* This macro is a hook if you want to do unconventional things. If it is |
* defined, it's inserted at the beginning of received message processing. |
* If you eat the received message and don't want default processing to |
* proceed, do a return after doing your things. One possible application |
* (besides debugging) is to flash a status LED on each packet. |
*/ |
/* #define USB_RESET_HOOK(resetStarts) if(!resetStarts){hadUsbReset();} */ |
/* This macro is a hook if you need to know when an USB RESET occurs. It has |
* one parameter which distinguishes between the start of RESET state and its |
* end. |
*/ |
/* #define USB_SET_ADDRESS_HOOK() hadAddressAssigned(); */ |
/* This macro (if defined) is executed when a USB SET_ADDRESS request was |
* received. |
*/ |
#define USB_COUNT_SOF 0 |
/* define this macro to 1 if you need the global variable "usbSofCount" which |
* counts SOF packets. This feature requires that the hardware interrupt is |
* connected to D- instead of D+. |
*/ |
/* #ifdef __ASSEMBLER__ |
* macro myAssemblerMacro |
* in YL, TCNT0 |
* sts timer0Snapshot, YL |
* endm |
* #endif |
* #define USB_SOF_HOOK myAssemblerMacro |
* This macro (if defined) is executed in the assembler module when a |
* Start Of Frame condition is detected. It is recommended to define it to |
* the name of an assembler macro which is defined here as well so that more |
* than one assembler instruction can be used. The macro may use the register |
* YL and modify SREG. If it lasts longer than a couple of cycles, USB messages |
* immediately after an SOF pulse may be lost and must be retried by the host. |
* What can you do with this hook? Since the SOF signal occurs exactly every |
* 1 ms (unless the host is in sleep mode), you can use it to tune OSCCAL in |
* designs running on the internal RC oscillator. |
* Please note that Start Of Frame detection works only if D- is wired to the |
* interrupt, not D+. THIS IS DIFFERENT THAN MOST EXAMPLES! |
*/ |
#define USB_CFG_CHECK_DATA_TOGGLING 0 |
/* define this macro to 1 if you want to filter out duplicate data packets |
* sent by the host. Duplicates occur only as a consequence of communication |
* errors, when the host does not receive an ACK. Please note that you need to |
* implement the filtering yourself in usbFunctionWriteOut() and |
* usbFunctionWrite(). Use the global usbCurrentDataToken and a static variable |
* for each control- and out-endpoint to check for duplicate packets. |
*/ |
#define USB_CFG_HAVE_MEASURE_FRAME_LENGTH 0 |
/* define this macro to 1 if you want the function usbMeasureFrameLength() |
* compiled in. This function can be used to calibrate the AVR's RC oscillator. |
*/ |
#define USB_USE_FAST_CRC 0 |
/* The assembler module has two implementations for the CRC algorithm. One is |
* faster, the other is smaller. This CRC routine is only used for transmitted |
* messages where timing is not critical. The faster routine needs 31 cycles |
* per byte while the smaller one needs 61 to 69 cycles. The faster routine |
* may be worth the 32 bytes bigger code size if you transmit lots of data and |
* run the AVR close to its limit. |
*/ |
/* -------------------------- Device Description --------------------------- */ |
#define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */ |
/* USB vendor ID for the device, low byte first. If you have registered your |
* own Vendor ID, define it here. Otherwise you may use one of obdev's free |
* shared VID/PID pairs. Be sure to read USB-IDs-for-free.txt for rules! |
* *** IMPORTANT NOTE *** |
* This template uses obdev's shared VID/PID pair for Vendor Class devices |
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand |
* the implications! |
*/ |
#define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x05dc = 1500 */ |
/* This is the ID of the product, low byte first. It is interpreted in the |
* scope of the vendor ID. If you have registered your own VID with usb.org |
* or if you have licensed a PID from somebody else, define it here. Otherwise |
* you may use one of obdev's free shared VID/PID pairs. See the file |
* USB-IDs-for-free.txt for details! |
* *** IMPORTANT NOTE *** |
* This template uses obdev's shared VID/PID pair for Vendor Class devices |
* with libusb: 0x16c0/0x5dc. Use this VID/PID pair ONLY if you understand |
* the implications! |
*/ |
#define USB_CFG_DEVICE_VERSION 0x00, 0x01 |
/* Version number of the device: Minor number first, then major number. |
*/ |
#define USB_CFG_VENDOR_NAME 'o', 'b', 'd', 'e', 'v', '.', 'a', 't' |
#define USB_CFG_VENDOR_NAME_LEN 8 |
/* These two values define the vendor name returned by the USB device. The name |
* must be given as a list of characters under single quotes. The characters |
* are interpreted as Unicode (UTF-16) entities. |
* If you don't want a vendor name string, undefine these macros. |
* ALWAYS define a vendor name containing your Internet domain name if you use |
* obdev's free shared VID/PID pair. See the file USB-IDs-for-free.txt for |
* details. |
*/ |
#define USB_CFG_DEVICE_NAME 'T', 'e', 'm', 'p', 'l', 'a', 't', 'e' |
#define USB_CFG_DEVICE_NAME_LEN 8 |
/* Same as above for the device name. If you don't want a device name, undefine |
* the macros. See the file USB-IDs-for-free.txt before you assign a name if |
* you use a shared VID/PID. |
*/ |
/*#define USB_CFG_SERIAL_NUMBER 'N', 'o', 'n', 'e' */ |
/*#define USB_CFG_SERIAL_NUMBER_LEN 0 */ |
/* Same as above for the serial number. If you don't want a serial number, |
* undefine the macros. |
* It may be useful to provide the serial number through other means than at |
* compile time. See the section about descriptor properties below for how |
* to fine tune control over USB descriptors such as the string descriptor |
* for the serial number. |
*/ |
#define USB_CFG_DEVICE_CLASS 0xff /* set to 0 if deferred to interface */ |
#define USB_CFG_DEVICE_SUBCLASS 0 |
/* See USB specification if you want to conform to an existing device class. |
* Class 0xff is "vendor specific". |
*/ |
#define USB_CFG_INTERFACE_CLASS 0 /* define class here if not at device level */ |
#define USB_CFG_INTERFACE_SUBCLASS 0 |
#define USB_CFG_INTERFACE_PROTOCOL 0 |
/* See USB specification if you want to conform to an existing device class or |
* protocol. The following classes must be set at interface level: |
* HID class is 3, no subclass and protocol required (but may be useful!) |
* CDC class is 2, use subclass 2 and protocol 1 for ACM |
*/ |
/* #define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH 42 */ |
/* Define this to the length of the HID report descriptor, if you implement |
* an HID device. Otherwise don't define it or define it to 0. |
* If you use this define, you must add a PROGMEM character array named |
* "usbHidReportDescriptor" to your code which contains the report descriptor. |
* Don't forget to keep the array and this define in sync! |
*/ |
/* #define USB_PUBLIC static */ |
/* Use the define above if you #include usbdrv.c instead of linking against it. |
* This technique saves a couple of bytes in flash memory. |
*/ |
/* ------------------- Fine Control over USB Descriptors ------------------- */ |
/* If you don't want to use the driver's default USB descriptors, you can |
* provide our own. These can be provided as (1) fixed length static data in |
* flash memory, (2) fixed length static data in RAM or (3) dynamically at |
* runtime in the function usbFunctionDescriptor(). See usbdrv.h for more |
* information about this function. |
* Descriptor handling is configured through the descriptor's properties. If |
* no properties are defined or if they are 0, the default descriptor is used. |
* Possible properties are: |
* + USB_PROP_IS_DYNAMIC: The data for the descriptor should be fetched |
* at runtime via usbFunctionDescriptor(). If the usbMsgPtr mechanism is |
* used, the data is in FLASH by default. Add property USB_PROP_IS_RAM if |
* you want RAM pointers. |
* + USB_PROP_IS_RAM: The data returned by usbFunctionDescriptor() or found |
* in static memory is in RAM, not in flash memory. |
* + USB_PROP_LENGTH(len): If the data is in static memory (RAM or flash), |
* the driver must know the descriptor's length. The descriptor itself is |
* found at the address of a well known identifier (see below). |
* List of static descriptor names (must be declared PROGMEM if in flash): |
* char usbDescriptorDevice[]; |
* char usbDescriptorConfiguration[]; |
* char usbDescriptorHidReport[]; |
* char usbDescriptorString0[]; |
* int usbDescriptorStringVendor[]; |
* int usbDescriptorStringDevice[]; |
* int usbDescriptorStringSerialNumber[]; |
* Other descriptors can't be provided statically, they must be provided |
* dynamically at runtime. |
* |
* Descriptor properties are or-ed or added together, e.g.: |
* #define USB_CFG_DESCR_PROPS_DEVICE (USB_PROP_IS_RAM | USB_PROP_LENGTH(18)) |
* |
* The following descriptors are defined: |
* USB_CFG_DESCR_PROPS_DEVICE |
* USB_CFG_DESCR_PROPS_CONFIGURATION |
* USB_CFG_DESCR_PROPS_STRINGS |
* USB_CFG_DESCR_PROPS_STRING_0 |
* USB_CFG_DESCR_PROPS_STRING_VENDOR |
* USB_CFG_DESCR_PROPS_STRING_PRODUCT |
* USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
* USB_CFG_DESCR_PROPS_HID |
* USB_CFG_DESCR_PROPS_HID_REPORT |
* USB_CFG_DESCR_PROPS_UNKNOWN (for all descriptors not handled by the driver) |
* |
* Note about string descriptors: String descriptors are not just strings, they |
* are Unicode strings prefixed with a 2 byte header. Example: |
* int serialNumberDescriptor[] = { |
* USB_STRING_DESCRIPTOR_HEADER(6), |
* 'S', 'e', 'r', 'i', 'a', 'l' |
* }; |
*/ |
#define USB_CFG_DESCR_PROPS_DEVICE 0 |
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 |
#define USB_CFG_DESCR_PROPS_STRINGS 0 |
#define USB_CFG_DESCR_PROPS_STRING_0 0 |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 |
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 |
#define USB_CFG_DESCR_PROPS_HID 0 |
#define USB_CFG_DESCR_PROPS_HID_REPORT 0 |
#define USB_CFG_DESCR_PROPS_UNKNOWN 0 |
/* ----------------------- Optional MCU Description ------------------------ */ |
/* The following configurations have working defaults in usbdrv.h. You |
* usually don't need to set them explicitly. Only if you want to run |
* the driver on a device which is not yet supported or with a compiler |
* which is not fully supported (such as IAR C) or if you use a differnt |
* interrupt than INT0, you may have to define some of these. |
*/ |
/* #define USB_INTR_CFG MCUCR */ |
/* #define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) */ |
/* #define USB_INTR_CFG_CLR 0 */ |
/* #define USB_INTR_ENABLE GIMSK */ |
/* #define USB_INTR_ENABLE_BIT INT0 */ |
/* #define USB_INTR_PENDING GIFR */ |
/* #define USB_INTR_PENDING_BIT INTF0 */ |
/* #define USB_INTR_VECTOR INT0_vect */ |
#endif /* __usbconfig_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrv.c |
---|
0,0 → 1,625 |
/* Name: usbdrv.c |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2004-12-29 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrv.c 791 2010-07-15 15:56:13Z cs $ |
*/ |
#include "usbportability.h" |
#include "usbdrv.h" |
#include "oddebug.h" |
/* |
General Description: |
This module implements the C-part of the USB driver. See usbdrv.h for a |
documentation of the entire driver. |
*/ |
/* ------------------------------------------------------------------------- */ |
/* raw USB registers / interface to assembler code: */ |
uchar usbRxBuf[2*USB_BUFSIZE]; /* raw RX buffer: PID, 8 bytes data, 2 bytes CRC */ |
uchar usbInputBufOffset; /* offset in usbRxBuf used for low level receiving */ |
uchar usbDeviceAddr; /* assigned during enumeration, defaults to 0 */ |
uchar usbNewDeviceAddr; /* device ID which should be set after status phase */ |
uchar usbConfiguration; /* currently selected configuration. Administered by driver, but not used */ |
volatile schar usbRxLen; /* = 0; number of bytes in usbRxBuf; 0 means free, -1 for flow control */ |
uchar usbCurrentTok; /* last token received or endpoint number for last OUT token if != 0 */ |
uchar usbRxToken; /* token for data we received; or endpont number for last OUT */ |
volatile uchar usbTxLen = USBPID_NAK; /* number of bytes to transmit with next IN token or handshake token */ |
uchar usbTxBuf[USB_BUFSIZE];/* data to transmit with next IN, free if usbTxLen contains handshake token */ |
#if USB_COUNT_SOF |
volatile uchar usbSofCount; /* incremented by assembler module every SOF */ |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE |
usbTxStatus_t usbTxStatus1; |
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
usbTxStatus_t usbTxStatus3; |
# endif |
#endif |
#if USB_CFG_CHECK_DATA_TOGGLING |
uchar usbCurrentDataToken;/* when we check data toggling to ignore duplicate packets */ |
#endif |
/* USB status registers / not shared with asm code */ |
uchar *usbMsgPtr; /* data to transmit next -- ROM or RAM address */ |
static usbMsgLen_t usbMsgLen = USB_NO_MSG; /* remaining number of bytes */ |
static uchar usbMsgFlags; /* flag values see below */ |
#define USB_FLG_MSGPTR_IS_ROM (1<<6) |
#define USB_FLG_USE_USER_RW (1<<7) |
/* |
optimizing hints: |
- do not post/pre inc/dec integer values in operations |
- assign value of USB_READ_FLASH() to register variables and don't use side effects in arg |
- use narrow scope for variables which should be in X/Y/Z register |
- assign char sized expressions to variables to force 8 bit arithmetics |
*/ |
/* -------------------------- String Descriptors --------------------------- */ |
#if USB_CFG_DESCR_PROPS_STRINGS == 0 |
#if USB_CFG_DESCR_PROPS_STRING_0 == 0 |
#undef USB_CFG_DESCR_PROPS_STRING_0 |
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0) |
PROGMEM char usbDescriptorString0[] = { /* language descriptor */ |
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */ |
3, /* descriptor type */ |
0x09, 0x04, /* language index (0x0409 = US-English) */ |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN |
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor) |
PROGMEM int usbDescriptorStringVendor[] = { |
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN), |
USB_CFG_VENDOR_NAME |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN |
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT |
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice) |
PROGMEM int usbDescriptorStringDevice[] = { |
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN), |
USB_CFG_DEVICE_NAME |
}; |
#endif |
#if USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER == 0 && USB_CFG_SERIAL_NUMBER_LEN |
#undef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER sizeof(usbDescriptorStringSerialNumber) |
PROGMEM int usbDescriptorStringSerialNumber[] = { |
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_SERIAL_NUMBER_LEN), |
USB_CFG_SERIAL_NUMBER |
}; |
#endif |
#endif /* USB_CFG_DESCR_PROPS_STRINGS == 0 */ |
/* --------------------------- Device Descriptor --------------------------- */ |
#if USB_CFG_DESCR_PROPS_DEVICE == 0 |
#undef USB_CFG_DESCR_PROPS_DEVICE |
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice) |
PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */ |
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */ |
USBDESCR_DEVICE, /* descriptor type */ |
0x10, 0x01, /* USB version supported */ |
USB_CFG_DEVICE_CLASS, |
USB_CFG_DEVICE_SUBCLASS, |
0, /* protocol */ |
8, /* max packet size */ |
/* the following two casts affect the first byte of the constant only, but |
* that's sufficient to avoid a warning with the default values. |
*/ |
(char)USB_CFG_VENDOR_ID,/* 2 bytes */ |
(char)USB_CFG_DEVICE_ID,/* 2 bytes */ |
USB_CFG_DEVICE_VERSION, /* 2 bytes */ |
USB_CFG_DESCR_PROPS_STRING_VENDOR != 0 ? 1 : 0, /* manufacturer string index */ |
USB_CFG_DESCR_PROPS_STRING_PRODUCT != 0 ? 2 : 0, /* product string index */ |
USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER != 0 ? 3 : 0, /* serial number string index */ |
1, /* number of configurations */ |
}; |
#endif |
/* ----------------------- Configuration Descriptor ------------------------ */ |
#if USB_CFG_DESCR_PROPS_HID_REPORT != 0 && USB_CFG_DESCR_PROPS_HID == 0 |
#undef USB_CFG_DESCR_PROPS_HID |
#define USB_CFG_DESCR_PROPS_HID 9 /* length of HID descriptor in config descriptor below */ |
#endif |
#if USB_CFG_DESCR_PROPS_CONFIGURATION == 0 |
#undef USB_CFG_DESCR_PROPS_CONFIGURATION |
#define USB_CFG_DESCR_PROPS_CONFIGURATION sizeof(usbDescriptorConfiguration) |
PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */ |
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */ |
USBDESCR_CONFIG, /* descriptor type */ |
18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + |
(USB_CFG_DESCR_PROPS_HID & 0xff), 0, |
/* total length of data returned (including inlined descriptors) */ |
1, /* number of interfaces in this configuration */ |
1, /* index of this configuration */ |
0, /* configuration name string index */ |
#if USB_CFG_IS_SELF_POWERED |
(1 << 7) | USBATTR_SELFPOWER, /* attributes */ |
#else |
(1 << 7), /* attributes */ |
#endif |
USB_CFG_MAX_BUS_POWER/2, /* max USB current in 2mA units */ |
/* interface descriptor follows inline: */ |
9, /* sizeof(usbDescrInterface): length of descriptor in bytes */ |
USBDESCR_INTERFACE, /* descriptor type */ |
0, /* index of this interface */ |
0, /* alternate setting for this interface */ |
USB_CFG_HAVE_INTRIN_ENDPOINT + USB_CFG_HAVE_INTRIN_ENDPOINT3, /* endpoints excl 0: number of endpoint descriptors to follow */ |
USB_CFG_INTERFACE_CLASS, |
USB_CFG_INTERFACE_SUBCLASS, |
USB_CFG_INTERFACE_PROTOCOL, |
0, /* string index for interface */ |
#if (USB_CFG_DESCR_PROPS_HID & 0xff) /* HID descriptor */ |
9, /* sizeof(usbDescrHID): length of descriptor in bytes */ |
USBDESCR_HID, /* descriptor type: HID */ |
0x01, 0x01, /* BCD representation of HID version */ |
0x00, /* target country code */ |
0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */ |
0x22, /* descriptor type: report */ |
USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0, /* total length of report descriptor */ |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT /* endpoint descriptor for endpoint 1 */ |
7, /* sizeof(usbDescrEndpoint) */ |
USBDESCR_ENDPOINT, /* descriptor type = endpoint */ |
(char)0x81, /* IN endpoint number 1 */ |
0x03, /* attrib: Interrupt endpoint */ |
8, 0, /* maximum packet size */ |
USB_CFG_INTR_POLL_INTERVAL, /* in ms */ |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */ |
7, /* sizeof(usbDescrEndpoint) */ |
USBDESCR_ENDPOINT, /* descriptor type = endpoint */ |
(char)(0x80 | USB_CFG_EP3_NUMBER), /* IN endpoint number 3 */ |
0x03, /* attrib: Interrupt endpoint */ |
8, 0, /* maximum packet size */ |
USB_CFG_INTR_POLL_INTERVAL, /* in ms */ |
#endif |
}; |
#endif |
/* ------------------------------------------------------------------------- */ |
static inline void usbResetDataToggling(void) |
{ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE |
USB_SET_DATATOKEN1(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */ |
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
USB_SET_DATATOKEN3(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */ |
# endif |
#endif |
} |
static inline void usbResetStall(void) |
{ |
#if USB_CFG_IMPLEMENT_HALT && USB_CFG_HAVE_INTRIN_ENDPOINT |
usbTxLen1 = USBPID_NAK; |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
usbTxLen3 = USBPID_NAK; |
#endif |
#endif |
} |
/* ------------------------------------------------------------------------- */ |
#if !USB_CFG_SUPPRESS_INTR_CODE |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
static void usbGenericSetInterrupt(uchar *data, uchar len, usbTxStatus_t *txStatus) |
{ |
uchar *p; |
char i; |
#if USB_CFG_IMPLEMENT_HALT |
if(usbTxLen1 == USBPID_STALL) |
return; |
#endif |
if(txStatus->len & 0x10){ /* packet buffer was empty */ |
txStatus->buffer[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* toggle token */ |
}else{ |
txStatus->len = USBPID_NAK; /* avoid sending outdated (overwritten) interrupt data */ |
} |
p = txStatus->buffer + 1; |
i = len; |
do{ /* if len == 0, we still copy 1 byte, but that's no problem */ |
*p++ = *data++; |
}while(--i > 0); /* loop control at the end is 2 bytes shorter than at beginning */ |
usbCrc16Append(&txStatus->buffer[1], len); |
txStatus->len = len + 4; /* len must be given including sync byte */ |
DBG2(0x21 + (((int)txStatus >> 3) & 3), txStatus->buffer, len + 3); |
} |
USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len) |
{ |
usbGenericSetInterrupt(data, len, &usbTxStatus1); |
} |
#endif |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len) |
{ |
usbGenericSetInterrupt(data, len, &usbTxStatus3); |
} |
#endif |
#endif /* USB_CFG_SUPPRESS_INTR_CODE */ |
/* ------------------ utilities for code following below ------------------- */ |
/* Use defines for the switch statement so that we can choose between an |
* if()else if() and a switch/case based implementation. switch() is more |
* efficient for a LARGE set of sequential choices, if() is better in all other |
* cases. |
*/ |
#if USB_CFG_USE_SWITCH_STATEMENT |
# define SWITCH_START(cmd) switch(cmd){{ |
# define SWITCH_CASE(value) }break; case (value):{ |
# define SWITCH_CASE2(v1,v2) }break; case (v1): case(v2):{ |
# define SWITCH_CASE3(v1,v2,v3) }break; case (v1): case(v2): case(v3):{ |
# define SWITCH_DEFAULT }break; default:{ |
# define SWITCH_END }} |
#else |
# define SWITCH_START(cmd) {uchar _cmd = cmd; if(0){ |
# define SWITCH_CASE(value) }else if(_cmd == (value)){ |
# define SWITCH_CASE2(v1,v2) }else if(_cmd == (v1) || _cmd == (v2)){ |
# define SWITCH_CASE3(v1,v2,v3) }else if(_cmd == (v1) || _cmd == (v2) || (_cmd == v3)){ |
# define SWITCH_DEFAULT }else{ |
# define SWITCH_END }} |
#endif |
#ifndef USB_RX_USER_HOOK |
#define USB_RX_USER_HOOK(data, len) |
#endif |
#ifndef USB_SET_ADDRESS_HOOK |
#define USB_SET_ADDRESS_HOOK() |
#endif |
/* ------------------------------------------------------------------------- */ |
/* We use if() instead of #if in the macro below because #if can't be used |
* in macros and the compiler optimizes constant conditions anyway. |
* This may cause problems with undefined symbols if compiled without |
* optimizing! |
*/ |
#define GET_DESCRIPTOR(cfgProp, staticName) \ |
if(cfgProp){ \ |
if((cfgProp) & USB_PROP_IS_RAM) \ |
flags = 0; \ |
if((cfgProp) & USB_PROP_IS_DYNAMIC){ \ |
len = usbFunctionDescriptor(rq); \ |
}else{ \ |
len = USB_PROP_LENGTH(cfgProp); \ |
usbMsgPtr = (uchar *)(staticName); \ |
} \ |
} |
/* usbDriverDescriptor() is similar to usbFunctionDescriptor(), but used |
* internally for all types of descriptors. |
*/ |
static inline usbMsgLen_t usbDriverDescriptor(usbRequest_t *rq) |
{ |
usbMsgLen_t len = 0; |
uchar flags = USB_FLG_MSGPTR_IS_ROM; |
SWITCH_START(rq->wValue.bytes[1]) |
SWITCH_CASE(USBDESCR_DEVICE) /* 1 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_DEVICE, usbDescriptorDevice) |
SWITCH_CASE(USBDESCR_CONFIG) /* 2 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_CONFIGURATION, usbDescriptorConfiguration) |
SWITCH_CASE(USBDESCR_STRING) /* 3 */ |
#if USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC |
if(USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_RAM) |
flags = 0; |
len = usbFunctionDescriptor(rq); |
#else /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ |
SWITCH_START(rq->wValue.bytes[0]) |
SWITCH_CASE(0) |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_0, usbDescriptorString0) |
SWITCH_CASE(1) |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_VENDOR, usbDescriptorStringVendor) |
SWITCH_CASE(2) |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_PRODUCT, usbDescriptorStringDevice) |
SWITCH_CASE(3) |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER, usbDescriptorStringSerialNumber) |
SWITCH_DEFAULT |
if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ |
len = usbFunctionDescriptor(rq); |
} |
SWITCH_END |
#endif /* USB_CFG_DESCR_PROPS_STRINGS & USB_PROP_IS_DYNAMIC */ |
#if USB_CFG_DESCR_PROPS_HID_REPORT /* only support HID descriptors if enabled */ |
SWITCH_CASE(USBDESCR_HID) /* 0x21 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID, usbDescriptorConfiguration + 18) |
SWITCH_CASE(USBDESCR_HID_REPORT)/* 0x22 */ |
GET_DESCRIPTOR(USB_CFG_DESCR_PROPS_HID_REPORT, usbDescriptorHidReport) |
#endif |
SWITCH_DEFAULT |
if(USB_CFG_DESCR_PROPS_UNKNOWN & USB_PROP_IS_DYNAMIC){ |
len = usbFunctionDescriptor(rq); |
} |
SWITCH_END |
usbMsgFlags = flags; |
return len; |
} |
/* ------------------------------------------------------------------------- */ |
/* usbDriverSetup() is similar to usbFunctionSetup(), but it's used for |
* standard requests instead of class and custom requests. |
*/ |
static inline usbMsgLen_t usbDriverSetup(usbRequest_t *rq) |
{ |
uchar len = 0, *dataPtr = usbTxBuf + 9; /* there are 2 bytes free space at the end of the buffer */ |
uchar value = rq->wValue.bytes[0]; |
#if USB_CFG_IMPLEMENT_HALT |
uchar index = rq->wIndex.bytes[0]; |
#endif |
dataPtr[0] = 0; /* default reply common to USBRQ_GET_STATUS and USBRQ_GET_INTERFACE */ |
SWITCH_START(rq->bRequest) |
SWITCH_CASE(USBRQ_GET_STATUS) /* 0 */ |
uchar recipient = rq->bmRequestType & USBRQ_RCPT_MASK; /* assign arith ops to variables to enforce byte size */ |
if(USB_CFG_IS_SELF_POWERED && recipient == USBRQ_RCPT_DEVICE) |
dataPtr[0] = USB_CFG_IS_SELF_POWERED; |
#if USB_CFG_IMPLEMENT_HALT |
if(recipient == USBRQ_RCPT_ENDPOINT && index == 0x81) /* request status for endpoint 1 */ |
dataPtr[0] = usbTxLen1 == USBPID_STALL; |
#endif |
dataPtr[1] = 0; |
len = 2; |
#if USB_CFG_IMPLEMENT_HALT |
SWITCH_CASE2(USBRQ_CLEAR_FEATURE, USBRQ_SET_FEATURE) /* 1, 3 */ |
if(value == 0 && index == 0x81){ /* feature 0 == HALT for endpoint == 1 */ |
usbTxLen1 = rq->bRequest == USBRQ_CLEAR_FEATURE ? USBPID_NAK : USBPID_STALL; |
usbResetDataToggling(); |
} |
#endif |
SWITCH_CASE(USBRQ_SET_ADDRESS) /* 5 */ |
usbNewDeviceAddr = value; |
USB_SET_ADDRESS_HOOK(); |
SWITCH_CASE(USBRQ_GET_DESCRIPTOR) /* 6 */ |
len = usbDriverDescriptor(rq); |
goto skipMsgPtrAssignment; |
SWITCH_CASE(USBRQ_GET_CONFIGURATION) /* 8 */ |
dataPtr = &usbConfiguration; /* send current configuration value */ |
len = 1; |
SWITCH_CASE(USBRQ_SET_CONFIGURATION) /* 9 */ |
usbConfiguration = value; |
usbResetStall(); |
SWITCH_CASE(USBRQ_GET_INTERFACE) /* 10 */ |
len = 1; |
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE |
SWITCH_CASE(USBRQ_SET_INTERFACE) /* 11 */ |
usbResetDataToggling(); |
usbResetStall(); |
#endif |
SWITCH_DEFAULT /* 7=SET_DESCRIPTOR, 12=SYNC_FRAME */ |
/* Should we add an optional hook here? */ |
SWITCH_END |
usbMsgPtr = dataPtr; |
skipMsgPtrAssignment: |
return len; |
} |
/* ------------------------------------------------------------------------- */ |
/* usbProcessRx() is called for every message received by the interrupt |
* routine. It distinguishes between SETUP and DATA packets and processes |
* them accordingly. |
*/ |
static inline void usbProcessRx(uchar *data, uchar len) |
{ |
usbRequest_t *rq = (void *)data; |
/* usbRxToken can be: |
* 0x2d 00101101 (USBPID_SETUP for setup data) |
* 0xe1 11100001 (USBPID_OUT: data phase of setup transfer) |
* 0...0x0f for OUT on endpoint X |
*/ |
DBG2(0x10 + (usbRxToken & 0xf), data, len + 2); /* SETUP=1d, SETUP-DATA=11, OUTx=1x */ |
USB_RX_USER_HOOK(data, len) |
#if USB_CFG_IMPLEMENT_FN_WRITEOUT |
if(usbRxToken < 0x10){ /* OUT to endpoint != 0: endpoint number in usbRxToken */ |
usbFunctionWriteOut(data, len); |
return; |
} |
#endif |
if(usbRxToken == (uchar)USBPID_SETUP){ |
if(len != 8) /* Setup size must be always 8 bytes. Ignore otherwise. */ |
return; |
usbMsgLen_t replyLen; |
usbTxBuf[0] = USBPID_DATA0; /* initialize data toggling */ |
usbTxLen = USBPID_NAK; /* abort pending transmit */ |
usbMsgFlags = 0; |
uchar type = rq->bmRequestType & USBRQ_TYPE_MASK; |
if(type != USBRQ_TYPE_STANDARD){ /* standard requests are handled by driver */ |
replyLen = usbFunctionSetup(data); |
}else{ |
replyLen = usbDriverSetup(rq); |
} |
#if USB_CFG_IMPLEMENT_FN_READ || USB_CFG_IMPLEMENT_FN_WRITE |
if(replyLen == USB_NO_MSG){ /* use user-supplied read/write function */ |
/* do some conditioning on replyLen, but on IN transfers only */ |
if((rq->bmRequestType & USBRQ_DIR_MASK) != USBRQ_DIR_HOST_TO_DEVICE){ |
if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ |
replyLen = rq->wLength.bytes[0]; |
}else{ |
replyLen = rq->wLength.word; |
} |
} |
usbMsgFlags = USB_FLG_USE_USER_RW; |
}else /* The 'else' prevents that we limit a replyLen of USB_NO_MSG to the maximum transfer len. */ |
#endif |
if(sizeof(replyLen) < sizeof(rq->wLength.word)){ /* help compiler with optimizing */ |
if(!rq->wLength.bytes[1] && replyLen > rq->wLength.bytes[0]) /* limit length to max */ |
replyLen = rq->wLength.bytes[0]; |
}else{ |
if(replyLen > rq->wLength.word) /* limit length to max */ |
replyLen = rq->wLength.word; |
} |
usbMsgLen = replyLen; |
}else{ /* usbRxToken must be USBPID_OUT, which means data phase of setup (control-out) */ |
#if USB_CFG_IMPLEMENT_FN_WRITE |
if(usbMsgFlags & USB_FLG_USE_USER_RW){ |
uchar rval = usbFunctionWrite(data, len); |
if(rval == 0xff){ /* an error occurred */ |
usbTxLen = USBPID_STALL; |
}else if(rval != 0){ /* This was the final package */ |
usbMsgLen = 0; /* answer with a zero-sized data packet */ |
} |
} |
#endif |
} |
} |
/* ------------------------------------------------------------------------- */ |
/* This function is similar to usbFunctionRead(), but it's also called for |
* data handled automatically by the driver (e.g. descriptor reads). |
*/ |
static uchar usbDeviceRead(uchar *data, uchar len) |
{ |
if(len > 0){ /* don't bother app with 0 sized reads */ |
#if USB_CFG_IMPLEMENT_FN_READ |
if(usbMsgFlags & USB_FLG_USE_USER_RW){ |
len = usbFunctionRead(data, len); |
}else |
#endif |
{ |
uchar i = len, *r = usbMsgPtr; |
if(usbMsgFlags & USB_FLG_MSGPTR_IS_ROM){ /* ROM data */ |
do{ |
uchar c = USB_READ_FLASH(r); /* assign to char size variable to enforce byte ops */ |
*data++ = c; |
r++; |
}while(--i); |
}else{ /* RAM data */ |
do{ |
*data++ = *r++; |
}while(--i); |
} |
usbMsgPtr = r; |
} |
} |
return len; |
} |
/* ------------------------------------------------------------------------- */ |
/* usbBuildTxBlock() is called when we have data to transmit and the |
* interrupt routine's transmit buffer is empty. |
*/ |
static inline void usbBuildTxBlock(void) |
{ |
usbMsgLen_t wantLen; |
uchar len; |
wantLen = usbMsgLen; |
if(wantLen > 8) |
wantLen = 8; |
usbMsgLen -= wantLen; |
usbTxBuf[0] ^= USBPID_DATA0 ^ USBPID_DATA1; /* DATA toggling */ |
len = usbDeviceRead(usbTxBuf + 1, wantLen); |
if(len <= 8){ /* valid data packet */ |
usbCrc16Append(&usbTxBuf[1], len); |
len += 4; /* length including sync byte */ |
if(len < 12) /* a partial package identifies end of message */ |
usbMsgLen = USB_NO_MSG; |
}else{ |
len = USBPID_STALL; /* stall the endpoint */ |
usbMsgLen = USB_NO_MSG; |
} |
usbTxLen = len; |
DBG2(0x20, usbTxBuf, len-1); |
} |
/* ------------------------------------------------------------------------- */ |
static inline void usbHandleResetHook(uchar notResetState) |
{ |
#ifdef USB_RESET_HOOK |
static uchar wasReset; |
uchar isReset = !notResetState; |
if(wasReset != isReset){ |
USB_RESET_HOOK(isReset); |
wasReset = isReset; |
} |
#endif |
} |
/* ------------------------------------------------------------------------- */ |
USB_PUBLIC void usbPoll(void) |
{ |
schar len; |
uchar i; |
len = usbRxLen - 3; |
if(len >= 0){ |
/* We could check CRC16 here -- but ACK has already been sent anyway. If you |
* need data integrity checks with this driver, check the CRC in your app |
* code and report errors back to the host. Since the ACK was already sent, |
* retries must be handled on application level. |
* unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3); |
*/ |
usbProcessRx(usbRxBuf + USB_BUFSIZE + 1 - usbInputBufOffset, len); |
#if USB_CFG_HAVE_FLOWCONTROL |
if(usbRxLen > 0) /* only mark as available if not inactivated */ |
usbRxLen = 0; |
#else |
usbRxLen = 0; /* mark rx buffer as available */ |
#endif |
} |
if(usbTxLen & 0x10){ /* transmit system idle */ |
if(usbMsgLen != USB_NO_MSG){ /* transmit data pending? */ |
usbBuildTxBlock(); |
} |
} |
for(i = 20; i > 0; i--){ |
uchar usbLineStatus = USBIN & USBMASK; |
if(usbLineStatus != 0) /* SE0 has ended */ |
goto isNotReset; |
} |
/* RESET condition, called multiple times during reset */ |
usbNewDeviceAddr = 0; |
usbDeviceAddr = 0; |
usbResetStall(); |
DBG1(0xff, 0, 0); |
isNotReset: |
usbHandleResetHook(i); |
} |
/* ------------------------------------------------------------------------- */ |
USB_PUBLIC void usbInit(void) |
{ |
#if USB_INTR_CFG_SET != 0 |
USB_INTR_CFG |= USB_INTR_CFG_SET; |
#endif |
#if USB_INTR_CFG_CLR != 0 |
USB_INTR_CFG &= ~(USB_INTR_CFG_CLR); |
#endif |
USB_INTR_ENABLE |= (1 << USB_INTR_ENABLE_BIT); |
usbResetDataToggling(); |
#if USB_CFG_HAVE_INTRIN_ENDPOINT && !USB_CFG_SUPPRESS_INTR_CODE |
usbTxLen1 = USBPID_NAK; |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
usbTxLen3 = USBPID_NAK; |
#endif |
#endif |
} |
/* ------------------------------------------------------------------------- */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrv.h |
---|
0,0 → 1,735 |
/* Name: usbdrv.h |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2004-12-29 |
* Tabsize: 4 |
* Copyright: (c) 2005 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrv.h 793 2010-07-15 15:58:11Z cs $ |
*/ |
#ifndef __usbdrv_h_included__ |
#define __usbdrv_h_included__ |
#include "usbconfig.h" |
#include "usbportability.h" |
/* |
Hardware Prerequisites: |
======================= |
USB lines D+ and D- MUST be wired to the same I/O port. We recommend that D+ |
triggers the interrupt (best achieved by using INT0 for D+), but it is also |
possible to trigger the interrupt from D-. If D- is used, interrupts are also |
triggered by SOF packets. D- requires a pull-up of 1.5k to +3.5V (and the |
device must be powered at 3.5V) to identify as low-speed USB device. A |
pull-down or pull-up of 1M SHOULD be connected from D+ to +3.5V to prevent |
interference when no USB master is connected. If you use Zener diodes to limit |
the voltage on D+ and D-, you MUST use a pull-down resistor, not a pull-up. |
We use D+ as interrupt source and not D- because it does not trigger on |
keep-alive and RESET states. If you want to count keep-alive events with |
USB_COUNT_SOF, you MUST use D- as an interrupt source. |
As a compile time option, the 1.5k pull-up resistor on D- can be made |
switchable to allow the device to disconnect at will. See the definition of |
usbDeviceConnect() and usbDeviceDisconnect() further down in this file. |
Please adapt the values in usbconfig.h according to your hardware! |
The device MUST be clocked at exactly 12 MHz, 15 MHz, 16 MHz or 20 MHz |
or at 12.8 MHz resp. 16.5 MHz +/- 1%. See usbconfig-prototype.h for details. |
Limitations: |
============ |
Robustness with respect to communication errors: |
The driver assumes error-free communication. It DOES check for errors in |
the PID, but does NOT check bit stuffing errors, SE0 in middle of a byte, |
token CRC (5 bit) and data CRC (16 bit). CRC checks can not be performed due |
to timing constraints: We must start sending a reply within 7 bit times. |
Bit stuffing and misplaced SE0 would have to be checked in real-time, but CPU |
performance does not permit that. The driver does not check Data0/Data1 |
toggling, but application software can implement the check. |
Input characteristics: |
Since no differential receiver circuit is used, electrical interference |
robustness may suffer. The driver samples only one of the data lines with |
an ordinary I/O pin's input characteristics. However, since this is only a |
low speed USB implementation and the specification allows for 8 times the |
bit rate over the same hardware, we should be on the safe side. Even the spec |
requires detection of asymmetric states at high bit rate for SE0 detection. |
Number of endpoints: |
The driver supports the following endpoints: |
- Endpoint 0, the default control endpoint. |
- Any number of interrupt- or bulk-out endpoints. The data is sent to |
usbFunctionWriteOut() and USB_CFG_IMPLEMENT_FN_WRITEOUT must be defined |
to 1 to activate this feature. The endpoint number can be found in the |
global variable 'usbRxToken'. |
- One default interrupt- or bulk-in endpoint. This endpoint is used for |
interrupt- or bulk-in transfers which are not handled by any other endpoint. |
You must define USB_CFG_HAVE_INTRIN_ENDPOINT in order to activate this |
feature and call usbSetInterrupt() to send interrupt/bulk data. |
- One additional interrupt- or bulk-in endpoint. This was endpoint 3 in |
previous versions of this driver but can now be configured to any endpoint |
number. You must define USB_CFG_HAVE_INTRIN_ENDPOINT3 in order to activate |
this feature and call usbSetInterrupt3() to send interrupt/bulk data. The |
endpoint number can be set with USB_CFG_EP3_NUMBER. |
Please note that the USB standard forbids bulk endpoints for low speed devices! |
Most operating systems allow them anyway, but the AVR will spend 90% of the CPU |
time in the USB interrupt polling for bulk data. |
Maximum data payload: |
Data payload of control in and out transfers may be up to 254 bytes. In order |
to accept payload data of out transfers, you need to implement |
'usbFunctionWrite()'. |
USB Suspend Mode supply current: |
The USB standard limits power consumption to 500uA when the bus is in suspend |
mode. This is not a problem for self-powered devices since they don't need |
bus power anyway. Bus-powered devices can achieve this only by putting the |
CPU in sleep mode. The driver does not implement suspend handling by itself. |
However, the application may implement activity monitoring and wakeup from |
sleep. The host sends regular SE0 states on the bus to keep it active. These |
SE0 states can be detected by using D- as the interrupt source. Define |
USB_COUNT_SOF to 1 and use the global variable usbSofCount to check for bus |
activity. |
Operation without an USB master: |
The driver behaves neutral without connection to an USB master if D- reads |
as 1. To avoid spurious interrupts, we recommend a high impedance (e.g. 1M) |
pull-down or pull-up resistor on D+ (interrupt). If Zener diodes are used, |
use a pull-down. If D- becomes statically 0, the driver may block in the |
interrupt routine. |
Interrupt latency: |
The application must ensure that the USB interrupt is not disabled for more |
than 25 cycles (this is for 12 MHz, faster clocks allow longer latency). |
This implies that all interrupt routines must either have the "ISR_NOBLOCK" |
attribute set (see "avr/interrupt.h") or be written in assembler with "sei" |
as the first instruction. |
Maximum interrupt duration / CPU cycle consumption: |
The driver handles all USB communication during the interrupt service |
routine. The routine will not return before an entire USB message is received |
and the reply is sent. This may be up to ca. 1200 cycles @ 12 MHz (= 100us) if |
the host conforms to the standard. The driver will consume CPU cycles for all |
USB messages, even if they address another (low-speed) device on the same bus. |
*/ |
/* ------------------------------------------------------------------------- */ |
/* --------------------------- Module Interface ---------------------------- */ |
/* ------------------------------------------------------------------------- */ |
#define USBDRV_VERSION 20100715 |
/* This define uniquely identifies a driver version. It is a decimal number |
* constructed from the driver's release date in the form YYYYMMDD. If the |
* driver's behavior or interface changes, you can use this constant to |
* distinguish versions. If it is not defined, the driver's release date is |
* older than 2006-01-25. |
*/ |
#ifndef USB_PUBLIC |
#define USB_PUBLIC |
#endif |
/* USB_PUBLIC is used as declaration attribute for all functions exported by |
* the USB driver. The default is no attribute (see above). You may define it |
* to static either in usbconfig.h or from the command line if you include |
* usbdrv.c instead of linking against it. Including the C module of the driver |
* directly in your code saves a couple of bytes in flash memory. |
*/ |
#ifndef __ASSEMBLER__ |
#ifndef uchar |
#define uchar unsigned char |
#endif |
#ifndef schar |
#define schar signed char |
#endif |
/* shortcuts for well defined 8 bit integer types */ |
#if USB_CFG_LONG_TRANSFERS /* if more than 254 bytes transfer size required */ |
# define usbMsgLen_t unsigned |
#else |
# define usbMsgLen_t uchar |
#endif |
/* usbMsgLen_t is the data type used for transfer lengths. By default, it is |
* defined to uchar, allowing a maximum of 254 bytes (255 is reserved for |
* USB_NO_MSG below). If the usbconfig.h defines USB_CFG_LONG_TRANSFERS to 1, |
* a 16 bit data type is used, allowing up to 16384 bytes (the rest is used |
* for flags in the descriptor configuration). |
*/ |
#define USB_NO_MSG ((usbMsgLen_t)-1) /* constant meaning "no message" */ |
struct usbRequest; /* forward declaration */ |
USB_PUBLIC void usbInit(void); |
/* This function must be called before interrupts are enabled and the main |
* loop is entered. We exepct that the PORT and DDR bits for D+ and D- have |
* not been changed from their default status (which is 0). If you have changed |
* them, set both back to 0 (configure them as input with no internal pull-up). |
*/ |
USB_PUBLIC void usbPoll(void); |
/* This function must be called at regular intervals from the main loop. |
* Maximum delay between calls is somewhat less than 50ms (USB timeout for |
* accepting a Setup message). Otherwise the device will not be recognized. |
* Please note that debug outputs through the UART take ~ 0.5ms per byte |
* at 19200 bps. |
*/ |
extern uchar *usbMsgPtr; |
/* This variable may be used to pass transmit data to the driver from the |
* implementation of usbFunctionWrite(). It is also used internally by the |
* driver for standard control requests. |
*/ |
USB_PUBLIC usbMsgLen_t usbFunctionSetup(uchar data[8]); |
/* This function is called when the driver receives a SETUP transaction from |
* the host which is not answered by the driver itself (in practice: class and |
* vendor requests). All control transfers start with a SETUP transaction where |
* the host communicates the parameters of the following (optional) data |
* transfer. The SETUP data is available in the 'data' parameter which can |
* (and should) be casted to 'usbRequest_t *' for a more user-friendly access |
* to parameters. |
* |
* If the SETUP indicates a control-in transfer, you should provide the |
* requested data to the driver. There are two ways to transfer this data: |
* (1) Set the global pointer 'usbMsgPtr' to the base of the static RAM data |
* block and return the length of the data in 'usbFunctionSetup()'. The driver |
* will handle the rest. Or (2) return USB_NO_MSG in 'usbFunctionSetup()'. The |
* driver will then call 'usbFunctionRead()' when data is needed. See the |
* documentation for usbFunctionRead() for details. |
* |
* If the SETUP indicates a control-out transfer, the only way to receive the |
* data from the host is through the 'usbFunctionWrite()' call. If you |
* implement this function, you must return USB_NO_MSG in 'usbFunctionSetup()' |
* to indicate that 'usbFunctionWrite()' should be used. See the documentation |
* of this function for more information. If you just want to ignore the data |
* sent by the host, return 0 in 'usbFunctionSetup()'. |
* |
* Note that calls to the functions usbFunctionRead() and usbFunctionWrite() |
* are only done if enabled by the configuration in usbconfig.h. |
*/ |
USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq); |
/* You need to implement this function ONLY if you provide USB descriptors at |
* runtime (which is an expert feature). It is very similar to |
* usbFunctionSetup() above, but it is called only to request USB descriptor |
* data. See the documentation of usbFunctionSetup() above for more info. |
*/ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT |
USB_PUBLIC void usbSetInterrupt(uchar *data, uchar len); |
/* This function sets the message which will be sent during the next interrupt |
* IN transfer. The message is copied to an internal buffer and must not exceed |
* a length of 8 bytes. The message may be 0 bytes long just to indicate the |
* interrupt status to the host. |
* If you need to transfer more bytes, use a control read after the interrupt. |
*/ |
#define usbInterruptIsReady() (usbTxLen1 & 0x10) |
/* This macro indicates whether the last interrupt message has already been |
* sent. If you set a new interrupt message before the old was sent, the |
* message already buffered will be lost. |
*/ |
#if USB_CFG_HAVE_INTRIN_ENDPOINT3 |
USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len); |
#define usbInterruptIsReady3() (usbTxLen3 & 0x10) |
/* Same as above for endpoint 3 */ |
#endif |
#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */ |
#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */ |
#define usbHidReportDescriptor usbDescriptorHidReport |
/* should be declared as: PROGMEM char usbHidReportDescriptor[]; */ |
/* If you implement an HID device, you need to provide a report descriptor. |
* The HID report descriptor syntax is a bit complex. If you understand how |
* report descriptors are constructed, we recommend that you use the HID |
* Descriptor Tool from usb.org, see http://www.usb.org/developers/hidpage/. |
* Otherwise you should probably start with a working example. |
*/ |
#endif /* USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH */ |
#if USB_CFG_IMPLEMENT_FN_WRITE |
USB_PUBLIC uchar usbFunctionWrite(uchar *data, uchar len); |
/* This function is called by the driver to provide a control transfer's |
* payload data (control-out). It is called in chunks of up to 8 bytes. The |
* total count provided in the current control transfer can be obtained from |
* the 'length' property in the setup data. If an error occurred during |
* processing, return 0xff (== -1). The driver will answer the entire transfer |
* with a STALL token in this case. If you have received the entire payload |
* successfully, return 1. If you expect more data, return 0. If you don't |
* know whether the host will send more data (you should know, the total is |
* provided in the usbFunctionSetup() call!), return 1. |
* NOTE: If you return 0xff for STALL, 'usbFunctionWrite()' may still be called |
* for the remaining data. You must continue to return 0xff for STALL in these |
* calls. |
* In order to get usbFunctionWrite() called, define USB_CFG_IMPLEMENT_FN_WRITE |
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. |
*/ |
#endif /* USB_CFG_IMPLEMENT_FN_WRITE */ |
#if USB_CFG_IMPLEMENT_FN_READ |
USB_PUBLIC uchar usbFunctionRead(uchar *data, uchar len); |
/* This function is called by the driver to ask the application for a control |
* transfer's payload data (control-in). It is called in chunks of up to 8 |
* bytes each. You should copy the data to the location given by 'data' and |
* return the actual number of bytes copied. If you return less than requested, |
* the control-in transfer is terminated. If you return 0xff, the driver aborts |
* the transfer with a STALL token. |
* In order to get usbFunctionRead() called, define USB_CFG_IMPLEMENT_FN_READ |
* to 1 in usbconfig.h and return 0xff in usbFunctionSetup().. |
*/ |
#endif /* USB_CFG_IMPLEMENT_FN_READ */ |
extern uchar usbRxToken; /* may be used in usbFunctionWriteOut() below */ |
#if USB_CFG_IMPLEMENT_FN_WRITEOUT |
USB_PUBLIC void usbFunctionWriteOut(uchar *data, uchar len); |
/* This function is called by the driver when data is received on an interrupt- |
* or bulk-out endpoint. The endpoint number can be found in the global |
* variable usbRxToken. You must define USB_CFG_IMPLEMENT_FN_WRITEOUT to 1 in |
* usbconfig.h to get this function called. |
*/ |
#endif /* USB_CFG_IMPLEMENT_FN_WRITEOUT */ |
#ifdef USB_CFG_PULLUP_IOPORTNAME |
#define usbDeviceConnect() ((USB_PULLUP_DDR |= (1<<USB_CFG_PULLUP_BIT)), \ |
(USB_PULLUP_OUT |= (1<<USB_CFG_PULLUP_BIT))) |
#define usbDeviceDisconnect() ((USB_PULLUP_DDR &= ~(1<<USB_CFG_PULLUP_BIT)), \ |
(USB_PULLUP_OUT &= ~(1<<USB_CFG_PULLUP_BIT))) |
#else /* USB_CFG_PULLUP_IOPORTNAME */ |
#define usbDeviceConnect() (USBDDR &= ~(1<<USBMINUS)) |
#define usbDeviceDisconnect() (USBDDR |= (1<<USBMINUS)) |
#endif /* USB_CFG_PULLUP_IOPORTNAME */ |
/* The macros usbDeviceConnect() and usbDeviceDisconnect() (intended to look |
* like a function) connect resp. disconnect the device from the host's USB. |
* If the constants USB_CFG_PULLUP_IOPORT and USB_CFG_PULLUP_BIT are defined |
* in usbconfig.h, a disconnect consists of removing the pull-up resisitor |
* from D-, otherwise the disconnect is done by brute-force pulling D- to GND. |
* This does not conform to the spec, but it works. |
* Please note that the USB interrupt must be disabled while the device is |
* in disconnected state, or the interrupt handler will hang! You can either |
* turn off the USB interrupt selectively with |
* USB_INTR_ENABLE &= ~(1 << USB_INTR_ENABLE_BIT) |
* or use cli() to disable interrupts globally. |
*/ |
extern unsigned usbCrc16(unsigned data, uchar len); |
#define usbCrc16(data, len) usbCrc16((unsigned)(data), len) |
/* This function calculates the binary complement of the data CRC used in |
* USB data packets. The value is used to build raw transmit packets. |
* You may want to use this function for data checksums or to verify received |
* data. We enforce 16 bit calling conventions for compatibility with IAR's |
* tiny memory model. |
*/ |
extern unsigned usbCrc16Append(unsigned data, uchar len); |
#define usbCrc16Append(data, len) usbCrc16Append((unsigned)(data), len) |
/* This function is equivalent to usbCrc16() above, except that it appends |
* the 2 bytes CRC (lowbyte first) in the 'data' buffer after reading 'len' |
* bytes. |
*/ |
#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH |
extern unsigned usbMeasureFrameLength(void); |
/* This function MUST be called IMMEDIATELY AFTER USB reset and measures 1/7 of |
* the number of CPU cycles during one USB frame minus one low speed bit |
* length. In other words: return value = 1499 * (F_CPU / 10.5 MHz) |
* Since this is a busy wait, you MUST disable all interrupts with cli() before |
* calling this function. |
* This can be used to calibrate the AVR's RC oscillator. |
*/ |
#endif |
extern uchar usbConfiguration; |
/* This value contains the current configuration set by the host. The driver |
* allows setting and querying of this variable with the USB SET_CONFIGURATION |
* and GET_CONFIGURATION requests, but does not use it otherwise. |
* You may want to reflect the "configured" status with a LED on the device or |
* switch on high power parts of the circuit only if the device is configured. |
*/ |
#if USB_COUNT_SOF |
extern volatile uchar usbSofCount; |
/* This variable is incremented on every SOF packet. It is only available if |
* the macro USB_COUNT_SOF is defined to a value != 0. |
*/ |
#endif |
#if USB_CFG_CHECK_DATA_TOGGLING |
extern uchar usbCurrentDataToken; |
/* This variable can be checked in usbFunctionWrite() and usbFunctionWriteOut() |
* to ignore duplicate packets. |
*/ |
#endif |
#define USB_STRING_DESCRIPTOR_HEADER(stringLength) ((2*(stringLength)+2) | (3<<8)) |
/* This macro builds a descriptor header for a string descriptor given the |
* string's length. See usbdrv.c for an example how to use it. |
*/ |
#if USB_CFG_HAVE_FLOWCONTROL |
extern volatile schar usbRxLen; |
#define usbDisableAllRequests() usbRxLen = -1 |
/* Must be called from usbFunctionWrite(). This macro disables all data input |
* from the USB interface. Requests from the host are answered with a NAK |
* while they are disabled. |
*/ |
#define usbEnableAllRequests() usbRxLen = 0 |
/* May only be called if requests are disabled. This macro enables input from |
* the USB interface after it has been disabled with usbDisableAllRequests(). |
*/ |
#define usbAllRequestsAreDisabled() (usbRxLen < 0) |
/* Use this macro to find out whether requests are disabled. It may be needed |
* to ensure that usbEnableAllRequests() is never called when requests are |
* enabled. |
*/ |
#endif |
#define USB_SET_DATATOKEN1(token) usbTxBuf1[0] = token |
#define USB_SET_DATATOKEN3(token) usbTxBuf3[0] = token |
/* These two macros can be used by application software to reset data toggling |
* for interrupt-in endpoints 1 and 3. Since the token is toggled BEFORE |
* sending data, you must set the opposite value of the token which should come |
* first. |
*/ |
#endif /* __ASSEMBLER__ */ |
/* ------------------------------------------------------------------------- */ |
/* ----------------- Definitions for Descriptor Properties ----------------- */ |
/* ------------------------------------------------------------------------- */ |
/* This is advanced stuff. See usbconfig-prototype.h for more information |
* about the various methods to define USB descriptors. If you do nothing, |
* the default descriptors will be used. |
*/ |
#define USB_PROP_IS_DYNAMIC (1 << 14) |
/* If this property is set for a descriptor, usbFunctionDescriptor() will be |
* used to obtain the particular descriptor. Data directly returned via |
* usbMsgPtr are FLASH data by default, combine (OR) with USB_PROP_IS_RAM to |
* return RAM data. |
*/ |
#define USB_PROP_IS_RAM (1 << 15) |
/* If this property is set for a descriptor, the data is read from RAM |
* memory instead of Flash. The property is used for all methods to provide |
* external descriptors. |
*/ |
#define USB_PROP_LENGTH(len) ((len) & 0x3fff) |
/* If a static external descriptor is used, this is the total length of the |
* descriptor in bytes. |
*/ |
/* all descriptors which may have properties: */ |
#ifndef USB_CFG_DESCR_PROPS_DEVICE |
#define USB_CFG_DESCR_PROPS_DEVICE 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_CONFIGURATION |
#define USB_CFG_DESCR_PROPS_CONFIGURATION 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRINGS |
#define USB_CFG_DESCR_PROPS_STRINGS 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_0 |
#define USB_CFG_DESCR_PROPS_STRING_0 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_VENDOR |
#define USB_CFG_DESCR_PROPS_STRING_VENDOR 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_PRODUCT |
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER |
#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER 0 |
#endif |
#ifndef USB_CFG_DESCR_PROPS_HID |
#define USB_CFG_DESCR_PROPS_HID 0 |
#endif |
#if !(USB_CFG_DESCR_PROPS_HID_REPORT) |
# undef USB_CFG_DESCR_PROPS_HID_REPORT |
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* do some backward compatibility tricks */ |
# define USB_CFG_DESCR_PROPS_HID_REPORT USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH |
# else |
# define USB_CFG_DESCR_PROPS_HID_REPORT 0 |
# endif |
#endif |
#ifndef USB_CFG_DESCR_PROPS_UNKNOWN |
#define USB_CFG_DESCR_PROPS_UNKNOWN 0 |
#endif |
/* ------------------ forward declaration of descriptors ------------------- */ |
/* If you use external static descriptors, they must be stored in global |
* arrays as declared below: |
*/ |
#ifndef __ASSEMBLER__ |
extern |
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorDevice[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorConfiguration[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorHidReport[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
char usbDescriptorString0[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
int usbDescriptorStringVendor[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
int usbDescriptorStringDevice[]; |
extern |
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM) |
PROGMEM |
#endif |
int usbDescriptorStringSerialNumber[]; |
#endif /* __ASSEMBLER__ */ |
/* ------------------------------------------------------------------------- */ |
/* ------------------------ General Purpose Macros ------------------------- */ |
/* ------------------------------------------------------------------------- */ |
#define USB_CONCAT(a, b) a ## b |
#define USB_CONCAT_EXPANDED(a, b) USB_CONCAT(a, b) |
#define USB_OUTPORT(name) USB_CONCAT(PORT, name) |
#define USB_INPORT(name) USB_CONCAT(PIN, name) |
#define USB_DDRPORT(name) USB_CONCAT(DDR, name) |
/* The double-define trick above lets us concatenate strings which are |
* defined by macros. |
*/ |
/* ------------------------------------------------------------------------- */ |
/* ------------------------- Constant definitions -------------------------- */ |
/* ------------------------------------------------------------------------- */ |
#if !defined __ASSEMBLER__ && (!defined USB_CFG_VENDOR_ID || !defined USB_CFG_DEVICE_ID) |
#warning "You should define USB_CFG_VENDOR_ID and USB_CFG_DEVICE_ID in usbconfig.h" |
/* If the user has not defined IDs, we default to obdev's free IDs. |
* See USB-IDs-for-free.txt for details. |
*/ |
#endif |
/* make sure we have a VID and PID defined, byte order is lowbyte, highbyte */ |
#ifndef USB_CFG_VENDOR_ID |
# define USB_CFG_VENDOR_ID 0xc0, 0x16 /* = 0x16c0 = 5824 = voti.nl */ |
#endif |
#ifndef USB_CFG_DEVICE_ID |
# if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH |
# define USB_CFG_DEVICE_ID 0xdf, 0x05 /* = 0x5df = 1503, shared PID for HIDs */ |
# elif USB_CFG_INTERFACE_CLASS == 2 |
# define USB_CFG_DEVICE_ID 0xe1, 0x05 /* = 0x5e1 = 1505, shared PID for CDC Modems */ |
# else |
# define USB_CFG_DEVICE_ID 0xdc, 0x05 /* = 0x5dc = 1500, obdev's free PID */ |
# endif |
#endif |
/* Derive Output, Input and DataDirection ports from port names */ |
#ifndef USB_CFG_IOPORTNAME |
#error "You must define USB_CFG_IOPORTNAME in usbconfig.h, see usbconfig-prototype.h" |
#endif |
#define USBOUT USB_OUTPORT(USB_CFG_IOPORTNAME) |
#define USB_PULLUP_OUT USB_OUTPORT(USB_CFG_PULLUP_IOPORTNAME) |
#define USBIN USB_INPORT(USB_CFG_IOPORTNAME) |
#define USBDDR USB_DDRPORT(USB_CFG_IOPORTNAME) |
#define USB_PULLUP_DDR USB_DDRPORT(USB_CFG_PULLUP_IOPORTNAME) |
#define USBMINUS USB_CFG_DMINUS_BIT |
#define USBPLUS USB_CFG_DPLUS_BIT |
#define USBIDLE (1<<USB_CFG_DMINUS_BIT) /* value representing J state */ |
#define USBMASK ((1<<USB_CFG_DPLUS_BIT) | (1<<USB_CFG_DMINUS_BIT)) /* mask for USB I/O bits */ |
/* defines for backward compatibility with older driver versions: */ |
#define USB_CFG_IOPORT USB_OUTPORT(USB_CFG_IOPORTNAME) |
#ifdef USB_CFG_PULLUP_IOPORTNAME |
#define USB_CFG_PULLUP_IOPORT USB_OUTPORT(USB_CFG_PULLUP_IOPORTNAME) |
#endif |
#ifndef USB_CFG_EP3_NUMBER /* if not defined in usbconfig.h */ |
#define USB_CFG_EP3_NUMBER 3 |
#endif |
#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT3 |
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0 |
#endif |
#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */ |
/* ----- Try to find registers and bits responsible for ext interrupt 0 ----- */ |
#ifndef USB_INTR_CFG /* allow user to override our default */ |
# if defined EICRA |
# define USB_INTR_CFG EICRA |
# else |
# define USB_INTR_CFG MCUCR |
# endif |
#endif |
#ifndef USB_INTR_CFG_SET /* allow user to override our default */ |
# if defined(USB_COUNT_SOF) || defined(USB_SOF_HOOK) |
# define USB_INTR_CFG_SET (1 << ISC01) /* cfg for falling edge */ |
/* If any SOF logic is used, the interrupt must be wired to D- where |
* we better trigger on falling edge |
*/ |
# else |
# define USB_INTR_CFG_SET ((1 << ISC00) | (1 << ISC01)) /* cfg for rising edge */ |
# endif |
#endif |
#ifndef USB_INTR_CFG_CLR /* allow user to override our default */ |
# define USB_INTR_CFG_CLR 0 /* no bits to clear */ |
#endif |
#ifndef USB_INTR_ENABLE /* allow user to override our default */ |
# if defined GIMSK |
# define USB_INTR_ENABLE GIMSK |
# elif defined EIMSK |
# define USB_INTR_ENABLE EIMSK |
# else |
# define USB_INTR_ENABLE GICR |
# endif |
#endif |
#ifndef USB_INTR_ENABLE_BIT /* allow user to override our default */ |
# define USB_INTR_ENABLE_BIT INT0 |
#endif |
#ifndef USB_INTR_PENDING /* allow user to override our default */ |
# if defined EIFR |
# define USB_INTR_PENDING EIFR |
# else |
# define USB_INTR_PENDING GIFR |
# endif |
#endif |
#ifndef USB_INTR_PENDING_BIT /* allow user to override our default */ |
# define USB_INTR_PENDING_BIT INTF0 |
#endif |
/* |
The defines above don't work for the following chips |
at90c8534: no ISC0?, no PORTB, can't find a data sheet |
at86rf401: no PORTB, no MCUCR etc, low clock rate |
atmega103: no ISC0? (maybe omission in header, can't find data sheet) |
atmega603: not defined in avr-libc |
at43usb320, at43usb355, at76c711: have USB anyway |
at94k: is different... |
at90s1200, attiny11, attiny12, attiny15, attiny28: these have no RAM |
*/ |
/* ------------------------------------------------------------------------- */ |
/* ----------------- USB Specification Constants and Types ----------------- */ |
/* ------------------------------------------------------------------------- */ |
/* USB Token values */ |
#define USBPID_SETUP 0x2d |
#define USBPID_OUT 0xe1 |
#define USBPID_IN 0x69 |
#define USBPID_DATA0 0xc3 |
#define USBPID_DATA1 0x4b |
#define USBPID_ACK 0xd2 |
#define USBPID_NAK 0x5a |
#define USBPID_STALL 0x1e |
#ifndef USB_INITIAL_DATATOKEN |
#define USB_INITIAL_DATATOKEN USBPID_DATA1 |
#endif |
#ifndef __ASSEMBLER__ |
typedef struct usbTxStatus{ |
volatile uchar len; |
uchar buffer[USB_BUFSIZE]; |
}usbTxStatus_t; |
extern usbTxStatus_t usbTxStatus1, usbTxStatus3; |
#define usbTxLen1 usbTxStatus1.len |
#define usbTxBuf1 usbTxStatus1.buffer |
#define usbTxLen3 usbTxStatus3.len |
#define usbTxBuf3 usbTxStatus3.buffer |
typedef union usbWord{ |
unsigned word; |
uchar bytes[2]; |
}usbWord_t; |
typedef struct usbRequest{ |
uchar bmRequestType; |
uchar bRequest; |
usbWord_t wValue; |
usbWord_t wIndex; |
usbWord_t wLength; |
}usbRequest_t; |
/* This structure matches the 8 byte setup request */ |
#endif |
/* bmRequestType field in USB setup: |
* d t t r r r r r, where |
* d ..... direction: 0=host->device, 1=device->host |
* t ..... type: 0=standard, 1=class, 2=vendor, 3=reserved |
* r ..... recipient: 0=device, 1=interface, 2=endpoint, 3=other |
*/ |
/* USB setup recipient values */ |
#define USBRQ_RCPT_MASK 0x1f |
#define USBRQ_RCPT_DEVICE 0 |
#define USBRQ_RCPT_INTERFACE 1 |
#define USBRQ_RCPT_ENDPOINT 2 |
/* USB request type values */ |
#define USBRQ_TYPE_MASK 0x60 |
#define USBRQ_TYPE_STANDARD (0<<5) |
#define USBRQ_TYPE_CLASS (1<<5) |
#define USBRQ_TYPE_VENDOR (2<<5) |
/* USB direction values: */ |
#define USBRQ_DIR_MASK 0x80 |
#define USBRQ_DIR_HOST_TO_DEVICE (0<<7) |
#define USBRQ_DIR_DEVICE_TO_HOST (1<<7) |
/* USB Standard Requests */ |
#define USBRQ_GET_STATUS 0 |
#define USBRQ_CLEAR_FEATURE 1 |
#define USBRQ_SET_FEATURE 3 |
#define USBRQ_SET_ADDRESS 5 |
#define USBRQ_GET_DESCRIPTOR 6 |
#define USBRQ_SET_DESCRIPTOR 7 |
#define USBRQ_GET_CONFIGURATION 8 |
#define USBRQ_SET_CONFIGURATION 9 |
#define USBRQ_GET_INTERFACE 10 |
#define USBRQ_SET_INTERFACE 11 |
#define USBRQ_SYNCH_FRAME 12 |
/* USB descriptor constants */ |
#define USBDESCR_DEVICE 1 |
#define USBDESCR_CONFIG 2 |
#define USBDESCR_STRING 3 |
#define USBDESCR_INTERFACE 4 |
#define USBDESCR_ENDPOINT 5 |
#define USBDESCR_HID 0x21 |
#define USBDESCR_HID_REPORT 0x22 |
#define USBDESCR_HID_PHYS 0x23 |
//#define USBATTR_BUSPOWER 0x80 // USB 1.1 does not define this value any more |
#define USBATTR_SELFPOWER 0x40 |
#define USBATTR_REMOTEWAKE 0x20 |
/* USB HID Requests */ |
#define USBRQ_HID_GET_REPORT 0x01 |
#define USBRQ_HID_GET_IDLE 0x02 |
#define USBRQ_HID_GET_PROTOCOL 0x03 |
#define USBRQ_HID_SET_REPORT 0x09 |
#define USBRQ_HID_SET_IDLE 0x0a |
#define USBRQ_HID_SET_PROTOCOL 0x0b |
/* ------------------------------------------------------------------------- */ |
#endif /* __usbdrv_h_included__ */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm.S |
---|
0,0 → 1,393 |
/* Name: usbdrvasm.S |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2007-06-13 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id: usbdrvasm.S 785 2010-05-30 17:57:07Z cs $ |
*/ |
/* |
General Description: |
This module is the assembler part of the USB driver. This file contains |
general code (preprocessor acrobatics and CRC computation) and then includes |
the file appropriate for the given clock rate. |
*/ |
#define __SFR_OFFSET 0 /* used by avr-libc's register definitions */ |
#include "usbportability.h" |
#include "usbdrv.h" /* for common defs */ |
/* register names */ |
#define x1 r16 |
#define x2 r17 |
#define shift r18 |
#define cnt r19 |
#define x3 r20 |
#define x4 r21 |
#define x5 r22 |
#define bitcnt x5 |
#define phase x4 |
#define leap x4 |
/* Some assembler dependent definitions and declarations: */ |
#ifdef __IAR_SYSTEMS_ASM__ |
extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset |
extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen |
extern usbTxBuf, usbTxStatus1, usbTxStatus3 |
# if USB_COUNT_SOF |
extern usbSofCount |
# endif |
public usbCrc16 |
public usbCrc16Append |
COMMON INTVEC |
# ifndef USB_INTR_VECTOR |
ORG INT0_vect |
# else /* USB_INTR_VECTOR */ |
ORG USB_INTR_VECTOR |
# undef USB_INTR_VECTOR |
# endif /* USB_INTR_VECTOR */ |
# define USB_INTR_VECTOR usbInterruptHandler |
rjmp USB_INTR_VECTOR |
RSEG CODE |
#else /* __IAR_SYSTEMS_ASM__ */ |
# ifndef USB_INTR_VECTOR /* default to hardware interrupt INT0 */ |
# ifdef INT0_vect |
# define USB_INTR_VECTOR INT0_vect // this is the "new" define for the vector |
# else |
# define USB_INTR_VECTOR SIG_INTERRUPT0 // this is the "old" vector |
# endif |
# endif |
.text |
.global USB_INTR_VECTOR |
.type USB_INTR_VECTOR, @function |
.global usbCrc16 |
.global usbCrc16Append |
#endif /* __IAR_SYSTEMS_ASM__ */ |
#if USB_INTR_PENDING < 0x40 /* This is an I/O address, use in and out */ |
# define USB_LOAD_PENDING(reg) in reg, USB_INTR_PENDING |
# define USB_STORE_PENDING(reg) out USB_INTR_PENDING, reg |
#else /* It's a memory address, use lds and sts */ |
# define USB_LOAD_PENDING(reg) lds reg, USB_INTR_PENDING |
# define USB_STORE_PENDING(reg) sts USB_INTR_PENDING, reg |
#endif |
#define usbTxLen1 usbTxStatus1 |
#define usbTxBuf1 (usbTxStatus1 + 1) |
#define usbTxLen3 usbTxStatus3 |
#define usbTxBuf3 (usbTxStatus3 + 1) |
;---------------------------------------------------------------------------- |
; Utility functions |
;---------------------------------------------------------------------------- |
#ifdef __IAR_SYSTEMS_ASM__ |
/* Register assignments for usbCrc16 on IAR cc */ |
/* Calling conventions on IAR: |
* First parameter passed in r16/r17, second in r18/r19 and so on. |
* Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) |
* Result is passed in r16/r17 |
* In case of the "tiny" memory model, pointers are only 8 bit with no |
* padding. We therefore pass argument 1 as "16 bit unsigned". |
*/ |
RTMODEL "__rt_version", "3" |
/* The line above will generate an error if cc calling conventions change. |
* The value "3" above is valid for IAR 4.10B/W32 |
*/ |
# define argLen r18 /* argument 2 */ |
# define argPtrL r16 /* argument 1 */ |
# define argPtrH r17 /* argument 1 */ |
# define resCrcL r16 /* result */ |
# define resCrcH r17 /* result */ |
# define ptrL ZL |
# define ptrH ZH |
# define ptr Z |
# define byte r22 |
# define bitCnt r19 |
# define polyL r20 |
# define polyH r21 |
# define scratch r23 |
#else /* __IAR_SYSTEMS_ASM__ */ |
/* Register assignments for usbCrc16 on gcc */ |
/* Calling conventions on gcc: |
* First parameter passed in r24/r25, second in r22/23 and so on. |
* Callee must preserve r1-r17, r28/r29 |
* Result is passed in r24/r25 |
*/ |
# define argLen r22 /* argument 2 */ |
# define argPtrL r24 /* argument 1 */ |
# define argPtrH r25 /* argument 1 */ |
# define resCrcL r24 /* result */ |
# define resCrcH r25 /* result */ |
# define ptrL XL |
# define ptrH XH |
# define ptr x |
# define byte r18 |
# define bitCnt r19 |
# define polyL r20 |
# define polyH r21 |
# define scratch r23 |
#endif |
#if USB_USE_FAST_CRC |
; This implementation is faster, but has bigger code size |
; Thanks to Slawomir Fras (BoskiDialer) for this code! |
; It implements the following C pseudo-code: |
; unsigned table(unsigned char x) |
; { |
; unsigned value; |
; |
; value = (unsigned)x << 6; |
; value ^= (unsigned)x << 7; |
; if(parity(x)) |
; value ^= 0xc001; |
; return value; |
; } |
; unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen) |
; { |
; unsigned crc = 0xffff; |
; |
; while(argLen--) |
; crc = table(lo8(crc) ^ *argPtr++) ^ hi8(crc); |
; return ~crc; |
; } |
; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen); |
; argPtr r24+25 / r16+r17 |
; argLen r22 / r18 |
; temp variables: |
; byte r18 / r22 |
; scratch r23 |
; resCrc r24+r25 / r16+r17 |
; ptr X / Z |
usbCrc16: |
mov ptrL, argPtrL |
mov ptrH, argPtrH |
ldi resCrcL, 0xFF |
ldi resCrcH, 0xFF |
rjmp usbCrc16LoopTest |
usbCrc16ByteLoop: |
ld byte, ptr+ |
eor resCrcL, byte ; resCrcL is now 'x' in table() |
mov byte, resCrcL ; compute parity of 'x' |
swap byte |
eor byte, resCrcL |
mov scratch, byte |
lsr byte |
lsr byte |
eor byte, scratch |
inc byte |
lsr byte |
andi byte, 1 ; byte is now parity(x) |
mov scratch, resCrcL |
mov resCrcL, resCrcH |
eor resCrcL, byte ; low byte of if(parity(x)) value ^= 0xc001; |
neg byte |
andi byte, 0xc0 |
mov resCrcH, byte ; high byte of if(parity(x)) value ^= 0xc001; |
clr byte |
lsr scratch |
ror byte |
eor resCrcH, scratch |
eor resCrcL, byte |
lsr scratch |
ror byte |
eor resCrcH, scratch |
eor resCrcL, byte |
usbCrc16LoopTest: |
subi argLen, 1 |
brsh usbCrc16ByteLoop |
com resCrcL |
com resCrcH |
ret |
#else /* USB_USE_FAST_CRC */ |
; This implementation is slower, but has less code size |
; |
; extern unsigned usbCrc16(unsigned char *argPtr, unsigned char argLen); |
; argPtr r24+25 / r16+r17 |
; argLen r22 / r18 |
; temp variables: |
; byte r18 / r22 |
; bitCnt r19 |
; poly r20+r21 |
; scratch r23 |
; resCrc r24+r25 / r16+r17 |
; ptr X / Z |
usbCrc16: |
mov ptrL, argPtrL |
mov ptrH, argPtrH |
ldi resCrcL, 0 |
ldi resCrcH, 0 |
ldi polyL, lo8(0xa001) |
ldi polyH, hi8(0xa001) |
com argLen ; argLen = -argLen - 1: modified loop to ensure that carry is set |
ldi bitCnt, 0 ; loop counter with starnd condition = end condition |
rjmp usbCrcLoopEntry |
usbCrcByteLoop: |
ld byte, ptr+ |
eor resCrcL, byte |
usbCrcBitLoop: |
ror resCrcH ; carry is always set here (see brcs jumps to here) |
ror resCrcL |
brcs usbCrcNoXor |
eor resCrcL, polyL |
eor resCrcH, polyH |
usbCrcNoXor: |
subi bitCnt, 224 ; (8 * 224) % 256 = 0; this loop iterates 8 times |
brcs usbCrcBitLoop |
usbCrcLoopEntry: |
subi argLen, -1 |
brcs usbCrcByteLoop |
usbCrcReady: |
ret |
; Thanks to Reimar Doeffinger for optimizing this CRC routine! |
#endif /* USB_USE_FAST_CRC */ |
; extern unsigned usbCrc16Append(unsigned char *data, unsigned char len); |
usbCrc16Append: |
rcall usbCrc16 |
st ptr+, resCrcL |
st ptr+, resCrcH |
ret |
#undef argLen |
#undef argPtrL |
#undef argPtrH |
#undef resCrcL |
#undef resCrcH |
#undef ptrL |
#undef ptrH |
#undef ptr |
#undef byte |
#undef bitCnt |
#undef polyL |
#undef polyH |
#undef scratch |
#if USB_CFG_HAVE_MEASURE_FRAME_LENGTH |
#ifdef __IAR_SYSTEMS_ASM__ |
/* Register assignments for usbMeasureFrameLength on IAR cc */ |
/* Calling conventions on IAR: |
* First parameter passed in r16/r17, second in r18/r19 and so on. |
* Callee must preserve r4-r15, r24-r29 (r28/r29 is frame pointer) |
* Result is passed in r16/r17 |
* In case of the "tiny" memory model, pointers are only 8 bit with no |
* padding. We therefore pass argument 1 as "16 bit unsigned". |
*/ |
# define resL r16 |
# define resH r17 |
# define cnt16L r30 |
# define cnt16H r31 |
# define cntH r18 |
#else /* __IAR_SYSTEMS_ASM__ */ |
/* Register assignments for usbMeasureFrameLength on gcc */ |
/* Calling conventions on gcc: |
* First parameter passed in r24/r25, second in r22/23 and so on. |
* Callee must preserve r1-r17, r28/r29 |
* Result is passed in r24/r25 |
*/ |
# define resL r24 |
# define resH r25 |
# define cnt16L r24 |
# define cnt16H r25 |
# define cntH r26 |
#endif |
# define cnt16 cnt16L |
; extern unsigned usbMeasurePacketLength(void); |
; returns time between two idle strobes in multiples of 7 CPU clocks |
.global usbMeasureFrameLength |
usbMeasureFrameLength: |
ldi cntH, 6 ; wait ~ 10 ms for D- == 0 |
clr cnt16L |
clr cnt16H |
usbMFTime16: |
dec cntH |
breq usbMFTimeout |
usbMFWaitStrobe: ; first wait for D- == 0 (idle strobe) |
sbiw cnt16, 1 ;[0] [6] |
breq usbMFTime16 ;[2] |
sbic USBIN, USBMINUS ;[3] |
rjmp usbMFWaitStrobe ;[4] |
usbMFWaitIdle: ; then wait until idle again |
sbis USBIN, USBMINUS ;1 wait for D- == 1 |
rjmp usbMFWaitIdle ;2 |
ldi cnt16L, 1 ;1 represents cycles so far |
clr cnt16H ;1 |
usbMFWaitLoop: |
in cntH, USBIN ;[0] [7] |
adiw cnt16, 1 ;[1] |
breq usbMFTimeout ;[3] |
andi cntH, USBMASK ;[4] |
brne usbMFWaitLoop ;[5] |
usbMFTimeout: |
#if resL != cnt16L |
mov resL, cnt16L |
mov resH, cnt16H |
#endif |
ret |
#undef resL |
#undef resH |
#undef cnt16 |
#undef cnt16L |
#undef cnt16H |
#undef cntH |
#endif /* USB_CFG_HAVE_MEASURE_FRAME_LENGTH */ |
;---------------------------------------------------------------------------- |
; Now include the clock rate specific code |
;---------------------------------------------------------------------------- |
#ifndef USB_CFG_CLOCK_KHZ |
# ifdef F_CPU |
# define USB_CFG_CLOCK_KHZ (F_CPU/1000) |
# else |
# error "USB_CFG_CLOCK_KHZ not defined in usbconfig.h and no F_CPU set!" |
# endif |
#endif |
#if USB_CFG_CHECK_CRC /* separate dispatcher for CRC type modules */ |
# if USB_CFG_CLOCK_KHZ == 18000 |
# include "usbdrvasm18-crc.inc" |
# else |
# error "USB_CFG_CLOCK_KHZ is not one of the supported crc-rates!" |
# endif |
#else /* USB_CFG_CHECK_CRC */ |
# if USB_CFG_CLOCK_KHZ == 12000 |
# include "usbdrvasm12.inc" |
# elif USB_CFG_CLOCK_KHZ == 12800 |
# include "usbdrvasm128.inc" |
# elif USB_CFG_CLOCK_KHZ == 15000 |
# include "usbdrvasm15.inc" |
# elif USB_CFG_CLOCK_KHZ == 16000 |
# include "usbdrvasm16.inc" |
# elif USB_CFG_CLOCK_KHZ == 16500 |
# include "usbdrvasm165.inc" |
# elif USB_CFG_CLOCK_KHZ == 20000 |
# include "usbdrvasm20.inc" |
# else |
# error "USB_CFG_CLOCK_KHZ is not one of the supported non-crc-rates!" |
# endif |
#endif /* USB_CFG_CHECK_CRC */ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm.asm |
---|
0,0 → 1,21 |
/* Name: usbdrvasm.asm |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2006-03-01 |
* Tabsize: 4 |
* Copyright: (c) 2006 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id$ |
*/ |
/* |
General Description: |
The IAR compiler/assembler system prefers assembler files with file extension |
".asm". We simply provide this file as an alias for usbdrvasm.S. |
Thanks to Oleg Semyonov for his help with the IAR tools port! |
*/ |
#include "usbdrvasm.S" |
end |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm12.inc |
---|
0,0 → 1,393 |
/* Name: usbdrvasm12.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2004-12-29 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrvasm12.inc 740 2009-04-13 18:23:31Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 12 MHz version of the asssembler part of the USB driver. It |
requires a 12 MHz crystal (not a ceramic resonator and not a calibrated RC |
oscillator). |
See usbdrv.h for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
Timing constraints according to spec (in bit times): |
timing subject min max CPUcycles |
--------------------------------------------------------------------------- |
EOP of OUT/SETUP to sync pattern of DATA0 (both rx) 2 16 16-128 |
EOP of IN to sync pattern of DATA0 (rx, then tx) 2 7.5 16-60 |
DATAx (rx) to ACK/NAK/STALL (tx) 2 7.5 16-60 |
*/ |
;Software-receiver engine. Strict timing! Don't change unless you can preserve timing! |
;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled |
;max allowable interrupt latency: 34 cycles -> max 25 cycles interrupt disable |
;max stack usage: [ret(2), YL, SREG, YH, shift, x1, x2, x3, cnt, x4] = 11 bytes |
;Numbers in brackets are maximum cycles since SOF. |
USB_INTR_VECTOR: |
;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt |
push YL ;2 [35] push only what is necessary to sync with edge ASAP |
in YL, SREG ;1 [37] |
push YL ;2 [39] |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
waitForK: |
;The following code results in a sampling window of 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
foundK: |
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] |
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push YH ;2 [2] |
lds YL, usbInputBufOffset;2 [4] |
clr YH ;1 [5] |
subi YL, lo8(-(usbRxBuf));1 [6] |
sbci YH, hi8(-(usbRxBuf));1 [7] |
sbis USBIN, USBMINUS ;1 [8] we want two bits K [sample 1 cycle too early] |
rjmp haveTwoBitsK ;2 [10] |
pop YH ;2 [11] undo the push from before |
rjmp waitForK ;2 [13] this was not the end of sync, retry |
haveTwoBitsK: |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
push shift ;2 [16] |
push x1 ;2 [12] |
push x2 ;2 [14] |
in x1, USBIN ;1 [17] <-- sample bit 0 |
ldi shift, 0xff ;1 [18] |
bst x1, USBMINUS ;1 [19] |
bld shift, 0 ;1 [20] |
push x3 ;2 [22] |
push cnt ;2 [24] |
in x2, USBIN ;1 [25] <-- sample bit 1 |
ser x3 ;1 [26] [inserted init instruction] |
eor x1, x2 ;1 [27] |
bst x1, USBMINUS ;1 [28] |
bld shift, 1 ;1 [29] |
ldi cnt, USB_BUFSIZE;1 [30] [inserted init instruction] |
rjmp rxbit2 ;2 [32] |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
unstuff0: ;1 (branch taken) |
andi x3, ~0x01 ;1 [15] |
mov x1, x2 ;1 [16] x2 contains last sampled (stuffed) bit |
in x2, USBIN ;1 [17] <-- sample bit 1 again |
ori shift, 0x01 ;1 [18] |
rjmp didUnstuff0 ;2 [20] |
unstuff1: ;1 (branch taken) |
mov x2, x1 ;1 [21] x1 contains last sampled (stuffed) bit |
andi x3, ~0x02 ;1 [22] |
ori shift, 0x02 ;1 [23] |
nop ;1 [24] |
in x1, USBIN ;1 [25] <-- sample bit 2 again |
rjmp didUnstuff1 ;2 [27] |
unstuff2: ;1 (branch taken) |
andi x3, ~0x04 ;1 [29] |
ori shift, 0x04 ;1 [30] |
mov x1, x2 ;1 [31] x2 contains last sampled (stuffed) bit |
nop ;1 [32] |
in x2, USBIN ;1 [33] <-- sample bit 3 |
rjmp didUnstuff2 ;2 [35] |
unstuff3: ;1 (branch taken) |
in x2, USBIN ;1 [34] <-- sample stuffed bit 3 [one cycle too late] |
andi x3, ~0x08 ;1 [35] |
ori shift, 0x08 ;1 [36] |
rjmp didUnstuff3 ;2 [38] |
unstuff4: ;1 (branch taken) |
andi x3, ~0x10 ;1 [40] |
in x1, USBIN ;1 [41] <-- sample stuffed bit 4 |
ori shift, 0x10 ;1 [42] |
rjmp didUnstuff4 ;2 [44] |
unstuff5: ;1 (branch taken) |
andi x3, ~0x20 ;1 [48] |
in x2, USBIN ;1 [49] <-- sample stuffed bit 5 |
ori shift, 0x20 ;1 [50] |
rjmp didUnstuff5 ;2 [52] |
unstuff6: ;1 (branch taken) |
andi x3, ~0x40 ;1 [56] |
in x1, USBIN ;1 [57] <-- sample stuffed bit 6 |
ori shift, 0x40 ;1 [58] |
rjmp didUnstuff6 ;2 [60] |
; extra jobs done during bit interval: |
; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs] |
; bit 1: se0 check |
; bit 2: overflow check |
; bit 3: recovery from delay [bit 0 tasks took too long] |
; bit 4: none |
; bit 5: none |
; bit 6: none |
; bit 7: jump, eor |
rxLoop: |
eor x3, shift ;1 [0] reconstruct: x3 is 0 at bit locations we changed, 1 at others |
in x1, USBIN ;1 [1] <-- sample bit 0 |
st y+, x3 ;2 [3] store data |
ser x3 ;1 [4] |
nop ;1 [5] |
eor x2, x1 ;1 [6] |
bst x2, USBMINUS;1 [7] |
bld shift, 0 ;1 [8] |
in x2, USBIN ;1 [9] <-- sample bit 1 (or possibly bit 0 stuffed) |
andi x2, USBMASK ;1 [10] |
breq se0 ;1 [11] SE0 check for bit 1 |
andi shift, 0xf9 ;1 [12] |
didUnstuff0: |
breq unstuff0 ;1 [13] |
eor x1, x2 ;1 [14] |
bst x1, USBMINUS;1 [15] |
bld shift, 1 ;1 [16] |
rxbit2: |
in x1, USBIN ;1 [17] <-- sample bit 2 (or possibly bit 1 stuffed) |
andi shift, 0xf3 ;1 [18] |
breq unstuff1 ;1 [19] do remaining work for bit 1 |
didUnstuff1: |
subi cnt, 1 ;1 [20] |
brcs overflow ;1 [21] loop control |
eor x2, x1 ;1 [22] |
bst x2, USBMINUS;1 [23] |
bld shift, 2 ;1 [24] |
in x2, USBIN ;1 [25] <-- sample bit 3 (or possibly bit 2 stuffed) |
andi shift, 0xe7 ;1 [26] |
breq unstuff2 ;1 [27] |
didUnstuff2: |
eor x1, x2 ;1 [28] |
bst x1, USBMINUS;1 [29] |
bld shift, 3 ;1 [30] |
didUnstuff3: |
andi shift, 0xcf ;1 [31] |
breq unstuff3 ;1 [32] |
in x1, USBIN ;1 [33] <-- sample bit 4 |
eor x2, x1 ;1 [34] |
bst x2, USBMINUS;1 [35] |
bld shift, 4 ;1 [36] |
didUnstuff4: |
andi shift, 0x9f ;1 [37] |
breq unstuff4 ;1 [38] |
nop2 ;2 [40] |
in x2, USBIN ;1 [41] <-- sample bit 5 |
eor x1, x2 ;1 [42] |
bst x1, USBMINUS;1 [43] |
bld shift, 5 ;1 [44] |
didUnstuff5: |
andi shift, 0x3f ;1 [45] |
breq unstuff5 ;1 [46] |
nop2 ;2 [48] |
in x1, USBIN ;1 [49] <-- sample bit 6 |
eor x2, x1 ;1 [50] |
bst x2, USBMINUS;1 [51] |
bld shift, 6 ;1 [52] |
didUnstuff6: |
cpi shift, 0x02 ;1 [53] |
brlo unstuff6 ;1 [54] |
nop2 ;2 [56] |
in x2, USBIN ;1 [57] <-- sample bit 7 |
eor x1, x2 ;1 [58] |
bst x1, USBMINUS;1 [59] |
bld shift, 7 ;1 [60] |
didUnstuff7: |
cpi shift, 0x04 ;1 [61] |
brsh rxLoop ;2 [63] loop control |
unstuff7: |
andi x3, ~0x80 ;1 [63] |
ori shift, 0x80 ;1 [64] |
in x2, USBIN ;1 [65] <-- sample stuffed bit 7 |
nop ;1 [66] |
rjmp didUnstuff7 ;2 [68] |
macro POP_STANDARD ; 12 cycles |
pop cnt |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop YH |
endm |
macro POP_RETI ; 5 cycles |
pop YL |
out SREG, YL |
pop YL |
endm |
#include "asmcommon.inc" |
;---------------------------------------------------------------------------- |
; Transmitting data |
;---------------------------------------------------------------------------- |
txByteLoop: |
txBitloop: |
stuffN1Delay: ; [03] |
ror shift ;[-5] [11] [59] |
brcc doExorN1 ;[-4] [60] |
subi x4, 1 ;[-3] |
brne commonN1 ;[-2] |
lsl shift ;[-1] compensate ror after rjmp stuffDelay |
nop ;[00] stuffing consists of just waiting 8 cycles |
rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear |
sendNakAndReti: ;0 [-19] 19 cycles until SOP |
ldi x3, USBPID_NAK ;1 [-18] |
rjmp usbSendX3 ;2 [-16] |
sendAckAndReti: ;0 [-19] 19 cycles until SOP |
ldi x3, USBPID_ACK ;1 [-18] |
rjmp usbSendX3 ;2 [-16] |
sendCntAndReti: ;0 [-17] 17 cycles until SOP |
mov x3, cnt ;1 [-16] |
usbSendX3: ;0 [-16] |
ldi YL, 20 ;1 [-15] 'x3' is R20 |
ldi YH, 0 ;1 [-14] |
ldi cnt, 2 ;1 [-13] |
; rjmp usbSendAndReti fallthrough |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 |
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 |
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte |
;uses: x1...x2, x4, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x4 = bitstuff cnt] |
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) |
usbSendAndReti: |
in x2, USBDDR ;[-12] 12 cycles until SOP |
ori x2, USBMASK ;[-11] |
sbi USBOUT, USBMINUS ;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) |
out USBDDR, x2 ;[-8] <--- acquire bus |
in x1, USBOUT ;[-7] port mirror for tx loop |
ldi shift, 0x40 ;[-6] sync byte is first byte sent (we enter loop after ror) |
ldi x2, USBMASK ;[-5] |
push x4 ;[-4] |
doExorN1: |
eor x1, x2 ;[-2] [06] [62] |
ldi x4, 6 ;[-1] [07] [63] |
commonN1: |
stuffN2Delay: |
out USBOUT, x1 ;[00] [08] [64] <--- set bit |
ror shift ;[01] |
brcc doExorN2 ;[02] |
subi x4, 1 ;[03] |
brne commonN2 ;[04] |
lsl shift ;[05] compensate ror after rjmp stuffDelay |
rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear |
doExorN2: |
eor x1, x2 ;[04] [12] |
ldi x4, 6 ;[05] [13] |
commonN2: |
nop ;[06] [14] |
subi cnt, 171 ;[07] [15] trick: (3 * 171) & 0xff = 1 |
out USBOUT, x1 ;[08] [16] <--- set bit |
brcs txBitloop ;[09] [25] [41] |
stuff6Delay: |
ror shift ;[42] [50] |
brcc doExor6 ;[43] |
subi x4, 1 ;[44] |
brne common6 ;[45] |
lsl shift ;[46] compensate ror after rjmp stuffDelay |
nop ;[47] stuffing consists of just waiting 8 cycles |
rjmp stuff6Delay ;[48] after ror, C bit is reliably clear |
doExor6: |
eor x1, x2 ;[45] [53] |
ldi x4, 6 ;[46] |
common6: |
stuff7Delay: |
ror shift ;[47] [55] |
out USBOUT, x1 ;[48] <--- set bit |
brcc doExor7 ;[49] |
subi x4, 1 ;[50] |
brne common7 ;[51] |
lsl shift ;[52] compensate ror after rjmp stuffDelay |
rjmp stuff7Delay ;[53] after ror, C bit is reliably clear |
doExor7: |
eor x1, x2 ;[51] [59] |
ldi x4, 6 ;[52] |
common7: |
ld shift, y+ ;[53] |
tst cnt ;[55] |
out USBOUT, x1 ;[56] <--- set bit |
brne txByteLoop ;[57] |
;make SE0: |
cbr x1, USBMASK ;[58] prepare SE0 [spec says EOP may be 15 to 18 cycles] |
lds x2, usbNewDeviceAddr;[59] |
lsl x2 ;[61] we compare with left shifted address |
subi YL, 2 + 20 ;[62] Only assign address on data packets, not ACK/NAK in x3 |
sbci YH, 0 ;[63] |
out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
breq skipAddrAssign ;[01] |
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;[04] |
ori x1, USBIDLE ;[05] |
in x2, USBDDR ;[06] |
cbr x2, USBMASK ;[07] set both pins to input |
mov x3, x1 ;[08] |
cbr x3, USBMASK ;[09] configure no pullup on both pins |
pop x4 ;[10] |
nop2 ;[12] |
nop2 ;[14] |
out USBOUT, x1 ;[16] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;[17] <-- release bus now |
out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active |
rjmp doReturn |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm128.inc |
---|
0,0 → 1,750 |
/* Name: usbdrvasm128.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2008-10-11 |
* Tabsize: 4 |
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbdrvasm128.inc 758 2009-08-06 10:12:54Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 12.8 MHz version of the USB driver. It is intended for use |
with the internal RC oscillator. Although 12.8 MHz is outside the guaranteed |
calibration range of the oscillator, almost all AVRs can reach this frequency. |
This version contains a phase locked loop in the receiver routine to cope with |
slight clock rate deviations of up to +/- 1%. |
See usbdrv.h for a description of the entire driver. |
LIMITATIONS |
=========== |
Although it may seem very handy to save the crystal and use the internal |
RC oscillator of the CPU, this method (and this module) has some serious |
limitations: |
(1) The guaranteed calibration range of the oscillator is only 8.1 MHz. |
They typical range is 14.5 MHz and most AVRs can actually reach this rate. |
(2) Writing EEPROM and Flash may be unreliable (short data lifetime) since |
the write procedure is timed from the RC oscillator. |
(3) End Of Packet detection (SE0) should be in bit 1, bit it is only checked |
if bits 0 and 1 both read as 0 on D- and D+ read as 0 in the middle. This may |
cause problems with old hubs which delay SE0 by up to one cycle. |
(4) Code size is much larger than that of the other modules. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
Implementation notes: |
====================== |
min frequency: 67 cycles for 8 bit -> 12.5625 MHz |
max frequency: 69.286 cycles for 8 bit -> 12.99 MHz |
nominal frequency: 12.77 MHz ( = sqrt(min * max)) |
sampling positions: (next even number in range [+/- 0.5]) |
cycle index range: 0 ... 66 |
bits: |
.5, 8.875, 17.25, 25.625, 34, 42.375, 50.75, 59.125 |
[0/1], [9], [17], [25/+26], [34], [+42/43], [51], [59] |
bit number: 0 1 2 3 4 5 6 7 |
spare cycles 1 2 1 2 1 1 1 0 |
operations to perform: duration cycle |
---------------- |
eor fix, shift 1 -> 00 |
andi phase, USBMASK 1 -> 08 |
breq se0 1 -> 16 (moved to 11) |
st y+, data 2 -> 24, 25 |
mov data, fix 1 -> 33 |
ser data 1 -> 41 |
subi cnt, 1 1 -> 49 |
brcs overflow 1 -> 50 |
layout of samples and operations: |
[##] = sample bit |
<##> = sample phase |
*##* = operation |
0: *00* [01] 02 03 04 <05> 06 07 |
1: *08* [09] 10 11 12 <13> 14 15 *16* |
2: [17] 18 19 20 <21> 22 23 |
3: *24* *25* [26] 27 28 29 <30> 31 32 |
4: *33* [34] 35 36 37 <38> 39 40 |
5: *41* [42] 43 44 45 <46> 47 48 |
6: *49* *50* [51] 52 53 54 <55> 56 57 58 |
7: [59] 60 61 62 <63> 64 65 66 |
*****************************************************************************/ |
/* we prefer positive expressions (do if condition) instead of negative |
* (skip if condition), therefore use defines for skip instructions: |
*/ |
#define ifioclr sbis |
#define ifioset sbic |
#define ifrclr sbrs |
#define ifrset sbrc |
/* The registers "fix" and "data" swap their meaning during the loop. Use |
* defines to keep their name constant. |
*/ |
#define fix x2 |
#define data x1 |
#undef phase /* phase has a default definition to x4 */ |
#define phase x3 |
USB_INTR_VECTOR: |
;order of registers pushed: YL, SREG [sofError], YH, shift, x1, x2, x3, cnt, r0 |
push YL ;2 push only what is necessary to sync with edge ASAP |
in YL, SREG ;1 |
push YL ;2 |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
waitForK: |
;The following code results in a sampling window of 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS ;[0] |
rjmp foundK ;[1] |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
foundK: |
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 4 for center sampling] |
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push YH ;[2] |
lds YL, usbInputBufOffset;[4] |
clr YH ;[6] |
subi YL, lo8(-(usbRxBuf));[7] |
sbci YH, hi8(-(usbRxBuf));[8] |
sbis USBIN, USBMINUS ;[9] we want two bits K [we want to sample at 8 + 4 - 1.5 = 10.5] |
rjmp haveTwoBitsK ;[10] |
pop YH ;[11] undo the push from before |
rjmp waitForK ;[13] this was not the end of sync, retry |
haveTwoBitsK: |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
#define fix x2 |
#define data x1 |
push shift ;[12] |
push x1 ;[14] |
push x2 ;[16] |
ldi shift, 0x80 ;[18] prevent bit-unstuffing but init low bits to 0 |
ifioset USBIN, USBMINUS ;[19] [01] <--- bit 0 [10.5 + 8 = 18.5] |
ori shift, 1<<0 ;[02] |
push x3 ;[03] |
push cnt ;[05] |
push r0 ;[07] |
ifioset USBIN, USBMINUS ;[09] <--- bit 1 |
ori shift, 1<<1 ;[10] |
ser fix ;[11] |
ldi cnt, USB_BUFSIZE ;[12] |
mov data, shift ;[13] |
lsl shift ;[14] |
nop2 ;[15] |
ifioset USBIN, USBMINUS ;[17] <--- bit 2 |
ori data, 3<<2 ;[18] store in bit 2 AND bit 3 |
eor shift, data ;[19] do nrzi decoding |
andi data, 1<<3 ;[20] |
in phase, USBIN ;[21] <- phase |
brne jumpToEntryAfterSet ;[22] if USBMINS at bit 3 was 1 |
nop ;[23] |
rjmp entryAfterClr ;[24] |
jumpToEntryAfterSet: |
rjmp entryAfterSet ;[24] |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
#undef fix |
#define fix x1 |
#undef data |
#define data x2 |
bit7IsSet: |
ifrclr phase, USBMINUS ;[62] check phase only if D- changed |
lpm ;[63] |
in phase, USBIN ;[64] <- phase (one cycle too late) |
ori shift, 1 << 7 ;[65] |
nop ;[66] |
;;;;rjmp bit0AfterSet ; -> [00] == [67] moved block up to save jump |
bit0AfterSet: |
eor fix, shift ;[00] |
#undef fix |
#define fix x2 |
#undef data |
#define data x1 /* we now have result in data, fix is reset to 0xff */ |
ifioclr USBIN, USBMINUS ;[01] <--- sample 0 |
rjmp bit0IsClr ;[02] |
andi shift, ~(7 << 0) ;[03] |
breq unstuff0s ;[04] |
in phase, USBIN ;[05] <- phase |
rjmp bit1AfterSet ;[06] |
unstuff0s: |
in phase, USBIN ;[06] <- phase (one cycle too late) |
andi fix, ~(1 << 0) ;[07] |
ifioclr USBIN, USBMINUS ;[00] |
ifioset USBIN, USBPLUS ;[01] |
rjmp bit0IsClr ;[02] executed if first expr false or second true |
se0AndStore: ; executed only if both bits 0 |
st y+, x1 ;[15/17] cycles after start of byte |
rjmp se0 ;[17/19] |
bit0IsClr: |
ifrset phase, USBMINUS ;[04] check phase only if D- changed |
lpm ;[05] |
in phase, USBIN ;[06] <- phase (one cycle too late) |
ori shift, 1 << 0 ;[07] |
bit1AfterClr: |
andi phase, USBMASK ;[08] |
ifioset USBIN, USBMINUS ;[09] <--- sample 1 |
rjmp bit1IsSet ;[10] |
breq se0AndStore ;[11] if D- was 0 in bits 0 AND 1 and D+ was 0 in between, we have SE0 |
andi shift, ~(7 << 1) ;[12] |
in phase, USBIN ;[13] <- phase |
breq unstuff1c ;[14] |
rjmp bit2AfterClr ;[15] |
unstuff1c: |
andi fix, ~(1 << 1) ;[16] |
nop2 ;[08] |
nop2 ;[10] |
bit1IsSet: |
ifrclr phase, USBMINUS ;[12] check phase only if D- changed |
lpm ;[13] |
in phase, USBIN ;[14] <- phase (one cycle too late) |
ori shift, 1 << 1 ;[15] |
nop ;[16] |
bit2AfterSet: |
ifioclr USBIN, USBMINUS ;[17] <--- sample 2 |
rjmp bit2IsClr ;[18] |
andi shift, ~(7 << 2) ;[19] |
breq unstuff2s ;[20] |
in phase, USBIN ;[21] <- phase |
rjmp bit3AfterSet ;[22] |
unstuff2s: |
in phase, USBIN ;[22] <- phase (one cycle too late) |
andi fix, ~(1 << 2) ;[23] |
nop2 ;[16] |
nop2 ;[18] |
bit2IsClr: |
ifrset phase, USBMINUS ;[20] check phase only if D- changed |
lpm ;[21] |
in phase, USBIN ;[22] <- phase (one cycle too late) |
ori shift, 1 << 2 ;[23] |
bit3AfterClr: |
st y+, data ;[24] |
entryAfterClr: |
ifioset USBIN, USBMINUS ;[26] <--- sample 3 |
rjmp bit3IsSet ;[27] |
andi shift, ~(7 << 3) ;[28] |
breq unstuff3c ;[29] |
in phase, USBIN ;[30] <- phase |
rjmp bit4AfterClr ;[31] |
unstuff3c: |
in phase, USBIN ;[31] <- phase (one cycle too late) |
andi fix, ~(1 << 3) ;[32] |
nop2 ;[25] |
nop2 ;[27] |
bit3IsSet: |
ifrclr phase, USBMINUS ;[29] check phase only if D- changed |
lpm ;[30] |
in phase, USBIN ;[31] <- phase (one cycle too late) |
ori shift, 1 << 3 ;[32] |
bit4AfterSet: |
mov data, fix ;[33] undo this move by swapping defines |
#undef fix |
#define fix x1 |
#undef data |
#define data x2 |
ifioclr USBIN, USBMINUS ;[34] <--- sample 4 |
rjmp bit4IsClr ;[35] |
andi shift, ~(7 << 4) ;[36] |
breq unstuff4s ;[37] |
in phase, USBIN ;[38] <- phase |
rjmp bit5AfterSet ;[39] |
unstuff4s: |
in phase, USBIN ;[39] <- phase (one cycle too late) |
andi fix, ~(1 << 4) ;[40] |
nop2 ;[33] |
nop2 ;[35] |
bit4IsClr: |
ifrset phase, USBMINUS ;[37] check phase only if D- changed |
lpm ;[38] |
in phase, USBIN ;[39] <- phase (one cycle too late) |
ori shift, 1 << 4 ;[40] |
bit5AfterClr: |
ser data ;[41] |
ifioset USBIN, USBMINUS ;[42] <--- sample 5 |
rjmp bit5IsSet ;[43] |
andi shift, ~(7 << 5) ;[44] |
breq unstuff5c ;[45] |
in phase, USBIN ;[46] <- phase |
rjmp bit6AfterClr ;[47] |
unstuff5c: |
in phase, USBIN ;[47] <- phase (one cycle too late) |
andi fix, ~(1 << 5) ;[48] |
nop2 ;[41] |
nop2 ;[43] |
bit5IsSet: |
ifrclr phase, USBMINUS ;[45] check phase only if D- changed |
lpm ;[46] |
in phase, USBIN ;[47] <- phase (one cycle too late) |
ori shift, 1 << 5 ;[48] |
bit6AfterSet: |
subi cnt, 1 ;[49] |
brcs jumpToOverflow ;[50] |
ifioclr USBIN, USBMINUS ;[51] <--- sample 6 |
rjmp bit6IsClr ;[52] |
andi shift, ~(3 << 6) ;[53] |
cpi shift, 2 ;[54] |
in phase, USBIN ;[55] <- phase |
brlt unstuff6s ;[56] |
rjmp bit7AfterSet ;[57] |
jumpToOverflow: |
rjmp overflow |
unstuff6s: |
andi fix, ~(1 << 6) ;[50] |
lpm ;[51] |
bit6IsClr: |
ifrset phase, USBMINUS ;[54] check phase only if D- changed |
lpm ;[55] |
in phase, USBIN ;[56] <- phase (one cycle too late) |
ori shift, 1 << 6 ;[57] |
nop ;[58] |
bit7AfterClr: |
ifioset USBIN, USBMINUS ;[59] <--- sample 7 |
rjmp bit7IsSet ;[60] |
andi shift, ~(1 << 7) ;[61] |
cpi shift, 4 ;[62] |
in phase, USBIN ;[63] <- phase |
brlt unstuff7c ;[64] |
rjmp bit0AfterClr ;[65] -> [00] == [67] |
unstuff7c: |
andi fix, ~(1 << 7) ;[58] |
nop ;[59] |
rjmp bit7IsSet ;[60] |
bit7IsClr: |
ifrset phase, USBMINUS ;[62] check phase only if D- changed |
lpm ;[63] |
in phase, USBIN ;[64] <- phase (one cycle too late) |
ori shift, 1 << 7 ;[65] |
nop ;[66] |
;;;;rjmp bit0AfterClr ; -> [00] == [67] moved block up to save jump |
bit0AfterClr: |
eor fix, shift ;[00] |
#undef fix |
#define fix x2 |
#undef data |
#define data x1 /* we now have result in data, fix is reset to 0xff */ |
ifioset USBIN, USBMINUS ;[01] <--- sample 0 |
rjmp bit0IsSet ;[02] |
andi shift, ~(7 << 0) ;[03] |
breq unstuff0c ;[04] |
in phase, USBIN ;[05] <- phase |
rjmp bit1AfterClr ;[06] |
unstuff0c: |
in phase, USBIN ;[06] <- phase (one cycle too late) |
andi fix, ~(1 << 0) ;[07] |
ifioclr USBIN, USBMINUS ;[00] |
ifioset USBIN, USBPLUS ;[01] |
rjmp bit0IsSet ;[02] executed if first expr false or second true |
rjmp se0AndStore ;[03] executed only if both bits 0 |
bit0IsSet: |
ifrclr phase, USBMINUS ;[04] check phase only if D- changed |
lpm ;[05] |
in phase, USBIN ;[06] <- phase (one cycle too late) |
ori shift, 1 << 0 ;[07] |
bit1AfterSet: |
andi shift, ~(7 << 1) ;[08] compensated by "ori shift, 1<<1" if bit1IsClr |
ifioclr USBIN, USBMINUS ;[09] <--- sample 1 |
rjmp bit1IsClr ;[10] |
breq unstuff1s ;[11] |
nop2 ;[12] do not check for SE0 if bit 0 was 1 |
in phase, USBIN ;[14] <- phase (one cycle too late) |
rjmp bit2AfterSet ;[15] |
unstuff1s: |
in phase, USBIN ;[13] <- phase |
andi fix, ~(1 << 1) ;[14] |
lpm ;[07] |
nop2 ;[10] |
bit1IsClr: |
ifrset phase, USBMINUS ;[12] check phase only if D- changed |
lpm ;[13] |
in phase, USBIN ;[14] <- phase (one cycle too late) |
ori shift, 1 << 1 ;[15] |
nop ;[16] |
bit2AfterClr: |
ifioset USBIN, USBMINUS ;[17] <--- sample 2 |
rjmp bit2IsSet ;[18] |
andi shift, ~(7 << 2) ;[19] |
breq unstuff2c ;[20] |
in phase, USBIN ;[21] <- phase |
rjmp bit3AfterClr ;[22] |
unstuff2c: |
in phase, USBIN ;[22] <- phase (one cycle too late) |
andi fix, ~(1 << 2) ;[23] |
nop2 ;[16] |
nop2 ;[18] |
bit2IsSet: |
ifrclr phase, USBMINUS ;[20] check phase only if D- changed |
lpm ;[21] |
in phase, USBIN ;[22] <- phase (one cycle too late) |
ori shift, 1 << 2 ;[23] |
bit3AfterSet: |
st y+, data ;[24] |
entryAfterSet: |
ifioclr USBIN, USBMINUS ;[26] <--- sample 3 |
rjmp bit3IsClr ;[27] |
andi shift, ~(7 << 3) ;[28] |
breq unstuff3s ;[29] |
in phase, USBIN ;[30] <- phase |
rjmp bit4AfterSet ;[31] |
unstuff3s: |
in phase, USBIN ;[31] <- phase (one cycle too late) |
andi fix, ~(1 << 3) ;[32] |
nop2 ;[25] |
nop2 ;[27] |
bit3IsClr: |
ifrset phase, USBMINUS ;[29] check phase only if D- changed |
lpm ;[30] |
in phase, USBIN ;[31] <- phase (one cycle too late) |
ori shift, 1 << 3 ;[32] |
bit4AfterClr: |
mov data, fix ;[33] undo this move by swapping defines |
#undef fix |
#define fix x1 |
#undef data |
#define data x2 |
ifioset USBIN, USBMINUS ;[34] <--- sample 4 |
rjmp bit4IsSet ;[35] |
andi shift, ~(7 << 4) ;[36] |
breq unstuff4c ;[37] |
in phase, USBIN ;[38] <- phase |
rjmp bit5AfterClr ;[39] |
unstuff4c: |
in phase, USBIN ;[39] <- phase (one cycle too late) |
andi fix, ~(1 << 4) ;[40] |
nop2 ;[33] |
nop2 ;[35] |
bit4IsSet: |
ifrclr phase, USBMINUS ;[37] check phase only if D- changed |
lpm ;[38] |
in phase, USBIN ;[39] <- phase (one cycle too late) |
ori shift, 1 << 4 ;[40] |
bit5AfterSet: |
ser data ;[41] |
ifioclr USBIN, USBMINUS ;[42] <--- sample 5 |
rjmp bit5IsClr ;[43] |
andi shift, ~(7 << 5) ;[44] |
breq unstuff5s ;[45] |
in phase, USBIN ;[46] <- phase |
rjmp bit6AfterSet ;[47] |
unstuff5s: |
in phase, USBIN ;[47] <- phase (one cycle too late) |
andi fix, ~(1 << 5) ;[48] |
nop2 ;[41] |
nop2 ;[43] |
bit5IsClr: |
ifrset phase, USBMINUS ;[45] check phase only if D- changed |
lpm ;[46] |
in phase, USBIN ;[47] <- phase (one cycle too late) |
ori shift, 1 << 5 ;[48] |
bit6AfterClr: |
subi cnt, 1 ;[49] |
brcs overflow ;[50] |
ifioset USBIN, USBMINUS ;[51] <--- sample 6 |
rjmp bit6IsSet ;[52] |
andi shift, ~(3 << 6) ;[53] |
cpi shift, 2 ;[54] |
in phase, USBIN ;[55] <- phase |
brlt unstuff6c ;[56] |
rjmp bit7AfterClr ;[57] |
unstuff6c: |
andi fix, ~(1 << 6) ;[50] |
lpm ;[51] |
bit6IsSet: |
ifrclr phase, USBMINUS ;[54] check phase only if D- changed |
lpm ;[55] |
in phase, USBIN ;[56] <- phase (one cycle too late) |
ori shift, 1 << 6 ;[57] |
bit7AfterSet: |
ifioclr USBIN, USBMINUS ;[59] <--- sample 7 |
rjmp bit7IsClr ;[60] |
andi shift, ~(1 << 7) ;[61] |
cpi shift, 4 ;[62] |
in phase, USBIN ;[63] <- phase |
brlt unstuff7s ;[64] |
rjmp bit0AfterSet ;[65] -> [00] == [67] |
unstuff7s: |
andi fix, ~(1 << 7) ;[58] |
nop ;[59] |
rjmp bit7IsClr ;[60] |
macro POP_STANDARD ; 14 cycles |
pop r0 |
pop cnt |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop YH |
endm |
macro POP_RETI ; 5 cycles |
pop YL |
out SREG, YL |
pop YL |
endm |
#include "asmcommon.inc" |
;---------------------------------------------------------------------------- |
; Transmitting data |
;---------------------------------------------------------------------------- |
txByteLoop: |
txBitloop: |
stuffN1Delay: ; [03] |
ror shift ;[-5] [11] [63] |
brcc doExorN1 ;[-4] [64] |
subi x3, 1 ;[-3] |
brne commonN1 ;[-2] |
lsl shift ;[-1] compensate ror after rjmp stuffDelay |
nop ;[00] stuffing consists of just waiting 8 cycles |
rjmp stuffN1Delay ;[01] after ror, C bit is reliably clear |
sendNakAndReti: |
ldi cnt, USBPID_NAK ;[-19] |
rjmp sendCntAndReti ;[-18] |
sendAckAndReti: |
ldi cnt, USBPID_ACK ;[-17] |
sendCntAndReti: |
mov r0, cnt ;[-16] |
ldi YL, 0 ;[-15] R0 address is 0 |
ldi YH, 0 ;[-14] |
ldi cnt, 2 ;[-13] |
; rjmp usbSendAndReti fallthrough |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) or USBOUT = 0x01 |
; K = (D+ = 1), (D- = 0) or USBOUT = 0x02 |
; Spec allows 7.5 bit times from EOP to SOP for replies (= 60 cycles) |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte |
;uses: x1...x3, shift, cnt, Y [x1 = mirror USBOUT, x2 = USBMASK, x3 = bitstuff cnt] |
;Numbers in brackets are time since first bit of sync pattern is sent (start of instruction) |
usbSendAndReti: |
in x2, USBDDR ;[-10] 10 cycles until SOP |
ori x2, USBMASK ;[-9] |
sbi USBOUT, USBMINUS ;[-8] prepare idle state; D+ and D- must have been 0 (no pullups) |
out USBDDR, x2 ;[-6] <--- acquire bus |
in x1, USBOUT ;[-5] port mirror for tx loop |
ldi shift, 0x40 ;[-4] sync byte is first byte sent (we enter loop after ror) |
ldi x2, USBMASK ;[-3] |
doExorN1: |
eor x1, x2 ;[-2] [06] [62] |
ldi x3, 6 ;[-1] [07] [63] |
commonN1: |
stuffN2Delay: |
out USBOUT, x1 ;[00] [08] [64] <--- set bit |
ror shift ;[01] |
brcc doExorN2 ;[02] |
subi x3, 1 ;[03] |
brne commonN2 ;[04] |
lsl shift ;[05] compensate ror after rjmp stuffDelay |
rjmp stuffN2Delay ;[06] after ror, C bit is reliably clear |
doExorN2: |
eor x1, x2 ;[04] [12] |
ldi x3, 6 ;[05] [13] |
commonN2: |
nop2 ;[06] [14] |
subi cnt, 171 ;[08] [16] trick: (3 * 171) & 0xff = 1 |
out USBOUT, x1 ;[09] [17] <--- set bit |
brcs txBitloop ;[10] [27] [44] |
stuff6Delay: |
ror shift ;[45] [53] |
brcc doExor6 ;[46] |
subi x3, 1 ;[47] |
brne common6 ;[48] |
lsl shift ;[49] compensate ror after rjmp stuffDelay |
nop ;[50] stuffing consists of just waiting 8 cycles |
rjmp stuff6Delay ;[51] after ror, C bit is reliably clear |
doExor6: |
eor x1, x2 ;[48] [56] |
ldi x3, 6 ;[49] |
common6: |
stuff7Delay: |
ror shift ;[50] [58] |
out USBOUT, x1 ;[51] <--- set bit |
brcc doExor7 ;[52] |
subi x3, 1 ;[53] |
brne common7 ;[54] |
lsl shift ;[55] compensate ror after rjmp stuffDelay |
rjmp stuff7Delay ;[56] after ror, C bit is reliably clear |
doExor7: |
eor x1, x2 ;[54] [62] |
ldi x3, 6 ;[55] |
common7: |
ld shift, y+ ;[56] |
nop ;[58] |
tst cnt ;[59] |
out USBOUT, x1 ;[60] [00]<--- set bit |
brne txByteLoop ;[61] [01] |
;make SE0: |
cbr x1, USBMASK ;[02] prepare SE0 [spec says EOP may be 15 to 18 cycles] |
lds x2, usbNewDeviceAddr;[03] |
lsl x2 ;[05] we compare with left shifted address |
subi YL, 2 + 0 ;[06] Only assign address on data packets, not ACK/NAK in r0 |
sbci YH, 0 ;[07] |
out USBOUT, x1 ;[00] <-- out SE0 -- from now 2 bits = 16 cycles until bus idle |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
breq skipAddrAssign ;[01] |
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;[03] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;[04] |
ori x1, USBIDLE ;[05] |
in x2, USBDDR ;[06] |
cbr x2, USBMASK ;[07] set both pins to input |
mov x3, x1 ;[08] |
cbr x3, USBMASK ;[09] configure no pullup on both pins |
lpm ;[10] |
lpm ;[13] |
out USBOUT, x1 ;[16] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;[17] <-- release bus now |
out USBOUT, x3 ;[18] <-- ensure no pull-up resistors are active |
rjmp doReturn |
/***************************************************************************** |
The following PHP script generates a code skeleton for the receiver routine: |
<?php |
function printCmdBuffer($thisBit) |
{ |
global $cycle; |
$nextBit = ($thisBit + 1) % 8; |
$s = ob_get_contents(); |
ob_end_clean(); |
$s = str_replace("#", $thisBit, $s); |
$s = str_replace("@", $nextBit, $s); |
$lines = explode("\n", $s); |
for($i = 0; $i < count($lines); $i++){ |
$s = $lines[$i]; |
if(ereg("\\[([0-9-][0-9])\\]", $s, $regs)){ |
$c = $cycle + (int)$regs[1]; |
$s = ereg_replace("\\[[0-9-][0-9]\\]", sprintf("[%02d]", $c), $s); |
} |
if(strlen($s) > 0) |
echo "$s\n"; |
} |
} |
function printBit($isAfterSet, $bitNum) |
{ |
ob_start(); |
if($isAfterSet){ |
?> |
ifioclr USBIN, USBMINUS ;[00] <--- sample |
rjmp bit#IsClr ;[01] |
andi shift, ~(7 << #) ;[02] |
breq unstuff#s ;[03] |
in phase, USBIN ;[04] <- phase |
rjmp bit@AfterSet ;[05] |
unstuff#s: |
in phase, USBIN ;[05] <- phase (one cycle too late) |
andi fix, ~(1 << #) ;[06] |
nop2 ;[-1] |
nop2 ;[01] |
bit#IsClr: |
ifrset phase, USBMINUS ;[03] check phase only if D- changed |
lpm ;[04] |
in phase, USBIN ;[05] <- phase (one cycle too late) |
ori shift, 1 << # ;[06] |
<?php |
}else{ |
?> |
ifioset USBIN, USBMINUS ;[00] <--- sample |
rjmp bit#IsSet ;[01] |
andi shift, ~(7 << #) ;[02] |
breq unstuff#c ;[03] |
in phase, USBIN ;[04] <- phase |
rjmp bit@AfterClr ;[05] |
unstuff#c: |
in phase, USBIN ;[05] <- phase (one cycle too late) |
andi fix, ~(1 << #) ;[06] |
nop2 ;[-1] |
nop2 ;[01] |
bit#IsSet: |
ifrclr phase, USBMINUS ;[03] check phase only if D- changed |
lpm ;[04] |
in phase, USBIN ;[05] <- phase (one cycle too late) |
ori shift, 1 << # ;[06] |
<?php |
} |
printCmdBuffer($bitNum); |
} |
$bitStartCycles = array(1, 9, 17, 26, 34, 42, 51, 59); |
for($i = 0; $i < 16; $i++){ |
$bit = $i % 8; |
$emitClrCode = ($i + (int)($i / 8)) % 2; |
$cycle = $bitStartCycles[$bit]; |
if($emitClrCode){ |
printf("bit%dAfterClr:\n", $bit); |
}else{ |
printf("bit%dAfterSet:\n", $bit); |
} |
ob_start(); |
echo " ***** ;[-1]\n"; |
printCmdBuffer($bit); |
printBit(!$emitClrCode, $bit); |
if($i == 7) |
echo "\n"; |
} |
?> |
*****************************************************************************/ |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm15.inc |
---|
0,0 → 1,423 |
/* Name: usbdrvasm15.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: contributed by V. Bosch |
* Creation Date: 2007-08-06 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id: usbdrvasm15.inc 740 2009-04-13 18:23:31Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 15 MHz version of the asssembler part of the USB driver. It |
requires a 15 MHz crystal (not a ceramic resonator and not a calibrated RC |
oscillator). |
See usbdrv.h for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
*/ |
;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes |
;nominal frequency: 15 MHz -> 10.0 cycles per bit, 80.0 cycles per byte |
; Numbers in brackets are clocks counted from center of last sync bit |
; when instruction starts |
;---------------------------------------------------------------------------- |
; order of registers pushed: |
; YL, SREG [sofError] YH, shift, x1, x2, x3, bitcnt, cnt, x4 |
;---------------------------------------------------------------------------- |
USB_INTR_VECTOR: |
push YL ;2 push only what is necessary to sync with edge ASAP |
in YL, SREG ;1 |
push YL ;2 |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
; |
; sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
; sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
;------------------------------------------------------------------------------- |
; The following code results in a sampling window of < 1/4 bit |
; which meets the spec. |
;------------------------------------------------------------------------------- |
waitForK: ;- |
sbis USBIN, USBMINUS ;1 [00] <-- sample |
rjmp foundK ;2 [01] |
sbis USBIN, USBMINUS ; <-- sample |
rjmp foundK |
sbis USBIN, USBMINUS ; <-- sample |
rjmp foundK |
sbis USBIN, USBMINUS ; <-- sample |
rjmp foundK |
sbis USBIN, USBMINUS ; <-- sample |
rjmp foundK |
sbis USBIN, USBMINUS ; <-- sample |
rjmp foundK |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
;------------------------------------------------------------------------------ |
; {3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for |
; center sampling] |
; we have 1 bit time for setup purposes, then sample again. |
; Numbers in brackets are cycles from center of first sync (double K) |
; bit after the instruction |
;------------------------------------------------------------------------------ |
foundK: ;- [02] |
lds YL, usbInputBufOffset;2 [03+04] tx loop |
push YH ;2 [05+06] |
clr YH ;1 [07] |
subi YL, lo8(-(usbRxBuf)) ;1 [08] [rx loop init] |
sbci YH, hi8(-(usbRxBuf)) ;1 [09] [rx loop init] |
push shift ;2 [10+11] |
ser shift ;1 [12] |
sbis USBIN, USBMINUS ;1 [-1] [13] <--sample:we want two bits K (sample 1 cycle too early) |
rjmp haveTwoBitsK ;2 [00] [14] |
pop shift ;2 [15+16] undo the push from before |
pop YH ;2 [17+18] undo the push from before |
rjmp waitForK ;2 [19+20] this was not the end of sync, retry |
; The entire loop from waitForK until rjmp waitForK above must not exceed two |
; bit times (= 20 cycles). |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
haveTwoBitsK: ;- [01] |
push x1 ;2 [02+03] |
push x2 ;2 [04+05] |
push x3 ;2 [06+07] |
push bitcnt ;2 [08+09] |
in x1, USBIN ;1 [00] [10] <-- sample bit 0 |
bst x1, USBMINUS ;1 [01] |
bld shift, 0 ;1 [02] |
push cnt ;2 [03+04] |
ldi cnt, USB_BUFSIZE ;1 [05] |
push x4 ;2 [06+07] tx loop |
rjmp rxLoop ;2 [08] |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
unstuff0: ;- [07] (branch taken) |
andi x3, ~0x01 ;1 [08] |
mov x1, x2 ;1 [09] x2 contains last sampled (stuffed) bit |
in x2, USBIN ;1 [00] [10] <-- sample bit 1 again |
andi x2, USBMASK ;1 [01] |
breq se0Hop ;1 [02] SE0 check for bit 1 |
ori shift, 0x01 ;1 [03] 0b00000001 |
nop ;1 [04] |
rjmp didUnstuff0 ;2 [05] |
;----------------------------------------------------- |
unstuff1: ;- [05] (branch taken) |
mov x2, x1 ;1 [06] x1 contains last sampled (stuffed) bit |
andi x3, ~0x02 ;1 [07] |
ori shift, 0x02 ;1 [08] 0b00000010 |
nop ;1 [09] |
in x1, USBIN ;1 [00] [10] <-- sample bit 2 again |
andi x1, USBMASK ;1 [01] |
breq se0Hop ;1 [02] SE0 check for bit 2 |
rjmp didUnstuff1 ;2 [03] |
;----------------------------------------------------- |
unstuff2: ;- [05] (branch taken) |
andi x3, ~0x04 ;1 [06] |
ori shift, 0x04 ;1 [07] 0b00000100 |
mov x1, x2 ;1 [08] x2 contains last sampled (stuffed) bit |
nop ;1 [09] |
in x2, USBIN ;1 [00] [10] <-- sample bit 3 |
andi x2, USBMASK ;1 [01] |
breq se0Hop ;1 [02] SE0 check for bit 3 |
rjmp didUnstuff2 ;2 [03] |
;----------------------------------------------------- |
unstuff3: ;- [00] [10] (branch taken) |
in x2, USBIN ;1 [01] [11] <-- sample stuffed bit 3 one cycle too late |
andi x2, USBMASK ;1 [02] |
breq se0Hop ;1 [03] SE0 check for stuffed bit 3 |
andi x3, ~0x08 ;1 [04] |
ori shift, 0x08 ;1 [05] 0b00001000 |
rjmp didUnstuff3 ;2 [06] |
;---------------------------------------------------------------------------- |
; extra jobs done during bit interval: |
; |
; bit 0: store, clear [SE0 is unreliable here due to bit dribbling in hubs], |
; overflow check, jump to the head of rxLoop |
; bit 1: SE0 check |
; bit 2: SE0 check, recovery from delay [bit 0 tasks took too long] |
; bit 3: SE0 check, recovery from delay [bit 0 tasks took too long] |
; bit 4: SE0 check, none |
; bit 5: SE0 check, none |
; bit 6: SE0 check, none |
; bit 7: SE0 check, reconstruct: x3 is 0 at bit locations we changed, 1 at others |
;---------------------------------------------------------------------------- |
rxLoop: ;- [09] |
in x2, USBIN ;1 [00] [10] <-- sample bit 1 (or possibly bit 0 stuffed) |
andi x2, USBMASK ;1 [01] |
brne SkipSe0Hop ;1 [02] |
se0Hop: ;- [02] |
rjmp se0 ;2 [03] SE0 check for bit 1 |
SkipSe0Hop: ;- [03] |
ser x3 ;1 [04] |
andi shift, 0xf9 ;1 [05] 0b11111001 |
breq unstuff0 ;1 [06] |
didUnstuff0: ;- [06] |
eor x1, x2 ;1 [07] |
bst x1, USBMINUS ;1 [08] |
bld shift, 1 ;1 [09] |
in x1, USBIN ;1 [00] [10] <-- sample bit 2 (or possibly bit 1 stuffed) |
andi x1, USBMASK ;1 [01] |
breq se0Hop ;1 [02] SE0 check for bit 2 |
andi shift, 0xf3 ;1 [03] 0b11110011 |
breq unstuff1 ;1 [04] do remaining work for bit 1 |
didUnstuff1: ;- [04] |
eor x2, x1 ;1 [05] |
bst x2, USBMINUS ;1 [06] |
bld shift, 2 ;1 [07] |
nop2 ;2 [08+09] |
in x2, USBIN ;1 [00] [10] <-- sample bit 3 (or possibly bit 2 stuffed) |
andi x2, USBMASK ;1 [01] |
breq se0Hop ;1 [02] SE0 check for bit 3 |
andi shift, 0xe7 ;1 [03] 0b11100111 |
breq unstuff2 ;1 [04] |
didUnstuff2: ;- [04] |
eor x1, x2 ;1 [05] |
bst x1, USBMINUS ;1 [06] |
bld shift, 3 ;1 [07] |
didUnstuff3: ;- [07] |
andi shift, 0xcf ;1 [08] 0b11001111 |
breq unstuff3 ;1 [09] |
in x1, USBIN ;1 [00] [10] <-- sample bit 4 |
andi x1, USBMASK ;1 [01] |
breq se0Hop ;1 [02] SE0 check for bit 4 |
eor x2, x1 ;1 [03] |
bst x2, USBMINUS ;1 [04] |
bld shift, 4 ;1 [05] |
didUnstuff4: ;- [05] |
andi shift, 0x9f ;1 [06] 0b10011111 |
breq unstuff4 ;1 [07] |
nop2 ;2 [08+09] |
in x2, USBIN ;1 [00] [10] <-- sample bit 5 |
andi x2, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for bit 5 |
eor x1, x2 ;1 [03] |
bst x1, USBMINUS ;1 [04] |
bld shift, 5 ;1 [05] |
didUnstuff5: ;- [05] |
andi shift, 0x3f ;1 [06] 0b00111111 |
breq unstuff5 ;1 [07] |
nop2 ;2 [08+09] |
in x1, USBIN ;1 [00] [10] <-- sample bit 6 |
andi x1, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for bit 6 |
eor x2, x1 ;1 [03] |
bst x2, USBMINUS ;1 [04] |
bld shift, 6 ;1 [05] |
didUnstuff6: ;- [05] |
cpi shift, 0x02 ;1 [06] 0b00000010 |
brlo unstuff6 ;1 [07] |
nop2 ;2 [08+09] |
in x2, USBIN ;1 [00] [10] <-- sample bit 7 |
andi x2, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for bit 7 |
eor x1, x2 ;1 [03] |
bst x1, USBMINUS ;1 [04] |
bld shift, 7 ;1 [05] |
didUnstuff7: ;- [05] |
cpi shift, 0x04 ;1 [06] 0b00000100 |
brlo unstuff7 ;1 [07] |
eor x3, shift ;1 [08] reconstruct: x3 is 0 at bit locations we changed, 1 at others |
nop ;1 [09] |
in x1, USBIN ;1 [00] [10] <-- sample bit 0 |
st y+, x3 ;2 [01+02] store data |
eor x2, x1 ;1 [03] |
bst x2, USBMINUS ;1 [04] |
bld shift, 0 ;1 [05] |
subi cnt, 1 ;1 [06] |
brcs overflow ;1 [07] |
rjmp rxLoop ;2 [08] |
;----------------------------------------------------- |
unstuff4: ;- [08] |
andi x3, ~0x10 ;1 [09] |
in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 4 |
andi x1, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for stuffed bit 4 |
ori shift, 0x10 ;1 [03] |
rjmp didUnstuff4 ;2 [04] |
;----------------------------------------------------- |
unstuff5: ;- [08] |
ori shift, 0x20 ;1 [09] |
in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 5 |
andi x2, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for stuffed bit 5 |
andi x3, ~0x20 ;1 [03] |
rjmp didUnstuff5 ;2 [04] |
;----------------------------------------------------- |
unstuff6: ;- [08] |
andi x3, ~0x40 ;1 [09] |
in x1, USBIN ;1 [00] [10] <-- sample stuffed bit 6 |
andi x1, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for stuffed bit 6 |
ori shift, 0x40 ;1 [03] |
rjmp didUnstuff6 ;2 [04] |
;----------------------------------------------------- |
unstuff7: ;- [08] |
andi x3, ~0x80 ;1 [09] |
in x2, USBIN ;1 [00] [10] <-- sample stuffed bit 7 |
andi x2, USBMASK ;1 [01] |
breq se0 ;1 [02] SE0 check for stuffed bit 7 |
ori shift, 0x80 ;1 [03] |
rjmp didUnstuff7 ;2 [04] |
macro POP_STANDARD ; 16 cycles |
pop x4 |
pop cnt |
pop bitcnt |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop YH |
endm |
macro POP_RETI ; 5 cycles |
pop YL |
out SREG, YL |
pop YL |
endm |
#include "asmcommon.inc" |
;--------------------------------------------------------------------------- |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) |
; K = (D+ = 1), (D- = 0) |
; Spec allows 7.5 bit times from EOP to SOP for replies |
;--------------------------------------------------------------------------- |
bitstuffN: ;- [04] |
eor x1, x4 ;1 [05] |
clr x2 ;1 [06] |
nop ;1 [07] |
rjmp didStuffN ;1 [08] |
;--------------------------------------------------------------------------- |
bitstuff6: ;- [04] |
eor x1, x4 ;1 [05] |
clr x2 ;1 [06] |
rjmp didStuff6 ;1 [07] |
;--------------------------------------------------------------------------- |
bitstuff7: ;- [02] |
eor x1, x4 ;1 [03] |
clr x2 ;1 [06] |
nop ;1 [05] |
rjmp didStuff7 ;1 [06] |
;--------------------------------------------------------------------------- |
sendNakAndReti: ;- [-19] |
ldi x3, USBPID_NAK ;1 [-18] |
rjmp sendX3AndReti ;1 [-17] |
;--------------------------------------------------------------------------- |
sendAckAndReti: ;- [-17] |
ldi cnt, USBPID_ACK ;1 [-16] |
sendCntAndReti: ;- [-16] |
mov x3, cnt ;1 [-15] |
sendX3AndReti: ;- [-15] |
ldi YL, 20 ;1 [-14] x3==r20 address is 20 |
ldi YH, 0 ;1 [-13] |
ldi cnt, 2 ;1 [-12] |
; rjmp usbSendAndReti fallthrough |
;--------------------------------------------------------------------------- |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] |
;uses: x1...x4, btcnt, shift, cnt, Y |
;Numbers in brackets are time since first bit of sync pattern is sent |
;We need not to match the transfer rate exactly because the spec demands |
;only 1.5% precision anyway. |
usbSendAndReti: ;- [-13] 13 cycles until SOP |
in x2, USBDDR ;1 [-12] |
ori x2, USBMASK ;1 [-11] |
sbi USBOUT, USBMINUS ;2 [-09-10] prepare idle state; D+ and D- must have been 0 (no pullups) |
in x1, USBOUT ;1 [-08] port mirror for tx loop |
out USBDDR, x2 ;1 [-07] <- acquire bus |
; need not init x2 (bitstuff history) because sync starts with 0 |
ldi x4, USBMASK ;1 [-06] exor mask |
ldi shift, 0x80 ;1 [-05] sync byte is first byte sent |
ldi bitcnt, 6 ;1 [-04] |
txBitLoop: ;- [-04] [06] |
sbrs shift, 0 ;1 [-03] [07] |
eor x1, x4 ;1 [-02] [08] |
ror shift ;1 [-01] [09] |
didStuffN: ;- [09] |
out USBOUT, x1 ;1 [00] [10] <-- out N |
ror x2 ;1 [01] |
cpi x2, 0xfc ;1 [02] |
brcc bitstuffN ;1 [03] |
dec bitcnt ;1 [04] |
brne txBitLoop ;1 [05] |
sbrs shift, 0 ;1 [06] |
eor x1, x4 ;1 [07] |
ror shift ;1 [08] |
didStuff6: ;- [08] |
nop ;1 [09] |
out USBOUT, x1 ;1 [00] [10] <-- out 6 |
ror x2 ;1 [01] |
cpi x2, 0xfc ;1 [02] |
brcc bitstuff6 ;1 [03] |
sbrs shift, 0 ;1 [04] |
eor x1, x4 ;1 [05] |
ror shift ;1 [06] |
ror x2 ;1 [07] |
didStuff7: ;- [07] |
ldi bitcnt, 6 ;1 [08] |
cpi x2, 0xfc ;1 [09] |
out USBOUT, x1 ;1 [00] [10] <-- out 7 |
brcc bitstuff7 ;1 [01] |
ld shift, y+ ;2 [02+03] |
dec cnt ;1 [04] |
brne txBitLoop ;1 [05] |
makeSE0: |
cbr x1, USBMASK ;1 [06] prepare SE0 [spec says EOP may be 19 to 23 cycles] |
lds x2, usbNewDeviceAddr;2 [07+08] |
lsl x2 ;1 [09] we compare with left shifted address |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
out USBOUT, x1 ;1 [00] [10] <-- out SE0-- from now 2 bits==20 cycl. until bus idle |
subi YL, 20 + 2 ;1 [01] Only assign address on data packets, not ACK/NAK in x3 |
sbci YH, 0 ;1 [02] |
breq skipAddrAssign ;1 [03] |
sts usbDeviceAddr, x2 ;2 [04+05] if not skipped: SE0 is one cycle longer |
;---------------------------------------------------------------------------- |
;end of usbDeviceAddress transfer |
skipAddrAssign: ;- [03/04] |
ldi x2, 1<<USB_INTR_PENDING_BIT ;1 [05] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;1 [06] |
ori x1, USBIDLE ;1 [07] |
in x2, USBDDR ;1 [08] |
cbr x2, USBMASK ;1 [09] set both pins to input |
mov x3, x1 ;1 [10] |
cbr x3, USBMASK ;1 [11] configure no pullup on both pins |
ldi x4, 3 ;1 [12] |
se0Delay: ;- [12] [15] |
dec x4 ;1 [13] [16] |
brne se0Delay ;1 [14] [17] |
nop2 ;2 [18+19] |
out USBOUT, x1 ;1 [20] <--out J (idle) -- end of SE0 (EOP sig.) |
out USBDDR, x2 ;1 [21] <--release bus now |
out USBOUT, x3 ;1 [22] <--ensure no pull-up resistors are active |
rjmp doReturn ;1 [23] |
;--------------------------------------------------------------------------- |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm16.inc |
---|
0,0 → 1,346 |
/* Name: usbdrvasm16.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2007-06-15 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id: usbdrvasm16.inc 760 2009-08-09 18:59:43Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 16 MHz version of the asssembler part of the USB driver. It |
requires a 16 MHz crystal (not a ceramic resonator and not a calibrated RC |
oscillator). |
See usbdrv.h for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
*/ |
;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes |
;nominal frequency: 16 MHz -> 10.6666666 cycles per bit, 85.333333333 cycles per byte |
; Numbers in brackets are clocks counted from center of last sync bit |
; when instruction starts |
USB_INTR_VECTOR: |
;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt |
push YL ;[-25] push only what is necessary to sync with edge ASAP |
in YL, SREG ;[-23] |
push YL ;[-22] |
push YH ;[-20] |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
waitForK: |
;The following code results in a sampling window of < 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS ;[-15] |
rjmp foundK ;[-14] |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
foundK: ;[-12] |
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] |
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push bitcnt ;[-12] |
; [---] ;[-11] |
lds YL, usbInputBufOffset;[-10] |
; [---] ;[-9] |
clr YH ;[-8] |
subi YL, lo8(-(usbRxBuf));[-7] [rx loop init] |
sbci YH, hi8(-(usbRxBuf));[-6] [rx loop init] |
push shift ;[-5] |
; [---] ;[-4] |
ldi bitcnt, 0x55 ;[-3] [rx loop init] |
sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) |
rjmp haveTwoBitsK ;[-1] |
pop shift ;[0] undo the push from before |
pop bitcnt ;[2] undo the push from before |
rjmp waitForK ;[4] this was not the end of sync, retry |
; The entire loop from waitForK until rjmp waitForK above must not exceed two |
; bit times (= 21 cycles). |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
haveTwoBitsK: |
push x1 ;[1] |
push x2 ;[3] |
push x3 ;[5] |
ldi shift, 0 ;[7] |
ldi x3, 1<<4 ;[8] [rx loop init] first sample is inverse bit, compensate that |
push x4 ;[9] == leap |
in x1, USBIN ;[11] <-- sample bit 0 |
andi x1, USBMASK ;[12] |
bst x1, USBMINUS ;[13] |
bld shift, 7 ;[14] |
push cnt ;[15] |
ldi leap, 0 ;[17] [rx loop init] |
ldi cnt, USB_BUFSIZE;[18] [rx loop init] |
rjmp rxbit1 ;[19] arrives at [21] |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
; duration of unstuffing code should be 10.66666667 cycles. We adjust "leap" |
; accordingly to approximate this value in the long run. |
unstuff6: |
andi x2, USBMASK ;[03] |
ori x3, 1<<6 ;[04] will not be shifted any more |
andi shift, ~0x80;[05] |
mov x1, x2 ;[06] sampled bit 7 is actually re-sampled bit 6 |
subi leap, -1 ;[07] total duration = 11 bits -> subtract 1/3 |
rjmp didUnstuff6 ;[08] |
unstuff7: |
ori x3, 1<<7 ;[09] will not be shifted any more |
in x2, USBIN ;[00] [10] re-sample bit 7 |
andi x2, USBMASK ;[01] |
andi shift, ~0x80;[02] |
subi leap, 2 ;[03] total duration = 10 bits -> add 1/3 |
rjmp didUnstuff7 ;[04] |
unstuffEven: |
ori x3, 1<<6 ;[09] will be shifted right 6 times for bit 0 |
in x1, USBIN ;[00] [10] |
andi shift, ~0x80;[01] |
andi x1, USBMASK ;[02] |
breq se0 ;[03] |
subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 |
nop2 ;[05] |
rjmp didUnstuffE ;[06] |
unstuffOdd: |
ori x3, 1<<5 ;[09] will be shifted right 4 times for bit 1 |
in x2, USBIN ;[00] [10] |
andi shift, ~0x80;[01] |
andi x2, USBMASK ;[02] |
breq se0 ;[03] |
subi leap, -1 ;[04] total duration = 11 bits -> subtract 1/3 |
nop2 ;[05] |
rjmp didUnstuffO ;[06] |
rxByteLoop: |
andi x1, USBMASK ;[03] |
eor x2, x1 ;[04] |
subi leap, 1 ;[05] |
brpl skipLeap ;[06] |
subi leap, -3 ;1 one leap cycle every 3rd byte -> 85 + 1/3 cycles per byte |
nop ;1 |
skipLeap: |
subi x2, 1 ;[08] |
ror shift ;[09] |
didUnstuff6: |
cpi shift, 0xfc ;[10] |
in x2, USBIN ;[00] [11] <-- sample bit 7 |
brcc unstuff6 ;[01] |
andi x2, USBMASK ;[02] |
eor x1, x2 ;[03] |
subi x1, 1 ;[04] |
ror shift ;[05] |
didUnstuff7: |
cpi shift, 0xfc ;[06] |
brcc unstuff7 ;[07] |
eor x3, shift ;[08] reconstruct: x3 is 1 at bit locations we changed, 0 at others |
st y+, x3 ;[09] store data |
rxBitLoop: |
in x1, USBIN ;[00] [11] <-- sample bit 0/2/4 |
andi x1, USBMASK ;[01] |
eor x2, x1 ;[02] |
andi x3, 0x3f ;[03] topmost two bits reserved for 6 and 7 |
subi x2, 1 ;[04] |
ror shift ;[05] |
cpi shift, 0xfc ;[06] |
brcc unstuffEven ;[07] |
didUnstuffE: |
lsr x3 ;[08] |
lsr x3 ;[09] |
rxbit1: |
in x2, USBIN ;[00] [10] <-- sample bit 1/3/5 |
andi x2, USBMASK ;[01] |
breq se0 ;[02] |
eor x1, x2 ;[03] |
subi x1, 1 ;[04] |
ror shift ;[05] |
cpi shift, 0xfc ;[06] |
brcc unstuffOdd ;[07] |
didUnstuffO: |
subi bitcnt, 0xab;[08] == addi 0x55, 0x55 = 0x100/3 |
brcs rxBitLoop ;[09] |
subi cnt, 1 ;[10] |
in x1, USBIN ;[00] [11] <-- sample bit 6 |
brcc rxByteLoop ;[01] |
rjmp overflow |
macro POP_STANDARD ; 14 cycles |
pop cnt |
pop x4 |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop bitcnt |
endm |
macro POP_RETI ; 7 cycles |
pop YH |
pop YL |
out SREG, YL |
pop YL |
endm |
#include "asmcommon.inc" |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) |
; K = (D+ = 1), (D- = 0) |
; Spec allows 7.5 bit times from EOP to SOP for replies |
bitstuffN: |
eor x1, x4 ;[5] |
ldi x2, 0 ;[6] |
nop2 ;[7] |
nop ;[9] |
out USBOUT, x1 ;[10] <-- out |
rjmp didStuffN ;[0] |
bitstuff6: |
eor x1, x4 ;[5] |
ldi x2, 0 ;[6] Carry is zero due to brcc |
rol shift ;[7] compensate for ror shift at branch destination |
rjmp didStuff6 ;[8] |
bitstuff7: |
ldi x2, 0 ;[2] Carry is zero due to brcc |
rjmp didStuff7 ;[3] |
sendNakAndReti: |
ldi x3, USBPID_NAK ;[-18] |
rjmp sendX3AndReti ;[-17] |
sendAckAndReti: |
ldi cnt, USBPID_ACK ;[-17] |
sendCntAndReti: |
mov x3, cnt ;[-16] |
sendX3AndReti: |
ldi YL, 20 ;[-15] x3==r20 address is 20 |
ldi YH, 0 ;[-14] |
ldi cnt, 2 ;[-13] |
; rjmp usbSendAndReti fallthrough |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] |
;uses: x1...x4, btcnt, shift, cnt, Y |
;Numbers in brackets are time since first bit of sync pattern is sent |
;We don't match the transfer rate exactly (don't insert leap cycles every third |
;byte) because the spec demands only 1.5% precision anyway. |
usbSendAndReti: ; 12 cycles until SOP |
in x2, USBDDR ;[-12] |
ori x2, USBMASK ;[-11] |
sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) |
in x1, USBOUT ;[-8] port mirror for tx loop |
out USBDDR, x2 ;[-7] <- acquire bus |
; need not init x2 (bitstuff history) because sync starts with 0 |
ldi x4, USBMASK ;[-6] exor mask |
ldi shift, 0x80 ;[-5] sync byte is first byte sent |
txByteLoop: |
ldi bitcnt, 0x35 ;[-4] [6] binary 0011 0101 |
txBitLoop: |
sbrs shift, 0 ;[-3] [7] |
eor x1, x4 ;[-2] [8] |
out USBOUT, x1 ;[-1] [9] <-- out N |
ror shift ;[0] [10] |
ror x2 ;[1] |
didStuffN: |
cpi x2, 0xfc ;[2] |
brcc bitstuffN ;[3] |
lsr bitcnt ;[4] |
brcc txBitLoop ;[5] |
brne txBitLoop ;[6] |
sbrs shift, 0 ;[7] |
eor x1, x4 ;[8] |
didStuff6: |
out USBOUT, x1 ;[-1] [9] <-- out 6 |
ror shift ;[0] [10] |
ror x2 ;[1] |
cpi x2, 0xfc ;[2] |
brcc bitstuff6 ;[3] |
ror shift ;[4] |
didStuff7: |
ror x2 ;[5] |
sbrs x2, 7 ;[6] |
eor x1, x4 ;[7] |
nop ;[8] |
cpi x2, 0xfc ;[9] |
out USBOUT, x1 ;[-1][10] <-- out 7 |
brcc bitstuff7 ;[0] [11] |
ld shift, y+ ;[1] |
dec cnt ;[3] |
brne txByteLoop ;[4] |
;make SE0: |
cbr x1, USBMASK ;[5] prepare SE0 [spec says EOP may be 21 to 25 cycles] |
lds x2, usbNewDeviceAddr;[6] |
lsl x2 ;[8] we compare with left shifted address |
subi YL, 20 + 2 ;[9] Only assign address on data packets, not ACK/NAK in x3 |
sbci YH, 0 ;[10] |
out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
breq skipAddrAssign ;[0] |
sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;[2] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;[3] |
ori x1, USBIDLE ;[4] |
in x2, USBDDR ;[5] |
cbr x2, USBMASK ;[6] set both pins to input |
mov x3, x1 ;[7] |
cbr x3, USBMASK ;[8] configure no pullup on both pins |
ldi x4, 4 ;[9] |
se0Delay: |
dec x4 ;[10] [13] [16] [19] |
brne se0Delay ;[11] [14] [17] [20] |
out USBOUT, x1 ;[21] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;[22] <-- release bus now |
out USBOUT, x3 ;[23] <-- ensure no pull-up resistors are active |
rjmp doReturn |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm165.inc |
---|
0,0 → 1,453 |
/* Name: usbdrvasm165.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2007-04-22 |
* Tabsize: 4 |
* Copyright: (c) 2007 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id: usbdrvasm165.inc 740 2009-04-13 18:23:31Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 16.5 MHz version of the USB driver. It is intended for the |
ATTiny45 and similar controllers running on 16.5 MHz internal RC oscillator. |
This version contains a phase locked loop in the receiver routine to cope with |
slight clock rate deviations of up to +/- 1%. |
See usbdrv.h for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
*/ |
;Software-receiver engine. Strict timing! Don't change unless you can preserve timing! |
;interrupt response time: 4 cycles + insn running = 7 max if interrupts always enabled |
;max allowable interrupt latency: 59 cycles -> max 52 cycles interrupt disable |
;max stack usage: [ret(2), r0, SREG, YL, YH, shift, x1, x2, x3, x4, cnt] = 12 bytes |
;nominal frequency: 16.5 MHz -> 11 cycles per bit |
; 16.3125 MHz < F_CPU < 16.6875 MHz (+/- 1.1%) |
; Numbers in brackets are clocks counted from center of last sync bit |
; when instruction starts |
USB_INTR_VECTOR: |
;order of registers pushed: YL, SREG [sofError], r0, YH, shift, x1, x2, x3, x4, cnt |
push YL ;[-23] push only what is necessary to sync with edge ASAP |
in YL, SREG ;[-21] |
push YL ;[-20] |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
waitForK: |
;The following code results in a sampling window of < 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS ;[-15] |
rjmp foundK ;[-14] |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
foundK: ;[-12] |
;{3, 5} after falling D- edge, average delay: 4 cycles [we want 5 for center sampling] |
;we have 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push r0 ;[-12] |
; [---] ;[-11] |
push YH ;[-10] |
; [---] ;[-9] |
lds YL, usbInputBufOffset;[-8] |
; [---] ;[-7] |
clr YH ;[-6] |
subi YL, lo8(-(usbRxBuf));[-5] [rx loop init] |
sbci YH, hi8(-(usbRxBuf));[-4] [rx loop init] |
mov r0, x2 ;[-3] [rx loop init] |
sbis USBIN, USBMINUS ;[-2] we want two bits K (sample 2 cycles too early) |
rjmp haveTwoBitsK ;[-1] |
pop YH ;[0] undo the pushes from before |
pop r0 ;[2] |
rjmp waitForK ;[4] this was not the end of sync, retry |
; The entire loop from waitForK until rjmp waitForK above must not exceed two |
; bit times (= 22 cycles). |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
haveTwoBitsK: ;[1] |
push shift ;[1] |
push x1 ;[3] |
push x2 ;[5] |
push x3 ;[7] |
ldi shift, 0xff ;[9] [rx loop init] |
ori x3, 0xff ;[10] [rx loop init] == ser x3, clear zero flag |
in x1, USBIN ;[11] <-- sample bit 0 |
bst x1, USBMINUS ;[12] |
bld shift, 0 ;[13] |
push x4 ;[14] == phase |
; [---] ;[15] |
push cnt ;[16] |
; [---] ;[17] |
ldi phase, 0 ;[18] [rx loop init] |
ldi cnt, USB_BUFSIZE;[19] [rx loop init] |
rjmp rxbit1 ;[20] |
; [---] ;[21] |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
/* |
byte oriented operations done during loop: |
bit 0: store data |
bit 1: SE0 check |
bit 2: overflow check |
bit 3: catch up |
bit 4: rjmp to achieve conditional jump range |
bit 5: PLL |
bit 6: catch up |
bit 7: jump, fixup bitstuff |
; 87 [+ 2] cycles |
------------------------------------------------------------------ |
*/ |
continueWithBit5: |
in x2, USBIN ;[055] <-- bit 5 |
eor r0, x2 ;[056] |
or phase, r0 ;[057] |
sbrc phase, USBMINUS ;[058] |
lpm ;[059] optional nop3; modifies r0 |
in phase, USBIN ;[060] <-- phase |
eor x1, x2 ;[061] |
bst x1, USBMINUS ;[062] |
bld shift, 5 ;[063] |
andi shift, 0x3f ;[064] |
in x1, USBIN ;[065] <-- bit 6 |
breq unstuff5 ;[066] *** unstuff escape |
eor phase, x1 ;[067] |
eor x2, x1 ;[068] |
bst x2, USBMINUS ;[069] |
bld shift, 6 ;[070] |
didUnstuff6: ;[ ] |
in r0, USBIN ;[071] <-- phase |
cpi shift, 0x02 ;[072] |
brlo unstuff6 ;[073] *** unstuff escape |
didUnstuff5: ;[ ] |
nop2 ;[074] |
; [---] ;[075] |
in x2, USBIN ;[076] <-- bit 7 |
eor x1, x2 ;[077] |
bst x1, USBMINUS ;[078] |
bld shift, 7 ;[079] |
didUnstuff7: ;[ ] |
eor r0, x2 ;[080] |
or phase, r0 ;[081] |
in r0, USBIN ;[082] <-- phase |
cpi shift, 0x04 ;[083] |
brsh rxLoop ;[084] |
; [---] ;[085] |
unstuff7: ;[ ] |
andi x3, ~0x80 ;[085] |
ori shift, 0x80 ;[086] |
in x2, USBIN ;[087] <-- sample stuffed bit 7 |
nop ;[088] |
rjmp didUnstuff7 ;[089] |
; [---] ;[090] |
;[080] |
unstuff5: ;[067] |
eor phase, x1 ;[068] |
andi x3, ~0x20 ;[069] |
ori shift, 0x20 ;[070] |
in r0, USBIN ;[071] <-- phase |
mov x2, x1 ;[072] |
nop ;[073] |
nop2 ;[074] |
; [---] ;[075] |
in x1, USBIN ;[076] <-- bit 6 |
eor r0, x1 ;[077] |
or phase, r0 ;[078] |
eor x2, x1 ;[079] |
bst x2, USBMINUS ;[080] |
bld shift, 6 ;[081] no need to check bitstuffing, we just had one |
in r0, USBIN ;[082] <-- phase |
rjmp didUnstuff5 ;[083] |
; [---] ;[084] |
;[074] |
unstuff6: ;[074] |
andi x3, ~0x40 ;[075] |
in x1, USBIN ;[076] <-- bit 6 again |
ori shift, 0x40 ;[077] |
nop2 ;[078] |
; [---] ;[079] |
rjmp didUnstuff6 ;[080] |
; [---] ;[081] |
;[071] |
unstuff0: ;[013] |
eor r0, x2 ;[014] |
or phase, r0 ;[015] |
andi x2, USBMASK ;[016] check for SE0 |
in r0, USBIN ;[017] <-- phase |
breq didUnstuff0 ;[018] direct jump to se0 would be too long |
andi x3, ~0x01 ;[019] |
ori shift, 0x01 ;[020] |
mov x1, x2 ;[021] mov existing sample |
in x2, USBIN ;[022] <-- bit 1 again |
rjmp didUnstuff0 ;[023] |
; [---] ;[024] |
;[014] |
unstuff1: ;[024] |
eor r0, x1 ;[025] |
or phase, r0 ;[026] |
andi x3, ~0x02 ;[027] |
in r0, USBIN ;[028] <-- phase |
ori shift, 0x02 ;[029] |
mov x2, x1 ;[030] |
rjmp didUnstuff1 ;[031] |
; [---] ;[032] |
;[022] |
unstuff2: ;[035] |
eor r0, x2 ;[036] |
or phase, r0 ;[037] |
andi x3, ~0x04 ;[038] |
in r0, USBIN ;[039] <-- phase |
ori shift, 0x04 ;[040] |
mov x1, x2 ;[041] |
rjmp didUnstuff2 ;[042] |
; [---] ;[043] |
;[033] |
unstuff3: ;[043] |
in x2, USBIN ;[044] <-- bit 3 again |
eor r0, x2 ;[045] |
or phase, r0 ;[046] |
andi x3, ~0x08 ;[047] |
ori shift, 0x08 ;[048] |
nop ;[049] |
in r0, USBIN ;[050] <-- phase |
rjmp didUnstuff3 ;[051] |
; [---] ;[052] |
;[042] |
unstuff4: ;[053] |
andi x3, ~0x10 ;[054] |
in x1, USBIN ;[055] <-- bit 4 again |
ori shift, 0x10 ;[056] |
rjmp didUnstuff4 ;[057] |
; [---] ;[058] |
;[048] |
rxLoop: ;[085] |
eor x3, shift ;[086] reconstruct: x3 is 0 at bit locations we changed, 1 at others |
in x1, USBIN ;[000] <-- bit 0 |
st y+, x3 ;[001] |
; [---] ;[002] |
eor r0, x1 ;[003] |
or phase, r0 ;[004] |
eor x2, x1 ;[005] |
in r0, USBIN ;[006] <-- phase |
ser x3 ;[007] |
bst x2, USBMINUS ;[008] |
bld shift, 0 ;[009] |
andi shift, 0xf9 ;[010] |
rxbit1: ;[ ] |
in x2, USBIN ;[011] <-- bit 1 |
breq unstuff0 ;[012] *** unstuff escape |
andi x2, USBMASK ;[013] SE0 check for bit 1 |
didUnstuff0: ;[ ] Z only set if we detected SE0 in bitstuff |
breq se0 ;[014] |
eor r0, x2 ;[015] |
or phase, r0 ;[016] |
in r0, USBIN ;[017] <-- phase |
eor x1, x2 ;[018] |
bst x1, USBMINUS ;[019] |
bld shift, 1 ;[020] |
andi shift, 0xf3 ;[021] |
didUnstuff1: ;[ ] |
in x1, USBIN ;[022] <-- bit 2 |
breq unstuff1 ;[023] *** unstuff escape |
eor r0, x1 ;[024] |
or phase, r0 ;[025] |
subi cnt, 1 ;[026] overflow check |
brcs overflow ;[027] |
in r0, USBIN ;[028] <-- phase |
eor x2, x1 ;[029] |
bst x2, USBMINUS ;[030] |
bld shift, 2 ;[031] |
andi shift, 0xe7 ;[032] |
didUnstuff2: ;[ ] |
in x2, USBIN ;[033] <-- bit 3 |
breq unstuff2 ;[034] *** unstuff escape |
eor r0, x2 ;[035] |
or phase, r0 ;[036] |
eor x1, x2 ;[037] |
bst x1, USBMINUS ;[038] |
in r0, USBIN ;[039] <-- phase |
bld shift, 3 ;[040] |
andi shift, 0xcf ;[041] |
didUnstuff3: ;[ ] |
breq unstuff3 ;[042] *** unstuff escape |
nop ;[043] |
in x1, USBIN ;[044] <-- bit 4 |
eor x2, x1 ;[045] |
bst x2, USBMINUS ;[046] |
bld shift, 4 ;[047] |
didUnstuff4: ;[ ] |
eor r0, x1 ;[048] |
or phase, r0 ;[049] |
in r0, USBIN ;[050] <-- phase |
andi shift, 0x9f ;[051] |
breq unstuff4 ;[052] *** unstuff escape |
rjmp continueWithBit5;[053] |
; [---] ;[054] |
macro POP_STANDARD ; 16 cycles |
pop cnt |
pop x4 |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop YH |
pop r0 |
endm |
macro POP_RETI ; 5 cycles |
pop YL |
out SREG, YL |
pop YL |
endm |
#include "asmcommon.inc" |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) |
; K = (D+ = 1), (D- = 0) |
; Spec allows 7.5 bit times from EOP to SOP for replies |
bitstuff7: |
eor x1, x4 ;[4] |
ldi x2, 0 ;[5] |
nop2 ;[6] C is zero (brcc) |
rjmp didStuff7 ;[8] |
bitstuffN: |
eor x1, x4 ;[5] |
ldi x2, 0 ;[6] |
lpm ;[7] 3 cycle NOP, modifies r0 |
out USBOUT, x1 ;[10] <-- out |
rjmp didStuffN ;[0] |
#define bitStatus x3 |
sendNakAndReti: |
ldi cnt, USBPID_NAK ;[-19] |
rjmp sendCntAndReti ;[-18] |
sendAckAndReti: |
ldi cnt, USBPID_ACK ;[-17] |
sendCntAndReti: |
mov r0, cnt ;[-16] |
ldi YL, 0 ;[-15] R0 address is 0 |
ldi YH, 0 ;[-14] |
ldi cnt, 2 ;[-13] |
; rjmp usbSendAndReti fallthrough |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] |
;uses: x1...x4, shift, cnt, Y |
;Numbers in brackets are time since first bit of sync pattern is sent |
usbSendAndReti: ; 12 cycles until SOP |
in x2, USBDDR ;[-12] |
ori x2, USBMASK ;[-11] |
sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) |
in x1, USBOUT ;[-8] port mirror for tx loop |
out USBDDR, x2 ;[-7] <- acquire bus |
; need not init x2 (bitstuff history) because sync starts with 0 |
ldi x4, USBMASK ;[-6] exor mask |
ldi shift, 0x80 ;[-5] sync byte is first byte sent |
ldi bitStatus, 0xff ;[-4] init bit loop counter, works for up to 12 bytes |
byteloop: |
bitloop: |
sbrs shift, 0 ;[8] [-3] |
eor x1, x4 ;[9] [-2] |
out USBOUT, x1 ;[10] [-1] <-- out |
ror shift ;[0] |
ror x2 ;[1] |
didStuffN: |
cpi x2, 0xfc ;[2] |
brcc bitstuffN ;[3] |
nop ;[4] |
subi bitStatus, 37 ;[5] 256 / 7 ~=~ 37 |
brcc bitloop ;[6] when we leave the loop, bitStatus has almost the initial value |
sbrs shift, 0 ;[7] |
eor x1, x4 ;[8] |
ror shift ;[9] |
didStuff7: |
out USBOUT, x1 ;[10] <-- out |
ror x2 ;[0] |
cpi x2, 0xfc ;[1] |
brcc bitstuff7 ;[2] |
ld shift, y+ ;[3] |
dec cnt ;[5] |
brne byteloop ;[6] |
;make SE0: |
cbr x1, USBMASK ;[7] prepare SE0 [spec says EOP may be 21 to 25 cycles] |
lds x2, usbNewDeviceAddr;[8] |
lsl x2 ;[10] we compare with left shifted address |
out USBOUT, x1 ;[11] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
subi YL, 2 ;[0] Only assign address on data packets, not ACK/NAK in r0 |
sbci YH, 0 ;[1] |
breq skipAddrAssign ;[2] |
sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;[4] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;[5] |
ori x1, USBIDLE ;[6] |
in x2, USBDDR ;[7] |
cbr x2, USBMASK ;[8] set both pins to input |
mov x3, x1 ;[9] |
cbr x3, USBMASK ;[10] configure no pullup on both pins |
ldi x4, 4 ;[11] |
se0Delay: |
dec x4 ;[12] [15] [18] [21] |
brne se0Delay ;[13] [16] [19] [22] |
out USBOUT, x1 ;[23] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;[24] <-- release bus now |
out USBOUT, x3 ;[25] <-- ensure no pull-up resistors are active |
rjmp doReturn |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm18-crc.inc |
---|
0,0 → 1,707 |
/* Name: usbdrvasm18.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Lukas Schrittwieser (based on 20 MHz usbdrvasm20.inc by Jeroen Benschop) |
* Creation Date: 2009-01-20 |
* Tabsize: 4 |
* Copyright: (c) 2008 by Lukas Schrittwieser and OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id: usbdrvasm18-crc.inc 740 2009-04-13 18:23:31Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 18 MHz version of the asssembler part of the USB driver. It |
requires a 18 MHz crystal (not a ceramic resonator and not a calibrated RC |
oscillator). |
See usbdrv.h for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
*/ |
;max stack usage: [ret(2), YL, SREG, YH, [sofError], bitcnt(x5), shift, x1, x2, x3, x4, cnt, ZL, ZH] = 14 bytes |
;nominal frequency: 18 MHz -> 12 cycles per bit |
; Numbers in brackets are clocks counted from center of last sync bit |
; when instruction starts |
;register use in receive loop to receive the data bytes: |
; shift assembles the byte currently being received |
; x1 holds the D+ and D- line state |
; x2 holds the previous line state |
; cnt holds the number of bytes left in the receive buffer |
; x3 holds the higher crc byte (see algorithm below) |
; x4 is used as temporary register for the crc algorithm |
; x5 is used for unstuffing: when unstuffing the last received bit is inverted in shift (to prevent further |
; unstuffing calls. In the same time the corresponding bit in x5 is cleared to mark the bit as beening iverted |
; zl lower crc value and crc table index |
; zh used for crc table accesses |
;-------------------------------------------------------------------------------------------------------------- |
; CRC mods: |
; table driven crc checker, Z points to table in prog space |
; ZL is the lower crc byte, x3 is the higher crc byte |
; x4 is used as temp register to store different results |
; the initialization of the crc register is not 0xFFFF but 0xFE54. This is because during the receipt of the |
; first data byte an virtual zero data byte is added to the crc register, this results in the correct initial |
; value of 0xFFFF at beginning of the second data byte before the first data byte is added to the crc. |
; The magic number 0xFE54 results form the crc table: At tabH[0x54] = 0xFF = crcH (required) and |
; tabL[0x54] = 0x01 -> crcL = 0x01 xor 0xFE = 0xFF |
; bitcnt is renamed to x5 and is used for unstuffing purposes, the unstuffing works like in the 12MHz version |
;-------------------------------------------------------------------------------------------------------------- |
; CRC algorithm: |
; The crc register is formed by x3 (higher byte) and ZL (lower byte). The algorithm uses a 'reversed' form |
; i.e. that it takes the least significant bit first and shifts to the right. So in fact the highest order |
; bit seen from the polynomial devision point of view is the lsb of ZL. (If this sounds strange to you i |
; propose a research on CRC :-) ) |
; Each data byte received is xored to ZL, the lower crc byte. This byte now builds the crc |
; table index. Next the new high byte is loaded from the table and stored in x4 until we have space in x3 |
; (its destination). |
; Afterwards the lower table is loaded from the table and stored in ZL (the old index is overwritten as |
; we don't need it anymore. In fact this is a right shift by 8 bits.) Now the old crc high value is xored |
; to ZL, this is the second shift of the old crc value. Now x4 (the temp reg) is moved to x3 and the crc |
; calculation is done. |
; Prior to the first byte the two CRC register have to be initialized to 0xFFFF (as defined in usb spec) |
; however the crc engine also runs during the receipt of the first byte, therefore x3 and zl are initialized |
; to a magic number which results in a crc value of 0xFFFF after the first complete byte. |
; |
; This algorithm is split into the extra cycles of the different bits: |
; bit7: XOR the received byte to ZL |
; bit5: load the new high byte to x4 |
; bit6: load the lower xor byte from the table, xor zl and x3, store result in zl (=the new crc low value) |
; move x4 (the new high byte) to x3, the crc value is ready |
; |
macro POP_STANDARD ; 18 cycles |
pop ZH |
pop ZL |
pop cnt |
pop x5 |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop x4 |
endm |
macro POP_RETI ; 7 cycles |
pop YH |
pop YL |
out SREG, YL |
pop YL |
endm |
macro CRC_CLEANUP_AND_CHECK |
; the last byte has already been xored with the lower crc byte, we have to do the table lookup and xor |
; x3 is the higher crc byte, zl the lower one |
ldi ZH, hi8(usbCrcTableHigh);[+1] get the new high byte from the table |
lpm x2, Z ;[+2][+3][+4] |
ldi ZH, hi8(usbCrcTableLow);[+5] get the new low xor byte from the table |
lpm ZL, Z ;[+6][+7][+8] |
eor ZL, x3 ;[+7] xor the old high byte with the value from the table, x2:ZL now holds the crc value |
cpi ZL, 0x01 ;[+8] if the crc is ok we have a fixed remainder value of 0xb001 in x2:ZL (see usb spec) |
brne ignorePacket ;[+9] detected a crc fault -> paket is ignored and retransmitted by the host |
cpi x2, 0xb0 ;[+10] |
brne ignorePacket ;[+11] detected a crc fault -> paket is ignored and retransmitted by the host |
endm |
USB_INTR_VECTOR: |
;order of registers pushed: YL, SREG, YH, [sofError], x4, shift, x1, x2, x3, x5, cnt, ZL, ZH |
push YL ;[-28] push only what is necessary to sync with edge ASAP |
in YL, SREG ;[-26] |
push YL ;[-25] |
push YH ;[-23] |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
waitForK: |
;The following code results in a sampling window of < 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS ;[-17] |
rjmp foundK ;[-16] |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
foundK: ;[-15] |
;{3, 5} after falling D- edge, average delay: 4 cycles |
;bit0 should be at 30 (2.5 bits) for center sampling. Currently at 4 so 26 cylces till bit 0 sample |
;use 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push x4 ;[-14] |
; [---] ;[-13] |
lds YL, usbInputBufOffset;[-12] used to toggle the two usb receive buffers |
; [---] ;[-11] |
clr YH ;[-10] |
subi YL, lo8(-(usbRxBuf));[-9] [rx loop init] |
sbci YH, hi8(-(usbRxBuf));[-8] [rx loop init] |
push shift ;[-7] |
; [---] ;[-6] |
ldi shift, 0x80 ;[-5] the last bit is the end of byte marker for the pid receiver loop |
clc ;[-4] the carry has to be clear for receipt of pid bit 0 |
sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) |
rjmp haveTwoBitsK ;[-2] |
pop shift ;[-1] undo the push from before |
pop x4 ;[1] |
rjmp waitForK ;[3] this was not the end of sync, retry |
; The entire loop from waitForK until rjmp waitForK above must not exceed two |
; bit times (= 24 cycles). |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
haveTwoBitsK: |
push x1 ;[0] |
push x2 ;[2] |
push x3 ;[4] crc high byte |
ldi x2, 1<<USBPLUS ;[6] [rx loop init] current line state is K state. D+=="1", D-=="0" |
push x5 ;[7] |
push cnt ;[9] |
ldi cnt, USB_BUFSIZE ;[11] |
;-------------------------------------------------------------------------------------------------------------- |
; receives the pid byte |
; there is no real unstuffing algorithm implemented here as a stuffing bit is impossible in the pid byte. |
; That's because the last four bits of the byte are the inverted of the first four bits. If we detect a |
; unstuffing condition something went wrong and abort |
; shift has to be initialized to 0x80 |
;-------------------------------------------------------------------------------------------------------------- |
; pid bit 0 - used for even more register saving (we need the z pointer) |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] filter only D+ and D- bits |
eor x2, x1 ;[2] generate inverted of actual bit |
sbrc x2, USBMINUS ;[3] if the bit is set we received a zero |
sec ;[4] |
ror shift ;[5] we perform no unstuffing check here as this is the first bit |
mov x2, x1 ;[6] |
push ZL ;[7] |
;[8] |
push ZH ;[9] |
;[10] |
ldi x3, 0xFE ;[11] x3 is the high order crc value |
bitloopPid: |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] filter only D+ and D- bits |
breq nse0 ;[2] both lines are low so handle se0 |
eor x2, x1 ;[3] generate inverted of actual bit |
sbrc x2, USBMINUS ;[4] set the carry if we received a zero |
sec ;[5] |
ror shift ;[6] |
ldi ZL, 0x54 ;[7] ZL is the low order crc value |
ser x4 ;[8] the is no bit stuffing check here as the pid bit can't be stuffed. if so |
; some error occured. In this case the paket is discarded later on anyway. |
mov x2, x1 ;[9] prepare for the next cycle |
brcc bitloopPid ;[10] while 0s drop out of shift we get the next bit |
eor x4, shift ;[11] invert all bits in shift and store result in x4 |
;-------------------------------------------------------------------------------------------------------------- |
; receives data bytes and calculates the crc |
; the last USBIN state has to be in x2 |
; this is only the first half, due to branch distanc limitations the second half of the loop is near the end |
; of this asm file |
;-------------------------------------------------------------------------------------------------------------- |
rxDataStart: |
in x1, USBIN ;[0] sample line state (note: a se0 check is not useful due to bit dribbling) |
ser x5 ;[1] prepare the unstuff marker register |
eor x2, x1 ;[2] generates the inverted of the actual bit |
bst x2, USBMINUS ;[3] copy the bit from x2 |
bld shift, 0 ;[4] and store it in shift |
mov x2, shift ;[5] make a copy of shift for unstuffing check |
andi x2, 0xF9 ;[6] mask the last six bits, if we got six zeros (which are six ones in fact) |
breq unstuff0 ;[7] then Z is set now and we branch to the unstuffing handler |
didunstuff0: |
subi cnt, 1 ;[8] cannot use dec because it doesn't affect the carry flag |
brcs nOverflow ;[9] Too many bytes received. Ignore packet |
st Y+, x4 ;[10] store the last received byte |
;[11] st needs two cycles |
; bit1 |
in x2, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] check for se0 during bit 0 |
breq nse0 ;[2] |
andi x2, USBMASK ;[3] check se0 during bit 1 |
breq nse0 ;[4] |
eor x1, x2 ;[5] |
bst x1, USBMINUS ;[6] |
bld shift, 1 ;[7] |
mov x1, shift ;[8] |
andi x1, 0xF3 ;[9] |
breq unstuff1 ;[10] |
didunstuff1: |
nop ;[11] |
; bit2 |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] check for se0 (as there is nothing else to do here |
breq nOverflow ;[2] |
eor x2, x1 ;[3] generates the inverted of the actual bit |
bst x2, USBMINUS ;[4] |
bld shift, 2 ;[5] store the bit |
mov x2, shift ;[6] |
andi x2, 0xE7 ;[7] if we have six zeros here (which means six 1 in the stream) |
breq unstuff2 ;[8] the next bit is a stuffing bit |
didunstuff2: |
nop2 ;[9] |
;[10] |
nop ;[11] |
; bit3 |
in x2, USBIN ;[0] sample line state |
andi x2, USBMASK ;[1] check for se0 |
breq nOverflow ;[2] |
eor x1, x2 ;[3] |
bst x1, USBMINUS ;[4] |
bld shift, 3 ;[5] |
mov x1, shift ;[6] |
andi x1, 0xCF ;[7] |
breq unstuff3 ;[8] |
didunstuff3: |
nop ;[9] |
rjmp rxDataBit4 ;[10] |
;[11] |
; the avr branch instructions allow an offset of +63 insturction only, so we need this |
; 'local copy' of se0 |
nse0: |
rjmp se0 ;[4] |
;[5] |
; the same same as for se0 is needed for overflow and StuffErr |
nOverflow: |
stuffErr: |
rjmp overflow |
unstuff0: ;[8] this is the branch delay of breq unstuffX |
andi x1, USBMASK ;[9] do an se0 check here (if the last crc byte ends with 5 one's we might end up here |
breq didunstuff0 ;[10] event tough the message is complete -> jump back and store the byte |
ori shift, 0x01 ;[11] invert the last received bit to prevent furhter unstuffing |
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
andi x5, 0xFE ;[1] mark this bit as inverted (will be corrected before storing shift) |
eor x1, x2 ;[2] x1 and x2 have to be different because the stuff bit is always a zero |
andi x1, USBMASK ;[3] mask the interesting bits |
breq stuffErr ;[4] if the stuff bit is a 1-bit something went wrong |
mov x1, x2 ;[5] the next bit expects the last state to be in x1 |
rjmp didunstuff0 ;[6] |
;[7] jump delay of rjmp didunstuffX |
unstuff1: ;[11] this is the jump delay of breq unstuffX |
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
ori shift, 0x02 ;[1] invert the last received bit to prevent furhter unstuffing |
andi x5, 0xFD ;[2] mark this bit as inverted (will be corrected before storing shift) |
eor x2, x1 ;[3] x1 and x2 have to be different because the stuff bit is always a zero |
andi x2, USBMASK ;[4] mask the interesting bits |
breq stuffErr ;[5] if the stuff bit is a 1-bit something went wrong |
mov x2, x1 ;[6] the next bit expects the last state to be in x2 |
nop2 ;[7] |
;[8] |
rjmp didunstuff1 ;[9] |
;[10] jump delay of rjmp didunstuffX |
unstuff2: ;[9] this is the jump delay of breq unstuffX |
ori shift, 0x04 ;[10] invert the last received bit to prevent furhter unstuffing |
andi x5, 0xFB ;[11] mark this bit as inverted (will be corrected before storing shift) |
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero |
andi x1, USBMASK ;[2] mask the interesting bits |
breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong |
mov x1, x2 ;[4] the next bit expects the last state to be in x1 |
nop2 ;[5] |
;[6] |
rjmp didunstuff2 ;[7] |
;[8] jump delay of rjmp didunstuffX |
unstuff3: ;[9] this is the jump delay of breq unstuffX |
ori shift, 0x08 ;[10] invert the last received bit to prevent furhter unstuffing |
andi x5, 0xF7 ;[11] mark this bit as inverted (will be corrected before storing shift) |
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero |
andi x2, USBMASK ;[2] mask the interesting bits |
breq stuffErr ;[3] if the stuff bit is a 1-bit something went wrong |
mov x2, x1 ;[4] the next bit expects the last state to be in x2 |
nop2 ;[5] |
;[6] |
rjmp didunstuff3 ;[7] |
;[8] jump delay of rjmp didunstuffX |
; the include has to be here due to branch distance restirctions |
#define __USE_CRC__ |
#include "asmcommon.inc" |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) |
; K = (D+ = 1), (D- = 0) |
; Spec allows 7.5 bit times from EOP to SOP for replies |
; 7.5 bit times is 90 cycles. ...there is plenty of time |
sendNakAndReti: |
ldi x3, USBPID_NAK ;[-18] |
rjmp sendX3AndReti ;[-17] |
sendAckAndReti: |
ldi cnt, USBPID_ACK ;[-17] |
sendCntAndReti: |
mov x3, cnt ;[-16] |
sendX3AndReti: |
ldi YL, 20 ;[-15] x3==r20 address is 20 |
ldi YH, 0 ;[-14] |
ldi cnt, 2 ;[-13] |
; rjmp usbSendAndReti fallthrough |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] |
;uses: x1...x4, btcnt, shift, cnt, Y |
;Numbers in brackets are time since first bit of sync pattern is sent |
usbSendAndReti: ; 12 cycles until SOP |
in x2, USBDDR ;[-12] |
ori x2, USBMASK ;[-11] |
sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) |
in x1, USBOUT ;[-8] port mirror for tx loop |
out USBDDR, x2 ;[-6] <- acquire bus |
ldi x2, 0 ;[-6] init x2 (bitstuff history) because sync starts with 0 |
ldi x4, USBMASK ;[-5] exor mask |
ldi shift, 0x80 ;[-4] sync byte is first byte sent |
txByteLoop: |
ldi bitcnt, 0x40 ;[-3]=[9] binary 01000000 |
txBitLoop: ; the loop sends the first 7 bits of the byte |
sbrs shift, 0 ;[-2]=[10] if we have to send a 1 don't change the line state |
eor x1, x4 ;[-1]=[11] |
out USBOUT, x1 ;[0] |
ror shift ;[1] |
ror x2 ;[2] transfers the last sent bit to the stuffing history |
didStuffN: |
nop ;[3] |
nop ;[4] |
cpi x2, 0xfc ;[5] if we sent six consecutive ones |
brcc bitstuffN ;[6] |
lsr bitcnt ;[7] |
brne txBitLoop ;[8] restart the loop while the 1 is still in the bitcount |
; transmit bit 7 |
sbrs shift, 0 ;[9] |
eor x1, x4 ;[10] |
didStuff7: |
ror shift ;[11] |
out USBOUT, x1 ;[0] transfer bit 7 to the pins |
ror x2 ;[1] move the bit into the stuffing history |
cpi x2, 0xfc ;[2] |
brcc bitstuff7 ;[3] |
ld shift, y+ ;[4] get next byte to transmit |
dec cnt ;[5] decrement byte counter |
brne txByteLoop ;[7] if we have more bytes start next one |
;[8] branch delay |
;make SE0: |
cbr x1, USBMASK ;[8] prepare SE0 [spec says EOP may be 25 to 30 cycles] |
lds x2, usbNewDeviceAddr;[9] |
lsl x2 ;[11] we compare with left shifted address |
out USBOUT, x1 ;[0] <-- out SE0 -- from now 2 bits = 24 cycles until bus idle |
subi YL, 20 + 2 ;[1] Only assign address on data packets, not ACK/NAK in x3 |
sbci YH, 0 ;[2] |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
breq skipAddrAssign ;[3] |
sts usbDeviceAddr, x2 ; if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;[5] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;[6] |
ori x1, USBIDLE ;[7] |
in x2, USBDDR ;[8] |
cbr x2, USBMASK ;[9] set both pins to input |
mov x3, x1 ;[10] |
cbr x3, USBMASK ;[11] configure no pullup on both pins |
ldi x4, 4 ;[12] |
se0Delay: |
dec x4 ;[13] [16] [19] [22] |
brne se0Delay ;[14] [17] [20] [23] |
out USBOUT, x1 ;[24] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;[25] <-- release bus now |
out USBOUT, x3 ;[26] <-- ensure no pull-up resistors are active |
rjmp doReturn |
bitstuffN: |
eor x1, x4 ;[8] generate a zero |
ldi x2, 0 ;[9] reset the bit stuffing history |
nop2 ;[10] |
out USBOUT, x1 ;[0] <-- send the stuffing bit |
rjmp didStuffN ;[1] |
bitstuff7: |
eor x1, x4 ;[5] |
ldi x2, 0 ;[6] reset bit stuffing history |
clc ;[7] fill a zero into the shift register |
rol shift ;[8] compensate for ror shift at branch destination |
rjmp didStuff7 ;[9] |
;[10] jump delay |
;-------------------------------------------------------------------------------------------------------------- |
; receives data bytes and calculates the crc |
; second half of the data byte receiver loop |
; most parts of the crc algorithm are here |
;-------------------------------------------------------------------------------------------------------------- |
nOverflow2: |
rjmp overflow |
rxDataBit4: |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] check for se0 |
breq nOverflow2 ;[2] |
eor x2, x1 ;[3] |
bst x2, USBMINUS ;[4] |
bld shift, 4 ;[5] |
mov x2, shift ;[6] |
andi x2, 0x9F ;[7] |
breq unstuff4 ;[8] |
didunstuff4: |
nop2 ;[9][10] |
nop ;[11] |
; bit5 |
in x2, USBIN ;[0] sample line state |
ldi ZH, hi8(usbCrcTableHigh);[1] use the table for the higher byte |
eor x1, x2 ;[2] |
bst x1, USBMINUS ;[3] |
bld shift, 5 ;[4] |
mov x1, shift ;[5] |
andi x1, 0x3F ;[6] |
breq unstuff5 ;[7] |
didunstuff5: |
lpm x4, Z ;[8] load the higher crc xor-byte and store it for later use |
;[9] lpm needs 3 cycles |
;[10] |
ldi ZH, hi8(usbCrcTableLow);[11] load the lower crc xor byte adress |
; bit6 |
in x1, USBIN ;[0] sample line state |
eor x2, x1 ;[1] |
bst x2, USBMINUS ;[2] |
bld shift, 6 ;[3] |
mov x2, shift ;[4] |
andi x2, 0x7E ;[5] |
breq unstuff6 ;[6] |
didunstuff6: |
lpm ZL, Z ;[7] load the lower xor crc byte |
;[8] lpm needs 3 cycles |
;[9] |
eor ZL, x3 ;[10] xor the old high crc byte with the low xor-byte |
mov x3, x4 ;[11] move the new high order crc value from temp to its destination |
; bit7 |
in x2, USBIN ;[0] sample line state |
eor x1, x2 ;[1] |
bst x1, USBMINUS ;[2] |
bld shift, 7 ;[3] now shift holds the complete but inverted data byte |
mov x1, shift ;[4] |
andi x1, 0xFC ;[5] |
breq unstuff7 ;[6] |
didunstuff7: |
eor x5, shift ;[7] x5 marks all bits which have not been inverted by the unstuffing subs |
mov x4, x5 ;[8] keep a copy of the data byte it will be stored during next bit0 |
eor ZL, x4 ;[9] feed the actual byte into the crc algorithm |
rjmp rxDataStart ;[10] next byte |
;[11] during the reception of the next byte this one will be fed int the crc algorithm |
unstuff4: ;[9] this is the jump delay of rjmp unstuffX |
ori shift, 0x10 ;[10] invert the last received bit to prevent furhter unstuffing |
andi x5, 0xEF ;[11] mark this bit as inverted (will be corrected before storing shift) |
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero |
andi x1, USBMASK ;[2] mask the interesting bits |
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong |
mov x1, x2 ;[4] the next bit expects the last state to be in x1 |
nop2 ;[5] |
;[6] |
rjmp didunstuff4 ;[7] |
;[8] jump delay of rjmp didunstuffX |
unstuff5: ;[8] this is the jump delay of rjmp unstuffX |
nop ;[9] |
ori shift, 0x20 ;[10] invert the last received bit to prevent furhter unstuffing |
andi x5, 0xDF ;[11] mark this bit as inverted (will be corrected before storing shift) |
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero |
andi x2, USBMASK ;[2] mask the interesting bits |
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong |
mov x2, x1 ;[4] the next bit expects the last state to be in x2 |
nop ;[5] |
rjmp didunstuff5 ;[6] |
;[7] jump delay of rjmp didunstuffX |
unstuff6: ;[7] this is the jump delay of rjmp unstuffX |
nop2 ;[8] |
;[9] |
ori shift, 0x40 ;[10] invert the last received bit to prevent furhter unstuffing |
andi x5, 0xBF ;[11] mark this bit as inverted (will be corrected before storing shift) |
in x2, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
eor x1, x2 ;[1] x1 and x2 have to be different because the stuff bit is always a zero |
andi x1, USBMASK ;[2] mask the interesting bits |
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong |
mov x1, x2 ;[4] the next bit expects the last state to be in x1 |
rjmp didunstuff6 ;[5] |
;[6] jump delay of rjmp didunstuffX |
unstuff7: ;[7] this is the jump delay of rjmp unstuffX |
nop ;[8] |
nop ;[9] |
ori shift, 0x80 ;[10] invert the last received bit to prevent furhter unstuffing |
andi x5, 0x7F ;[11] mark this bit as inverted (will be corrected before storing shift) |
in x1, USBIN ;[0] we have some free cycles so we could check for bit stuffing errors |
eor x2, x1 ;[1] x1 and x2 have to be different because the stuff bit is always a zero |
andi x2, USBMASK ;[2] mask the interesting bits |
breq stuffErr2 ;[3] if the stuff bit is a 1-bit something went wrong |
mov x2, x1 ;[4] the next bit expects the last state to be in x2 |
rjmp didunstuff7 ;[5] |
;[6] jump delay of rjmp didunstuff7 |
; local copy of the stuffErr desitnation for the second half of the receiver loop |
stuffErr2: |
rjmp stuffErr |
;-------------------------------------------------------------------------------------------------------------- |
; The crc table follows. It has to be aligned to enable a fast loading of the needed bytes. |
; There are two tables of 256 entries each, the low and the high byte table. |
; Table values were generated with the following C code: |
/* |
#include <stdio.h> |
int main (int argc, char **argv) |
{ |
int i, j; |
for (i=0; i<512; i++){ |
unsigned short crc = i & 0xff; |
for(j=0; j<8; j++) crc = (crc >> 1) ^ ((crc & 1) ? 0xa001 : 0); |
if((i & 7) == 0) printf("\n.byte "); |
printf("0x%02x, ", (i > 0xff ? (crc >> 8) : crc) & 0xff); |
if(i == 255) printf("\n"); |
} |
return 0; |
} |
// Use the following algorithm to compute CRC values: |
ushort computeCrc(uchar *msg, uchar msgLen) |
{ |
uchar i; |
ushort crc = 0xffff; |
for(i = 0; i < msgLen; i++) |
crc = usbCrcTable16[lo8(crc) ^ msg[i]] ^ hi8(crc); |
return crc; |
} |
*/ |
.balign 256 |
usbCrcTableLow: |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41 |
.byte 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 |
; .balign 256 |
usbCrcTableHigh: |
.byte 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2 |
.byte 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04 |
.byte 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E |
.byte 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8 |
.byte 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A |
.byte 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC |
.byte 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6 |
.byte 0xD2, 0x12, 0x13, 0xD3, 0x11, 0xD1, 0xD0, 0x10 |
.byte 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32 |
.byte 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4 |
.byte 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE |
.byte 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38 |
.byte 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA |
.byte 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C |
.byte 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26 |
.byte 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0 |
.byte 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62 |
.byte 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4 |
.byte 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE |
.byte 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68 |
.byte 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA |
.byte 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C |
.byte 0xB4, 0x74, 0x75, 0xB5, 0x77, 0xB7, 0xB6, 0x76 |
.byte 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0 |
.byte 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92 |
.byte 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54 |
.byte 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E |
.byte 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98 |
.byte 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A |
.byte 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C |
.byte 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86 |
.byte 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbdrvasm20.inc |
---|
0,0 → 1,360 |
/* Name: usbdrvasm20.inc |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Jeroen Benschop |
* Based on usbdrvasm16.inc from Christian Starkjohann |
* Creation Date: 2008-03-05 |
* Tabsize: 4 |
* Copyright: (c) 2008 by Jeroen Benschop and OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* Revision: $Id: usbdrvasm20.inc 740 2009-04-13 18:23:31Z cs $ |
*/ |
/* Do not link this file! Link usbdrvasm.S instead, which includes the |
* appropriate implementation! |
*/ |
/* |
General Description: |
This file is the 20 MHz version of the asssembler part of the USB driver. It |
requires a 20 MHz crystal (not a ceramic resonator and not a calibrated RC |
oscillator). |
See usbdrv.h for a description of the entire driver. |
Since almost all of this code is timing critical, don't change unless you |
really know what you are doing! Many parts require not only a maximum number |
of CPU cycles, but even an exact number of cycles! |
*/ |
#define leap2 x3 |
#ifdef __IAR_SYSTEMS_ASM__ |
#define nextInst $+2 |
#else |
#define nextInst .+0 |
#endif |
;max stack usage: [ret(2), YL, SREG, YH, bitcnt, shift, x1, x2, x3, x4, cnt] = 12 bytes |
;nominal frequency: 20 MHz -> 13.333333 cycles per bit, 106.666667 cycles per byte |
; Numbers in brackets are clocks counted from center of last sync bit |
; when instruction starts |
;register use in receive loop: |
; shift assembles the byte currently being received |
; x1 holds the D+ and D- line state |
; x2 holds the previous line state |
; x4 (leap) is used to add a leap cycle once every three bytes received |
; X3 (leap2) is used to add a leap cycle once every three stuff bits received |
; bitcnt is used to determine when a stuff bit is due |
; cnt holds the number of bytes left in the receive buffer |
USB_INTR_VECTOR: |
;order of registers pushed: YL, SREG YH, [sofError], bitcnt, shift, x1, x2, x3, x4, cnt |
push YL ;[-28] push only what is necessary to sync with edge ASAP |
in YL, SREG ;[-26] |
push YL ;[-25] |
push YH ;[-23] |
;---------------------------------------------------------------------------- |
; Synchronize with sync pattern: |
;---------------------------------------------------------------------------- |
;sync byte (D-) pattern LSb to MSb: 01010100 [1 = idle = J, 0 = K] |
;sync up with J to K edge during sync pattern -- use fastest possible loops |
;The first part waits at most 1 bit long since we must be in sync pattern. |
;YL is guarenteed to be < 0x80 because I flag is clear. When we jump to |
;waitForJ, ensure that this prerequisite is met. |
waitForJ: |
inc YL |
sbis USBIN, USBMINUS |
brne waitForJ ; just make sure we have ANY timeout |
waitForK: |
;The following code results in a sampling window of < 1/4 bit which meets the spec. |
sbis USBIN, USBMINUS ;[-19] |
rjmp foundK ;[-18] |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
sbis USBIN, USBMINUS |
rjmp foundK |
#if USB_COUNT_SOF |
lds YL, usbSofCount |
inc YL |
sts usbSofCount, YL |
#endif /* USB_COUNT_SOF */ |
#ifdef USB_SOF_HOOK |
USB_SOF_HOOK |
#endif |
rjmp sofError |
foundK: ;[-16] |
;{3, 5} after falling D- edge, average delay: 4 cycles |
;bit0 should be at 34 for center sampling. Currently at 4 so 30 cylces till bit 0 sample |
;use 1 bit time for setup purposes, then sample again. Numbers in brackets |
;are cycles from center of first sync (double K) bit after the instruction |
push bitcnt ;[-16] |
; [---] ;[-15] |
lds YL, usbInputBufOffset;[-14] |
; [---] ;[-13] |
clr YH ;[-12] |
subi YL, lo8(-(usbRxBuf));[-11] [rx loop init] |
sbci YH, hi8(-(usbRxBuf));[-10] [rx loop init] |
push shift ;[-9] |
; [---] ;[-8] |
ldi shift,0x40 ;[-7] set msb to "1" so processing bit7 can be detected |
nop2 ;[-6] |
; [---] ;[-5] |
ldi bitcnt, 5 ;[-4] [rx loop init] |
sbis USBIN, USBMINUS ;[-3] we want two bits K (sample 3 cycles too early) |
rjmp haveTwoBitsK ;[-2] |
pop shift ;[-1] undo the push from before |
pop bitcnt ;[1] |
rjmp waitForK ;[3] this was not the end of sync, retry |
; The entire loop from waitForK until rjmp waitForK above must not exceed two |
; bit times (= 27 cycles). |
;---------------------------------------------------------------------------- |
; push more registers and initialize values while we sample the first bits: |
;---------------------------------------------------------------------------- |
haveTwoBitsK: |
push x1 ;[0] |
push x2 ;[2] |
push x3 ;[4] (leap2) |
ldi leap2, 0x55 ;[6] add leap cycle on 2nd,5th,8th,... stuff bit |
push x4 ;[7] == leap |
ldi leap, 0x55 ;[9] skip leap cycle on 2nd,5th,8th,... byte received |
push cnt ;[10] |
ldi cnt, USB_BUFSIZE ;[12] [rx loop init] |
ldi x2, 1<<USBPLUS ;[13] current line state is K state. D+=="1", D-=="0" |
bit0: |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] filter only D+ and D- bits |
rjmp handleBit ;[2] make bit0 14 cycles long |
;---------------------------------------------------------------------------- |
; Process bit7. However, bit 6 still may need unstuffing. |
;---------------------------------------------------------------------------- |
b6checkUnstuff: |
dec bitcnt ;[9] |
breq unstuff6 ;[10] |
bit7: |
subi cnt, 1 ;[11] cannot use dec becaus it does not affect the carry flag |
brcs overflow ;[12] Too many bytes received. Ignore packet |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] filter only D+ and D- bits |
cpse x1, x2 ;[2] when previous line state equals current line state, handle "1" |
rjmp b7handle0 ;[3] when line state differs, handle "0" |
sec ;[4] |
ror shift ;[5] shift "1" into the data |
st y+, shift ;[6] store the data into the buffer |
ldi shift, 0x40 ;[7] reset data for receiving the next byte |
subi leap, 0x55 ;[9] trick to introduce a leap cycle every 3 bytes |
brcc nextInst ;[10 or 11] it will fail after 85 bytes. However low speed can only receive 11 |
dec bitcnt ;[11 or 12] |
brne bit0 ;[12 or 13] |
ldi x1, 1 ;[13 or 14] unstuffing bit 7 |
in bitcnt, USBIN ;[0] sample stuff bit |
rjmp unstuff ;[1] |
b7handle0: |
mov x2,x1 ;[5] Set x2 to current line state |
ldi bitcnt, 6 ;[6] |
lsr shift ;[7] shift "0" into the data |
st y+, shift ;[8] store data into the buffer |
ldi shift, 0x40 ;[10] reset data for receiving the next byte |
subi leap, 0x55 ;[11] trick to introduce a leap cycle every 3 bytes |
brcs bit0 ;[12] it will fail after 85 bytes. However low speed can only receive 11 |
rjmp bit0 ;[13] |
;---------------------------------------------------------------------------- |
; Handle unstuff |
; x1==0xFF indicate unstuffing bit6 |
;---------------------------------------------------------------------------- |
unstuff6: |
ldi x1,0xFF ;[12] indicate unstuffing bit 6 |
in bitcnt, USBIN ;[0] sample stuff bit |
nop ;[1] fix timing |
unstuff: ;b0-5 b6 b7 |
mov x2,bitcnt ;[3] [2] [3] Set x2 to match line state |
subi leap2, 0x55 ;[4] [3] [4] delay loop |
brcs nextInst ;[5] [4] [5] add one cycle every three stuff bits |
sbci leap2,0 ;[6] [5] [6] |
ldi bitcnt,6 ;[7] [6] [7] reset bit stuff counter |
andi x2, USBMASK ;[8] [7] [8] only keep D+ and D- |
cpi x1,0 ;[9] [8] [9] |
brmi bit7 ;[10] [9] [10] finished unstuffing bit6 When x1<0 |
breq bitloop ;[11] --- [11] finished unstuffing bit0-5 when x1=0 |
nop ;--- --- [12] |
in x1, USBIN ;--- --- [0] sample line state for bit0 |
andi x1, USBMASK ;--- --- [1] filter only D+ and D- bits |
rjmp handleBit ;--- --- [2] make bit0 14 cycles long |
;---------------------------------------------------------------------------- |
; Receiver loop (numbers in brackets are cycles within byte after instr) |
;---------------------------------------------------------------------------- |
bitloop: |
in x1, USBIN ;[0] sample line state |
andi x1, USBMASK ;[1] filter only D+ and D- bits |
breq se0 ;[2] both lines are low so handle se0 |
handleBit: |
cpse x1, x2 ;[3] when previous line state equals current line state, handle "1" |
rjmp handle0 ;[4] when line state differs, handle "0" |
sec ;[5] |
ror shift ;[6] shift "1" into the data |
brcs b6checkUnstuff ;[7] When after shift C is set, next bit is bit7 |
nop2 ;[8] |
dec bitcnt ;[10] |
brne bitloop ;[11] |
ldi x1,0 ;[12] indicate unstuff for bit other than bit6 or bit7 |
in bitcnt, USBIN ;[0] sample stuff bit |
rjmp unstuff ;[1] |
handle0: |
mov x2, x1 ;[6] Set x2 to current line state |
ldi bitcnt, 6 ;[7] reset unstuff counter. |
lsr shift ;[8] shift "0" into the data |
brcs bit7 ;[9] When after shift C is set, next bit is bit7 |
nop ;[10] |
rjmp bitloop ;[11] |
;---------------------------------------------------------------------------- |
; End of receive loop. Now start handling EOP |
;---------------------------------------------------------------------------- |
macro POP_STANDARD ; 14 cycles |
pop cnt |
pop x4 |
pop x3 |
pop x2 |
pop x1 |
pop shift |
pop bitcnt |
endm |
macro POP_RETI ; 7 cycles |
pop YH |
pop YL |
out SREG, YL |
pop YL |
endm |
#include "asmcommon.inc" |
; USB spec says: |
; idle = J |
; J = (D+ = 0), (D- = 1) |
; K = (D+ = 1), (D- = 0) |
; Spec allows 7.5 bit times from EOP to SOP for replies |
; 7.5 bit times is 100 cycles. This implementation arrives a bit later at se0 |
; then specified in the include file but there is plenty of time |
bitstuffN: |
eor x1, x4 ;[8] |
ldi x2, 0 ;[9] |
nop2 ;[10] |
out USBOUT, x1 ;[12] <-- out |
rjmp didStuffN ;[0] |
bitstuff7: |
eor x1, x4 ;[6] |
ldi x2, 0 ;[7] Carry is zero due to brcc |
rol shift ;[8] compensate for ror shift at branch destination |
nop2 ;[9] |
rjmp didStuff7 ;[11] |
sendNakAndReti: |
ldi x3, USBPID_NAK ;[-18] |
rjmp sendX3AndReti ;[-17] |
sendAckAndReti: |
ldi cnt, USBPID_ACK ;[-17] |
sendCntAndReti: |
mov x3, cnt ;[-16] |
sendX3AndReti: |
ldi YL, 20 ;[-15] x3==r20 address is 20 |
ldi YH, 0 ;[-14] |
ldi cnt, 2 ;[-13] |
; rjmp usbSendAndReti fallthrough |
;usbSend: |
;pointer to data in 'Y' |
;number of bytes in 'cnt' -- including sync byte [range 2 ... 12] |
;uses: x1...x4, btcnt, shift, cnt, Y |
;Numbers in brackets are time since first bit of sync pattern is sent |
;We don't match the transfer rate exactly (don't insert leap cycles every third |
;byte) because the spec demands only 1.5% precision anyway. |
usbSendAndReti: ; 12 cycles until SOP |
in x2, USBDDR ;[-12] |
ori x2, USBMASK ;[-11] |
sbi USBOUT, USBMINUS;[-10] prepare idle state; D+ and D- must have been 0 (no pullups) |
in x1, USBOUT ;[-8] port mirror for tx loop |
out USBDDR, x2 ;[-7] <- acquire bus |
; need not init x2 (bitstuff history) because sync starts with 0 |
ldi x4, USBMASK ;[-6] exor mask |
ldi shift, 0x80 ;[-5] sync byte is first byte sent |
txByteLoop: |
ldi bitcnt, 0x49 ;[-4] [10] binary 01001001 |
txBitLoop: |
sbrs shift, 0 ;[-3] [10] [11] |
eor x1, x4 ;[-2] [11] [12] |
out USBOUT, x1 ;[-1] [12] [13] <-- out N |
ror shift ;[0] [13] [14] |
ror x2 ;[1] |
didStuffN: |
nop2 ;[2] |
nop ;[4] |
cpi x2, 0xfc ;[5] |
brcc bitstuffN ;[6] |
lsr bitcnt ;[7] |
brcc txBitLoop ;[8] |
brne txBitLoop ;[9] |
sbrs shift, 0 ;[10] |
eor x1, x4 ;[11] |
didStuff7: |
out USBOUT, x1 ;[-1] [13] <-- out 7 |
ror shift ;[0] [14] |
ror x2 ;[1] |
nop ;[2] |
cpi x2, 0xfc ;[3] |
brcc bitstuff7 ;[4] |
ld shift, y+ ;[5] |
dec cnt ;[7] |
brne txByteLoop ;[8] |
;make SE0: |
cbr x1, USBMASK ;[9] prepare SE0 [spec says EOP may be 25 to 30 cycles] |
lds x2, usbNewDeviceAddr;[10] |
lsl x2 ;[12] we compare with left shifted address |
out USBOUT, x1 ;[13] <-- out SE0 -- from now 2 bits = 22 cycles until bus idle |
subi YL, 20 + 2 ;[0] Only assign address on data packets, not ACK/NAK in x3 |
sbci YH, 0 ;[1] |
;2006-03-06: moved transfer of new address to usbDeviceAddr from C-Code to asm: |
;set address only after data packet was sent, not after handshake |
breq skipAddrAssign ;[2] |
sts usbDeviceAddr, x2; if not skipped: SE0 is one cycle longer |
skipAddrAssign: |
;end of usbDeviceAddress transfer |
ldi x2, 1<<USB_INTR_PENDING_BIT;[4] int0 occurred during TX -- clear pending flag |
USB_STORE_PENDING(x2) ;[5] |
ori x1, USBIDLE ;[6] |
in x2, USBDDR ;[7] |
cbr x2, USBMASK ;[8] set both pins to input |
mov x3, x1 ;[9] |
cbr x3, USBMASK ;[10] configure no pullup on both pins |
ldi x4, 5 ;[11] |
se0Delay: |
dec x4 ;[12] [15] [18] [21] [24] |
brne se0Delay ;[13] [16] [19] [22] [25] |
out USBOUT, x1 ;[26] <-- out J (idle) -- end of SE0 (EOP signal) |
out USBDDR, x2 ;[27] <-- release bus now |
out USBOUT, x3 ;[28] <-- ensure no pull-up resistors are active |
rjmp doReturn |
/Modules/AVR/AVRUSB01A/SW/fw_usbasp/usbdrv/usbportability.h |
---|
0,0 → 1,144 |
/* Name: usbportability.h |
* Project: V-USB, virtual USB port for Atmel's(r) AVR(r) microcontrollers |
* Author: Christian Starkjohann |
* Creation Date: 2008-06-17 |
* Tabsize: 4 |
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH |
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt) |
* This Revision: $Id: usbportability.h 785 2010-05-30 17:57:07Z cs $ |
*/ |
/* |
General Description: |
This header is intended to contain all (or at least most of) the compiler |
and library dependent stuff. The C code is written for avr-gcc and avr-libc. |
The API of other development environments is converted to gcc's and avr-libc's |
API by means of defines. |
This header also contains all system includes since they depend on the |
development environment. |
Thanks to Oleg Semyonov for his help with the IAR tools port! |
*/ |
#ifndef __usbportability_h_INCLUDED__ |
#define __usbportability_h_INCLUDED__ |
/* We check explicitly for IAR and CodeVision. Default is avr-gcc/avr-libc. */ |
/* ------------------------------------------------------------------------- */ |
#if defined __IAR_SYSTEMS_ICC__ || defined __IAR_SYSTEMS_ASM__ /* check for IAR */ |
/* ------------------------------------------------------------------------- */ |
#ifndef ENABLE_BIT_DEFINITIONS |
# define ENABLE_BIT_DEFINITIONS 1 /* Enable bit definitions */ |
#endif |
/* Include IAR headers */ |
#include <ioavr.h> |
#ifndef __IAR_SYSTEMS_ASM__ |
# include <inavr.h> |
#endif |
#define __attribute__(arg) /* not supported on IAR */ |
#ifdef __IAR_SYSTEMS_ASM__ |
# define __ASSEMBLER__ /* IAR does not define standard macro for asm */ |
#endif |
#ifdef __HAS_ELPM__ |
# define PROGMEM __farflash |
#else |
# define PROGMEM __flash |
#endif |
#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) |
/* The following definitions are not needed by the driver, but may be of some |
* help if you port a gcc based project to IAR. |
*/ |
#define cli() __disable_interrupt() |
#define sei() __enable_interrupt() |
#define wdt_reset() __watchdog_reset() |
#define _BV(x) (1 << (x)) |
/* assembler compatibility macros */ |
#define nop2 rjmp $+2 /* jump to next instruction */ |
#define XL r26 |
#define XH r27 |
#define YL r28 |
#define YH r29 |
#define ZL r30 |
#define ZH r31 |
#define lo8(x) LOW(x) |
#define hi8(x) (((x)>>8) & 0xff) /* not HIGH to allow XLINK to make a proper range check */ |
/* Depending on the device you use, you may get problems with the way usbdrv.h |
* handles the differences between devices. Since IAR does not use #defines |
* for MCU registers, we can't check for the existence of a particular |
* register with an #ifdef. If the autodetection mechanism fails, include |
* definitions for the required USB_INTR_* macros in your usbconfig.h. See |
* usbconfig-prototype.h and usbdrv.h for details. |
*/ |
/* ------------------------------------------------------------------------- */ |
#elif __CODEVISIONAVR__ /* check for CodeVision AVR */ |
/* ------------------------------------------------------------------------- */ |
/* This port is not working (yet) */ |
/* #define F_CPU _MCU_CLOCK_FREQUENCY_ seems to be defined automatically */ |
#include <io.h> |
#include <delay.h> |
#define __attribute__(arg) /* not supported on IAR */ |
#define PROGMEM __flash |
#define USB_READ_FLASH(addr) (*(PROGMEM char *)(addr)) |
#ifndef __ASSEMBLER__ |
static inline void cli(void) |
{ |
#asm("cli"); |
} |
static inline void sei(void) |
{ |
#asm("sei"); |
} |
#endif |
#define _delay_ms(t) delay_ms(t) |
#define _BV(x) (1 << (x)) |
#define USB_CFG_USE_SWITCH_STATEMENT 1 /* macro for if() cascase fails for unknown reason */ |
#define macro .macro |
#define endm .endmacro |
#define nop2 rjmp .+0 /* jump to next instruction */ |
/* ------------------------------------------------------------------------- */ |
#else /* default development environment is avr-gcc/avr-libc */ |
/* ------------------------------------------------------------------------- */ |
#include <avr/io.h> |
#ifdef __ASSEMBLER__ |
# define _VECTOR(N) __vector_ ## N /* io.h does not define this for asm */ |
#else |
# include <avr/pgmspace.h> |
#endif |
#if USB_CFG_DRIVER_FLASH_PAGE |
# define USB_READ_FLASH(addr) pgm_read_byte_far(((long)USB_CFG_DRIVER_FLASH_PAGE << 16) | (long)(addr)) |
#else |
# define USB_READ_FLASH(addr) pgm_read_byte(addr) |
#endif |
#define macro .macro |
#define endm .endm |
#define nop2 rjmp .+0 /* jump to next instruction */ |
#endif /* development environment */ |
/* for conveniecne, ensure that PRG_RDB exists */ |
#ifndef PRG_RDB |
# define PRG_RDB(addr) USB_READ_FLASH(addr) |
#endif |
#endif /* __usbportability_h_INCLUDED__ */ |
/Modules/AVR/AVRUSB01A/CAM_AMA/T1_AMA.pdf |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/Modules/AVR/AVRUSB01A/CAM_AMA/T1_AMA_MULTI.pdf |
---|
0,0 → 1,781 |
+%âãÏÓ |
+stream |
+HÍ®9÷ßU|7Çÿ?ëYÄffX ¡ ´F |
+#¸}Þªnw×[Pç<ÇvËår±úòßù×?¤Âl#½KKaÔ:ßWÂ{\uÿñóO@_Þe^ò|ÿûâûOïôþþÿÇ÷ÿß{¿~øùó׿þöå_üõë¯ß¾ûöåÓûÛ×?ý_úû?_Æj{W(ïãÕFÌã_àëëW˵ 8Ö)´IY-ýYÖ |
+«Ä ½JÏ=Ì_,5 _¼É(=´¤¿X#ÖÍ`µ¹B.dyf¬kt²îïÑU3زRY9ÄÎcƲwì¸7R¥ i&lè´É=ÞÉÚVê1LÝÎÚ8g³R5}®[ ÷ H¨å± |
+4å ';®{ÊÃn#uÐM¸DpL6fi¯ÂéÂ츷Êf%jD¹¡8Y5ÑkD©¿úÐ`Úõ'¥<S+Ë3ÈÎèZQî>³tÄARF>X©U®Ô·1µ´[¤ùÉ#Sa¼pFêhÝ£8FÖ}¬Zªý<O<ózÌ3±ðÓ¼ÿý±.b£0ð |
+}ÆÚïIÏìXhjwcL¬ª1©£Ób¦VQEL¬µ¤©ÕÎ=kC®âË"¦n;ù½%[.«¶]Ô=;LÑê®êb2ýÆ¥å3µìç3µb>Ù}´32S-}sYÈLγ>æ+gÍ5s¤obJcj!Ϋcjµë¦ºË#uäÇÄÂÅ:]¡qL*'æ#¤Ú÷åVÎL-ÄÊu |
+èU±¤RYDûX8&n{ÏÔ*auoåc7#3µPð¤Ë[k'3µª¤í<³33ãÓÉ8dÖn7¥3µ0tñ1Ý(Åæ#t<{j×MH&EÀ¶re3o¦öSffå´3ÌLLßëÍ+²Ù¼¢\ fóÊ®Ùw2fö!%<³¢¼.CjÞo<ÏÔj¡âÂ*å½cjé1Að$»-bjEy@ #½×EL,L¼{Ùb¦ºÁáfd¦ÞªnñÔACQ\5îê°¢dSôܺµÏFµû=±zSÖ<¤9Õå!P_Î:Z]ºbtXxÚÜcS«ÊµgnZIòlDä]ïÛ"&ÖÚPÅL*ã©¥µWÏL-m¼8ÌÈjÒb© Ö["l¢Úp&¾Ú>©ÕôzëV`Hg(²3!m¹N&H¹2g/Ú"uÆùe£Ë|IÄÄÊøVØÖ˱D®-JQÞ[CL-TìâÈÌZMwÙÍþ:¦V=³Çäc Jç¼sì0;N1»7vFfvíê© «lºH0³*3;£Ý!fjM©.´Õ4U+&ç1|<O¤É>Bvwl3³;mN!ëÜ§Ê ;=Ìlgóà9ç|òµWt&RwǪrG´;J©õA#6·EL,ÔfyÐÜu[ÌÔªú ¸£çØ1µÖ@¶ ªÆgd¦V×Ç$Z3kõ´;º4OÿÓÌkRt¨Ç»»wL-ä¢|sßùâ8ØÕª ìºïZCN³©5Õì|Ä+ÄìVÎL-D¶ï¾$¬¾&'ÌÎ7ÇýXrÌ®y¹{ |
+ÇlÎÜæ(Üù~G,bvoìÌì>ÛÕ3;|z|/c.`sÁ";[«»b{fWnNc6 |
+yBÙz&V8¼ÅL)sóÌÔZ^=3±z±ºH0#%cxK±jCûî˹¢>WA{ |
+U¬Ù¼[vö¡«a¿©^lѲ3E@p7Cd¡ÓÇ Èô:pæÙà¸ôQs0. ,ºcÍRª9ÌYÛ¨V¸×±c¨jW£ú¸cçï¬óËÔxXá3&V¶ë¢¯TëwF «Löôù,)rÑy®^UeT ùi¯>T,wùïïÿ¾d`$ ÷,o»ßDàÆEÉxʨı}ô¼pÖ÷/üBnwé(~)Òö÷´_l[?ng{ áå»m¬o±±¼Ø |
+õRW°qüzûó?o¸û$°ÞpÿC57-xbGÆ&HÀÕó®$]±-¯oNê»® ßËE'O±VOt¥ÛÃÉàü¦è¶BýÖl£?7¸Qºt1ZNtJ¶oX7Tò½÷Eäþpâ-QÆH>+è÷nå® ¾«z±ê·®`ã¥û±ÁÒ²N]W'ZÞ3eû¶ê»®°¿÷LÙdM]A'Ú83E½Ø |
+õRW°qØÒý¸àFéâ®v¯ WÂC°KqX§xr§"û¾Äå-ªß°Ð,²ßUbÜ+ìïiC~±H»o9÷ |
+M|%ë[ò±¼Ø奮àâ¥û±ÁÒÅ< |
+Ph·Ú|"¸wdzþü¤¸ôß{ë×Î[²ª ë2öæñ~a·¿ÿñöç=x7åÏ5¥´879ÞCXþÆË |
+µî¿Stçø"'Fñ[EiõQíýúNó´{½Ê¿p©ücÉß°C%G= oD6R®§Ú/×Çt¥ÔÚ¿Yhi^®ñzåóì TD+®T帿¿qIE/}j¸-"¥¯WRÑg+¡ºÏ0nLPìa9÷'í¿FtÐed|.Â̼j´+Õü¹È¬ôAtãóÔoVZ¢+áÇìóFAÈnjïù Ïå<)øùNhö¾¿½eÜGXªhÈ.Ë{ õ½Là |
+nl.4§.Ð:wº· ýÆ/[¡^ë |
+6qþÐÈÆyZpgÎ |
+M:Ö |
+©r]^··$ |
+%óÍ"[Ûª~/¯ô×êµ®âR¶B]Öl£b?1,.WpNöBÝ!>×½ãªceW¿O\[1×߯(×ú;.ÜÑáåwv¨)mëûµêñZÀ`ªõ¢bí)±ÃR²ÜÒ«Në>aé®ß5t"Ûî&Ó±=vß{0íÈöèR :½p1yø³Õ(WJÜz/âÖo"¸w÷ø^eTy×Æ[®s5T¼,ïýýë<¯^[WQxhý6äJ*®Xé}¯Ðs¸z;6Ö·üby¡íåZÁÅ1Êös¥ËåK8E·Éò-ãÓëñ=ãb×9¸tGùé¤6{ý½Ûd¹¦+¨ëËÄM}Øõq-ࢠû¡¡IÙp¯ÌèÞñ@jØòÔÌùj·DYñõÙä/)óGÕ&âÕ«&U×ûÒÓ¢4ÏTY6Trâ¶|®äßï0ë§aü´%±l¨ÚU«W&ª'³Ä³l¨ê¸&¿-ªG6Íe¬â|*Cunuö^ó(¦_K û:Õ¨ñZówÍ®d,p_±nbU»Î_m¿ÖZƯ¥"¿¶Eò«ÝÕ#)ªaÐïk¾BRaãÓ®Å{ü¾LcC¯(]RʳªcdON5[ÄN«Þâdì}ªÛ/Ç~SÔ)ËîµLTÈ\âöÞ1Q¡VOu*ËDU²TÁZ´l¨©õÞ2Q¡VMEC/6§±êãÙ£R[Äs×XÆYÝf³p:P³Ç*eÇ«OT»kz»B4NòZÕCÀ×úFn,äÕ&¦xÕd§á{¨Ö2ì4<*rWv¾Ë½#دì4|-\±WvoUR[¶±Þ[¶Ð$Â"Î<åÔ±ÏëÓb |
+¥Åh(åìD@&£»4qÖC¸Kú@CS¯,Û,[dbO¼âc«¼«îxuÔMÆG]G£uk1ê $C¢Û^XzUñ!F£*ïç:E=vçqLTm,jÛݲ¡ |
+U¾Bv¾[FóÝ1QÁ¶´·±c¤2ÍeYLØ,ÁY\¼7å±2aË2ʪi.ËN}È ª´±gum-ÃÎyhÒ°¦+ZÏ>öÊ2>ÃXµvb}Ò*ïÄ;{Mv'.F;± xµfwâb´YåíD¶èíÄå©·ÇûMð÷¹j2ʵ?WwWÅÅدޮÚ_ÑT®x}òF³¹6Üv¾ãÜãõ²Ëýd4«ôÝ»Ñܵ\-¹jOƪR¥[¬j2ö÷ç×dÔÃå¶-1ui,â¼5ǸÒìù#§·°OEHG®-;;ßìhçs:6ThµdÔ1Ü~±Á2¶yV¼ÅÉØ{N©eî(£v>/Þ$)é\I^kRÂþ¹1ôºZq6øEDUëKQïÙ±¡$¶Édèä«u¯l¨àhòÈvZ*ÃDýáN{©,ª:^ËÓ¥2LTò@hNeÙPaÀ5gÑ2QåøÑ{Ë*Qa2a«ûâD±=tcÌÎÞdÃ÷>t)8únØÈ|Ï[EÃEì¡æTh79ï©Ö÷¸´ëþ?ååeIÑy¯¢Wðós`Q1îí·Ià¸"¢²²&ç¦=KON¹ªúY*3®2WaïUÂL s9JØQ«ÒòG¯ÌTmzÞ_½TÊ\u¯H¹BÊX ÃX[P-Æ;æÛþ¯;.ÆѧigK£_3© D8ârq}D%kMû b×päʾÈm n×üäJBQý Bu¨k3e9tÀ\U>cèÙÌU~SÉÙUhÿ9ªã1Ïv\£¯ÕúF¿gzD`URt¯O¾zË=biÿ½ª]ßUwþ7ª?]zÄ!ÿ¨W±S)ÌUs¹<©R^§ <«|°Oƪ÷>PÄûQ· c'ßÆy ßÆ9%Õcþ£:Ræ!³ù¯üÛ\sD+AzϳíÕ}uëÀªêxèÙ/±ÂµUɾóðô¥*í©KÝ°8Ra༧¨6ùgUÇÀsõCÖ1Sf*l8I§æ*èaúñè~¡2WuzAÎû52RõyÛÕf´cGQFÖ7£èû¸íë%úÍ(ÃckÍ8«¢J5©N¤ûno"YÝU£·É¸ÚºÍ×IS«»r«RpêÈùRP)3=BãÊ\å§wºEHÓç´Ñf®*ëáe5«¢âRæ_xSF¥Ì³ æ¿»>õdKeÿ}òÐÌofª |
+½Ìõ©!£¯·¨ýîf:)ôf¬jãSï Z£j¨ÛQ-F~k)#?JgwTƵæèqWT±Ö²ß7=Þf0©2Sáì´LªÌUÅ«Ú'OíHJlªv*£è¹F*£¾¢Z3*}Á[Õ\Ktz»Ûd©ÚÁ/\'»ê!ãøUu&xÌçùÀ»ªæO®FNº"3æ«äÌ=e¼#ë#&ªSêÈh?{ÂÝo!ÞF!qzDÊ<WÕðMý ]©ðÎÁWèZʼ:'ÇK¥ÌU÷§#åSJU:á5ÒJ«ìÓj1Þk¨ÌUè. |
+ç¡ý |
+.GÏÜåäaG0Ò[G ûÂgþU6×ÎiøüÈ·#ÖÙð ¿{ó÷BÕ ÌTøU5㲿00V¡ç¨ZÌTø2k+lÓÀ\Uí/K"Þ_Ee뺼ë³*0WaöMºc`ù¶Nù40ªû40VOãɧ¹*{wc£æßx¯NN=ªãÔ³ú}Ùª;.Æѯßiô?¬Õlæ k9ûúº6.½ñû`Õ ÈcëHêÁÍD5l. |
+£DZ#ÏC¬S¡Û>¬7ÀY©©}æÕdö3sÏÁd-¥ÌU÷ç²Õ+^zÏü¤×¦|ePµ«ÚR?÷NW`¦²GT*e®öX3Þ#ÙN@NO&¹ªÙ|µÏ³ ^ Én%¬´ØeI9d~1ýö »áí]gÖ¸µÔ¹*ûLª*a\EÚ10WÃmmz«¹*Y3îþõ{æil=Ç7í®«×Èöfúê¾ç²øQÝPq¢þ®È5×'²5LÓ7¨ûäæªfÍD«^Ï(âý0U¸ßb9YFeʧèòöS.nÜ $«j÷äîÍOW檹zç@©f^qR6±ë¢÷ã+ãØÙ.Ê(ì;AOê¢qmH ÇÆ:YGuÕæUÖuUõ°RµKx¨ÛÞ2Ö6Y"ÌWøAÖÔ¬ÐøZS5Ríøî¥}ÅÍÂMöÛ46ÅWÕ,Ļ٠î¶Ø×e·A·jä¹jXÓ |
+4ªRöÞº£²×.½²×.e¬â>cÒx¾Îæ/;ï·÷½½½Û ¹ªû@2p¥ñ¨± |
+Ñ+sÕíc¤dB«~Èj*¸{+ç+bsäk3ÏÄå£sÊïÈ«¼íÜöõ[%Ì3qîn¤~êÉ0S¡Úà**e¦Â#´Ç¹ |
+_[BôÊÜ ÕîN"rêÎß cU}§±Àh?¼Yî¢û-Ä£«ùb<*÷%2Î(?Ïé«Ã*e\iÞQ»£WƤDF§sØ×7« |
+½µ©ÎJ\+ãÄοåÔ>a»lc÷4h9YEü¢:Íú |
+íTÁõÕÚïygýÙwC:ªE~Q=¤`(aͨÐ%7»¤ÐQk.¹Ûä!y3jÍ×ZÂÜÌR®"AdxÙOµo]e^ò ëÃ9=ª.E~"[5Ñ¥+óY&«èZyÖJi?mjU/Á¬ÿ´\IûÕCÞ×çygýû}mÕM¯¨zÉh;Õb®êv!Ë©lÃÚÏäg0¯ÏelÒ#K«ðmÖ2øUÇÈÇ·f |
+ã^û)³lÙèxKì¹ |
+3®îóðQF~ȸ¼åbM-` x7êÌqÜprÛg Úû`æ~)ötR2rmÇd?B¦|ôhQírά^5è¯×¾OúÄiñ|àIÕë¨=k½ÝãQq'ú®:ºÇ@/ÎMÖza}ÞÖ:ësTäôïªC¨æªn7éDÙ4òÔN«õ!0Sá]»L`¦*x6©pL®¸£2Ï×õ)%D¯ÌU·åD2ç²Ø/×mß1ôI 5ETDjh³WðøªØëÿýOÍeÚ>R¾ÖxPsº\¥?ï¶Tw²Cª*k@èrwQóåChÀá*ÉvYêÿ[ô(·Ò+ð1Æ\¼¨|íOHPVM§þûË($ëÈpÖØ*|v)VMòªßÖQ2S!È}OXu2WÕã²Ð ªùZ*a®êv·õ·ÓÝJ©Nüý|FFOD²=jq2òþÄwÍJ"qv<xFb2*«`%ËM |
+üz¸tÕs>ªÌUÍÜ맹W%ÌTöÞ5XáçøÌTö¯P§¹ÊÜ fªREe¦ªþ¤Pï¹ê>p$µäs4ÐÙ-)PD0k*2ýë')3bT)3¯PlgS¹ê´â_~N0QkqÌUþð@\ǽ"¯üâÆÌ¿1Ù,Ç«ÑÕêÑVPíÈ-¯# ×´1Ok_Ã>²ÏÎ*×C`¬¢Ú |
+¼¢2UDõÀÕ¨qܹ/Q¦ÅwtORÅoUOv¡h*3ÕãÿÒÆPæªË²)<0W¿ïxF*àE®ÓÀÈ{©Se Íoßéü£J[äWÆÞsÑ+ãHÐÕ«°(\%¨cxÜÑâ`ì=½2ײ_ª°b5¿dÖë±UKê+0WÝcý Ê ÌUi¬7íÀXE±,rT#ï9^}öWÿ¯wèó2SëÛ¢2Wõ£Fï |
+Æàl+cUÚ<0¶Hý{O½EBêKÙ/UØÐC2æµ'û¼öÃIÛ\;±þ¦x°Ot`«d3µâ%A÷' |
+7jY"a~V{Jcæªd,i²À>ï®*e®Êß |
+EvFï}Þ}`~4¯ìO+i±ÀX÷Ã%0¶gWf cßSzÁÀ8ieS)eQ)ã\³Ee\7ì½²E¢cµ>eìvô@X&"þ¶ëKD'=¸´ÎçÿücÕe/ÞÖm+rý ¹â;&->olCÊ\G·ßÏûÞÌT©Å& |