;*************************************************************************** ;* U S B S T A C K F O R T H E A V R F A M I L Y ;* ;* File Name :"USB90S2313.asm" ;* Title :USB stack + Infrared remote control to nonUSB MCU ;* Date :5.4.2003 ;* Version :1.6 ;* Target MCU :AT90S2313-10,AT90S2323-10,AT90S2343-10 ;* AUTHOR :Ing. Igor Cesko ;* Slovakia ;* cesko@internet.sk ;* http://www.cesko.host.sk ;* ;* DESCRIPTION: ;* USB protocol implementation into MCU with noUSB interface: ;* Device: ;* Infrared remote control with TSOP17xx/SFH511x sensor and USB connection ;* + Universal USB interface (8-bit I/O port + RS232 serial line + EEPROM) ;* ;* The timing is adapted for 12 MHz crystal (overclocked MCU !!!) ;* ;* Copyright (c) Ing. Igor Cesko 2002-2003 ;* ;* 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., 675 Mass Ave, Cambridge, MA 02139, USA. ;* ;*************************************************************************** ;*************************************************************************** .include "2313def.inc" .equ inputport =PINB .equ outputport =PORTB .equ USBdirection =DDRB .equ DATAplus =1 ;signal D+ na PB1 .equ DATAminus =0 ;signal D- na PB0 - treba dat na tento pin pull-up 1.5kOhm .equ USBpinmask =0b11111100 ;mask low 2 bits (D+,D-) on PB .equ USBpinmaskDplus =~(1<>8 ;do bitcount CRC polynom - vrchny byte eor temp1,bitcount ;a urob XOR zo zvyskom a CRC polynomom - vrchny byte ldi bitcount,CRC16poly ;do bitcount CRC polynom - spodny byte eor temp0,bitcount ;a urob XOR zo zvyskom a CRC polynomom - spodny byte CRC16NoXOR: dec temp3 ;boli uz vsetky bity v byte brne CRC16LoopByte ;ak nie, tak chod na dalsi bit cp USBBufptrY,ByteCount ;bol uz koniec spravy brne CRC16Loop ;ak nie tak opakuj CRC16End: ret ;inak skonci (v temp0 a temp1 je vysledok) ;------------------------------------------------------------------------------------------ LoadDescriptorFromROM: lpm ;nahraj z pozicie ROM pointra do R0 st Y+,R0 ;R0 uloz do buffera a zvys buffer adiw ZH:ZL,1 ;zvys ukazovatel do ROM dec ByteCount ;pokial nie su vsetky byty brne LoadDescriptorFromROM ;tak nahravaj dalej rjmp EndFromRAMROM ;inak skonci ;------------------------------------------------------------------------------------------ LoadDescriptorFromROMZeroInsert: lpm ;nahraj z pozicie ROM pointra do R0 st Y+,R0 ;R0 uloz do buffera a zvys buffer bst RAMread,3 ;ak je 3 bit jednotkovy - nebude sa vkladat nula brtc InsertingZero ;inak sa bude vkladat nula adiw ZH:ZL,1 ;zvys ukazovatel do ROM lpm ;nahraj z pozicie ROM pointra do R0 st Y+,R0 ;R0 uloz do buffera a zvys buffer clt ;a znuluj bld RAMread,3 ;treti bit v RAMread - aby sa v dalsom vkladali nuly rjmp InsertingZeroEnd ;a pokracuj InsertingZero: clr R0 ;na vkladanie nul st Y+,R0 ;nulu uloz do buffera a zvys buffer InsertingZeroEnd: adiw ZH:ZL,1 ;zvys ukazovatel do ROM subi ByteCount,2 ;pokial nie su vsetky byty brne LoadDescriptorFromROMZeroInsert ;tak nahravaj dalej rjmp EndFromRAMROM ;inak skonci ;------------------------------------------------------------------------------------------ LoadDescriptorFromSRAM: ld R0,Z ;nahraj z pozicie RAM pointra do R0 st Y+,R0 ;R0 uloz do buffera a zvys buffer inc ZL ;zvys ukazovatel do RAM dec ByteCount ;pokial nie su vsetky byty brne LoadDescriptorFromSRAM ;tak nahravaj dalej rjmp EndFromRAMROM ;inak skonci ;------------------------------------------------------------------------------------------ LoadDescriptorFromEEPROM: out EEAR,ZL ;nastav adresu EEPROM sbi EECR,EERE ;vycitaj EEPROM do registra EEDR in R0,EEDR ;nahraj z EEDR do R0 st Y+,R0 ;R0 uloz do buffera a zvys buffer inc ZL ;zvys ukazovatel do RAM dec ByteCount ;pokial nie su vsetky byty brne LoadDescriptorFromEEPROM;tak nahravaj dalej rjmp EndFromRAMROM ;inak skonci ;------------------------------------------------------------------------------------------ LoadXXXDescriptor: ldi temp0,SOPbyte ;SOP byte sts OutputBufferBegin,temp0 ;na zaciatok vysielacieho buffera dat SOP ldi ByteCount,8 ;8 bytov nahrat ldi USBBufptrY,OutputBufferBegin+2 ;do vysielacieho buffera and RAMread,RAMread ;ci sa bude citat z RAM alebo ROM-ky alebo EEPROM-ky brne FromRAMorEEPROM ;0=ROM,1=RAM,2=EEPROM,4=ROM s vkladanim nuly FromROM: rjmp LoadDescriptorFromROM ;nahrat descriptor z ROM-ky FromRAMorEEPROM: sbrc RAMread,2 ;ak RAMread=4 rjmp LoadDescriptorFromROMZeroInsert ;citaj z ROM s vkladanim nuly sbrc RAMread,0 ;ak RAMread=1 rjmp LoadDescriptorFromSRAM ;nahraj data zo SRAM-ky rjmp LoadDescriptorFromEEPROM ;inak citaj z EEPROM EndFromRAMROM: sbrc RAMread,7 ;ak je najvyssi bit v premennej RAMread=1 clr RAMread ;znuluj RAMread rcall ToggleDATAPID ;zmenit DATAPID ldi USBBufptrY,OutputBufferBegin+1 ;do vysielacieho buffera - pozicia DATA PID ret ;------------------------------------------------------------------------------------------ PrepareUSBOutAnswer: ;pripravenie odpovede do buffera rcall PrepareUSBAnswer ;pripravenie odpovede do buffera MakeOutBitStuff: inc BitStuffInOut ;vysielaci buffer - vkladanie bitstuff bitov ldi USBBufptrY,OutputBufferBegin ;do vysielacieho buffera rcall BitStuff mov OutputBufferLength,ByteCount ;dlzku odpovede zapamatat pre vysielanie clr BitStuffInOut ;prijimaci buffer - mazanie bitstuff bitov ret ;------------------------------------------------------------------------------------------ PrepareUSBAnswer: ;pripravenie odpovede do buffera clr RAMread ;nulu do RAMread premennej - cita sa z ROM-ky lds temp0,InputBufferBegin+2 ;bmRequestType do temp0 lds temp1,InputBufferBegin+3 ;bRequest do temp1 cbr temp0,0b10011111 ;ak je 5 a 6 bit nulovy brne VendorRequest ;tak to nie je Vendor Request rjmp StandardRequest ;ale je to standardny request ;-------------------------- DoSetInfraBufferEmpty: clr InfraBufferFull ;nastav prazdnost buffera SendZeroAnswerInfraEmpty: rjmp OneZeroAnswer ;potvrd prijem jednou nulou ;-------------------------- VendorRequest: clr ZH ;pre citanie z RAM alebo EEPROM cpi temp1,1 ; breq DoSetInfraBufferEmpty ;restartne infra prijimanie (ak bolo zastavene citanim z RAM-ky) cpi temp1,2 ; breq DoGetInfraCode ;vysle prijaty infra kod (ak je v bufferi) cpi temp1,3 ; breq DoSetDataPortDirection ;nastavi smer toku datovych bitov cpi temp1,4 ; breq DoGetDataPortDirection ;zisti smer toku datovych bitov cpi temp1,5 ; breq DoSetOutDataPort ;nastavi datove bity (ak su vstupne, tak ich pull-up) cpi temp1,6 ; breq DoGetOutDataPort ;zisti nastavenie datovych out bitov (ak su vstupne, tak ich pull-up) cpi temp1,7 ; breq DoGetInDataPort ;vrati hodnotu datoveho vstupneho portu cpi temp1,8 ; breq DoEEPROMRead ;vrati obsah EEPROM od urcitej adresy cpi temp1,9 ; breq DoEEPROMWrite ;zapise EEPROM na urcitu adresu urcite data cpi temp1,10 ; breq DoRS232Send ;vysle byte na seriovy linku cpi temp1,11 ; breq DoRS232Read ;vrati prijaty byte zo seriovej linky (ak sa nejaky prijal) cpi temp1,12 ; breq DoSetRS232Baud ;nastavi prenosovu rychlost seriovej linky cpi temp1,13 ; breq DoGetRS232Baud ;vrati prenosovu rychlost seriovej linky rjmp ZeroDATA1Answer ;ak to bolo nieco nezname, tak priprav nulovu odpoved ;----------------------------- USER FUNCTIONS -------------------------------------- DoGetInfraCode: cpi InfraBufferFull,0 ;ak je Infra Buffer prazdny breq SendZeroAnswerInfraEmpty ;tak nic neposli ldi ZL,InfraBufferBegin lds temp1,InputBufferBegin+4 ;prvy parameter - offset v infra bufferi add ZL,temp1 ;plus offset v buffri lds temp0,InfraBufferBegin ;pocet mojich bytovych odpovedi do temp0 ldi temp1,3 ;plus 3 byty hlavicky add temp0,temp1 inc RAMread ;RAMread=1 - cita sa z RAM-ky rjmp ComposeEndXXXDescriptor ;a priprav data DoEEPROMRead: lds ZL,InputBufferBegin+4 ;prvy parameter - offset v EEPROM-ke ldi temp0,2 mov RAMread,temp0 ;RAMread=2 - cita sa z EEPROM-ky ldi temp0,E2END+1 ;pocet mojich bytovych odpovedi do temp0 - cela dlzka EEPROM rjmp ComposeEndXXXDescriptor ;inak priprav data DoEEPROMWrite: lds ZL,InputBufferBegin+4 ;prvy parameter - offset v EEPROM-ke (adresa) lds R0,InputBufferBegin+6 ;druhy parameter - data, ktore sa maju zapisat do EEPROM-ky (data) rjmp EEPROMWrite ;zapis do EEPROM a aj ukonci prikaz DoSetDataPortDirection: lds ACC,InputBufferBegin+4 ;prvy parameter - smer datovych bitov rcall SetDataPortDirection rjmp OneZeroAnswer ;potvrd prijem jednou nulou DoGetDataPortDirection: rcall GetDataPortDirection rjmp DoGetIn DoSetOutDataPort: lds ACC,InputBufferBegin+4 ;prvy parameter - hodnota datovych bitov rcall SetOutDataPort rjmp OneZeroAnswer ;potvrd prijem jednou nulou DoGetOutDataPort: rcall GetOutDataPort rjmp DoGetIn DoGetInDataPort: rcall GetInDataPort DoGetIn: ldi ZL,0 ;posiela sa hodnota v R0 ldi temp0,0x81 ;RAMread=1 - cita sa z RAM-ky mov RAMread,temp0 ;(najvyssi bit na 1 - aby sa hned premenna RAMread znulovala) ldi temp0,1 ;posli iba jeden byte rjmp ComposeEndXXXDescriptor ;a priprav data DoSetRS232Baud: lds temp0,InputBufferBegin+4 ;prvy parameter - hodnota baudrate na RS232 out UBRR,temp0 ;nastav rychlost UART-u rjmp OneZeroAnswer ;potvrd prijem jednou nulou DoGetRS232Baud: in R0,UBRR ;vrat rychlost UART-u v R0 rjmp DoGetIn ;a ukonci DoRS232Send: lds temp0,InputBufferBegin+4 ;prvy parameter - hodnota vysielana na RS232 out UDR,temp0 ;vysli data na UART WaitForRS232Send: sbis UCR,TXEN ;ak nie je povoleny UART vysielac rjmp OneZeroAnswer ;tak skonci - ochrana kvoli zacykleniu v AT90S2323/2343 sbis USR,TXC ;pockat na dovysielanie bytu rjmp WaitForRS232Send rjmp OneZeroAnswer ;potvrd prijem jednou nulou DoRS232Read: sbis USR,RXC ;ak je prijimaci register prazdny rjmp TwoZeroAnswer ;tak iba potvrd prijem dvoma nulami in R0,UDR ;inak nacitaj do R0 prijate data z UART-u ldi ZL,0 ;posiela sa hodnota v R0 ldi temp0,0x81 ;RAMread=1 - cita sa z RAM-ky mov RAMread,temp0 ;(najvyssi bit na 1 - aby sa hned premenna RAMread znulovala) ldi temp0,1 ;posli iba jeden byte sbic USR,OR ;ak bolo pretecenie prijimacieho buffera ldi temp0,3 ;posli 3 byty :prvy je prijata hodnota (na ostatnych nezalezi) rjmp ComposeEndXXXDescriptor ;tak priprav data ;----------------------------- END USER FUNCTIONS ---------------------------------- OneZeroAnswer: ;posle jednu nulu ldi temp0,1 ;pocet mojich bytovych odpovedi do temp0 rjmp ComposeGET_STATUS2 StandardRequest: cpi temp1,GET_STATUS ; breq ComposeGET_STATUS ; cpi temp1,CLEAR_FEATURE ; breq ComposeCLEAR_FEATURE ; cpi temp1,SET_FEATURE ; breq ComposeSET_FEATURE ; cpi temp1,SET_ADDRESS ;ak sa ma nastavit adresa breq ComposeSET_ADDRESS ;nastav adresu cpi temp1,GET_DESCRIPTOR ;ak sa ziada descriptor breq ComposeGET_DESCRIPTOR ;vygeneruj ho cpi temp1,SET_DESCRIPTOR ; breq ComposeSET_DESCRIPTOR ; cpi temp1,GET_CONFIGURATION ; breq ComposeGET_CONFIGURATION ; cpi temp1,SET_CONFIGURATION ; breq ComposeSET_CONFIGURATION ; cpi temp1,GET_INTERFACE ; breq ComposeGET_INTERFACE ; cpi temp1,SET_INTERFACE ; breq ComposeSET_INTERFACE ; cpi temp1,SYNCH_FRAME ; breq ComposeSYNCH_FRAME ; ;ak sa nenasla znama poziadavka rjmp ZeroDATA1Answer ;ak to bolo nieco nezname, tak priprav nulovu odpoved ComposeSET_ADDRESS: lds MyUpdatedAddress,InputBufferBegin+4 ;nova adresa do MyUpdatedAddress rjmp ZeroDATA1Answer ;posli nulovu odpoved ComposeSET_CONFIGURATION: lds ConfigByte,InputBufferBegin+4 ;cislo konfiguracie do premennej ConfigByte ComposeCLEAR_FEATURE: ComposeSET_FEATURE: ComposeSET_INTERFACE: ZeroStringAnswer: rjmp ZeroDATA1Answer ;posli nulovu odpoved ComposeGET_STATUS: TwoZeroAnswer: ldi temp0,2 ;pocet mojich bytovych odpovedi do temp0 ComposeGET_STATUS2: ldi ZH, high(StatusAnswer<<1) ;ROMpointer na odpoved ldi ZL, low(StatusAnswer<<1) rjmp ComposeEndXXXDescriptor ;a dokonci ComposeGET_CONFIGURATION: and ConfigByte,ConfigByte ;ak som nenakonfigurovany breq OneZeroAnswer ;tak posli jednu nulu - inak posli moju konfiguraciu ldi temp0,1 ;pocet mojich bytovych odpovedi do temp0 ldi ZH, high(ConfigAnswerMinus1<<1) ;ROMpointer na odpoved ldi ZL, low(ConfigAnswerMinus1<<1)+1 rjmp ComposeEndXXXDescriptor ;a dokonci ComposeGET_INTERFACE: ldi ZH, high(InterfaceAnswer<<1) ;ROMpointer na odpoved ldi ZL, low(InterfaceAnswer<<1) ldi temp0,1 ;pocet mojich bytovych odpovedi do temp0 rjmp ComposeEndXXXDescriptor ;a dokonci ComposeSYNCH_FRAME: ComposeSET_DESCRIPTOR: rcall ComposeSTALL ret ComposeGET_DESCRIPTOR: lds temp1,InputBufferBegin+5 ;DescriptorType do temp1 cpi temp1,DEVICE ;DeviceDescriptor breq ComposeDeviceDescriptor ; cpi temp1,CONFIGURATION ;ConfigurationDescriptor breq ComposeConfigDescriptor ; cpi temp1,STRING ;StringDeviceDescriptor breq ComposeStringDescriptor ; ret ComposeDeviceDescriptor: ldi ZH, high(DeviceDescriptor<<1) ;ROMpointer na descriptor ldi ZL, low(DeviceDescriptor<<1) ldi temp0,0x12 ;pocet mojich bytovych odpovedi do temp0 rjmp ComposeEndXXXDescriptor ;a dokonci ComposeConfigDescriptor: ldi ZH, high(ConfigDescriptor<<1) ;ROMpointer na descriptor ldi ZL, low(ConfigDescriptor<<1) ldi temp0,9+9+7 ;pocet mojich bytovych odpovedi do temp0 ComposeEndXXXDescriptor: lds TotalBytesToSend,InputBufferBegin+8 ;pocet pozadovanych bytov do TotalBytesToSend cp TotalBytesToSend,temp0 ;ak sa neziada viac ako mozem dodat brcs HostConfigLength ;vysli tolko kolko sa ziada mov TotalBytesToSend,temp0 ;inak posli pocet mojich odpovedi HostConfigLength: mov temp0,TotalBytesToSend ; clr TransmitPart ;nuluj pocet 8 bytovych odpovedi andi temp0,0b00000111 ;ak je dlzka delitelna 8-mimi breq Length8Multiply ;tak nezapocitaj jednu necelu odpoved (pod 8 bytov) inc TransmitPart ;inak ju zapocitaj Length8Multiply: mov temp0,TotalBytesToSend ; lsr temp0 ;dlzka 8 bytovych odpovedi sa dosiahne lsr temp0 ;delenie celociselne 8-mimi lsr temp0 add TransmitPart,temp0 ;a pripocitanim k poslednej necelej 8-mici do premennej TransmitPart ldi temp0,DATA0PID ;DATA0 PID - v skutocnosti sa stoggluje na DATA1PID v nahrati deskriptora sts OutputBufferBegin+1,temp0 ;nahraj do vyst buffera rjmp ComposeNextAnswerPart ComposeStringDescriptor: ldi temp1,4+8 ;ak RAMread=4(vkladaj nuly z ROM-koveho citania) + 8(za prvy byte nevkldadaj nulu) mov RAMread,temp1 lds temp1,InputBufferBegin+4 ;DescriptorIndex do temp1 cpi temp1,0 ;LANGID String breq ComposeLangIDString ; cpi temp1,2 ;DevNameString breq ComposeDevNameString ; brcc ZeroStringAnswer ;ak je DescriptorIndex vyssi nez 2 - posli nulovu odpoved ;inak to bude VendorString ComposeVendorString: ldi ZH, high(VendorStringDescriptor<<1) ;ROMpointer na descriptor ldi ZL, low(VendorStringDescriptor<<1) ldi temp0,(VendorStringDescriptorEnd-VendorStringDescriptor)*4-2 ;pocet mojich bytovych odpovedi do temp0 rjmp ComposeEndXXXDescriptor ;a dokonci ComposeDevNameString: ldi ZH, high(DevNameStringDescriptor<<1) ;ROMpointer na descriptor ldi ZL, low(DevNameStringDescriptor<<1) ldi temp0,(DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2 ;pocet mojich bytovych odpovedi do temp0 rjmp ComposeEndXXXDescriptor ;a dokonci ComposeLangIDString: clr RAMread ldi ZH, high(LangIDStringDescriptor<<1) ;ROMpointer na descriptor ldi ZL, low(LangIDStringDescriptor<<1) ldi temp0,(LangIDStringDescriptorEnd-LangIDStringDescriptor)*2;pocet mojich bytovych odpovedi do temp0 rjmp ComposeEndXXXDescriptor ;a dokonci ;------------------------------------------------------------------------------------------ ZeroDATA1Answer: rcall ComposeZeroDATA1PIDAnswer ret ;------------------------------------------------------------------------------------------ PrepareOutContinuousBuffer: rcall PrepareContinuousBuffer rcall MakeOutBitStuff ret ;------------------------------------------------------------------------------------------ PrepareContinuousBuffer: mov temp0,TransmitPart cpi temp0,1 brne NextAnswerInBuffer ;ak uz je buffer prazdny rcall ComposeZeroAnswer ;priprav nulovu odpoved ret NextAnswerInBuffer: dec TransmitPart ;znizit celkovu dlzku odpovede ComposeNextAnswerPart: mov temp1,TotalBytesToSend ;zniz pocet bytov na vyslanie subi temp1,8 ;ci je este treba poslat viac ako 8 bytov ldi temp3,8 ;ak ano - posli iba 8 bytov brcc Nad8Bytov mov temp3,TotalBytesToSend ;inak posli iba dany pocet bytov clr TransmitPart inc TransmitPart ;a bude to posledna odpoved Nad8Bytov: mov TotalBytesToSend,temp1 ;znizeny pocet bytov do TotalBytesToSend rcall LoadXXXDescriptor ldi ByteCount,2 ;dlzka vystupneho buffera (iba SOP a PID) add ByteCount,temp3 ;+ pocet bytov rcall AddCRCOut ;pridanie CRC do buffera inc ByteCount ;dlzka vystupneho buffera + CRC16 inc ByteCount ret ;skonci ;------------------------------------------------------------------------------------------ .equ USBversion =0x0100 ;pre aku verziu USB je to (1.00) .equ VendorUSBID =0x03EB ;identifikator dodavatela (Atmel=0x03EB) .equ DeviceUSBID =0x0002 ;identifikator vyrobku (USB dialkove ovladanie=0x0002) .equ DeviceVersion =0x0001 ;cislo verzie vyrobku (verzia=0.01) .equ MaxUSBCurrent =40 ;prudovy odber z USB (40mA) ;------------------------------------------------------------------------------------------ DeviceDescriptor: .db 0x12,0x01 ;0 byte - velkost deskriptora v bytoch ;1 byte - typ deskriptora: Deskriptor zariadenia .dw USBversion ;2,3 byte - verzia USB LSB (1.00) .db 0x00,0x00 ;4 byte - trieda zariadenia ;5 byte - podtrieda zariadenia .db 0x00,0x08 ;6 byte - kod protokolu ;7 byte - velkost FIFO v bytoch .dw VendorUSBID ;8,9 byte - identifikator dodavatela (Cypress=0x04B4) .dw DeviceUSBID ;10,11 byte - identifikator vyrobku (teplomer=0x0002) .dw DeviceVersion ;12,13 byte - cislo verzie vyrobku (verzia=0.01) .db 0x01,0x02 ;14 byte - index stringu "vyrobca" ;15 byte - index stringu "vyrobok" .db 0x00,0x01 ;16 byte - index stringu "seriove cislo" ;17 byte - pocet moznych konfiguracii DeviceDescriptorEnd: ;------------------------------------------------------------------------------------------ ConfigDescriptor: .db 0x9,0x02 ;dlzka,typ deskriptoru ConfigDescriptorLength: .dw 9+9+7 ;celkova dlzka vsetkych deskriptorov ConfigAnswerMinus1: ;pre poslanie cisla congiguration number (pozor je treba este pricitat 1) .db 1,1 ;numInterfaces,congiguration number .db 0,0x80 ;popisny index stringu, atributy;bus powered .db MaxUSBCurrent/2,0x09 ;prudovy odber, interface descriptor length .db 0x04,0 ;interface descriptor; cislo interface InterfaceAnswer: ;pre poslanie cisla alternativneho interface .db 0,1 ;alternativne nastavenie interface; pocet koncovych bodov okrem EP0 StatusAnswer: ;2 nulove odpovede (na usetrenie miestom) .db 0,0 ;trieda rozhrania; podtrieda rozhrania .db 0,0 ;kod protokolu; index popisneho stringu .db 0x07,0x5 ;dlzka,typ deskriptoru - endpoint .db 0x81,0 ;endpoint address; transfer type .dw 0x08 ;max packet size .db 10,0 ;polling interval [ms]; dummy byte (pre vyplnenie) ConfigDescriptorEnd: ;------------------------------------------------------------------------------------------ LangIDStringDescriptor: .db (LangIDStringDescriptorEnd-LangIDStringDescriptor)*2,3 ;dlzka, typ: string deskriptor .dw 0x0409 ;English LangIDStringDescriptorEnd: ;------------------------------------------------------------------------------------------ VendorStringDescriptor: .db (VendorStringDescriptorEnd-VendorStringDescriptor)*4-2,3 ;dlzka, typ: string deskriptor CopyRight: .db "Ing. Igor Cesko, Copyright(c) 2003" CopyRightEnd: VendorStringDescriptorEnd: ;------------------------------------------------------------------------------------------ DevNameStringDescriptor: .db (DevNameStringDescriptorEnd-DevNameStringDescriptor)*4-2,3;dlzka, typ: string deskriptor .db "IgorPlug-USB (AVR)" DevNameStringDescriptorEnd: ;------------------------------------------------------------------------------------------ MaskPortData: bst ACC,0 bld temp0,LEDlsb0 bst ACC,1 bld temp0,LEDlsb1 bst ACC,2 bld temp0,LEDlsb2 bst ACC,3 bld temp1,LEDmsb3 bst ACC,4 bld temp1,LEDmsb4 bst ACC,5 bld temp1,LEDmsb5 bst ACC,6 bld temp1,LEDmsb6 bst ACC,7 bld temp1,LEDmsb7 ret ;------------------------------------------------------------------------------------------ SetDataPortDirection: in temp0,LEDdirectionLSB ;nacitaj aktualny stav LSB do temp0 (aby sa nezmenili ostatne smery bitov) in temp1,LEDdirectionMSB ;nacitaj aktualny stav MSB do temp1 (aby sa nezmenili ostatne smery bitov) rcall MaskPortData out LEDdirectionLSB,temp0 ;a update smeru LSB datoveho portu out LEDdirectionMSB,temp1 ;a update smeru MSB datoveho portu ret ;------------------------------------------------------------------------------------------ SetOutDataPort: in temp0,LEDPortLSB ;nacitaj aktualny stav LSB do temp0 (aby sa nezmenili ostatne bity) in temp1,LEDPortMSB ;nacitaj aktualny stav MSB do temp1 (aby sa nezmenili ostatne bity) rcall MaskPortData out LEDPortLSB,temp0 ;a update LSB datoveho portu out LEDPortMSB,temp1 ;a update MSB datoveho portu ret ;------------------------------------------------------------------------------------------ GetInDataPort: in temp0,LEDPinMSB ;nacitaj aktualny stav MSB do temp0 in temp1,LEDPinLSB ;nacitaj aktualny stav LSB do temp1 MoveLEDin: bst temp1,LEDlsb0 ;a daj bity LSB na spravne pozicie (z temp1 do temp0) bld temp0,0 ;(bity MSB su na spravnom mieste) bst temp1,LEDlsb1 bld temp0,1 bst temp1,LEDlsb2 bld temp0,2 mov R0,temp0 ;a vysledok uloz do R0 ret ;------------------------------------------------------------------------------------------ GetOutDataPort: in temp0,LEDPortMSB ;nacitaj aktualny stav MSB do temp0 in temp1,LEDPortLSB ;nacitaj aktualny stav LSB do temp1 rjmp MoveLEDin ;------------------------------------------------------------------------------------------ GetDataPortDirection: in temp0,LEDdirectionMSB ;nacitaj aktualny stav MSB do temp0 in temp1,LEDdirectionLSB ;nacitaj aktualny stav LSB do temp1 rjmp MoveLEDin ;------------------------------------------------------------------------------------------ EEPROMWrite: out EEAR,ZL ;nastav adresu EEPROM out EEDR,R0 ;nastav data do EEPROM cli ;zakaz prerusenie sbi EECR,EEMWE ;nastav master write enable sei ;povol prerusenie (este sa vykona nasledujuca instrukcia) sbi EECR,EEWE ;samotny zapis WaitForEEPROMReady: sbic EECR,EEWE ;pockaj si na koniec zapisu rjmp WaitForEEPROMReady ;v slucke (max cca 4ms) (kvoli naslednemu citaniu/zapisu) rjmp OneZeroAnswer ;potvrd prijem jednou nulou ;------------------------------------------------------------------------------------------ ;******************************************************************** ;* End of Program ;******************************************************************** ;------------------------------------------------------------------------------------------ ;******************************************************************** ;* EEPROM contents ;******************************************************************** ;------------------------------------------------------------------------------------------ .eseg ;data v EEPROM-ke (vo finalnej verzii zapoznamkovat) ;.org 0x400 ;pre naplnenie EEPROM dat na spravne adresy - hned za kod programu (vo finalnej verzii odpoznamkovat) EEData: .db "This device was developed by Ing. Igor Cesko: cesko@internet.sk " .db "For more information see: http://www.cesko.host.sk. " .db "S/N:00000001" ;------------------------------------------------------------------------------------------ ;******************************************************************** ;* End of file ;********************************************************************