Hauptmenü

 

Login



 
 

Content

Seiten: [1]   Nach unten
Autor Thema: Wieder mal USB  (Gelesen 996 mal)
BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« am: Juni 23, 2010, 14:04:34 »
ZitierenZitat

Moin,

ich kämpfe mit USB.
Ich versuche das Bootloader-Beispiel von Sprut (http://sprut.de/electronic/pic/8bit/18f/programm/usbbootloader/usbboot.htm#1) auf einer eigenen Platine zum laufen zu bringen.

Die Platine "lebt" inzwischen. Der Pic taktet ordentlich und ohne die USB-Geschichte macht er zu Testzwecken auch eine LED an und aus. Den Schalter, wonach der Pic beim Booten erst guckt, ob er per Bootloader neue Daten kriegt, habe ich zunächst auskommentiert. Also enabelt er als erstes die USB-Schnittstelle. Dadurch schaltet er auch das "D+"-Pin auf 3,3 V(gemessen 2,89V). Nun hatte ich gedacht, dass der Host diese 3,3V sieht und damit weiß, dass da was dranhängen muß. Anschließend müßte er doch diese USB-Schnittstelle ansprechen. Oder ist diese Denke falsch?
Jedenfalls merkt Windows auch nichts von einem neuen Gerät. Es müßte ja eigentlich nach einem Treiber fragen.

Darauf habe ich mich mit dem Debug-Mode per ICD2 dahin getastet, wo er die 3,3V auf D+ legt. Indem er im UCON USBEN auf 1 setzt. Anschließend wartet er, dass das Bit SE0 gelöscht wird. An der Stelle schwimme ich. Normalerweise müßte doch der Host/Hub nachdem er die 3,3V erkannt hat, beide D-Leitungen auf Null ziehen und das der Pic mit dem SE0-Bit erkennen. Oder? Der Pic schaltet auch das SE0-Bit von 1 auf 0, auf dem Oszi sieht man das aber nicht.

Müßte es also nun so sein oder anders oder steht das irgendwo so, dass es auch die älteren Symester verstehen?

Code:
void USBCheckBusStatus(void)
{
    UCON = 0b00001000;              // Enable USBEN only
    /*
     * After enabling the USB module, it takes some time for the voltage
     * on the D+ or D- line to rise high enough to get out of the SE0 condition.
     * The USB Reset interrupt should not be unmasked until the SE0 condition is
     * cleared. This helps preventing the firmware from misinterpreting this
     * unique event as a USB bus reset from the USB host.
     */
    while(UCONbits.SE0);            // Blocking loop
    UIR = 0;                        // Clear all USB interrupts
    UIE = 0b00010001;               // Unmask RESET & IDLE interrupts only
    usb_device_state = POWERED_STATE;
}//end USBCheckBusStatus


BL
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #1 am: Juni 24, 2010, 10:14:52 »
ZitierenZitat

Hi BL,

zeig mal die komplette main.c mit allen deinen Änderungen her. Die USB Beispiele von MC laufen eigentlich immer problemlos, daher wundert es mich dass der da angeblich hängen bleibt. Ist der PIC auch richtig knfiguriert (PLL, WDT, etc.) ?

Grüße
Stefan
Gespeichert


BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #2 am: Juni 27, 2010, 09:24:12 »
ZitierenZitat

zeig mal die komplette main.c mit allen deinen Änderungen her.

Kein Problem:

Code:
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include <p18f4455.h>
#include "system\typedefs.h"                        // Required
#include "system\usb\usb.h"                         // Required
#include "io_cfg.h"                                 // Required

#include "system\usb\usb_compile_time_validation.h" // Optional

/** C O N F I G U R A T I O N ************************************************/

#if   defined(__18F4550)||defined(__18F4455)|| \
      defined(__18F2550)||defined(__18F2455)|| \
      defined(__18F4553)||defined(__18F4458)|| \
      defined(__18F2553)||defined(__18F2458)

// Note: Some of the below configuration bits are commented out
// to prevent build errors with some of the above listed devices.
// For example, on the PIC18F4458 CP3, WRT3, and EBTR3 don't exist.

#pragma config PLLDIV   = 2       //8MHz (5:20 MHz input)
#pragma config CPUDIV   = OSC1_PLL2
#pragma config USBDIV   = 2       // Clock source from 96MHz PLL/2 
#pragma config FOSC     = HSPLL_HS
//#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config PWRT     = ON
#pragma config BOR      = OFF
//#pragma config BORV     = 3
#pragma config VREGEN   = ON
#pragma config WDT      = OFF
#pragma config WDTPS    = 32768
#pragma config MCLRE    = ON
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
#pragma config CCP2MX   = OFF
#pragma config STVREN   = ON
#pragma config LVP      = OFF
//#pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
#pragma config XINST    = OFF       // Extended Instruction Set
#pragma config CP0      = OFF
#pragma config CP1      = OFF
#pragma config CP2      = OFF
//#pragma config CP3      = OFF
#pragma config CPB      = OFF
#pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
#pragma config WRT2     = OFF
//#pragma config WRT3     = OFF
#pragma config WRTB     = OFF       // Boot Block Write Protection
#pragma config WRTC     = OFF
#pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
#pragma config EBTR2    = OFF
//#pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF

#endif

/** V A R I A B L E S ********************************************************/
#pragma udata

/** P R I V A T E  P R O T O T Y P E S ***************************************/

/** V E C T O R  R E M A P P I N G *******************************************/

#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
void _high_ISR (void)
{
    _asm goto RM_HIGH_INTERRUPT_VECTOR _endasm
}

#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
void _low_ISR (void)
{
    _asm goto RM_LOW_INTERRUPT_VECTOR _endasm
}

void mein_main(void);

#pragma code

/** D E C L A R A T I O N S **************************************************/
#pragma code
/******************************************************************************
 * Function:        void main(void)
 *
 * PreCondition:    None
 *
 * Input:           None
 *
 * Output:          None
 *
 * Side Effects:    None
 *
 * Overview:        Main program entry point.
 *
 * Note:            None
 *****************************************************************************/
void main(void)
{
    byte temp;
    temp = ADCON1;
    ADCON1 |= 0x0F;
   
    //TRISBbits.TRISB4 = 1;     // Reset value is already '1'
   
    //Check Bootload Mode Entry Condition
//    if(PORTBbits.RB4 == 1)      // If not pressed, User Mode

//    if (PORTEbits.RE3 == 1)  // kein jumper
    {
//        _asm goto RM_RESET_VECTOR _endasm //
    }//end if
   
    //Bootload Mode
    mInitAllLEDs();
    mInitializeUSBDriver();     // See usbdrv.h
    USBCheckBusStatus();        // Modified to always enable USB module
    while(1)
    {
       USBDriverService();     // See usbdrv.c
       BootService();          // See boot.c
    }//end while
}//end main

#pragma code user = RM_RESET_VECTOR

/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/

void mein_main(void)
{
    while(1)
    {
PORTAbits.RA4 = 1;
PORTAbits.RA4 = 0;
    }//end while
}
/** EOF main.c ***************************************************************/

Inzwischen ist die Geschichte so weit gediehen, als dass ich einmal im Gerätemanager ein neues unbekanntes Gerät gesehen hatte. Den Treiber dafür einzubinden habe ich zwar nichzt gleich hingekriegt, aber das war mir im Moment noch nicht wichtig.
Das Problem scheint zumindest auch am Windows7 zu liegen. Der Rechner mußte erst mit angestöpseltem Pic hochlaufen, um zu erkennen, das da was dran war. Um gekehrt blieb das nicht erkannte Gerät sowohl im Gerätemanager als auch im usbview stehen, als es wieder abgestöpselt war. Wieder erst nach Neustart war es weg.
Ich habe es zunächst nicht weiter verfolgt, da zunächst noch einige Wissenslücken schließen wollte, wie auch C18 für mich neu ist(bisher CC8e). Dabei bin ich auf ein Buch gestoßen, dass einen anderen Ansatz verfolgt, nämlich USB via Interrupt zu steuern. Das ist mir sympathischer, weil die Baugruppe später Logging-Funktionen erfüllen soll.

Ich komme später drauf zurück.





BL
Gespeichert

BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #3 am: Juli 06, 2010, 11:18:09 »
ZitierenZitat

Hallo,


ich bin ein Stück weiter - oder auch nicht.

Ich habe also die Sache nochmal neu angefangen, mit einer anderen Softwarevorlage. Das ist mir übersichtlicher und wegen der Interrups sympathischer. Dazu habe ich jetzt auch einen anderen Host-Rechner mit XP, statt Win7.

Nur, ich bleibe an der gleichen Stelle stehen. Der D+-Pin zieht hoch, wenn USBEN gesetzt wird, SE0 geht mit hoch und im nächsten Takt wieder runter, wenn die D+-Leitung eingeschwungen ist und dann passiert nichts mehr.

Muß an der Stelle der Host nicht einen USB-Reset auslösen, auch ohne, dass er einen Treiber für das Device hat? Wie sollte er sonst herausfinden, was es für ein Gerät ist?



BL
Gespeichert

BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #4 am: Juli 07, 2010, 08:39:25 »
ZitierenZitat

Manchmal stellt man fest, dass man auch im "mittleren" Alter, selbst nach vielen, vielen und sogar wirklich glücklichen Ehejahren nachts noch Erfolgserlebnisse haben kann. Zwinkernd

So jedenfalls kam mir des Nachts die Erleuchtung, doch mal das USB-Kabel zu prüfen. Und siehe da....

Ich möchte hier nicht schildern, welche Tobsuchtsanfälle ich vorher durchlebt, nachdem ich alles andere, mir Erdenkliche ausprobiert hatte. Danach auf das Kabel zu kommen, war jetzt nichts die wirklich große geistige Glanztat. (anderer Host, anderes Betriebssytem, andere Device-Software, zum Schluß andere Device-HW) Aber schön ist es nun doch, etwas gefunden zu haben.


BL
Gespeichert

Edson
Globaler Moderator
Sr. Member
*****
Offline Offline

Beiträge: 298



Profil anzeigen
« Antworten #5 am: Juli 07, 2010, 13:20:55 »
ZitierenZitat

Manchmal stellt man fest, dass man auch im "mittleren" Alter, selbst nach vielen, vielen und sogar wirklich glücklichen Ehejahren nachts noch Erfolgserlebnisse haben kann. Zwinkernd

Freut mich das zu hören, man selbst wird ja auch nicht jünger... Zwinkernd

Zitat
Danach auf das Kabel zu kommen, war jetzt nichts die wirklich große geistige Glanztat. (anderer Host, anderes Betriebssytem, andere Device-Software, zum Schluß andere Device-HW) Aber schön ist es nun doch, etwas gefunden zu haben.

Solche Vorgänge haben glücklicherweise nichts mit dem Alter zu tun, es besteht also Hoffnung. Zwinkernd


Viele Grüße,
Edson
Gespeichert

BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #6 am: Juli 29, 2010, 08:01:15 »
ZitierenZitat

Hallo,


ich hänge wieder mit dem USB.

Folgender Stand: Das Device läuft ordentlich hoch, schaltet den USB-D+ auf 3,3V, der PC löst einen USB-Reset aus, das Device geht in den Inzerrupt.
Dann müßte doch eigentlich vom PC aus ein Request angestoßen werden, indem das Device seine Adresse kriegt?
Das macht der komischer Weise nicht, sondern immer neue Resets.

Muß da vielleicht das Device auf den Bus-Reset irgendwas antworten?



BL
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #7 am: Juli 29, 2010, 15:21:25 »
ZitierenZitat

Hi,

noch mal die Nachfrage: Führst du die "mein_main" irgendwo aus?
Ich verstehe ehrlich gesagt nicht, warum der Code nicht laufen sollte. Durch die auskommentieren IF Anweisungen springst du immer in den Bootloader Code, der eigentlich alles von alleine tut, von Init über Enumeration bis zum Schreiben in den Flash. Und der funktioniert auch unter Windows 7, ich habe meinen Code unter XP und Win7 immer erfolgreich zum laufen gebracht.

Grundsätzlich verwendet der Bootloader keine Interrupts, ich sehe auch keinen Vorteil warum man diese nutzen sollte.

Ich glaube, du hast bei dem Lösungsansatz einen Denkfehler: Du versuchst, Applikation und Bootloader in eine Applikation zu gießen. Davon rate ich dir aber ab, weil das die Sache nur unnötiger Weise verkompliziert. Ich schlage vor, dass du in einem Projekt den reinen USB BL programmierst, dort wird auch abgefragt, ob der BL oder die Applikation gestartet wird. Sinnvollerweise aktivierst du gleich die BL Code Protection, damit ist sichergestellt, dass der Bootloader nicht zerstört werden kann.
Für die eigentliche Applikation erstellst du wiederum ein eigenes Projekt, das alle gewünschten Funktionen zur Verfügung stellt. Dabei musst du nur die Interruptvektoren und die Startadresse auf die im Bootloader festgelegten Adressem um biegen. Hier spricht auch nichts gegen die Benutzung von einer interruptbasierten Abarbeitung der USB Anfragen.

Bei mir sieht der BL so aus (Auszug):
Code:
void main(void)
{
[...]
    //Check Bootload Mode Entry Condition
    if(PORTAbits.RA1 == 1 && boot != 0xA9 && boot != 0xff)      // If not pressed, value set by setup or
    { // if program space is emtpy (eeprom is 0xff)
        _asm goto RM_RESET_VECTOR _endasm
    }//end if

[..]

    //Bootload Mode
    mInitAllLEDs();
mLED_1_Off();
mLED_2_On();
    led_count = 0; //Initialize blink rate counter
    mInitializeUSBDriver();     // See usbdrv.h
    USBCheckBusStatus();        // Modified to always enable USB module
    while(1)
    {
        USBDriverService();     // See usbdrv.c
        BootService();          // See boot.c
    }//end while
}//end main

Grüße
Stefan
Gespeichert


BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #8 am: Juli 29, 2010, 16:53:39 »
ZitierenZitat

Hallo,


da gibt es ein Mißverständnis. Ich nehme nicht mehr das Sprut-/Microchip-Projekt zur Grundlage, sondern eines aus einem Buch "USB in der Meßtechnik" von Henry Bruhns. Der wiederum hat sein Projekt in Assembler geschrieben und ich daraus meinen C-Code gemacht.
Sieht ungefähr so aus:

Code:
#pragma config PLLDIV   = 2       //8MHz (5:20 MHz input)
#pragma config CPUDIV   = OSC1_PLL2
#pragma config USBDIV   = 2       // Clock source from 96MHz PLL/2  
#pragma config FOSC     = HSPLL_HS
//#pragma config FCMEN    = OFF
#pragma config IESO     = OFF
#pragma config PWRT     = ON
#pragma config BOR      = OFF
//#pragma config BORV     = 3
#pragma config VREGEN   = ON
#pragma config WDT      = OFF
#pragma config WDTPS    = 32768
#pragma config MCLRE    = ON
#pragma config LPT1OSC  = OFF
#pragma config PBADEN   = OFF
#pragma config CCP2MX   = OFF
#pragma config STVREN   = ON
#pragma config LVP      = OFF
//#pragma config ICPRT    = OFF       // Dedicated In-Circuit Debug/Programming
#pragma config XINST    = OFF       // Extended Instruction Set
#pragma config CP0      = OFF
#pragma config CP1      = OFF
#pragma config CP2      = OFF
//#pragma config CP3      = OFF
#pragma config CPB      = OFF
#pragma config CPD      = OFF
#pragma config WRT0     = OFF
#pragma config WRT1     = OFF
#pragma config WRT2     = OFF
//#pragma config WRT3     = OFF
#pragma config WRTB     = OFF       // Boot Block Write Protection
#pragma config WRTC     = OFF
#pragma config WRTD     = OFF
#pragma config EBTR0    = OFF
#pragma config EBTR1    = OFF
#pragma config EBTR2    = OFF
//#pragma config EBTR3    = OFF
#pragma config EBTRB    = OFF

...
//----------------------------------------------------------------------------
// High priority interrupt vector

#pragma code InterruptVectorHigh = 0x08
void
InterruptVectorHigh (void)
{
  _asm
    goto InterruptHandlerHigh //jump to interrupt routine
  _endasm
}

//----------------------------------------------------------------------------
// Low priority interrupt vector

#pragma code InterruptVectorLowh = 0x18
void
InterruptVectorLow (void)
{
  _asm
    goto InterruptHandlerLow //jump to interrupt routine
  _endasm
}

//---------------------------------------------------------------------------------
#pragma code boot_sector = 0x0020
void main(void)
{
// OSCCON = 0b01100010;
regsetup();
DEVICE_init();
USB_init();
USB_reset();
PIR2bits.USBIF = 0; //reset any USB interrupts pending
  IPR2bits.USBIP = 1; //USB is a high priority interrupt source
RCONbits.IPEN = 1; //enable interrupt priority levels
INTCONbits.PEIE = 1; //enable peripheral interrupt sources
PIE2bits.USBIE = 1; //enable USB interrupt
UIR = 0;
INTCONbits.GIE = 1; //global interrupt enable bit

USBTMCindicator_pulse();//fliegt noch raus

Hauptschleife:

while (1)
{
PORTAbits.RA4 = !PORTAbits.RA4;
}

}
//-----------------------------Register einstellen---------------------------------
void regsetup(void)
{
InitAdcons(); //Macro in iocfg.h
InitPORTA(); //Macro in iocfg.h
InitPORTB(); //Macro in iocfg.h
InitPORTC(); //Macro in iocfg.h
InitPORTD(); //Macro in iocfg.h
InitPORTE(); //Macro in iocfg.h
EECON1 = 0;
EECON2 = 0;
TABLAT = 0;
TBLPTRL = 0;
TBLPTRH = 0;
TBLPTRU = 0;
IPR1 = 0; //nur USB hohe Int.Priority
IPR2 = 0x20; //nur USB hohe Int.Priority
T0CON = 0;
T1CON = 0;
T2CON = 0;
T3CON = 0;
TMR0L = 0;
TMR0H = 0;
TMR1L = 0;
TMR1H = 0;
TMR2 = 0;
TMR3L = 0;
TMR3H= 0;

PIR1 = 0; //Alle Flags aus
PIR2 = 0; //Alle Flags aus
// PIR3 = 0; //Alle Flags aus
RCON = 0b00000000; //IP verbieten
INTCON = 0b00000000; //nix erlauben
INTCON2 = 0b10000000; //
INTCON3 = 0b00000000; //nix erlauben
PIE1 = 0b00000000; //CCPIE an
PIE2 = 0; //
hilf = 0;
// PIE3 = 0; //
}
//----------------------------------------------------------------------------
// High priority interrupt routine

#pragma code
#pragma interrupt InterruptHandlerHigh

void InterruptHandlerHigh (void)
{
//HighInt
//; save working registers
retteArbeitsregisterHighInt() //Macro in inthandvo1.h

LATCbits.LATC0 = 1;
if (hilf==4)
{
Nop();
Nop();
}
TestCounter[hilf] = UIR;
hilf++;

HighIntuerrif_test:
if (UIRbits.UERRIF)
goto HighIntUerrif;
HighIntStallif_test:
if (UIRbits.STALLIF)
goto HighIntStall;
HighIntUrstif_test:
if (UIRbits.URSTIF)
goto HighIntUSBreset;
HighIntTrnif_test:
if (UIRbits.TRNIF)
goto HighIntTrnif;
HighIntActvif_test:
if (UIRbits.ACTVIF)
goto HighIntActvif;

HighInt2:

//; insert here: any other high priority interrupt queries

HighIntEnd:
PIR2bits.USBIF = 0;
goto fast_end;
//; this is an USB reset interrupt
HighIntUSBreset:
USB_reset();
HighIntSE0Test:
while (UCONbits.SE0);
UIRbits.URSTIF = 0;
goto fast_end;
//; this is an USB transaction complete interrupt
HighIntTrnif:
USBtranscompleteInterrupt();
UIRbits.TRNIF = 0;
goto fast_end;
//; this is an USB stall interrupt
HighIntStall:
UIRbits.STALLIF = 0;
USBStallInterrupt();
goto fast_end;
//; this is an USB resume interrupt
HighIntActvif:
USBresumeInterrupt();
goto fast_end;
//; this is an USB error interrupt
HighIntUerrif:
USBerrorInterrupt();
goto fast_end;

//; insert here: all other fast interrupt service routine calls

//; this is all fast ISR's end

fast_end:
//; restore working registers
UIR = 0;
PIR2bits.USBIF = 0;
LATCbits.LATC0 = 0;
holeArbeitsregisterHighInt() //Macro in inthandvo1.h
_asm
RETFIE 1
_endasm //;never use 'retfie fast' because of early silicon errors

}


//; Low priority interrupt routine
#pragma interrupt InterruptHandlerLow

void
InterruptHandlerLow()
{
retteArbeitsregisterLowInt() //Macro in inthandvo1.h
/*** low priority interrupt code goes here ***/
//; execute operation pending function

holeArbeitsregisterLowInt()
// retfie
}


void DEVICE_init(void)
{
REN = 0;
RLstate = 0; //LOCS
STB = 0; //
ESR.byte = 0; //
ESE = 0; //
BULKOUT_PROGRESS = 0; //no transfer is in progress
BULKOUT_CONTENT = 0; //bulk-OUT is empty
BULKOUT_RXD[0] = 0; //no data transmitted
BULKOUT_RXD[1] = 0; //
BULKOUT_RXD[2] = 0; //
BULKOUT_RXD[3] = 0; //
BULKIN_PROGRESS = 0; //no transfer is in progress
BULKIN_CONTENT = 0; //bulk-IN is empty
BULKIN_TXD[0] = 0; //no data transmitted
BULKIN_TXD[1] = 0; //
BULKIN_TXD[2] = 0; //
BULKIN_TXD[3] = 0; //
OperCond[0] = 0; //status reporting acc. SCPI Syntax & Style chapter 9
OperCond[1] = 0; //
OperEven[0] = 0; //
OperEven[1] = 0; //
OperEnab[0] = 0; //
OperEnab[1] = 0; //
QuesCond[0] = 0; //
QuesCond[1] = 0; //
QuesEven[0] = 0; //
QuesEven[1] = 0; //
QuesEnab[0] = 0; //
QuesEnab[1] = 0; //
ErrorCount = 0; //no errors in the Error/Event Queue
ESR.PON = 1; //ESR
noopFLAG = 0xFF;
// OPCstate.OCIS = 1;
OPCstate.byte = 0xFF;
// OQIS = 0xFF;
OPCqstate.byte = 0xFF;
return;
}

void USB_init(void)
{
UCON = 0; //;clear USB Control Register
UADDR = 0; //USB address 0 (done automatically if USB reset occurs)
SetAddress = 0;
USBAddress = 0;
bConfigurationValue = 0; //device is not configured
//; CPU gets ownership of the whole USB RAM and clears the buffer descriptors
// FSR0L = 0;
// FSR0H = 0x04;
DescriptorPointer = 0;
EPx.EParray[0] = 0x00;
do
{
DescriptorPointer++;
EPx.EParray[DescriptorPointer] = 0x00;
}while (DescriptorPointer<0xFF);

UCFG = 0b00010100;

UEP0 = 0;
UEP1 = 0;
UEP2 = 0;
UEP3 = 0;
UEP4 = 0;
UEP5 = 0;
UEP6 = 0;
UEP7 = 0;
UEP8 = 0;
UEP9 = 0;
UEP10 = 0;
UEP11 = 0;
UEP12 = 0;
UEP13 = 0;
UEP14 = 0;
UEP15 = 0;

//; Initialization of the USB interrupt funnel (reference: DS39632C Section 17.5)
clearACTVIF();
UIR = 0;
UIE = 0;
UEIR = 0;
UEIE = 0;
UIRbits.URSTIF = 0; //clear interrupt status flag
UIEbits.URSTIE = 1; //enable reset interrupt
UIEbits.STALLIE = 1; //enable stall interrupt
UIEbits.TRNIE = 1; //enable transaction complete interrupt

//; enable USB interface
UCONbits.USBEN = 1;

while (UCONbits.SE0);

return;
}
/
void clearACTVIF(void)
{
UCONbits.SUSPND = 0;
while (UIRbits.ACTVIF)
{
UIRbits.ACTVIF = 0;
}
return;
}

void USB_unconfig(void)
{
  bConfigurationValue = 0; //this will be read back with "GET_CON-
//; FIGURATION
USBindicatorUNCONFIG();
return;
}

void USBindicatorUNCONFIG(void)

{
return;
}

void USB_reset(void)
{
UADDR = 0; //USB address 0 (done automatically if USB reset occurs)
bConfigurationValue = 0; //device is not configured
UIR = 0; //clear all pending USB interrupts
UEIR = 0; //clear all USB error interrupts
//;disable all endpoints
UEP0 = 0;
UEP1 = 0;
UEP2 = 0;
UEP3 = 0;
UEP4 = 0;
UEP5 = 0;
UEP6 = 0;
UEP7 = 0;
UEP8 = 0;
UEP9 = 0;
UEP10 = 0;
UEP11 = 0;
UEP12 = 0;
UEP13 = 0;
UEP14 = 0;
UEP15 = 0;
//;unconfigure device
USB_unconfig();
//;configure endpoint 0
config_EP0();
UCONbits.PKTDIS = 0; //clear packet transfer disable
//;flush any pending transactions
while (UIRbits.TRNIF);
return;
}

void config_EP0(void)
{
//; Control OUT Buffer Descriptor
//; can receive 64 bytes
//; buffer starts at adress 0x0480
union
{
struct
{
unsigned char low8;
unsigned char high8;
};
unsigned int gesamt;
}adr;

//Die Adresse des Output-Buffers in den Endpunkt0 schreiben
adr.gesamt = (unsigned short long) USB_CONTROL_OUT;
EPx.BD0ADRL = adr.low8;
EPx.BD0ADRH = adr.high8;

//Die Adresse des Input-Buffers in den Endpunkt1 schreiben
adr.gesamt = (unsigned short long) USB_CONTROL_IN;
EPx.BD1ADRL = adr.low8;
EPx.BD1ADRH = adr.high8;

EPx.BD0CNT = 64; //Buffer-Breite 64Bit
EPx.BD0STAT = 0b10000000; //turn ownership to SIE

//; configure UEP0 Register
UEP0 = 0;

return;
}

void USBTMCindicator_pulse(void)
{

// timerIndicator = 100; //count down in 0.5s
// IndicateINDICATORon();
return;
}


void BulkTransferIndicator(void)
{

if (timerBulk==0)
return;
timerBulk = 30;
return;
}

void USBresumeInterrupt(void)
{
clearACTVIF();
//; set oscillator to primary clock source
OSCCONbits.SCS1 = 0;
OSCCONbits.SCS0 = 0;
OSCCONbits.IDLEN = 0;
UIEbits.ACTVIE = 0; //;disable bus activity interrupt
UIRbits.IDLEIF = 0;
return;
}

void USBtranscompleteInterrupt(void)
{
//; read USB status register to localize the endpoint
TINKER = 0x78 & USTAT;
switch (TINKER)
{
case 0x00:
// goto transcmpl_0; //transaction complete in physical endpoint 0
break;

case 0x08:
// goto transcmpl_1; //transaction complete in physical endpoint 1
break;

case 0x10:
// goto transcmpl_2; //transaction complete in physical endpoint 2
break;

case 0x18:
// goto transtest_over; //transaction complete in physical endpoint 3
break;
}



transtest_over:
return;
}

void USBStallInterrupt(void)
{
    if (UEP0bits.EPSTALL==0)
return;

StallTrap:
//; return ownership of control OUT endpoint to SIE
EPx.BD0STAT = 0x08; //10000000
//; return ownership of control IN endpoint to CPU
EPx.BD1STAT = 0;
//; reset EPSTALL-bit
UEP0bits.EPSTALL = 0;
return;
}

void USBerrorInterrupt()
{
UEIR = 0;
return;
}


void transtest_over_ctl_out(void)
{
UCONbits.PKTDIS = 0; //clear packet transfer disable
//; Control OUT Buffer Descriptor
//; can receive 64 bytes
//; buffer starts at adress 0x0500
EPx.BD0CNT = 64;
EPx.BD0STAT = 0x80; //turn ownership to SIE
return;
}



Ist natürlich noch unfertig.
Ziel ist zunächst ausschließlich, die Schnittstelle zum Leben zu bringen. Bootlader, Meßroutinen usw. kommen erst lande danach.
Nahziel ist im Moment, nach dem ersten Bus Reset den ersten Request zu empfangen.

In der High-Priotity-Interruptroutine stehen einige Befehlszeilen ganz am linken Rand. Das sind Codeschnipsel, mit denen ich beispielsweise einen Ausgang zu Triggerzwecken schalte und die UIR-Werte der einzelnen Interupts mitschreibe, um sie später via ICD2 auslesen zu können.
Die Situation ist nun die, dass der Bus seinen ersten Reset macht und der Controller daher in den richtigen Interrupt geht. Dann aber macht der Bus weitere Resets, statt den SET_ADDRESS-Request zu bringen. Folglich müßte irgendwas doch dem Bus mitteilen, dass weitere Resets nicht notwendig sind.
Der Controller geht bei jedem Reset in den Interrupt und zeigt dann aber eine 0x41 im UIR, also das Reset- und das Start-of-frame-Flag. Das eine(SOFIF) kann ich mir erklären. Das wäre ja das, was ich will. Das andere eigentlich auch. Beides zusammen aber nicht.

Da weiß ich im Moment noch nicht weiter.



BL
Gespeichert

BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #9 am: Juli 30, 2010, 08:09:11 »
ZitierenZitat

Inzwischen habe ich den Oszi etwas gequält.

Der PC sendet nach dem Reset eben doch Daten. Ist nur schwer, es mit den Reset-Impulsen zusammen auf einem Billig-Oszi darzustellen. Daher erkennt der PIC folgerichtig den SOF(K-Zustand). Im Bruhns sind Buch und Software nun darauf getrimmt, dass der Pic keinen SOF-Interrupt bringt. Der würde sich erst melden, wenn die Transaktion abgeschlossen ist(Transaction-Complete-Interrupt). Nun kommt mein Pic nicht bis dahin und an der Stelle weiß ich noch nicht, warum. Das zweite ist, wie erkennt denn der PC, dass der Pic nicht reagiert?



BL
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #10 am: Juli 31, 2010, 12:24:59 »
ZitierenZitat

Hi BL,

da haben wir wirklich aneinander vorbei geredet, ich dachte du nutzt noch das Microchip Beispiel.
Ich habe mal auf Basis eines Assembler Codes aus dem MC Forum eine Firmware geschrieben, bei der ich noch die BULK Transfers für MSD ergänzt habe. Die Enumeration war schon implementiert, ich habe mich darum also nicht mehr kümmern müssen, daher kenne ich mit damit auch nicht so detailiert aus.

Was ich allerdings nicht verstehe, ist warum du den USB neu schreiben möchtest. Der MC Code funktioniert super, is USB zertifiziert und kostenlos verfügbar. Dein Vorhaben hat eher akademischen Charakter...  Smiley

Fall du Literatur benötigst, so kann ich dir die beiden Bücher von Jan Axelson empfehlen: "USB Complete" und "USB Mass Storage". Bei Interesse PM an mich.

Zitat
Das zweite ist, wie erkennt denn der PC, dass der Pic nicht reagiert?
Simpler Timeout. Daher müssen die USB Routinen so groß alle 1ms ausgeführt werden, sonst wird hostseitig ein Timeout erkannt.

Noch etwas: Du programmierst in C und nutzt "goto" Befehle! Das ist ganz schlechter Stil. Nimm anstatt dieser if und goto Kombinationen lieber ein switch / case Anweisungen.

Grüße
Stefan
Gespeichert


BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #11 am: August 01, 2010, 16:48:00 »
ZitierenZitat

Hallo Stefan,


es mag ja im Prinzip so aussehen, dass ich das Rad neu erfinden wollte, nur ganz so ist es auch wieder nicht. So wie Du eine Vorlage aus dem MC-Forum(?) genommen hast, hatte ich es auf diese aus dem Bruhns abgesehen. Zudem habe ich Erfahrungen mit Software-Vorlage dahingehend gemacht, dass ich es sowieso nicht hinkriege, bevor ich nicht jede Zeile einigermaßen versteh. Das ist beim MC-Framework nun auch nicht eben simpel.

Mit meinem Problem hier bin ich blöderweise noch nicht weiter. Ich habe beide Varianten(meine und die Vorlage) bis zur ersten Kommunikation nach dem Reset durchgespielt. Alles wesentlichen Register sind gleich. Der PC funkt den Pic an. Die Vorlage reagiert darauf und mein Ding nicht.

Was für einen Assembler Codes aus dem MC Forum hattest Du den verwendet?




BL
Gespeichert

Stampede
Globaler Moderator
Hero Member
*****
Offline Offline

Beiträge: 728



Profil anzeigen WWW
« Antworten #12 am: August 03, 2010, 14:05:52 »
ZitierenZitat

Hi BL,

Zitat
es mag ja im Prinzip so aussehen, dass ich das Rad neu erfinden wollte
Ja, es scheint so Smiley
Zitat
So wie Du eine Vorlage aus dem MC-Forum(?) genommen hast, hatte ich es auf diese aus dem Bruhns abgesehen. Zudem habe ich Erfahrungen mit Software-Vorlage dahingehend gemacht, dass ich es sowieso nicht hinkriege, bevor ich nicht jede Zeile einigermaßen versteh. Das ist beim MC-Framework nun auch nicht eben simpel.
Im Nachhinein war es blödsinnig, alles mit Assembler neu zu schreiben, und bei C wird es nicht anders sein. Klar, man lernt viel über USB, aber bis man einen halbwegs stabilen Code hat, vergehen Ewigkeiten. Daher rate ich dir, den MC Stack zu verwenden. Wenn du die Zeit, die du für die Entwicklung deiner eigenen Software brauchst, nimmst um dich in den Stack einzuarbeiten, wird das viel schneller und effektiver zum Ziel führen.
Meiner Meinung nach ist das USB Framework recht gut zu bedienen. Man fügt in seine Applikation die Init des USBs rein, in die main muss dann nur noch der USB Handler der alles übernimmt. Ein paar Callback-Routinen müssen noch kopiert werden, aber das ist nicht der Rede wert. Und mit den vielen Beispielen findet man sich gut zurecht. Zugebenermaßen dachte ich am Anfang auch, die Stacks seien schwierig in der Bedienung, aber das stimmt nicht. Da findet sich schnell ein, ohne zu tief in die Materie gehen zu müssen.
Zitat
Was für einen Assembler Codes aus dem MC Forum hattest Du den verwendet?
Der Code ist von Brad Minch, Link:
http://www.microchip.com/forums/m89669.aspx

Gruß
Stefan
Gespeichert


BL1
Newbie
*
Offline Offline

Beiträge: 37


Profil anzeigen
« Antworten #13 am: August 04, 2010, 07:57:33 »
ZitierenZitat

Moin Stefan,


Im Prinzip will ich Dir ja nicht wiedersprechen.

Nur, ich hatte halt andere Überlegungen und die führten zur Interruptsteuerung, was ich im Framework nicht gefunden habe, aber im Bruhns. Nun hat der aber eben den Nachteil, dass er den ganzen Quatsch in Assembler gemacht hat. Nach Deinem Beitrag habe ich mir das Ganze nochmal angesehen und durch den Kopf gehen lassen. Ich bleibe beim Bruhns. Jetzt noch mal von vorne anzufangen, hieße, die ganzen bisherigen Wochen wegzuschmeißen.

Also habe ich weitergemacht. Und siehe da... Mit Geduld uns Spucke findet man doch mal was.
Ich hatte in einer Unterfunkrion der USB-Reset-Routine den UEP0 falsch, bzw. beschrieben. Dadurch war das Bit EPHSHK nicht gesetzt. Das wiederum hat verhindet, dass das Device einen Handshake generiert(obwohl ich gelesen hatte, dass dies bei einem Setup-Token ohnehin gemacht wird). Ohne Handshake hat aber der PIC keinen Transaction-Complet-Interrupt generiert und der PC wiederum den USB immer wieder resetet. Dadurch ging der PIC zwar immer schön in den Interrupt, aber in den falschen.

So, dann stehen wir mal, wo es als nächstes hängt.




BL
Gespeichert

Seiten: [1]   Nach oben
AntwortenDrucken
 
Gehe zu:  

Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC | Theme Kani By Fussilet

Seite erstellt in 0.157 Sekunden mit 19 Zugriffen.


 
Design by Next Level Design / Script by Joomla!