Ausgangspunkt ist ein ATmega32U4 mit 16-MHz-Quarz,
verbaut in Arduino Leonardo
und Nachfolgern,
etwa dem sehr preiswerten Pro Micro
.
FĂĽr die zeitkritischen Routinen kommt nur Assembler in Frage.
Zur Kombination mit gcc wird der
Gnu-Assembler-Dialekt gas verwendet,
nicht avrasm.
So ungefähr sollte es aussehen:
// Als Makro, Unterprogrammaufrufe sind beim AVR lahm und fressen 9 Takte // Vorgehaltene Register: // R16 = Word-Zähler 32..0, -1 = Commit, -2 = nächster Datenblock // R3 = USB-Block-Zähler, 7..0 (bei Sektorlänge 512 Byte) // X = Datenquelle (Sektordaten) im RAM // UENUM steht bereits richtig .macro usb_write retlbl ;Rücksprungziel als Argumentsubi r16, 1 ;herunterzählen mit Carry-Flagbrmi 1f ;(negativ)ld r24,X+ sts UEDATX,r24 ld r24,X+ sts UEDATX,r24 rjmp \retlbl ;Σ 12 Takte (ohne Ansprung) 1 : brcs2f ldi r16,- 2 ;-2 wiederherstellensbrc r3, 7 ;Weitere USB-Blöcke?rjmp \retlbl ;Σ 8 Takte (nein wenn negativ) lds r24,UEINTX sbrc r24, 7 ;wenn FIFO bereit …ldi r16, 32 ;… 32 WORDs schreiben lassenrjmp \retlbl ;Σ 13 Takte 2 : ldi r24,0x7E sts UEINTX,r24 ;Commit dec r3 rjmp \retlbl ;Σ 11 Takte .endm