- #include <usbd/hal/numicro/nuc.hpp>
- #include <usbd/hid.hpp>
- #include <sfr/numicro/nuc/gpio.hpp>
- using namespace lestl::usb; // 使用 lestl::usb 名空间
- namespace ukey {
- using namespace hid; // 使用 hid 名空间
- template <typename Parent, typename Param> // 定式
- class ep_t // 定义 Endpoint 类
- : public hid::in::ep_impl_t <
- ep_t, Parent, Param, // 定式
- 64, // 指定 wMaxPacketSize
- 10 // 指定 bInterval
- > { };
- template <typename Parent, typename Param> // 定式
- class if_t : public if_impl_t < // 定义 Interface 类
- if_t, Parent, Param, // 定式
- 0, // 指定 bInterfaceSubClass
- 1, // 指定 bInterfaceProtocol
- string_t <>, // 指定 iInterface
- 0x110, // 指定 bcdHID
- 0, // 指定 bCountryCode
- optional_t < // 定义 hid optional descriptor
- report_t < // 定义 hid report descriptor
- usage_page_t <CONSUMER_DEVICE>, // 0x05, 0x0C, // Usage Page (Consumer Devices),
- usage_t <1>, // 0x09, 0x01, // Usage (Consumer Control),
- collection_t <APPLICATION, // 0xA1, 0x01, // Collection (Application),
- logical_extremum_t <0, 1>, // 0x15, 0x00, // Logical Minimum (0),
- // 0x25, 0x01, // Logical Maximum (1),
- report_size_t <1>, // 0x75, 0x01, // Report Size (1),
- report_count_t <2>, // 0x95, 0x02, // Report Count (2),
- usage_t <0x23, 2>, // 0x0A, 0x23, 0x02,// USAGE (0x223), // WWW Browser
- usage_t <0x94, 1>, // 0x0A, 0x94, 0x01,// USAGE (0x194), // My Computer
- input_t <DATA, VARIABLE, ABSOLUTE>, // 0x81, 0x02, // Input (Data, Variable, Absolute),
- report_count_t <6>, // 0x95, 0x06, // Report Count (6),
- input_t <CONSTANT> // 0x81, 0x01, // Input (Constant)
- > // 0xC0 // End Collection
- >
- >,
- ep_t // 指定本 Interface 包含的 Endpoint
- > {
- public:
- __INLINE void config () // Interface 初始化,当 Set Configuration 时被调用
- {
- if_t::if_impl_t::config (); // 使用默认的 config 处理
- using namespace sfr::gpio;
- *reinterpret_cast<volatile uint32_t*>(0xe000e100) = (1 << EINT0_IRQn) | (1 << EINT1_IRQn); // NVIC 使能 EINT0、EINT1 中断
- GPIOB.IEN()
- .IF_EN14(1) // 使能 EINT0 下降沿中断
- .IR_EN14(1) // 使能 EINT0 上升沿中断
- .IF_EN15(1) // 使能 EINT1 下降沿中断
- .IR_EN15(1); // 使能 EINT1 上升沿中断
- }
- };
- }
- class usbd_t // 定义 USB 类
- : public core::usbd_impl_t <
- usbd_t, // 定式
- 0x110, // bcdUSB
- 0, // bDeviceClass
- 0, // bDeviceSubClass
- 0, // bDeviceProtocol
- 64, // bMaxPacketSize
- 0x0416, // idVendor
- 0x5011, // idProduct
- 0x100, // bcdDevice
- string_langid_t <langid_t::English_UnitedStates>, // 指定 language id
- string_t <u'j', u'.', u'y', u'.', u'l', u'e', u'e', u'@', u'y', u'e', u'a', u'h', u'.', u'n', u'e', u't'>, // iManufacture
- string_t <u'U', u'S', u'B', u' ', u'渭', u'K', u'e', u'y'>, // iProduct
- string_t <u'0', u'0', u'0', u'0'>, // iSerialNumber
- true, // bmAttributes, Bus Powered
- false, // bmAttributes, Self Powered
- false, // bmAttributes, Remote Wakeup
- 10_mA, // bMaxPower
- string_t <>, // iConfiguration
- ukey::if_t> { // 指定 usb 包含的 Interface,可连续加入多个 Function 和 Interface
- public:
- __INLINE usbd_t () { }
- };
- usbd_t usbd; // 定义 USB 类对象
- void usbd_isr () // USBD_IRQn 中断向量 handler
- {
- usbd.isr (); // 调用 USB 类的中断处理
- }
- void eint0_isr () // EINT0_IRQn 中断向量 handler
- {
- static uint8_t code;
- using namespace sfr::gpio;
- auto pin = GPIOB.PIN();
- auto isrc = GPIOB.ISRC();
- GPIOB.ISRC = isrc;
- if (isrc.ISRC14)
- code = pin.PIN14 == 0 ? 1 : 0; // WWW Browser
- else
- code = pin.PIN15 == 0 ? 2 : 0; // My Computer
- static_cast<usbd_t::if_t>(usbd).write (&code, sizeof (code)); // 使用 usbd_t::if_t 发送数据
- }
- void eint1_isr () // EINT1_IRQn 中断向量 handler
- {
- eint0_isr ();
- }
- int main ()
- {
- usbd.open (true); // 初始化 usb 对象
- while (true);
- }