Forum: Mikrocontroller und Digitale Elektronik vusb auf tiny2313: Timing Problem


von Dieter R. (Firma: Paul Scherrer Institut) (beerserc)


Angehängte Dateien:

Lesenswert?

Hi,

ich habe hier mit einem tiny2313 und vusb eine Schaltung zum Senden von 
TTL pulsen gebaut. Funktioniert auch alles soweit, nur bekomme ich die 
Länge der Pulse nicht in den Griff.

Wenn ich mit dem Oszilloskop drauf schaue, sehe ich zu ca. 50% etwa die 
Pulslänge die ich eingestellt habe, und beim Rest der Pulse etwa 4.5-5 
mal die gewünschte Dauer.

Ursprünglich hatte ich die Pulslänge über _delay_ms() gesteuert, weil es 
dann aber auch schon nicht zuverlässig war, habe ich es jetzt auf einen 
Timer umgestrickt.

Die Firmware basiert auf dem hid-custum-rq Beispiel aus der neusten vusb 
Version. Ich habe ein neues Request definiert, und übergebe die 
gewünschte Länge des Pulses dort.

Die komplette main.c hängt an, hier die (denke ich) relevanten Teile:
1
usbMsgLen_t usbFunctionSetup(uchar data[8]){
2
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR){
3
4
<cut ... >
5
6
    }else if(rq->bRequest == CUSTOM_RQ_SEND_TTL){
7
        int length,i;
8
        length=*(rq->wValue.bytes);
9
        TCNT1 = 0xFFFF-length;
10
        LED_PORT_OUTPUT |= _BV(TOGGLE_BIT); /* TTL High */
11
        TCCR1B =(1<<CS11); /* Start counter */
12
    }
13
}
14
15
<cut ... >
16
17
int __attribute__((noreturn)) main(void)
18
{
19
<cut ... >
20
    usbDeviceConnect();
21
    LED_PORT_DDR |= _BV(LED_BIT | TOGGLE_BIT);   /* make the LED bit an output */
22
    sei();
23
    TIMSK = (1<<TOIE1);
24
    TCNT1 = 0x0000;*/
25
    for(;;){                /* main event loop */
26
        wdt_reset();
27
        usbPoll();
28
    }
29
}
30
ISR(TIMER1_OVF_vect)
31
{
32
        TCCR1B=0x00; /* Stop Counter */
33
        LED_PORT_OUTPUT &= ~_BV(TOGGLE_BIT); /* TTL Low */
34
}

Wie kann das sein, dass ich zwischen TTL High und TTL Low verschieden 
lange Zeiten sehe?

Clock ist 12MHz extern, d.h. ich sollte auch noch einen Faktor 1.5 
zwischen Eingabe in der Host Software und echter Puslslänge sehen, das 
ist aber auch nicht so. Das wäre aber konstant nicht tragisch. Nur dass 
viele Pulse so viel länger werden geht nicht.


Schöne Grüsse,

Dieter

von holger (Gast)


Lesenswert?

>Wie kann das sein, dass ich zwischen TTL High und TTL Low verschieden
>lange Zeiten sehe?

Was erwartest du von einem Controller der eigentlich gar kein
USB kann? Der ist doch zu 80% nur mit dem USB Geraffel beschäftigt.

Wenn du genaue Zeiten willst dann verabschiede dich von vusb.

von Thomas E. (thomase)


Lesenswert?

Dieter Ries schrieb:
> habe ich es jetzt auf einen Timer umgestrickt.
Aber du hast nur halben Kram gemacht.
Um Pulse zu erzeugen, benutzt man den CTC-Mode des Timers und lässt das 
Schalten des Ausgangs von der Hardware erledigen. Dann kann das USB 
Rechenzeit, wie es lustig ist, verbraten. Das interessiert dann nicht.

mfg.

von Dieter R. (Firma: Paul Scherrer Institut) (beerserc)


Lesenswert?

@holger: klar erwarte ich von dem Kleinen keine Höchstleistungen, aber 
ein counter sollte davon ja nicht betroffen sein, und da das USB zeugs 
keine Interrupts macht, sollte es sehr selten vorkommen, dass es genau 
zwischen das Hochziehen des Pins und das starten des Timers funkt. Aber 
es scheint, dass ich da was nicht fertig gemacht habe.

@Thomas Eckmann: Ich dachte, das hätte ich so gut wie möglich gemacht, 
aber es scheint, dass mir da was entgangen ist.

Ich werd allerdings aus der Beschreibung im Datenblatt nicht 100%ig 
schlau, wie ich dass damit lösen soll. Gibt's dazu irgendwo Beispiele 
oder ausführlichere Doku?

Schöne Grüsse und schon mal danke für die Hilfe,

Dieter

von Karl H. (kbuchegg)


Lesenswert?

Dieter Ries schrieb:
> @holger: klar erwarte ich von dem Kleinen keine Höchstleistungen, aber
> ein counter sollte davon ja nicht betroffen sein, und da das USB zeugs
> keine Interrupts macht,

es reicht, wenn das USB Zeugs zum richtigen Zeitpunkt die Interrupts 
mittels cli() abstellt und nach einer gewissen Zeit mittels sei() wieder 
einschaltet.

Dünnes Eis:
Und da das USB Timing eher von der happigen Sorte ist, kann ich mir 
schon vorstellen, dass der Code genau das immer wieder mal macht.

von holger (Gast)


Lesenswert?

>und da das USB zeugs keine Interrupts macht,

