Hjälp med USB-kommunikation och timer interrupt
Hjälp med USB-kommunikation och timer interrupt
Jag håller på med ett projekt med en USB styrd radiosändare, liknande TELstick, som styrs av en PIC18F25K50. Hittills har jag lyckats få både dataströmmen till radiomodulen och USB kommunikationen till PC att fungera var för sig. Dataströmmen till radiomodulen sköts med interrupt med 300µs mellanrum där jag beroende på hur dataströmmen ser ut togglar en pinne. USB kommunikationen är mer eller mindre Microchips CDC basic demo exempel där den interrupt drivna varianten används.
Det stora problemet kom när jag lade ihop de båda funktionerna i ett och samma projekt. Då ville PICen inte längre ansluta till PCn via USB och interrupten fungerade inte heller. Gissar på att anledningen till att det inte fungerar är att interrupten stör varandra på något sätt. USB kommunikationen lär väl vara ganska känslig och kräver sitt interrupt varje 1 ms. Men jag tycker ändå det borde fungera då Timer0 interruptet bara togglade en diod och borde således inte ta särskilt lång tid att köra igenom. Men det är väl några goto-instruktioner för att nå interruptet som tar tid också kanske. USB interruptet är satt som high-priority och Timer0 som low-priority. Radioprotokollet är Manchester-kodat och klarar ganska så stor spridning. Om det varierar mellan 275 µs och 325 µs spelar inte så stor roll.
Nu är frågan, hur löser jag detta? Har funderat och kommit fram till några alternativ men tänkte även höra med er hur ni skulle löst det? USB och timerinterrupt måste ju gå att köra samtidigt?
De alternativ jag kommit på är..
-Använda Capture/Compare/PWM modulen. Har dock ingen erfarenhet av denna och har därför svårt att bedöma om det kommer fungera eller inte. Tanken är då att istället för att ha en dataström bestående av 1or och 0or göra en ström av tidsintervall som sedan laddas in i CCP modulens compare register och bestämmer när datat ska toggla.
-Är det möjligt att stänga ner USB kommunikationen? I så fall skulle en ide kunna vara att efter mottagen dataström från PCn stänga av USB interrupten och därefter sköta kommunikationen via Timer0 interrupt till radiomodulen. När hela datastömmen är ivägskickad återupptas USB interrupten igen. Ett möjligt problem med denna lösning är att enheten ska drivas av USB-bussen. Suspend-mode får alltså inte användas då det begränsar strömförbrukningen till 2.5 mA.
-Just nu används den inbyggda klockan på 16 MHz. Jag har möjlighet att montera en extern kristall på 48 MHz och använda denna. Det skulle ge 3 gånger snabbare beräkningar och kanske kan man då klara av interrupten tillräckligt snabbt för att hinna serva nästa.
Ge mig gärna era synpunkter. Hur har ni löst liknande problem?
Det stora problemet kom när jag lade ihop de båda funktionerna i ett och samma projekt. Då ville PICen inte längre ansluta till PCn via USB och interrupten fungerade inte heller. Gissar på att anledningen till att det inte fungerar är att interrupten stör varandra på något sätt. USB kommunikationen lär väl vara ganska känslig och kräver sitt interrupt varje 1 ms. Men jag tycker ändå det borde fungera då Timer0 interruptet bara togglade en diod och borde således inte ta särskilt lång tid att köra igenom. Men det är väl några goto-instruktioner för att nå interruptet som tar tid också kanske. USB interruptet är satt som high-priority och Timer0 som low-priority. Radioprotokollet är Manchester-kodat och klarar ganska så stor spridning. Om det varierar mellan 275 µs och 325 µs spelar inte så stor roll.
Nu är frågan, hur löser jag detta? Har funderat och kommit fram till några alternativ men tänkte även höra med er hur ni skulle löst det? USB och timerinterrupt måste ju gå att köra samtidigt?
De alternativ jag kommit på är..
-Använda Capture/Compare/PWM modulen. Har dock ingen erfarenhet av denna och har därför svårt att bedöma om det kommer fungera eller inte. Tanken är då att istället för att ha en dataström bestående av 1or och 0or göra en ström av tidsintervall som sedan laddas in i CCP modulens compare register och bestämmer när datat ska toggla.
-Är det möjligt att stänga ner USB kommunikationen? I så fall skulle en ide kunna vara att efter mottagen dataström från PCn stänga av USB interrupten och därefter sköta kommunikationen via Timer0 interrupt till radiomodulen. När hela datastömmen är ivägskickad återupptas USB interrupten igen. Ett möjligt problem med denna lösning är att enheten ska drivas av USB-bussen. Suspend-mode får alltså inte användas då det begränsar strömförbrukningen till 2.5 mA.
-Just nu används den inbyggda klockan på 16 MHz. Jag har möjlighet att montera en extern kristall på 48 MHz och använda denna. Det skulle ge 3 gånger snabbare beräkningar och kanske kan man då klara av interrupten tillräckligt snabbt för att hinna serva nästa.
Ge mig gärna era synpunkter. Hur har ni löst liknande problem?
Re: Hjälp med USB-kommunikation och timer interrupt
Har du verifierat ATT interrupten kommer?
- PHermansson
- EF Sponsor
- Inlägg: 4340
- Blev medlem: 22 december 2004, 00:46:38
- Ort: Särestad Grästorp
- Kontakt:
Re: Hjälp med USB-kommunikation och timer interrupt
När jag experimenterade med USB-Pic för några år sedan kom jag fram till att USB-kommunikationen är mycket tidskritisk. Interrupts gav alltid problem, lösningen var att använda en State Machine.
Re: Hjälp med USB-kommunikation och timer interrupt
Icecap/ Har felsökt lite under kvällen och kommit fram till följande. Jag har lyckats köra USB kommunikation och Timer0 interrupts samtidigt så länge jag inte använder prescaler. Det ger mig interrupts varje 2.5µs. Men, så fort jag försöker använda mig av prescaler till Timer0 så vägrar enheten att enumerera via USB och USB interrupten slutar komma. Dock verkar inte prescalern ge någon effekt då interrupten fortfarande kommer varje 2.5µs.
Edit: Ska forska vidare lite vad det verkligen är som ge interrupten. Frågan är om det verkligen är Timer0..
Edit: Ska forska vidare lite vad det verkligen är som ge interrupten. Frågan är om det verkligen är Timer0..
Senast redigerad av foal 19 november 2013, 10:13:13, redigerad totalt 1 gång.
Re: Hjälp med USB-kommunikation och timer interrupt
PHermansson/ Vet inte riktigt hur jag ska lyckas få till en statemaskin som gör det jag vill. Behöver ju någon form av time-beat för att kunna hoppa i statemaskinen och det uppnås ju lättast med interrupt.
-
- Inlägg: 1045
- Blev medlem: 2 juli 2010, 23:04:07
Re: Hjälp med USB-kommunikation och timer interrupt
Jag kan inte mycket om PIC, men jag kom på några hypoteser som du skulle kunna arbeta för att avfärda:
* Skriver USB-koden och din kod över varandras bittar i något register?
* Hur ser USB-koden ut, och hur skickar den data? Finns det någon kodsnutt där den stänger av interrupts och sitter och busy-wait'ar på något eller dröjer tidsintervall?
* Om du använder full-speed USB, skulle du kunna gå ner till low-speed?
* Om du använder C, hur mycket overhead har din snabba interruptrutin? Skulle det hjälpa att skriva om den i maskinkod?
* Skriver USB-koden och din kod över varandras bittar i något register?
* Hur ser USB-koden ut, och hur skickar den data? Finns det någon kodsnutt där den stänger av interrupts och sitter och busy-wait'ar på något eller dröjer tidsintervall?
* Om du använder full-speed USB, skulle du kunna gå ner till low-speed?
* Om du använder C, hur mycket overhead har din snabba interruptrutin? Skulle det hjälpa att skriva om den i maskinkod?
Re: Hjälp med USB-kommunikation och timer interrupt
Tack för dina hypoteser. Jag har utgått från en exempelkod som går att få från processortillverkaren. Exemplet innehåller en USB stack som består av ganska så mycket kod och jag har inte haft tid att på djupet gå igenom all kod. Vet inte om jag kan förstå allt heller. Så det är inte helt omöjligt att exempelkoden sätter någon bit som jag sedan är inne och ändrar på.
Hur som helst lyckades jag lokalisera källan till 2.5µs interrupten. Det visade sig inte vara Timer0 utan Active Clock Tuning interrupt. USB koden använder sig av PICens inbyggda kristall som tunas efter USB host controllern om jag förstått det rätt. Varje gång det sedan sker ett Active Tuning Event fås ett interrupt. Detta är ingen funktion jag själv valt att sätta igång så jag får helt enkelt gå igenom koden rad för rad och se vart detta aktiveras och då stänga av den och se om det blir bättre.
Är det någon som har någon erfarenhet med att köra med en intern kristall? Någon som vet något mer om Active Tuning Event, vad dom är till för t.ex.? Databladet gav inte särskilt mycket information.
Hur som helst lyckades jag lokalisera källan till 2.5µs interrupten. Det visade sig inte vara Timer0 utan Active Clock Tuning interrupt. USB koden använder sig av PICens inbyggda kristall som tunas efter USB host controllern om jag förstått det rätt. Varje gång det sedan sker ett Active Tuning Event fås ett interrupt. Detta är ingen funktion jag själv valt att sätta igång så jag får helt enkelt gå igenom koden rad för rad och se vart detta aktiveras och då stänga av den och se om det blir bättre.
Är det någon som har någon erfarenhet med att köra med en intern kristall? Någon som vet något mer om Active Tuning Event, vad dom är till för t.ex.? Databladet gav inte särskilt mycket information.
Re: Hjälp med USB-kommunikation och timer interrupt
> med att köra med en intern kristall?
Intern oscillator. Ingen processor har "intern kristall"...
OK, så detta är alltså en av de rellativt nya USB-PIC'arna som är specificerade
att kunna köra från interna oscillatorn. Ja, de har en automatisk "tuning" med
hjälp av timingen på USB bussen, se styckena 3.15 till 3.22.
Ja, ACT modulen kan generera interrupt vid vissa händelser (som du
har upptäckt), men det bör inte vara så ofta som du anger. Det står
även att man kan stänga interrupten via ACTIE flaggen, då snurrar ACT
på i bakgrunden utan att man har någon speciell koll på det.
Å andra sidan så genereras enbart interrupt då en av två händelser inträffar:
"The ACTLOCK bit will be set to ‘1’, when the 16 MHz internal oscillator is successfully tuned..."
"If the ACT module requires an OSCTUNE value outside the range to achieve ± 0.20% accuracy,
then the ACT Out-of-Range (ACTORS) Status bit will be set to ‘1’.
Så om allt fungerar normalt så ger det kanske ett interrupt i början (då modulen
"låser"), men sedan bör det vara lungt. Det låter lite som att du kanske har
ACT interrupt påslaget, men du clearar aldring ACTIF flaggan. Då kommer
detta interrupt att triggas om och om igen hela tiden. Man kan även stänga av
ACT helt (efter att den har "låst" mot USB signalen) och sedan kan man vänta
på ett ACTORS "Out of range" interrupt och låta modulen "tune'a om sig" igen genom
att tillfälligt slå på ACT. Det framgår dock inte vad fördelen skulle vara med detta.
Se "3.20 Active Clock Tuning Update Disable".
Så min fråga är om det kan vara detta: "The ACTIF bit must be cleared in software,
regardless of the interrupt enable setting."
Intern oscillator. Ingen processor har "intern kristall"...
OK, så detta är alltså en av de rellativt nya USB-PIC'arna som är specificerade
att kunna köra från interna oscillatorn. Ja, de har en automatisk "tuning" med
hjälp av timingen på USB bussen, se styckena 3.15 till 3.22.
Ja, ACT modulen kan generera interrupt vid vissa händelser (som du
har upptäckt), men det bör inte vara så ofta som du anger. Det står
även att man kan stänga interrupten via ACTIE flaggen, då snurrar ACT
på i bakgrunden utan att man har någon speciell koll på det.
Å andra sidan så genereras enbart interrupt då en av två händelser inträffar:
"The ACTLOCK bit will be set to ‘1’, when the 16 MHz internal oscillator is successfully tuned..."
"If the ACT module requires an OSCTUNE value outside the range to achieve ± 0.20% accuracy,
then the ACT Out-of-Range (ACTORS) Status bit will be set to ‘1’.
Så om allt fungerar normalt så ger det kanske ett interrupt i början (då modulen
"låser"), men sedan bör det vara lungt. Det låter lite som att du kanske har
ACT interrupt påslaget, men du clearar aldring ACTIF flaggan. Då kommer
detta interrupt att triggas om och om igen hela tiden. Man kan även stänga av
ACT helt (efter att den har "låst" mot USB signalen) och sedan kan man vänta
på ett ACTORS "Out of range" interrupt och låta modulen "tune'a om sig" igen genom
att tillfälligt slå på ACT. Det framgår dock inte vad fördelen skulle vara med detta.
Se "3.20 Active Clock Tuning Update Disable".
Så min fråga är om det kan vara detta: "The ACTIF bit must be cleared in software,
regardless of the interrupt enable setting."
Re: Hjälp med USB-kommunikation och timer interrupt
Sodjan/ Ber om ursäkt för kristall/oscillator tabben.
Tack för informationen. Det är mycket troligt att du har rätt. Eftersom jag inte vetat vilken källa som givit interruptet har jag inte kunnat cleara rätt flagga. Gjorde en felsökning igår genom att skapa en if-sats i interruptrutinen innehållande alla flaggor. Sedan körde jag uteslutningsmetoden tills det bara var en flagga kvar. Sen var det dock läggdags så jag hann aldrig testas något mer.
Felet stämmer väldigt bra med informationen. Första interruptet fås när den interna oscillatorn tunas och eftersom flaggan inte clearas fås ett nytt interrupt så fort interruptrutinen avslutats.
Jag ska testa detta så fort jag kommer hem. Stort tack för informationen!
Tack för informationen. Det är mycket troligt att du har rätt. Eftersom jag inte vetat vilken källa som givit interruptet har jag inte kunnat cleara rätt flagga. Gjorde en felsökning igår genom att skapa en if-sats i interruptrutinen innehållande alla flaggor. Sedan körde jag uteslutningsmetoden tills det bara var en flagga kvar. Sen var det dock läggdags så jag hann aldrig testas något mer.
Felet stämmer väldigt bra med informationen. Första interruptet fås när den interna oscillatorn tunas och eftersom flaggan inte clearas fås ett nytt interrupt så fort interruptrutinen avslutats.
Jag ska testa detta så fort jag kommer hem. Stort tack för informationen!
Re: Hjälp med USB-kommunikation och timer interrupt
> ...och eftersom flaggan inte clearas fås ett nytt interrupt så fort interruptrutinen avslutats.
Det är exakt det som händer om xxIF flaggorna *inte* nollas före "return from interrupt" !
Det är inget unikt för ACT modulen så klart, det är samma sak för *alla* interruptkällor.
Som sagt, efter att ACT modulen har synkat så ska det inte inträffa fler
interrupt alls (i princip). Om inte något går helt fel i ACT modulen.
Det är exakt det som händer om xxIF flaggorna *inte* nollas före "return from interrupt" !
Det är inget unikt för ACT modulen så klart, det är samma sak för *alla* interruptkällor.
Som sagt, efter att ACT modulen har synkat så ska det inte inträffa fler
interrupt alls (i princip). Om inte något går helt fel i ACT modulen.
Re: Hjälp med USB-kommunikation och timer interrupt
Testat vidare lite nu. Riktigt pinsamt att missa på interruptflaggorna. Tack Sodjan för påminnelsen!