#include <usb/hal/numicro> // USB HAL(Hardware Abstract Layer),新唐 Numicro
#include <usb/hid> // USB HID Class
#include <numicro/nuc/sfr/gpio> // GPIO Register
using namespace usb; // 使用 usb 名空间
using namespace hid; // 使用 hid 名空间
template<typename PARENT, uint32_t PARAM> // 定式
class ep_t : public in::ep_impl_t< // 定义 Endpoint 类
ep_t, PARENT, PARAM, // 定式
10 // 指定 bInterval
> { };
template<typename PARENT, uint32_t PARAM> // 定式
class if_t : public if_impl_t< // 定义 Interface 类
if_t, PARENT, PARAM, // 定式
0, // 指定 bInterfaceSubClass
1, // 指定 bInterfaceProtocol
0, // 指定 String ID
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, 0x06, // Usage (Consumer Control),
collection_t<APPLICATION, // 0xA1, 0x01, // Collection (Application),
logical_extremum_t<0, 1>, // 0x15, 0x00, // Logical Minimum (0),
// 0x25, 0x65, // Logical Maximum (101),
report_size_t<1>, // 0x75, 0x08, // Report Size (1),
report_count_t<2>, // 0x95, 0x01, // 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, 0x07, // 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 : public core::usbd_impl_t< // 定义 USB 类
usbd_t, // 定式
0x110, // bcdUSB
0, // bDeviceClass
0, // bDeviceSubClass
0, // bDeviceProtocol
0x0416, // idVendor
0x5011, // idProduct
0x100, // bcdDevice
1, // iManufacture
2, // iProduct
3, // iSerialNumber
true, // bmAttributes, Bus Powered
false, // bmAttributes, Self Powered
false, // bmAttributes, Remote Wakeup
10_mA, // bMaxPower
0, // iConfiguration
if_t> { // 指定 usb 包含的 Interface,可连续加入多个 Function 和 Interface
public:
__INLINE usbd_t() { }
#if 1
__INLINE bool data_out(uint_fast8_t type, uint_fast8_t request, uint_fast16_t value, uint_fast16_t index, uint_fast16_t length)
{
out();
return true;
}
__INLINE bool data_in(uint_fast8_t type, uint_fast8_t request, uint_fast16_t value, uint_fast16_t index, uint_fast16_t length)
{
in();
return true;
}
#endif
__INLINE const uint8_t* get_string_descriptor(uint_fast8_t index, uint_fast16_t lang_id) // GetDescriptor(String) 处理
{
static const string_langid_t<langid_t::English_UnitedStates> desc0;
static const 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'> desc1;
static const string_t<u'U', u'S', u'B', u' ', u'渭', u'K', u'e', u'y'> desc2;
static const string_t<u'0', u'0', u'0', u'0'> desc3;
static const uint8_t* const descriptor[] {
reinterpret_cast<const uint8_t*>(&desc0),
reinterpret_cast<const uint8_t*>(&desc1),
reinterpret_cast<const uint8_t*>(&desc2),
reinterpret_cast<const uint8_t*>(&desc3)
};
return index < sizeof(descriptor) / sizeof(descriptor[0]) ? descriptor[index] : nullptr;
}
};
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
get_if<0>(usbd).write(&code, sizeof(code)); // 使用 usbd 的 interface 0 发送数据
}
void eint1_isr() // EINT1_IRQn 中断向量 handler
{
eint0_isr();
}
int main()
{
usbd.open(true); // 初始化 usb 对象
while (true);
}