#ifndef __USB_H__ #define __USB_H__ #include "stm32f4xx.h" class USB { public: typedef uint8_t Uint8; typedef uint16_t Uint16; typedef uint32_t Uint32; enum dev_state_t {DEV_DEFAULT, DEV_ADDRESS, DEV_CONFIGURED}; enum ep_state_t {EP_IDLE, EP_HALT, EP_TX, EP_RX, EP_VOID, EP_NACK}; static const int NULL = 0; protected: dev_state_t dev_state; public: /** * Setup Packet Type Definition */ struct SetupBuffer { Uint8 bmRequestType; // Request recipient, type, and direction Uint8 bRequest; // Specific standard request number Uint16 wValue; // varies according to request Uint16 wIndex; // varies according to request Uint16 wLength; // Number of bytes to transfer // Device Request Direction (bmRequestType bit7) static const Uint8 DRD_MASK = 0x80; // Mask for device request direction static const Uint8 DRD_OUT = 0x00; // OUT: host to device static const Uint8 DRD_IN = 0x80; // IN: device to host // Device Request Type (bmRequestType bit 6-5) static const Uint8 DRT_MASK = 0x60; // Mask for device request type static const Uint8 DRT_STD = 0x00; // Standard device request static const Uint8 DRT_CLASS = 0x20; // Class specific request static const Uint8 DRT_VENDOR = 0x40; // Vendor specific request // Device Request Recipient (bmRequestType bit4-0) static const Uint8 DRR_MASK = 0x1F; // Mask for device request recipient static const Uint8 DRR_DEVICE = 0x00; // Device static const Uint8 DRR_INTERFACE = 0x01; // Interface static const Uint8 DRR_ENDPOINT = 0x02; // Endpoint // Define bmRequestType bitmaps static const Uint8 OUT_DEVICE = (DRD_OUT | DRT_STD | DRR_DEVICE); static const Uint8 IN_DEVICE = (DRD_IN | DRT_STD | DRR_DEVICE); static const Uint8 OUT_INTERFACE = (DRD_OUT | DRT_STD | DRR_INTERFACE); static const Uint8 IN_INTERFACE = (DRD_IN | DRT_STD | DRR_INTERFACE); static const Uint8 OUT_ENDPOINT = (DRD_OUT | DRT_STD | DRR_ENDPOINT); static const Uint8 IN_ENDPOINT = (DRD_IN | DRT_STD | DRR_ENDPOINT); static const Uint8 OUT_CL_INTERFACE = (DRD_OUT | DRT_CLASS | DRR_INTERFACE); static const Uint8 IN_CL_INTERFACE = (DRD_IN | DRT_CLASS | DRR_INTERFACE); static const Uint8 OUT_VR_INTERFACE = (DRD_OUT | DRT_VENDOR | DRR_INTERFACE); static const Uint8 IN_VR_INTERFACE = (DRD_IN | DRT_VENDOR | DRR_INTERFACE); }; virtual int interfaces() const = 0; struct CallbackFunctor { virtual void operator()() = 0; }; protected: virtual Uint8 get_address() const = 0; virtual Uint8 set_address(const Uint8 &new_address) = 0; virtual void suspend(); virtual void resume(); virtual void reset(); virtual bool descriptor(const Uint16 wValue, const Uint16 wIndex, unsigned char **buf, int *size) = 0; virtual bool setup(const int &configuration); public: virtual void ep0_tx(const void *buf, const Uint16 &size) = 0; virtual void ep0_tx(const void *buf, const Uint16 &size, CallbackFunctor &callback) = 0; virtual void ep0_rx(void *buf, const Uint16 &size) = 0; virtual void ep0_rx(void *buf, const Uint16 &size, CallbackFunctor &callback) = 0; /** * エンドポイントの状態を読み出す * * @param ep_index エンドポイントの方向指定付インデックス (DRD_IN or DRD_OUT) | index */ virtual ep_state_t get_ep_state(const Uint8 &ep_index) const = 0; /** * エンドポイントの状態を指定する * * @param ep_index エンドポイントの方向指定付インデックス (DRD_IN or DRD_OUT) | index * @param state * @return 設定後の状態(設定に失敗した場合は設定した状態以外の状態が返る) */ virtual ep_state_t set_ep_state(const Uint8 &ep_index, const ep_state_t &state) = 0; /** * OUTエンドポイントから読み出す * * @param out_index OUTエンドポイントのインデックス * @param buf 読み出しデータを書き込むバッファ * @param size 最大サイズ * @return 実際読み出したサイズ */ virtual Uint16 read(const Uint8 &out_index, void *buf, const Uint16 &size) = 0; /** * OUTエンドポイントから読み飛ばす * * @param out_index OUTエンドポイントのインデックス * @param size 最大サイズ * @return 実際読み飛ばすサイズ */ virtual Uint16 read_skip(const Uint8 &out_index, const Uint16 &size) = 0; /** * INエンドポイントに書き出す * * @param in_index INエンドポイントのインデックス * @param buf 書き込みデータ * @param size 最大サイズ * @return 実際書き込んだサイズ */ virtual Uint16 write(const Uint8 &in_index, const void *buf, const Uint16 &size) = 0; /** * INエンドポイントを特定の文字で埋める * * @param in_index INエンドポイントのインデックス * @param buf 書き込みデータ * @param c 書き込む文字 * @return 実際埋めたサイズ */ virtual Uint16 write_fill(const Uint8 &in_index, const Uint8 c, const Uint16 &size) = 0; class StandardRequest{ public: static const unsigned char one_packet[2]; static const unsigned char zero_packet[2]; // @see Table 9-6 usb20 static const Uint8 DEVICE_REMOTE_WAKEUP = 0x01; // Remote wakeup feature static const Uint8 ENDPOINT_HALT = 0x00; // Endpoint_Halt feature selector static const Uint8 TEST_MODE = 0x02; protected: USB &usb; /** * This routine can clear Halt Endpoint features on EPs. * @see 9.4.1 * */ bool clear_feature(const SetupBuffer &buf); /** * This routine returns current configuration value * @see 9.4.2 * */ bool get_configuration(const SetupBuffer &buf); /** * This routine sets the data pointer and size to correct * descriptor and sets the endpoint status to transmit * @see 9.4.3 */ bool get_descriptor(const SetupBuffer &buf); /** * This routine returns 0x00, since only one interface * is supported by this firmware * @see 9.4.4 */ bool get_interface(const SetupBuffer &buf); /** * This routine returns a two byte status packet to the host * @see 9.4.5 */ bool get_status(const SetupBuffer &buf); /** * Set new function address * @see 9.4.6 */ bool set_address(const SetupBuffer &buf); /** * This routine allows host to change current device configuration value * @see 9.4.7 */ bool set_configuration(const SetupBuffer &buf); /** * This routine will set the EP Halt feature for EPs. * @see 9.4.9 */ bool set_feature(const SetupBuffer &buf); /** * This function sets interface if it's supported * @see 9.4.10 */ bool set_interface(const SetupBuffer &buf); public: static const Uint8 GET_STATUS = 0x00; ///< Code for Get Status static const Uint8 CLEAR_FEATURE = 0x01; ///< Code for Clear Feature static const Uint8 SET_FEATURE = 0x03; ///< Code for Set Feature static const Uint8 SET_ADDRESS = 0x05; ///< Code for Set Address static const Uint8 GET_DESCRIPTOR = 0x06; ///< Code for Get Descriptor static const Uint8 SET_DESCRIPTOR = 0x07; ///< Code for Set Descriptor(not used) static const Uint8 GET_CONFIGURATION = 0x08; ///< Code for Get Configuration static const Uint8 SET_CONFIGURATION = 0x09; ///< Code for Set Configuration static const Uint8 GET_INTERFACE = 0x0A; ///< Code for Get Interface static const Uint8 SET_INTERFACE = 0x0B; ///< Code for Set Interface static const Uint8 SYNCH_FRAME = 0x0C; ///< Code for Synch Frame(not used) StandardRequest(USB &target); ~StandardRequest(); bool handle(const SetupBuffer &buf); }; protected: StandardRequest standard_request_handler; virtual bool class_request_handle(const SetupBuffer &buf){return false;} virtual bool vendor_request_handle(const SetupBuffer &buf){return false;} public: enum descriptor_type_t { DSC_TYPE_DEVICE = 0x01, ///< Device Descriptor DSC_TYPE_CONFIG = 0x02, ///< Configuration Descriptor DSC_TYPE_STRING = 0x03, ///< String Descriptor DSC_TYPE_INTERFACE = 0x04, ///< Interface Descriptor DSC_TYPE_ENDPOINT = 0x05, ///< Endpoint Descriptor DSC_TYPE_IASSOC = 0x0B, ///< Interface Association Descriptor }; enum endpoint_transfer_type_t { DSC_EP_CONTROL = 0x00, DSC_EP_ISOC = 0x01, DSC_EP_BULK = 0x02, DSC_EP_INTERRUPT = 0x03, }; struct DeviceDescriptor { Uint8 bLength; // Size of this Descriptor in Bytes Uint8 bDescriptorType; // Descriptor Type (=1) Uint8 bcdUSB_L; // USB Spec Release Number in BCD Uint8 bcdUSB_H; Uint8 bDeviceClass; // Device Class Code Uint8 bDeviceSubClass; // Device Subclass Code Uint8 bDeviceProtocol; // Device Protocol Code Uint8 bMaxPacketSize0; // Maximum Packet Size for EP0 Uint8 idVendor_L; // Vendor ID Uint8 idVendor_H; Uint8 idProduct_L; // Product ID Uint8 idProduct_H; Uint8 bcdDevice_L; // Device Release Number in BCD Uint8 bcdDevice_H; Uint8 iManufacturer; // Index of String Desc for Manufacturer Uint8 iProduct; // Index of String Desc for Product Uint8 iSerialNumber; // Index of String Desc for SerNo Uint8 bNumConfigurations; // Number of possible Configurations }; struct ConfigurationDescriptor { Uint8 bLength; // Size of this Descriptor in Bytes Uint8 bDescriptorType; // Descriptor Type (=2) Uint8 wTotalLength_L; // Total Length of Data for this Conf Uint8 wTotalLength_H; Uint8 bNumInterfaces; // No of Interfaces supported by this Conf Uint8 bConfigurationValue; // Designator Value for *this* Configuration Uint8 iConfiguration; // Index of String Desc for this Conf Uint8 bmAttributes; // Configuration Characteristics (see below) Uint8 bMaxPower; // Max. Power Consumption in this Conf (*2mA) }; struct InterfaceDescriptor { Uint8 bLength; // Size of this Descriptor in Bytes Uint8 bDescriptorType; // Descriptor Type (=4) Uint8 bInterfaceNumber; // Number of *this* Interface (0..) Uint8 bAlternateSetting; // Alternative for this Interface (if any) Uint8 bNumEndpoints; // No of EPs used by this IF (excl. EP0) Uint8 bInterfaceClass; // Interface Class Code Uint8 bInterfaceSubClass; // Interface Subclass Code Uint8 bInterfaceProtocol; // Interface Protocol Code Uint8 iInterface; // Index of String Desc for this Interface }; struct EndpointDescriptor { Uint8 bLength; // Size of this Descriptor in Bytes Uint8 bDescriptorType; // Descriptor Type (=5) Uint8 bEndpointAddress; // Endpoint Address (Number + Direction) Uint8 bmAttributes; // Endpoint Attributes (Transfer Type) Uint8 wMaxPacketSize_L; // Max. Endpoint Packet Size Uint8 wMaxPacketSize_H; Uint8 bInterval; // Polling Interval (Interrupt) ms }; struct InterfaceAssociationDescriptor { Uint8 bLength; // Size of this Descriptor in Bytes Uint8 bDescriptorType; // Descriptor Type (=11) Uint8 bFirstInterface; // Uint8 bInterfaceCount; // Uint8 bFunctionClass; // Function Class Code Uint8 bFunctionSubClass; // Function Subclass Code Uint8 bFunctionProtocol; // Function Protocol Code Uint8 iInterface; // Index of String Desc for this function }; public: USB(); virtual ~USB(); }; #endif /* __USB_H__ */