Und wovon träumst du Nachts? Das USB Zeugs macht jede
Menge Interrupts. Das auch noch auf Int0 oder Int1?
Die haben höchste Priorität beim ATTiny2313.
Dein Timer kommt da nur noch mal so nebenbei dran.

von Dieter R. (Firma: Paul Scherrer Institut) (beerserc)


Lesenswert?

ui, heute freundlich...

stimmt, dass es am Int1 hängt hab ich übersehen, cli()s sind keine im 
code, danach hatte ich geschaut.

Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das 
scheint mir schon recht viel.

Anyway, ich denke das Problem muss sich lösen lassen, zumal es mir nicht 
auf's exakte Timing, wann der Puls ankommt, sondern nur auf die 
Pulslänge ankommt. Ich werd mal in die Sache mit dem CTC reinschauen, 
vielleicht hilft das.

Schöne Grüsse,

Dieter

von holger (Gast)


Lesenswert?

>ui, heute freundlich...

Du hast mich an einem guten Tag erwischt;)
Ich kann noch ganz anders.

>stimmt, dass es am Int1 hängt hab ich übersehen, cli()s sind keine im
>code, danach hatte ich geschaut.

Das braucht man in einem Interrupt nicht.

>Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das
>scheint mir schon recht viel.

Das ist völlig irrelevant was dir viel erscheint.
Dieser Software USB Kram verbrennt halt einiges an Rechenzeit.

von Karl H. (kbuchegg)


Lesenswert?

Dieter Ries schrieb:

> Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das
> scheint mir schon recht viel.

Ich kenn jetzt die USB Spec nicht, ob das zulässig ist bzw. ob du da 
Probleme bekommst.
Aber du kannst ja mal versuchen, die Aufrufe von usbPoll() auszusetzen, 
während du den Puls laufen lässt.


Aber im Grunde stimmt das schon. Den Puls kann dir der Timer ganz 
alleine auch erzeugen. Allerdings ist das dann ein PWM Modus. Das 
einzige Problem sehe ich eigentlich darin, dass du eine Obergrenze für 
die Pulslänge hast, weil du einplanen musst, dass der Timer rechtzeitig 
gestoppt werden muss, ehe er in den nächsten PWM-Zyklus geht. So etwas 
wie eine "One-Puls"-PWM gibt es leider nicht.

von Uwe (de0508)


Lesenswert?

Man könnte noch den Takt erhöhen.
Die aktuelle Version gibt es hier: 
http://www.obdev.at/downloads/vusb/vusb-20120109.zip.

von Dieter R. (Firma: Paul Scherrer Institut) (beerserc)


Lesenswert?

@holger: da hab ich ja noch mal Glück gehabt. War im Endeffekt auch 
genau das Problem, die Interrupts haben dazwischengefunkt.

@Uwe S.: Ich benutze schon die neuste Version. Und von 12MHz auf 20MHz, 
was wieder Timingschwierigkeiten mit dem USB mit sich bringen dürfte, 
würde das Problem ja auch nur weniger häufig auftreten lassen.

Vorerst läuft das ganze jetzt, ich disable das entsprechende Interrupt 
während ich den Puls mache, so kommt es zwar manchmal zu broken pipe 
fehlern in der USB Kommunikation, aber das erholt sich wieder, und meine 
Pulse werden halbwegs genau generiert.

Ich glaube ich schau mir das aber trotzdem noch mal über PWM an.

Schöne Grüsse

von Oliver J. (skriptkiddy)


Lesenswert?

Nimm doch einen zweiten AVR zum erzeugen der Pulse.

Gruß Oliver

von peter (Gast)


Lesenswert?

Hallo,

ich habe ein ähnliches Problem mit dem VUSB und dem Timer Overflow 
Interrupt.
Scheinbar schein mein Overflow Interrupt das USB und dadurch das 
Speichern von Variablen etwas durcheinander zu bringen. Mal klappt alles 
doch meistens nicht.

In meinem Fall verwende ich die beiden Timer des Tiny44 im FastPWM mode.
Jetzt wollte ich noch nen laufenden Timr haben und dafür im Overflow ISR 
einfach eine Variable hochzählen und in der Main loop abfragen.
Leider klappt das nicht zuverlässig.

Daher die Frage, wie man bei Nutzung von VUSB noch irgendwie mit den 
Timer ISRs arbeiten kann.

Hier wäre ich um Tipps sehr dankbar.

von c-hater (Gast)


Lesenswert?

Dieter Ries schrieb:

> Davon abgesehen sind 40µs Verzögerung knapp 500 Clock Cycles', das
> scheint mir schon recht viel.

Ist es nicht. VUSB arbeitet immer eine komplette 
LowSpeed-USB-Transaktion in einer einzigen ISR ab. Das sind (Kleinkram 
wie Reaktionszeiten nicht mitgerechnet) bis zu 96 USB-Bits bei einer 
Bitrate von 1,5MBit/s.

Rechnen kannst du alleine? Wenn's schon zum Lesen der Quelltexte nicht 
reicht...

Da steht die Arbeitsweise von VUSB nämlich auch als recht umfangreicher 
Kommentar drinne...

von peter (Gast)


Lesenswert?

@c-hater: der Kommentar war wohl eher auf die vorherigen Post bezogen. 
Da dies schon etwas zurück liegt, scheint das Problem bei Herrn Ries als 
erledigt.

Sollte dies nicht der Fall sein, bitte ich um eine kurze Erläuterung 
zwischen dem Zusammenhang zu dem Post vom 20.10.2013

Grüße
Peter

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.