#include "LPC17xx.h" #include "GPIO_LPC17xx.h" #include "GPDMA_LPC17xx.h" #include "Global.h" #include //*****************************************// // //*** Define fuer Eingabe von Binary // //*****************************************// #define LongToBin(n) \ (\ ((n >> 21) & 0x80) | \ ((n >> 18) & 0x40) | \ ((n >> 15) & 0x20) | \ ((n >> 12) & 0x10) | \ ((n >> 9) & 0x08) | \ ((n >> 6) & 0x04) | \ ((n >> 3) & 0x02) | \ ((n ) & 0x01) \ ) #define Bin(n) LongToBin(0x##n##l) //*****************************************// // //*** Vorwaertsdefinition der Funktionen // //*****************************************// void USBCmdToSIE(unsigned char CMD_Code, unsigned char CMD_Data); unsigned int USBSIEtoCPU(unsigned char CMD_Code, unsigned char CMD_Data); void USB_ReadEndpoint(unsigned char ucEndpointNr); void USB_WriteEndpoint(unsigned char ucEndpointNr, unsigned char ucPaketlaenge); void USB_IRQHandler(void); void USB_Init(void); char Get_Descriptor_Request(unsigned char *DscPtr, unsigned char ucLength); void USBProtocolResetHandler(void); void USB_Tasten_Out(void); void USB_Mouse_Out(void); void USB_Mouse_Out(void); void USB_Register_Init(void); //*****************************************// // //*** Globale Variablen // //*****************************************// unsigned int uiTest1; unsigned int uiTest2; unsigned int uiADBackup; ///*********** Alte Daten vom PIC18F4550 ************** ///*********** Diese Daten werden nach nach erfolgreicher Initialisierung ncoh geloescht ********** //*** Globale Variablen fuer USB *** #define USB_BD0_OUT_STATUS 0x400 //EP0 Adressen fuer den SIE Buffer (SIE to PIC) #define USB_BD0_OUT_LAENGE 0x401 #define USB_BD0_OUT_ADR_LOW 0x402 #define USB_BD0_OUT_ADR_HIGH 0x403 #define USB_BD0_IN_STATUS 0x404 //EP0 Adressen fuer den SIE Buffer (PIC to SIE) #define USB_BD0_IN_LAENGE 0x405 #define USB_BD0_IN_ADR_LOW 0x406 #define USB_BD0_IN_ADR_HIGH 0x407 #define USB_BD1_OUT_STATUS 0x408 //EP1 Adressen fuer den SIE Buffer (SIE to PIC) #define USB_BD1_OUT_LAENGE 0x409 #define USB_BD1_OUT_ADR_LOW 0x40A #define USB_BD1_OUT_ADR_HIGH 0x40B #define USB_BD1_IN_STATUS 0x40C //EP1 Adressen fuer den SIE Buffer (PIC to SIE) #define USB_BD1_IN_LAENGE 0x40D #define USB_BD1_IN_ADR_LOW 0x40E #define USB_BD1_IN_ADR_HIGH 0x40F #define USB_BD2_OUT_STATUS 0x410 //EP2 Adressen fuer den SIE Buffer (SIE to PIC) #define USB_BD2_OUT_LAENGE 0x411 #define USB_BD2_OUT_ADR_LOW 0x412 #define USB_BD2_OUT_ADR_HIGH 0x413 #define USB_BD2_IN_STATUS 0x414 //EP2 Adressen fuer den SIE Buffer (PIC to SIE) #define USB_BD2_IN_LAENGE 0x415 #define USB_BD2_IN_ADR_LOW 0x416 #define USB_BD2_IN_ADR_HIGH 0x417 unsigned char USB_bmRequestType; //EP0 Dateneingang (verbunden mit BD0_OUT) unsigned char USB_bRequest; unsigned char USB_wValue_low; unsigned char USB_wValue_high; unsigned char USB_wIndex_low; unsigned char USB_wIndex_high; unsigned char USB_wLength_low; unsigned char USB_wLength_high; unsigned char USB_EP0_OUT_BYTE[8]; //EP0 Datenausgang (verbunden mit BD0_IN) unsigned char USB_EP1_IN_BYTE0; //EP1 Dateneingang (verbunden mit BD1_OUT) unsigned char USB_EP1_IN_BYTE1; unsigned char USB_EP1_IN_BYTE2; unsigned char USB_EP1_IN_BYTE3; unsigned char USB_EP1_IN_BYTE4; unsigned char USB_EP1_IN_BYTE5; unsigned char USB_EP1_IN_BYTE6; unsigned char USB_EP1_IN_BYTE7; unsigned char USB_EP1_OUT_BYTE0; //EP1 Datenausgang (verbunden mit BD1_IN) unsigned char USB_EP1_OUT_BYTE1; unsigned char USB_EP1_OUT_BYTE2; unsigned char USB_EP1_OUT_BYTE3; unsigned char USB_EP1_OUT_BYTE4; unsigned char USB_EP1_OUT_BYTE5; unsigned char USB_EP1_OUT_BYTE6; unsigned char USB_EP1_OUT_BYTE7; unsigned char USB_EP2_IN_BYTE0; //EP2 Dateneingang (verbunden mit BD2_OUT) unsigned char USB_EP2_IN_BYTE1; unsigned char USB_EP2_IN_BYTE2; unsigned char USB_EP2_IN_BYTE3; unsigned char USB_EP2_IN_BYTE4; unsigned char USB_EP2_IN_BYTE5; unsigned char USB_EP2_IN_BYTE6; unsigned char USB_EP2_IN_BYTE7; unsigned char USB_EP2_OUT_BYTE0; //EP2 Datenausgang (verbunden mit BD2_IN) unsigned char USB_EP2_OUT_BYTE1; unsigned char USB_EP2_OUT_BYTE2; unsigned char USB_EP2_OUT_BYTE3; unsigned char USB_EP2_OUT_BYTE4; unsigned char USB_EP2_OUT_BYTE5; unsigned char USB_EP2_OUT_BYTE6; unsigned char USB_EP2_OUT_BYTE7; ///*************** ENDE Daten PIC 18F4550 ********* unsigned char ucTastentur[8]; //USB String Tastatur Report unsigned char ucMouse[3]; //USB String Mouse Report char *iUsbPtr=NULL; //Pointer fuer den Zugriff auf die USB Speicheradressen unsigned char ucDscCounter = 0x00; //Hilfsvariable: Da die Strings etc. in 8Byte lange Pakete gesendet werden, wird jeweils die Anzahl der gesendeten Zeichen zwischengespeichert. unsigned char ucUsbDscEnd = 0x00; //Hilfsvariable: Sperrt nachdem ein String etc. gesendet wurde, ein ungewolltes durchlaufen der USB Ennumeration unsigned char ucUsbConnect = 0x00; //Hilfsvariable: Speichert die USB Detektion unsigned char ucUADDR = 0x00; //Hilfsvariable der USB Device Adresse unsigned char ucDataToggle = 0x00; //Hilfsvariable: Toggelt beim Senden vom EP0 zwischen DATA0 und DATA1 (Paket=Data0 naechstes Paket=Data1). Wird zur Fehlerpruefung benoetigt. Jeder EP toggelt selber! unsigned char ucDataToggleTasten = 0x00; //Hilfsvariable: Toggelt beim Senden vom EP1 zwischen DATA0 und DATA1 (Paket=Data0 naechstes Paket=Data1). Wird zur Fehlerpruefung benoetigt. Jeder EP toggelt selber! unsigned char ucDataToggleMouse = 0x00; //Hilfsvariable: Toggelt beim Senden vom EP2 zwischen DATA0 und DATA1 (Paket=Data0 naechstes Paket=Data1). Wird zur Fehlerpruefung benoetigt. Jeder EP toggelt selber! unsigned int uiUsbReciveLength = 0x00; //Hilfsvariable: Zaehlt die angeforderte Descriptorlaenge/Interfacelaenge aus dem Low und High Byte (EP0) zusammen. unsigned char ucTaste = 0x00; //*****************************************// // //*** USB SIE Engine // //*****************************************// unsigned char ucEpReceived[10]; unsigned char ucEpTransmit[10]; //*** USB SIE Command Code Tabelle *** //************************************* //*** SIE Commandos *** #define USB_SIE_Write 0x01 #define USB_SIE_Read 0x02 #define USB_SIE_Command 0x05 //*** Device commands *** #define USB_SetAddress 0xD0 #define USB_ConfigureDevice 0xD8 #define USB_SetMode 0xF3 #define USB_ReadCurrentFrameNumber 0xF5 #define USB_ReadTestRegister 0xFD #define USB_SetDeviceStatus 0xFE #define USB_GetDeviceStatus 0xFE #define USB_ReadErrorStatus 0xFB //*** Device commands *** #define USB_SelectEndpoint_00 0 #define USB_SelectEndpoint_01 1 #define USB_SelectEndpoint_02 2 #define USB_SelectEndpoint_03 3 #define USB_SelectEndpoint_04 4 #define USB_SelectEndpoint_05 5 #define USB_SelectEndpoint_06 6 #define USB_SelectEndpoint_07 7 #define USB_SelectEndpoint_08 8 #define USB_SelectEndpoint_09 9 #define USB_SelectEndpoint_10 10 #define USB_SelectEndpoint_11 11 #define USB_SelectEndpoint_12 12 #define USB_SelectEndpoint_13 13 #define USB_SelectEndpoint_15 14 #define USB_SelectEndpointClearIRQ_00 40 #define USB_SelectEndpointClearIRQ_01 41 #define USB_SelectEndpointClearIRQ_02 42 #define USB_SelectEndpointClearIRQ_03 43 #define USB_SelectEndpointClearIRQ_04 44 #define USB_SelectEndpointClearIRQ_05 45 #define USB_SelectEndpointClearIRQ_06 46 #define USB_SelectEndpointClearIRQ_07 47 #define USB_SelectEndpointClearIRQ_08 48 #define USB_SelectEndpointClearIRQ_09 49 #define USB_SelectEndpointClearIRQ_10 50 #define USB_SelectEndpointClearIRQ_11 51 #define USB_SelectEndpointClearIRQ_12 52 #define USB_SelectEndpointClearIRQ_13 53 #define USB_SelectEndpointClearIRQ_15 54 #define USB_SetEndpointStatus_00 40 #define USB_SetEndpointStatus_01 41 #define USB_SetEndpointStatus_02 42 #define USB_SetEndpointStatus_03 43 #define USB_SetEndpointStatus_04 44 #define USB_SetEndpointStatus_05 45 #define USB_SetEndpointStatus_06 46 #define USB_SetEndpointStatus_07 47 #define USB_SetEndpointStatus_08 48 #define USB_SetEndpointStatus_09 49 #define USB_SetEndpointStatus_10 50 #define USB_SetEndpointStatus_11 51 #define USB_SetEndpointStatus_12 52 #define USB_SetEndpointStatus_13 53 #define USB_SetEndpointStatus_15 54 #define USB_ClearBuffer 0xF2 #define USB_ValidateBuffer 0xFA //*** Set Address Command *** unsigned int USB_DEV_ADDR = 0x0000; #define USB_DEV_EN_Off 0x00 #define USB_DEV_EN_On 0x80 //*** Config Device *** #define USB_Config_Device_Led_Off 0 #define USB_Config_Device_Led_On 1 //*** Set Mode *** Werden OR Verknuepft!! #define USB_SetMode_APPClk_Functionel Bin(00000000) //USB PLL Clock ist 48MHz und wird im Suspend Mode gestoppt #define USB_SetMode_APPClk_Fix Bin(00000001) //USB PLL Clock ist fix 48MHz und wird im Suspend Mode nicht gestoppt #define USB_SetMode_INAKCL Bin(00000000) //USB Interrupt Control IN nur bei Succesfull transaction #define USB_SetMode_INAKCL_Both Bin(00000010) //USB Interrupt Control IN bei Succesfull und NAK transaction #define USB_SetMode_INAKCO Bin(00000000) //USB Interrupt Control OUT nur bei Succesfull transaction #define USB_SetMode_INAKCO_Both Bin(00000100) //USB Interrupt Control OUT bei Succesfull und NAK transaction #define USB_SetMode_INAKII Bin(00000000) //USB Interrupt IN Endpoint nur bei Succesfull transaction #define USB_SetMode_INAKII_Both Bin(00001000) //USB Interrupt IN Endpoint bei Succesfull und NAK transaction #define USB_SetMode_INAKIO Bin(00000000) //USB Interrupt OUT Endpoint nur bei Succesfull transaction #define USB_SetMode_INAKIO_Both Bin(00010000) //USB Interrupt OUT Endpoint bei Succesfull und NAK transaction #define USB_SetMode_INAKBI Bin(00000000) //USB Interrupt Bulk IN Endpoint nur bei Succesfull transaction #define USB_SetMode_INAKBI_Both Bin(00100000) //USB Interrupt Bulk IN bei Succesfull und NAK transaction #define USB_SetMode_INAKBO Bin(00000000) //USB Interrupt Bulk OUT Endpoint nur bei Succesfull transaction #define USB_SetMode_INAKBO_Both Bin(01000000) //USB Interrupt Bulk OUT bei Succesfull und NAK transaction //*** Error Code *** #define USB_ErrorCode_NoError 0 //Kein Fehler #define USB_ErrorCode_PIDError 1 //PID Encoding Error #define USB_ErrorCode_UnbekPID 2 //Unbekannter PID #define USB_ErrorCode_UnbekPkt 3 //Unbekanntes Paket #define USB_ErrorCode_ErrorTokenCRC 4 //Unbekannter Token CRC #define USB_ErrorCode_ErrorDataCRC 5 //Unbekannter Data CRC #define USB_ErrorCode_TimeOur 6 //Time Out Error #define USB_ErrorCode_Babble 7 //Babble #define USB_ErrorCode_EndOfPacket 8 //Error in Endof Packet #define USB_ErrorCode_SendRecNAK 9 //Send/Received NAK #define USB_ErrorCode_SendStall 10 //Sent Stall #define USB_ErrorCode_UnkPID 11 //Buffer Overun #define USB_ErrorCode_SendEmptyPaket 12 //Send Enpty Packet #define USB_ErrorCode_Bitstuff 13 //Bitstuff Error #define USB_ErrorCode_Sync 14 //Error im Sync #define USB_ErrorCode_WrongToggle 15 //Wrong Toggle Bit in DAA PID //*** Error Status *** #define USB_ErrorStatus_PIDErr 0 //PID Encoding Error oder Unbekannter PID oder Token CRC #define USB_ErrorStatus_UEPKT 1 //Unerlaubtes Paket #define USB_ErrorStatus_DCRC 4 //Data CRC Fehler #define USB_ErrorStatus_TimeErr 8 //Time Out Error #define USB_ErrorStatus_EoD 16 //End of Packet Fehler #define USB_ErrorStatus_BOVRN 32 //Bufferueberlauf #define USB_ErrorStatus_BTSTF 64 //Bit stuff Fehler #define USB_ErrorStatus_TGLERR 128 //Fehlerhaftes Togglebit im Data PID /******************************************************************************************************************************** * Function: void USBCmdToSIE(unsigned char CMD_Code, unsigned char CMD_Data) * * Input: CMD_Code = Befehl * CMD_Data = Daten * * Output: none * * Overview: - Schreibt einen Befehl mit den entsprechenden Daten in den SIE * - Wartet bis der SIE den Erhalt des Befehls quittiert und schreibt anschliessend automatisch * die Daten in den SIE * *******************************************************************************************************************************/ void USBCmdToSIE(unsigned char CMD_Code, unsigned char CMD_Data) { //*** SIE Operationstyp "Command" laden *** LPC_USB->USBDevIntClr = 0x10; //Loesche CCEMPTY Bit LPC_USB->USBCmdCode = (CMD_Code << 16); //Schreibe den Code ins SIE Register LPC_USB->USBCmdCode = LPC_USB->USBCmdCode | (USB_SIE_Command << 8); //Schreibe den SIE Operationstyp ins SIE Register while((LPC_USB->USBDevIntSt & 0x10) == 0x00); //Warte bis der Befehl beschrieben wurde LPC_USB->USBDevIntClr = 0x10; //Loesche CCEMPTY Bit //*** SIE Daten in den Ausgewaehlten SIE Register schreiben *** LPC_USB->USBCmdCode = (CMD_Data << 16); //Schreibe die Daten ins SIE Register LPC_USB->USBCmdCode = LPC_USB->USBCmdCode | (USB_SIE_Write << 8); //Schreibe den SIE Operationsty WRITE ins SIE Register while((LPC_USB->USBDevIntSt & 0x10) == 0x00); //Warte bis der Befehl beschrieben wurde LPC_USB->USBDevIntClr = 0x10; //Loesche CCEMPTY Bit } /******************************************************************************************************************************** * Function: unsigned int USBSIEtoCPU(unsigned char CMD_Code, unsigned char CMD_Data) * * Input: CMD_Code = Befehl * CMD_Data = Daten * * Output: Gewaehlte Daten * * Overview: - Liest Daten aus dem SIE heraus * - Schreibt den Befehl an den SIE, dass Daten gelesen werden muessen * - Liest automatisch die Daten aus dem Rueckgaberegister aus * *******************************************************************************************************************************/ unsigned int USBSIEtoCPU(unsigned char CMD_Code, unsigned char CMD_Data) { unsigned int uiReturnvariable; uiReturnvariable = 0x00; //*** SIE Operationstyp "Command" laden *** LPC_USB->USBDevIntClr = 0x30; //Loesche CCEMPTY und CDFULL LPC_USB->USBCmdCode = (CMD_Code << 16); //Schreibe den Code ins SIE Register LPC_USB->USBCmdCode = LPC_USB->USBCmdCode | (USB_SIE_Command << 8); //Schreibe den SIE Operationstyp ins SIE Register while((LPC_USB->USBDevIntSt & 0x10) == 0x00); //Warte bis der Befehl beschrieben wurde LPC_USB->USBDevIntClr = 0x10; //Loesche CCEMPTY Bit //*** SIE Daten in den Ausgewaehlten SIE Register schreiben *** LPC_USB->USBCmdCode = (CMD_Data << 16); //Schreibe die Daten ins SIE Register LPC_USB->USBCmdCode = LPC_USB->USBCmdCode | (USB_SIE_Read << 8); //Schreibe den SIE Operationsty Read ins SIE Register while((LPC_USB->USBDevIntSt & 0x20) == 0x00); //Warte bis der Befehl beschrieben wurde CDFULL LPC_USB->USBDevIntClr = 0x20; //Loesche CDFULL uiReturnvariable = LPC_USB->USBCmdData; //Liest die Daten vom SIE uiReturnvariable = uiReturnvariable << 8; //*** SIE Daten in den Ausgewaehlten SIE Register schreiben *** LPC_USB->USBCmdCode = (CMD_Data << 16); //Schreibe die Daten ins SIE Register LPC_USB->USBCmdCode = LPC_USB->USBCmdCode | (USB_SIE_Read << 8); //Schreibe den SIE Operationsty Read ins SIE Register while((LPC_USB->USBDevIntSt & 0x20) == 0x00); //Warte bis der Befehl beschrieben wurde CDFULL LPC_USB->USBDevIntClr = 0x20; //Loesche CDFULL uiReturnvariable = uiReturnvariable | LPC_USB->USBCmdData; return uiReturnvariable; } //*****************************************// // //*** USB Descriptoren HID // //*****************************************// //********** USB Descriptoren ********* //************************************* //*** USB Device Descriptor *****************************************/ unsigned char Usb_Device_Descriptor[]= { 0x12, //char bLength // Länge des Deskriptors in Byte 0x01, //char bDescriptorType // Kennzeichen für Device-Deskriptor 0x00, 0x02, //int bcdUSB // Kennzeichen für USB2.0 (BCD) 0x00, //char bDeviceClass // Geräteklasse 0x00, //char bDeviceSubClass // Geräteunterklasse 0x00, //char bDeviceProtocol // Geräteprotokoll 0x08, //char bMaxPacketSize0 // 8 / 16 / 32 / 64 Größe des Pufferspeichers von Endpunkt0 0xD8, 0x04, //int idVendor // Hersteller-ID von Microchip 0x03, 0x00, //int idProduct // ..0xFFFF Produkt-ID 0x01, 0x00, //int bcdDevice // ..0x9999 Device-Relaise (BCD) 0x01, //char iManufacturer // Index des Strings für den Herstellernamen 0x02, //char iProduct // Indes des Strings der Produktbeschreibung 0x00, //char iSerialnumber // Index des Strings mit der Seriennummer des Device 0x01 //char bNumConfigurations // 1...255 Anzahl der möglichen Configurationen }; //*** USB Konfiguration Descriptor ***************************************** unsigned char Usb_Descriptor[]= { 0x09, //char bLength // Länge des Deskriptors in Byte 0x02, //char bDescriptorType // Kennzeichen für Konfigurations-Deskriptor 0x3B, 0x00, //int wTotalLength // Länge der gesamten Konfiguration mit Interface- und Endpoint-Deskriptoren 0x02, //char wNumInterfaces // 1..16 Anzahl der Interfaces in dieser Konfiguration 0x01, //char bConfigurationValue // 1.. Kennummer mit der diese Konfiguration via SetConfiguration() ausgewählt wird. 0x00, //char iConfiguration // 0 Index des Strings mit der Beschreibung der Konfiguration 0xC0, //char bmAttributes // self-powered:0xC0 bus-powered;0x80 Einstellung der Stromversorgung und von remote Wakeup 0x50, //char bMaxPower // 50..250 Stromaufnahme aus dem USB-Bus in der Einheit "2 mA" //*** USB Interface Descriptor *** Tastentur ************************************** 0x09, //char bLength // Länge des Deskriptors in Byte 0x04, //char bDescriptorType // Kennzeichen für Interface-Deskriptor 0x01, //char bInterfaceNumber // 0... Nummer dieses Interfaces 0x00, //char bAlternateSettings 0x01, //char bNumEndpoints // 1..16 Anzahl der Endpunkte dieses Interfaces 0x03, //char bInterfaceClass // Klasse 0x01, //char bInterfaceSubClass // SubKlasse 0x01, //char bInterfaceProtokoll // Protokoll 0x00, //char iInterface // Index des Strings mit der Beschreibung des Interfaces //*** USB HID Descriptor *** Tastentur ************************************** 0x09, //char bLength // Size of this descriptor in bytes. 0x09 0x21, //char bDescriptorType // HID descriptor type (assigned by USB). 0x21 0x11, 0x01, //int bcdHID // HID Class Specification release number in binarycoded decimal—for example, 2.10 is 0x210).0x101 0x00, //char bCountryCode // Hardware target country. 0x00 0x01, //char bNumDescriptors // Number of HID class descriptors to follow. 0x01 0x22, //char bDescriptorType // Report descriptor type. 0x22 0x3F, 0x00, //int wDescriptorLength // Total length of Report descriptor. 0x3F //*** USB Endpunkt Descriptor *** Tastentur ************************************** 0x07, //char bLength // Länge des Deskriptors in Byte 0x05, //char bDescriptorType // Kennzeichen für Endpoint-Deskriptor 0x81, //char bEndpointAdress // out: 0x01..0x0F in: 0x81..0x8F Nummer und Datenrichtung des Endpunktes 0x03, //char bmAttributes // Transfer-Typ & Extrainfos für den isochonous-Mode 0x08, 0x00, //int wMaxPacketSize // maximale Datenpaketgröße 0x0A, //char bInterval // Abfrageintervall in der Einheit "1 ms" (low speed) oder "125 µs" (full speed) oder als dBµs //*** USB Interface Descriptor *** Mouse ************************************** 0x09, //char bLength // Länge des Deskriptors in Byte 0x04, //char bDescriptorType // Kennzeichen für Interface-Deskriptor 0x02, //char bInterfaceNumber // 0... Nummer dieses Interfaces 0x00, //char bAlternateSettings 0x01, //char bNumEndpoints // 1..16 Anzahl der Endpunkte dieses Interfaces 0x03, //char bInterfaceClass // Klasse 0x01, //char bInterfaceSubClass // SubKlasse 0x02, //char bInterfaceProtokoll // Protokoll 0x00, //char iInterface // Index des Strings mit der Beschreibung des Interfaces //*** USB HID Descriptor *** Mouse ************************************** 0x09, //char bLength // Size of this descriptor in bytes. 0x09 0x21, //char bDescriptorType // HID descriptor type (assigned by USB). 0x21 0x11, 0x01, //int bcdHID // HID Class Specification release number in binarycoded decimal—for example, 2.10 is 0x210).0x101 0x00, //char bCountryCode // Hardware target country. 0x00 0x01, //char bNumDescriptors // Number of HID class descriptors to follow. 0x01 0x22, //char bDescriptorType // Report descriptor type. 0x22 0x32, 0x00, //int wDescriptorLength // Total length of Report descriptor. 0x3F //*** USB Endpunkt Descriptor *** Mouse ************************************** 0x07, //char bLength // Länge des Deskriptors in Byte 0x05, //char bDescriptorType // Kennzeichen für Endpoint-Deskriptor 0x82, //char bEndpointAdress // out: 0x01..0x0F in: 0x81..0x8F Nummer und Datenrichtung des Endpunktes 0x03, //char bmAttributes // Transfer-Typ & Extrainfos für den isochonous-Mode 0x03, 0x00, //int wMaxPacketSize // maximale Datenpaketgröße 0x08 //char bInterval // Abfrageintervall in der Einheit "1 ms" (low speed) oder "125 µs" (full speed) oder als dBµs }; //*** USB String ***************************************** unsigned char Usb_String0[]={ 0x04, //char bLength // Länge des Deskriptors in Byte 0x03, //char bDescriptorType // Kennzeichen für Endpoint-Deskriptor 0x09, 0x04, //char bString // Kennzeichen der Sprache/Region 409US C09AU 407DE }; unsigned char Usb_String1[]={ 0x0A, //char bLength // Länge des Deskriptors in Byte 0x03, //char bDescriptorType // Kennzeichen für Endpoint-Deskriptor 'S',' ','P',' ','I',' ','!',' ', //char bString // Kennzeichen des Herstellers }; unsigned char Usb_String2[]={ 0x22, //char bLength // Länge des Deskriptors in Byte 0x03, //char bDescriptorType // Kennzeichen für Endpoint-Deskriptor 'H',' ','I',' ','D',' ',' ',' ','T',' ','E',' ','S',' ','T',' ','S',' ','T',' ','R',' ','I',' ','N',' ','G',' ','*',' ','*',' ', }; //*** USB Report Descriptor *** Tastentur ********************************************/ unsigned char USB_Report_Dsc[]= { 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x06, // USAGE (Keyboard) 0xa1, 0x01, // COLLECTION (Application) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x01, // REPORT_SIZE (1) 0x95, 0x08, // REPORT_COUNT (8) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x08, // REPORT_SIZE (8) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x05, 0x08, // USAGE_PAGE (LEDs) 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 0x29, 0x05, // USAGE_MAXIMUM (Kana) 0x91, 0x02, // OUTPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) 0x75, 0x03, // REPORT_SIZE (3) 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 0x95, 0x06, // REPORT_COUNT (6) 0x75, 0x08, // REPORT_SIZE (8) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x65, // LOGICAL_MAXIMUM (101) 0x05, 0x07, // USAGE_PAGE (Keyboard) 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 0x81, 0x00, // INPUT (Data,Ary,Abs) 0xc0 // End Collection }; //*** USB Report Descriptor *** Mouse ********************************************/ unsigned char USB_Report_Dsc1[]= { 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x02, /* Usage (Mouse) */ 0xA1, 0x01, /* Collection (Application) */ 0x09, 0x01, /* Usage (Pointer) */ 0xA1, 0x00, /* Collection (Physical) */ 0x05, 0x09, /* Usage Page (Buttons) */ 0x19, 0x01, /* Usage Minimum (01) */ 0x29, 0x03, /* Usage Maximum (03) */ 0x15, 0x00, /* Logical Minimum (0) */ 0x25, 0x01, /* Logical Maximum (0) */ 0x95, 0x03, /* Report Count (3) */ 0x75, 0x01, /* Report Size (1) */ 0x81, 0x02, /* Input (Data, Variable, Absolute) */ 0x95, 0x01, /* Report Count (1) */ 0x75, 0x05, /* Report Size (5) */ 0x81, 0x01, /* Input (Constant) ;5 bit padding */ 0x05, 0x01, /* Usage Page (Generic Desktop) */ 0x09, 0x30, /* Usage (X) */ 0x09, 0x31, /* Usage (Y) */ 0x15, 0x81, /* Logical Minimum (-127) */ 0x25, 0x7F, /* Logical Maximum (127) */ 0x75, 0x08, /* Report Size (8) */ 0x95, 0x02, /* Report Count (2) */ 0x81, 0x06, /* Input (Data, Variable, Relative) */ 0xC0, 0xC0 /* End Collection,End Collection */ }; /******************************************************************************************************************************** * Function: void USB_ReadEndpoint(unsigned char ucEndpointNr) * * Input: ucEndpointNr = Endpunkt aus welchem gelesen werden soll * * Output: none * * Overview: - Liest saemtliche Daten vom Eingestellen Endpunkt * - Empfangende Daten werden im Array ucEpREceived gespeichert * *******************************************************************************************************************************/ void USB_ReadEndpoint(unsigned char ucEndpointNr) { unsigned char ucPaketlaenge, ucCounter; ucPaketlaenge = ucCounter = 0x00; for(ucCounter=0; ucCounterUSBCtrl = 0x00; LPC_USB->USBCtrl = Bin(00000001); //RD_EN einschalten LPC_USB->USBCtrl = LPC_USB->USBCtrl | (ucEndpointNr << 2); //LOG_ENDPOINT mit dem ausgewaehlten Endpunkt laden ucPaketlaenge = LPC_USB->USBRxPLen; //Speichert die Laenge des empfangenen Paketes if(ucPaketlaenge > sizeof(ucEpReceived)) //Empfangspaket waehre zu Gross fuer den Empfangsbuffer { return; } while((!(LPC_USB->USBCtrl & 0x01)) && (!(LPC_USB->USBDevIntSt & 0x40))) //Lese solange aus dem Empfangsbuffer bis RD_EN im Register USBCtrl oder RxENDPKT im Register USBDevIntSt gesetzt werden. { ucEpReceived[ucCounter] = LPC_USB->USBRxData; //Daten aus dem Empfangsbuffer lesen ucCounter = ucCounter + 1; //Pointer Inkrementieren } USBSIEtoCPU(USB_ClearBuffer, USB_ClearBuffer); } /******************************************************************************************************************************** * Function: void USB_WriteEndpoint(unsigned char ucEndpointNr, unsigned char ucPaketlaenge) * * Input: ucEndpointNr = Endpunkt aus welchem gelesen werden soll * ucPaketlaenge = Laenge des zu sendenden Paketes in Byte * * Output: none * * Overview: - Liest saemtliche Daten vom Eingestellen Endpunkt * - Zu sendende Daten werden aus dem Array ucEpTransmit gelesen * *******************************************************************************************************************************/ void USB_WriteEndpoint(unsigned char ucEndpointNr, unsigned char ucPaketlaenge) { unsigned char ucCounter; ucCounter = 0x00; //*** USBCtrl *** LPC_USB->USBCtrl = 0x00; LPC_USB->USBCtrl = Bin(00000010); //WR_EN einschalten LPC_USB->USBCtrl = LPC_USB->USBCtrl | (ucEndpointNr << 2); //LOG_ENDPOINT mit dem ausgewaehlten Endpunkt laden LPC_USB->USBTxPLen = ucPaketlaenge; //Anzahl zu sendenden Bytes while(((LPC_USB->USBCtrl & 0x02)) && (!(LPC_USB->USBDevIntSt & 0x80))) //Lese solange aus dem Empfangsbuffer bis WR_EN im Register USBCtrl oder TxENDPKT im Register USBDevIntSt gesetzt werden. { LPC_USB->USBTxData = ucEpTransmit[ucCounter]; //Zu sendende Daten in den Sendebuffer vom SIE laden ucCounter = ucCounter + 1; //Pointer Inkrementieren } USBCmdToSIE(USB_ValidateBuffer, 0x00); //Daten im SIE validieren for(ucCounter=0; ucCounterUSBDevIntSt & 0x08) != 0x00) { GPIO_PinWrite(2,0,0); uiTest1 = LPC_USB->USBDevIntSt; // Disable Endpoint interrupts and clear all interrupts LPC_USB->USBEpIntEn = 0x0E; LPC_USB->USBEpIntClr = 0xFFFFFFFF; LPC_USB->USBDevIntClr = 0xFFFFFFFF; // USB_Register_Init(); } if(!(LPC_USB->USBDevIntSt & Bin(00001110))) //Interruptflag / DEV_STAT, EP_SLOW, EP_FAST ausmaskieren { if(LPC_USB->USBEpIntSt & 0x03) //Rx oder Tx vom EP0 { USB_Init(); //Initialisierung der USB Transaktion } if(LPC_USB->USBEpIntSt & 0x0C) //Rx oder Tx vom EP1 { USB_Tasten_Out(); //Funktion der Tastatur } if(LPC_USB->USBEpIntSt & 0x30) //Rx oder Tx vom EP2 { USB_Mouse_Out(); //Funktion der Maus } if(LPC_USB->USBEpIntSt & 0xC0) //Rx oder Tx vom EP3 { } if(LPC_USB->USBEpIntSt & 0x0300) //Rx oder Tx vom EP4 { } if(LPC_USB->USBEpIntSt & 0x0C00) //Rx oder Tx vom EP5 { } if(LPC_USB->USBEpIntSt & 0x3000) //Rx oder Tx vom EP6 { } if(LPC_USB->USBEpIntSt & 0xC000) //Rx oder Tx vom EP7 { } if(LPC_USB->USBEpIntSt & 0x30000) //Rx oder Tx vom EP8 { } if(LPC_USB->USBEpIntSt & 0xC0000) //Rx oder Tx vom EP9 { } if(LPC_USB->USBEpIntSt & 0x300000) //Rx oder Tx vom EP10 { } if(LPC_USB->USBEpIntSt & 0xC00000) //Rx oder Tx vom EP11 { } if(LPC_USB->USBEpIntSt & 0x3000000) //Rx oder Tx vom EP12 { } if(LPC_USB->USBEpIntSt & 0xC000000) //Rx oder Tx vom EP13 { } if(LPC_USB->USBEpIntSt & 0x30000000) //Rx oder Tx vom EP14 { } if(LPC_USB->USBEpIntSt & 0xC0000000) //Rx oder Tx vom EP15 { } } // LPC_USB->USBDevIntClr = 0xFFFFFFFF; // LPC_USB->USBEpIntClr = 0xFFFFFFFF; // NVIC_ClearPendingIRQ(USB_IRQn); } /******************************************************************************************************************************** * Function: void USB_Init(void) * * Input: none * * Output: none * * Overview: - Funktion fuer die Initialisierung der USB Transaktion mit dem Host (Endpoint 0) * *******************************************************************************************************************************/ void USB_Init(void) { if((LPC_USB->USBDevIntSt & Bin(10000000)) == 1) //Abfrage, ob eine neue Descriptor Anfrage fuer die Ennumeration stattgefunden hat. TxENDPKT wird gesetzt, sobald die Anzahl im Register USBTxLEN festgehaltenen Bytes gesendeten wurden { ucUsbDscEnd=0; //Freigeben der Funktion fuer die Ennumeraion. ucDscCounter=0; //Loeschen der Hilfsvariable. ucDataToggle=0; } if(ucUADDR!=0x00) //USB Adresse setzen. Nicht verschieben!! (UADDR darf erst ein Zyklus nach dem Empfangen der Adresse gesetzt werden) { ucUADDR=ucUADDR; //USB Adresse im SIE setzen. ucUADDR=0x00; //Hilfsvariable loeschen, damit diese Funktion nicht mehr durchlaufen wird. ucUsbDscEnd=0; //Freigeben der Funktion fuer die Ennumeraion. ucDscCounter=0; //Loeschen der Hilfsvariable. } //*** Abschnitt fuer die USB Ennumeration *** //******************************************* if(ucUsbDscEnd==0) //Sperrt nachdem ein String etc. gesendet wurde ein erneutes durchlaufen der USB Ennumeration. { //Um die USB Ennumeration neu zu durchlaufen, muss ein USB Reset oder eine andere Deskriptor Anfrage via EP0 empfangen werden. if(USB_bmRequestType==0x00) //Abfrage vom bmRequestType. (SET_ADDRESS oder SET_CONFIGURATION oder SET_DESCRIPTOR oder SET_FEATURE) { switch(USB_bRequest) //Abfrage vom bmRequest. (SET_ADDRESS oder SET_CONFIGURATION oder SET_DESCRIPTOR oder SET_FEATURE) { case 0x05: //bRequest SET_ADDRESS (USB Adresse setzen) { ucUADDR=USB_wValue_low; //Die Adresse Darf noch nicht in UADDR geschrieben werden. Get_Descriptor_Request(Usb_Device_Descriptor, 0); //Leerer String zurückgeben (ACK) ucUsbDscEnd=0; ucDscCounter=0; break; } case 0x09: //bRequest SET_CONFIGURATION (Konfiguration setzen) { Get_Descriptor_Request(Usb_Device_Descriptor, 0); //Leerer String zurückgeben (ACK) ucUsbDscEnd=0; ucDscCounter=0; break; } } } else if((USB_bmRequestType==0x80)||(USB_bmRequestType==0x81)) //Abfrage vom bmRequestType. (GET_CONFIGURATION oder GET_DESCRIPTOR oder GET_INTERFACE) { switch(USB_bRequest) //Abfrage welche bRequest Anforderung empfangen wurde. (GET_CONFIGURATION oder GET_DESCRIPTOR oder GET_INTERFACE) { case 0x06: //bRequest GET_CONFIGURATION (Konfiguration abfragen) { if(USB_wValue_high==0x01) //Abfrage welche wValue Anforderung empfangen wurde. (Descriptor Index) { //Anfrage der Device Deskriptoren uiUsbReciveLength=0x00; //Abfrage ob der ganze Device Deskriptor oder nur Teile gesendet werden sollen. In USB_wLength_low / USB_wLength_high steht wieviele Zeichen zurückgesendet werden sollen. Sollte USB_wLength_low / USB_wLength_high ungleich Device Deskriptor sein, dann werden nur 8/9Bytes ausgebeben. uiUsbReciveLength=USB_wLength_high; uiUsbReciveLength=uiUsbReciveLength << 8; uiUsbReciveLength=uiUsbReciveLength + USB_wLength_low; if(uiUsbReciveLength==sizeof(Usb_Device_Descriptor)) //Ganzer Device Descriptor ausgeben { if(Get_Descriptor_Request(Usb_Device_Descriptor, sizeof(Usb_Device_Descriptor))!=0) {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. } else { Get_Descriptor_Request(Usb_Device_Descriptor, 8); //Nur die ersten 8 Bytes vom Desciptor ausgeben. (Gem. USB erfolgt danach ein Reset) ucUsbDscEnd=1; //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. } } if(USB_wValue_high==0x02) //Anfrage der Deskriptoren { uiUsbReciveLength=0x00; //Abfrage ob der ganze Deskriptor oder nur Teile gesendet werden sollen. (Analog Device Deskriptor) uiUsbReciveLength=USB_wLength_high; uiUsbReciveLength=uiUsbReciveLength << 8; uiUsbReciveLength=uiUsbReciveLength + USB_wLength_low; if(uiUsbReciveLength==0x09) { if(Get_Descriptor_Request(Usb_Descriptor, 0x09)!=0) //9 Bytes vom Deskriptor ausgeben. {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. } else { if(Get_Descriptor_Request(Usb_Descriptor, sizeof(Usb_Descriptor))!=0) //Ganzer Deskriptor ausgeben. {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. } break; } if(USB_wValue_high==0x03) //Anfrage der String Deskriptoren { switch(USB_wValue_low) //Anfrage welcher String genau gesendet werden soll { case 0: //Anfrage String wLANGID { if(Get_Descriptor_Request(Usb_String0, sizeof(Usb_String0))!=0) {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. break; } case 1: { if(Get_Descriptor_Request(Usb_String1, sizeof(Usb_String1))!=0) {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. break; } case 2: { if(Get_Descriptor_Request(Usb_String2, sizeof(Usb_String2))!=0) {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. break; } } } if(USB_wValue_high==0x06) //STALL senden da eine Anfrage 0x06 nicht bekannt ist. { /////************** NOCH VOM PIC HER !!!! ************** // iUsbPtr=(char*)USB_BD0_IN_LAENGE; // *iUsbPtr=0x00; // iUsbPtr=(char*)USB_BD0_IN_STATUS; // *iUsbPtr=0xCC; } if(USB_wValue_high==0x22) //Report Deskriptoren senden { if(USB_wIndex_low==0x01) //Report Deskriptor der Konfiguration Nr. 1 senden { if(Get_Descriptor_Request(USB_Report_Dsc, sizeof(USB_Report_Dsc))!=0) {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. } if(USB_wIndex_low==0x02) //Report Deskriptor der Konfiguration Nr. 2 senden { if(Get_Descriptor_Request(USB_Report_Dsc1, sizeof(USB_Report_Dsc1))!=0) {ucUsbDscEnd=1;} //Nachdem der String komplett gesendet wurde, sperrt diese Variable ein erneutes abarbeiten der USB Ennumeration. } } break; } } } else if(USB_bmRequestType==0x21) //Anfrage Class Interface { Get_Descriptor_Request(Usb_Device_Descriptor, 0); //Leerer String zurückgeben (ACK) ucUsbDscEnd=0; ucDscCounter=0; } else //Unbekannte Anfrage, welche mit einem STALL abgelehnt wird. { /////************** NOCH VOM PIC HER !!!! ************** // iUsbPtr=(char*)USB_BD0_IN_LAENGE; // *iUsbPtr=0x00; // iUsbPtr=(char*)USB_BD0_IN_STATUS; // *iUsbPtr=0xCC; } } if((LPC_USB->USBDevIntSt & Bin(0000001000)) == 1) //Reset Empfangen { GPIO_PinWrite(2,0,0); USB_Register_Init(); // USBProtocolResetHandler(); ucDscCounter=0; ucUsbDscEnd=0; ucDataToggle=0; } } /******************************************************************************************************************************** * Function: char Get_Descriptor_Request(unsigned char *DscPtr, unsigned char ucLength) * * Input: none * * Output: none * * Overview: - Funktion fuer die Ausgabe der Descriptoren. * - Diese Funktion wird vom Endpunkt 0 aus aufgerufen! * *******************************************************************************************************************************/ char Get_Descriptor_Request(unsigned char *DscPtr, unsigned char ucLength) { unsigned char i; for(i=ucDscCounter;((i<(ucDscCounter+8))&&(iUSBTxData = USB_EP0_OUT_BYTE[i]; //Sendedaten dem USB Engine Transmit Register uebergeben } if(ucLength>=(ucDscCounter+8)) //Solange nicht der komplette String gesendet wurde Returnvariable auf 0 setzen. USB fordert nachdem die 8Byte gesendet wurden nie naechsten 8Byte an!! { ucDscCounter=ucDscCounter+8; //Globale Variable ucDscCounter um 8Byte erhoehen. Wird fuer die naechsten Paketezaehlungen benoetigt LPC_USB->USBTxPLen = 0x08; //Am BD0 mitteilen, dass das naechste Paket wiederum um 8Byte handelt. /////************** NOCH VOM PIC HER !!!! ************** /* iUsbPtr=(char*)USB_BD0_IN_STATUS; if(ucDataToggle==0) //Hilfsvariable welche bei jedem senden vom EP0 Togglet. (Data0 oder Data1) { *iUsbPtr=0xC8; ucDataToggle=1; } else { *iUsbPtr=0x88; ucDataToggle=0; } */ return 0; } else { LPC_USB->USBTxPLen = ucLength-ucDscCounter; //Dito oben, jedoch wird nur noch der Rest des Stringes gesendet. (Senden kleiner 8Byte) ucDscCounter=0; /////************** NOCH VOM PIC HER !!!! ************** /* iUsbPtr=(char*)USB_BD0_IN_STATUS; if(ucDataToggle==0) { *iUsbPtr=0xC8; ucDataToggle=1; } else { *iUsbPtr=0x88; ucDataToggle=0; } */ return 1; } } /******************************************************************************************************************************** * Function: void USBProtocolResetHandler(void) * * Input: none * * Output: none * * Overview: - Bus Reset empfangen * *******************************************************************************************************************************/ void USBProtocolResetHandler(void) { } /******************************************************************************************************************************** * Function: void USB_Init(void) * * Input: none * * Output: none * * Overview: - Funktion fuer die USB HID Tastatur * *******************************************************************************************************************************/ void USB_Tasten_Out(void) //Funktion der Tastatur { /* if(PORTAbits.RA0==1) { ucTaste=0x13; } else { ucTaste=0x00; } iUsbPtr=(char*)USB_BD1_IN_STATUS; //Fraegt ab ob eine USB Anfrage fuer EP1 in BD1 vorhanden ist if(*iUsbPtr<0x80) { ucTastentur[0]=0; //Variablen gemaes USB Spezifikation der Tastatur ucTastentur[1]=0; ucTastentur[2]=ucTaste; ucTastentur[3]=0; ucTastentur[4]=0; ucTastentur[5]=0; ucTastentur[6]=0; ucTastentur[7]=0; iUsbPtr=(char*)USB_BD1_IN_LAENGE; *iUsbPtr=0x08; iUsbPtr=(char*)USB_BD1_IN_STATUS; if(ucDataToggleTasten==0) { *iUsbPtr=0xC8; ucDataToggleTasten=1; } else { *iUsbPtr=0x88; ucDataToggleTasten=0; } } */ } /******************************************************************************************************************************** * Function: void USB_Mouse_Out(void) * * Input: none * * Output: none * * Overview: - Funktion fuer die USB Hid Maus * *******************************************************************************************************************************/ void USB_Mouse_Out(void) //Funktion der Maus { /* iUsbPtr=(char*)USB_BD2_IN_STATUS; //Fraegt ab ob eine USB Anfrage fuer EP2 in BD2 vorhanden ist if(*iUsbPtr<0x80) { ucMouse[0]=0; //Variablen gemaes USB Spezifikation der Maus ucMouse[1]=1; ucMouse[2]=1; iUsbPtr=(char*)USB_BD2_IN_LAENGE; *iUsbPtr=0x03; iUsbPtr=(char*)USB_BD2_IN_STATUS; if(ucDataToggleMouse==0) { *iUsbPtr=0xC8; ucDataToggleMouse=1; } else { *iUsbPtr=0x88; ucDataToggleMouse=0; } } */ } void USB_Register_Init(void) { //*** USB Einstellungen *** //************************* //*** Spannungsfreigabe USB / PCONP *** LPC_SC->PCONP = LPC_SC->PCONP | (1UL << 31); //PCUSB einschalten LPC_SC->USBCLKCFG = 0; //*** PINCON *** //P1.30-USB_VBUS //P1.18-USB PIN Connect LPC_PINCON->PINSEL3 = LPC_PINCON->PINSEL3 | 0x20000010; LPC_PINCON->PINMODE3 = LPC_PINCON->PINMODE3 | 0x20000000; //Pull-Up und Pull-Down am Vbus PIN ausschalten //USB PIN[0]29/30 LPC_PINCON->PINSEL1 = LPC_PINCON->PINSEL1 | 0x14000000; //PIN 0.29 und 0.30 auf USB Stellen LPC_PINCON->PINMODE1 = LPC_PINCON->PINMODE1 | 0x28000000; //Pull-Up und Pull-Down ausschalten //USB PIN[2]9 SoftConnect LPC_PINCON->PINSEL4 = LPC_PINCON->PINSEL4 | 0x00040000; //PIN 2.9 auf SoftConnect einstellen //*** PLL1 Einstellung 48MHz *** //****************************** LPC_SC->PLL1CFG = 0x23; LPC_SC->PLL1FEED = 0xAA; LPC_SC->PLL1FEED = 0x55; LPC_SC->PLL1CON = 0x01; // PLL1 Enable LPC_SC->PLL1FEED = 0xAA; LPC_SC->PLL1FEED = 0x55; while (!(LPC_SC->PLL1STAT & (1<<10))); // Wait for PLOCK1 LPC_SC->PLL1CON = 0x03; // PLL1 Enable & Connect LPC_SC->PLL1FEED = 0xAA; LPC_SC->PLL1FEED = 0x55; while (!(LPC_SC->PLL1STAT & ((1<< 9) | (1<< 8)))); // Wait for PLLC1_STAT & PLLE1_STAT //*** Einstellung USB Engine *** //****************************** //*** USBClkCtrl *** LPC_USB->USBClkCtrl = 0x12; //Device Clock Enable / Disable :Bit1 / AHB Clock Enable / Disable :Bit4 while((LPC_USB->USBClkSt & 0x12) != 0x12); //*** Interrupts loeschen *** LPC_USB->USBEpIntClr = 0xFFFFFFFF; //Endpunkt Interrupt loeschen LPC_USB->USBDevIntClr = 0xFFFFFFFF; //Device Interrupt loeschen //*** Endpunkt 0 *** LPC_USB->USBReEp = LPC_USB->USBReEp | 1; //*** USBEplnd *** LPC_USB->USBEpInd = 0; //:Bit0-4 PHY_EP = Auswahl vom Endpoint //*** USBMaxPSize *** LPC_USB->USBMaxPSize = 8; //:Bit0-9 = MPS / Groesse vom Endpoint while((LPC_USB->USBDevIntSt & 0x0100) == 0x00); //Warte bis EP_RLZED gesetzt wurde LPC_USB->USBDevIntClr = 0x0100; //*** Endpunkt 1 *** LPC_USB->USBReEp = LPC_USB->USBReEp | 2; //*** USBEplnd *** LPC_USB->USBEpInd = 1; //:Bit0-4 PHY_EP = Auswahl vom Endpoint //*** USBMaxPSize *** LPC_USB->USBMaxPSize = 8; //:Bit0-9 = MPS / Groesse vom Endpoint while((LPC_USB->USBDevIntSt & 0x0100) == 0x00); //Warte bis EP_RLZED gesetzt wurde LPC_USB->USBDevIntClr = 0x0100; //*** Endpunkt 2 *** //*** USBEplnd *** LPC_USB->USBReEp = LPC_USB->USBReEp | 4; LPC_USB->USBEpInd = 2; //:Bit0-4 PHY_EP = Auswahl vom Endpoint //*** USBMaxPSize *** LPC_USB->USBMaxPSize = 8; //:Bit0-9 = MPS / Groesse vom Endpoint while((LPC_USB->USBDevIntSt & 0x0100) == 0x00); //Warte bis EP_RLZED gesetzt wurde LPC_USB->USBDevIntClr = 0x0100; //*** Interrupts loeschen *** LPC_USB->USBEpIntClr = 0xFFFFFFFF; //Endpunkt Interrupt loeschen LPC_USB->USBDevIntClr = 0xFFFFFFFF; //Device Interrupt loeschen //*** USBEpIntEn *** LPC_USB->USBEpIntClr = 0xFFFFFFFF; LPC_USB->USBEpIntEn = 0x3F; //Interruptfreigabe EP0, EP1 und EP2. Wird zudaetzlich der Slave Mode fuer diese EP freigegeben //*** USBEpIntPri *** LPC_USB->USBEpIntPri = 0x0000; //Interruptprioritaet der einzelnen Endpunkte //*** USBCmdCode *** //SIE SetMode USBCmdToSIE(USB_SetMode, 0x7F); //*** USBEpDMADis *** //Endpunkte vom DMA loeschen LPC_USB->USBEpDMADis = 0xFFFFFFFC; //*** USBDMARClr *** //Endpunkt DMA Interruptflag loeschen LPC_USB->USBDMARClr = 0xFFFFFFFC; //*** DMA Interrupts loeschen *** LPC_USB->USBEoTIntClr = 0xFFFFFFFF; LPC_USB->USBNDDRIntClr = 0xFFFFFFFF; LPC_USB->USBSysErrIntClr = 0xFFFFFFFF; //*** USBCmdCode *** //SIE SetAddress und DEV_EN einschalten USBCmdToSIE(USB_SetAddress, 0x80); //*** USBDevIntEn *** LPC_USB->USBDevIntEn = 0x0E; //Interruptffreigabe / DEV_STAT, EP_SLOW, EP_FAST LPC_SC->USBIntSt = 0x80000000; //*** Interrupteinstellung *** NVIC_ClearPendingIRQ(USB_IRQn); //Clear pending USB interrupt NVIC_EnableIRQ(USB_IRQn); //USB Interrupt einschalten //*** USBCmdCode *** //CON Pin auf LOW Level setzen USBCmdToSIE(USB_SetDeviceStatus, 0x01); //*** USBCmdCode *** //USB PIN Connect LED einschalten USBCmdToSIE(USB_ConfigureDevice, 0x01); } int main(void) { //*** Startup Einstellung *** //**************************** SystemInit(); SystemCoreClockUpdate (); /* Update system core clock */ //*** Ende Startup Einstellung *** //********************************* //*** GPIO Einstellung *** //************************* //*** Porteinstellung *** GPIO_SetDir(2,0,GPIO_DIR_OUTPUT); GPIO_SetDir(2,1,GPIO_DIR_OUTPUT); GPIO_SetDir(2,2,GPIO_DIR_OUTPUT); GPIO_SetDir(2,3,GPIO_DIR_OUTPUT); GPIO_SetDir(2,4,GPIO_DIR_OUTPUT); GPIO_SetDir(2,5,GPIO_DIR_OUTPUT); GPIO_SetDir(2,6,GPIO_DIR_OUTPUT); GPIO_SetDir(2,7,GPIO_DIR_OUTPUT); GPIO_SetDir(2,8,GPIO_DIR_OUTPUT); GPIO_SetDir(2,9,GPIO_DIR_OUTPUT); GPIO_SetDir(2,10,GPIO_DIR_OUTPUT); GPIO_SetDir(2,11,GPIO_DIR_INPUT); GPIO_SetDir(2,12,GPIO_DIR_INPUT); GPIO_SetDir(2,13,GPIO_DIR_OUTPUT); GPIO_SetDir(1,18,GPIO_DIR_OUTPUT); GPIO_SetDir(1,30,GPIO_DIR_INPUT); GPIO_SetDir(0,29,GPIO_DIR_INPUT); GPIO_SetDir(0,30,GPIO_DIR_INPUT); GPIO_SetDir(2,9,GPIO_DIR_OUTPUT); //*** Einzelne Pins setzen / loeschen GPIO_PinWrite(2,0,1); GPIO_PinWrite(2,1,1); GPIO_PinWrite(2,2,1); GPIO_PinWrite(2,3,1); GPIO_PinWrite(2,4,1); GPIO_PinWrite(2,5,1); GPIO_PinWrite(1,18,1); GPIO_PinWrite(2,9,1); GPDMA_Uninitialize(); // GPIO_PinWrite(2,9,0); USB_Register_Init(); // GPIO_PinWrite(2,9,0); while(1) { if(USBSIEtoCPU(0xFD,0xFD) == 0xA50F) { GPIO_PinWrite(2,2,0); } if(GPIO_PinRead(2,12) == 0x00) { GPIO_PinWrite(2,0,1); GPIO_PinWrite(2,1,1); GPIO_PinWrite(2,2,1); GPIO_PinWrite(2,3,1); GPIO_PinWrite(2,4,1); } } }