Skip to content

Instantly share code, notes, and snippets.

@wararyo
Last active July 21, 2024 20:08
Show Gist options
  • Save wararyo/770436ae6995665fb7e15b55699b86d0 to your computer and use it in GitHub Desktop.
Save wararyo/770436ae6995665fb7e15b55699b86d0 to your computer and use it in GitHub Desktop.
HID Mouse
// Includes Pointer X/Y, Left Btn, Right Btn, Middle Btn, Vertical Wheel
PROGMEM const char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */
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 (Button)
0x19, 0x01, // USAGE_MINIMUM
0x29, 0x03, // USAGE_MAXIMUM
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x03, // INPUT (Const,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (3)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xC0, // END_COLLECTION
0xC0, // END COLLECTION
};
// Includes Pointer X/Y, Left Btn, Right Btn, Middle Btn, Vertical Wheel
// Reference: https://docs.microsoft.com/en-us/previous-versions/windows/hardware/design/dn613912(v=vs.85)
// https://www.microchip.com/forums/tm.aspx?m=391435
PROGMEM const char usbHidReportDescriptor[118] = { /* USB report descriptor, size must match usbconfig.h */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x02, // COLLECTION (Logical)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
// ------------------------------ Buttons
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x05, // USAGE_MAXIMUM (Button 5)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x05, // REPORT_COUNT (5 Buttons)
0x81, 0x02, // INPUT (Data,Var,Abs)
// ------------------------------ Padding
0x75, 0x03, // REPORT_SIZE (8-5buttons 3)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
// ------------------------------ X,Y position
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,Var,Rel)
0xa1, 0x02, // COLLECTION (Logical)
// ------------------------------ Vertical wheel res multiplier
0x09, 0x48, // USAGE (Resolution Multiplier)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x35, 0x01, // PHYSICAL_MINIMUM (1)
0x45, 0x08, // PHYSICAL_MAXIMUM (8)
0x75, 0x02, // REPORT_SIZE (2)
0x95, 0x01, // REPORT_COUNT (1)
0xa4, // PUSH
0xb1, 0x02, // FEATURE (Data,Var,Abs)
// ------------------------------ Vertical wheel
0x09, 0x38, // USAGE (Wheel)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
0x45, 0x00, // PHYSICAL_MAXIMUM (0)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xa1, 0x02, // COLLECTION (Logical)
// ------------------------------ Horizontal wheel res multiplier
0x09, 0x48, // USAGE (Resolution Multiplier)
0xb4, // POP
0xb1, 0x02, // FEATURE (Data,Var,Abs)
// ------------------------------ Padding for Feature report
0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical
0x45, 0x00, // PHYSICAL_MAXIMUM (0)
0x75, 0x04, // REPORT_SIZE (4)
0xb1, 0x03, // FEATURE (Cnst,Var,Abs)
// ------------------------------ Horizontal wheel
0x05, 0x0c, // USAGE_PAGE (Consumer Devices)
0x0a, 0x38, 0x02, // USAGE (AC Pan)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
};
#define cbi(addr,bit) addr &= ~(1<<bit)
#define sbi(addr,bit) addr |= (1<<bit)
#define tbi(addr,bit) addr ^= (1<<bit)
// PB3: Rotary Encoder A
// PB4: Rotary Encoder B
// Method A: Watch A change and read B
ISR(PCINT0_vect)//A変化
{
if(bit_is_set(PINB,3)) {//立ち上がり(プルアップなので)時のみ処理を行う
_delay_ms(2); //チャタリング防止
cbi(GIFR,PCIF); //チャタリング防止の後で、割り込みフラグをクリア
if (bit_is_set(PINB,3)) { // エンコーダ出力AがやっぱりHighのとき
if (bit_is_clear(PINB,4)) { // エンコーダ出力BがLowのとき
delta++; //時計回り
} else { // エンコーダ出力BがHighのとき
delta--; //反時計回り
}
}
}
}
// Method B: Set Timer and compare current AB and previous AB
ISR(TIMER0_COMPA_vect) {
static const int dir[] = { 0,1,-1,0,-1,0,0,1,1,0,0,-1,0,-1,1,0 }; /* 回転方向テーブル */
static int i;//インデックス
int n;
i = (i << 2) | (bit_is_clear(PINB,3)<<1) | bit_is_clear(PINB,4); /* 前回値と今回値でインデックスとする */
n = dir[i & 0x0F];
delta += n;
}
int __attribute__((noreturn)) main(void)
{
// When Method A
sbi(GIMSK,PCIE);//5 外部割り込み一般許可
sbi(PCMSK,PCINT3);//3 外部割り込み3許可
// When Method B
// CTC 16MHz / 1024 / 127 = 120Hzくらい
TCCR0A = 0b00000010;
TCCR0B = 0b00000011;
OCR0A = 144;
sbi(TIMSK0,OCIE0A);
// Common
cbi(DDRB,PB3);//PB3入力
cbi(DDRB,PB4);//PB4入力
sbi(PORTB,PB3);//PB3内部プルアップ
sbi(PORTB,PB4);//PB4内部プルアップ
sei();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment