Improvements to extrakey HID descriptors (#8156)
This commit is contained in:
parent
ef8878fba5
commit
088b64ab3d
7 changed files with 78 additions and 62 deletions
|
@ -130,7 +130,6 @@ void send_extra(uint8_t report_id, uint16_t data) {
|
||||||
|
|
||||||
void send_system(uint16_t data) {
|
void send_system(uint16_t data) {
|
||||||
#ifdef EXTRAKEY_ENABLE
|
#ifdef EXTRAKEY_ENABLE
|
||||||
if (data != 0) data = data - SYSTEM_POWER_DOWN + 1;
|
|
||||||
send_extra(REPORT_ID_SYSTEM, data);
|
send_extra(REPORT_ID_SYSTEM, data);
|
||||||
#endif // EXTRAKEY_ENABLE
|
#endif // EXTRAKEY_ENABLE
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,7 +327,7 @@ typedef struct {
|
||||||
} udi_hid_exk_desc_t;
|
} udi_hid_exk_desc_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t array[54];
|
uint8_t array[50];
|
||||||
} udi_hid_exk_report_desc_t;
|
} udi_hid_exk_report_desc_t;
|
||||||
|
|
||||||
# define UDI_HID_EXK_DESC \
|
# define UDI_HID_EXK_DESC \
|
||||||
|
@ -429,7 +429,7 @@ typedef struct {
|
||||||
} udi_hid_raw_desc_t;
|
} udi_hid_raw_desc_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t array[27];
|
uint8_t array[26];
|
||||||
} udi_hid_raw_report_desc_t;
|
} udi_hid_raw_report_desc_t;
|
||||||
|
|
||||||
# define UDI_HID_RAW_DESC \
|
# define UDI_HID_RAW_DESC \
|
||||||
|
|
|
@ -377,18 +377,15 @@ static uint8_t udi_hid_exk_report_trans[UDI_HID_EXK_REPORT_SIZE];
|
||||||
|
|
||||||
COMPILER_WORD_ALIGNED
|
COMPILER_WORD_ALIGNED
|
||||||
UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
|
UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
|
||||||
|
// clang-format off
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
0x09, 0x80, // Usage (System Control)
|
0x09, 0x80, // Usage (System Control)
|
||||||
0xA1, 0x01, // Collection (Application)
|
0xA1, 0x01, // Collection (Application)
|
||||||
0x85, REPORT_ID_SYSTEM, // Report ID
|
0x85, REPORT_ID_SYSTEM, // Report ID
|
||||||
0x1A, 0x81,
|
0x19, 0x01, // Usage Minimum (Pointer)
|
||||||
0x00, // Usage Minimum (81) (System Power Down)
|
0x2A, 0xB7, 0x00, // Usage Maximum (System Display LCD Autoscale)
|
||||||
0x2A, 0x83,
|
0x15, 0x01, // Logical Minimum
|
||||||
0x00, // Usage Maximum (83) (System Wake Up)
|
0x26, 0xB7, 0x00, // Logical Maximum
|
||||||
0x16, 0x01,
|
|
||||||
0x00, // Logical Minimum (1)
|
|
||||||
0x26, 0x03,
|
|
||||||
0x00, // Logical Maximum (3)
|
|
||||||
0x95, 0x01, // Report Count (1)
|
0x95, 0x01, // Report Count (1)
|
||||||
0x75, 0x10, // Report Size (16)
|
0x75, 0x10, // Report Size (16)
|
||||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
|
@ -398,18 +395,15 @@ UDC_DESC_STORAGE udi_hid_exk_report_desc_t udi_hid_exk_report_desc = {{
|
||||||
0x09, 0x01, // Usage (Consumer Control)
|
0x09, 0x01, // Usage (Consumer Control)
|
||||||
0xA1, 0x01, // Collection (Application)
|
0xA1, 0x01, // Collection (Application)
|
||||||
0x85, REPORT_ID_CONSUMER, // Report ID
|
0x85, REPORT_ID_CONSUMER, // Report ID
|
||||||
0x1A, 0x01,
|
0x19, 0x01, // Usage Minimum (Consumer Control)
|
||||||
0x00, // Usage Minimum (Consumer Control)
|
0x2A, 0xA0, 0x02, // Usage Maximum (AC Desktop Show All Applications)
|
||||||
0x2A, 0x9C,
|
0x15, 0x01, // Logical Minimum
|
||||||
0x02, // Usage Maximum (AC Distribute Vertically)
|
0x26, 0xA0, 0x02, // Logical Maximum
|
||||||
0x16, 0x01,
|
|
||||||
0x00, // Logical Minimum
|
|
||||||
0x26, 0x9C,
|
|
||||||
0x02, // Logical Maximum
|
|
||||||
0x95, 0x01, // Report Count (1)
|
0x95, 0x01, // Report Count (1)
|
||||||
0x75, 0x10, // Report Size (16)
|
0x75, 0x10, // Report Size (16)
|
||||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
0xC0 // End Collection
|
0xC0 // End Collection
|
||||||
|
//clang-format on
|
||||||
}};
|
}};
|
||||||
|
|
||||||
static bool udi_hid_exk_setreport(void);
|
static bool udi_hid_exk_setreport(void);
|
||||||
|
|
|
@ -732,7 +732,7 @@ void shared_in_cb(USBDriver *usbp, usbep_t ep) {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef EXTRAKEY_ENABLE
|
#ifdef EXTRAKEY_ENABLE
|
||||||
static void send_extra_report(uint8_t report_id, uint16_t data) {
|
static void send_extra(uint8_t report_id, uint16_t data) {
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
|
if (usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) {
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
@ -744,15 +744,19 @@ static void send_extra_report(uint8_t report_id, uint16_t data) {
|
||||||
usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
|
usbStartTransmitI(&USB_DRIVER, SHARED_IN_EPNUM, (uint8_t *)&report, sizeof(report_extra_t));
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void send_system(uint16_t data) { send_extra_report(REPORT_ID_SYSTEM, data); }
|
void send_system(uint16_t data) {
|
||||||
|
#ifdef EXTRAKEY_ENABLE
|
||||||
|
send_extra(REPORT_ID_SYSTEM, data);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void send_consumer(uint16_t data) { send_extra_report(REPORT_ID_CONSUMER, data); }
|
void send_consumer(uint16_t data) {
|
||||||
|
#ifdef EXTRAKEY_ENABLE
|
||||||
#else /* EXTRAKEY_ENABLE */
|
send_extra(REPORT_ID_CONSUMER, data);
|
||||||
void send_system(uint16_t data) { (void)data; }
|
#endif
|
||||||
void send_consumer(uint16_t data) { (void)data; }
|
}
|
||||||
#endif /* EXTRAKEY_ENABLE */
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------
|
/* ---------------------------------------------------------
|
||||||
* Console functions
|
* Console functions
|
||||||
|
|
|
@ -690,7 +690,7 @@ static void send_extra(uint8_t report_id, uint16_t data) {
|
||||||
*/
|
*/
|
||||||
static void send_system(uint16_t data) {
|
static void send_system(uint16_t data) {
|
||||||
#ifdef EXTRAKEY_ENABLE
|
#ifdef EXTRAKEY_ENABLE
|
||||||
send_extra(REPORT_ID_SYSTEM, data - SYSTEM_POWER_DOWN + 1);
|
send_extra(REPORT_ID_SYSTEM, data);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -166,10 +166,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
|
||||||
HID_RI_USAGE(8, 0x80), // System Control
|
HID_RI_USAGE(8, 0x80), // System Control
|
||||||
HID_RI_COLLECTION(8, 0x01), // Application
|
HID_RI_COLLECTION(8, 0x01), // Application
|
||||||
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
|
HID_RI_REPORT_ID(8, REPORT_ID_SYSTEM),
|
||||||
HID_RI_USAGE_MINIMUM(16, 0x0081), // System Power Down
|
HID_RI_USAGE_MINIMUM(8, 0x01), // Pointer
|
||||||
HID_RI_USAGE_MAXIMUM(16, 0x0083), // System Wake Up
|
HID_RI_USAGE_MAXIMUM(16, 0x00B7), // System Display LCD Autoscale
|
||||||
HID_RI_LOGICAL_MINIMUM(16, 0x0001),
|
HID_RI_LOGICAL_MINIMUM(8, 0x01),
|
||||||
HID_RI_LOGICAL_MAXIMUM(16, 0x0003),
|
HID_RI_LOGICAL_MAXIMUM(16, 0x00B7),
|
||||||
HID_RI_REPORT_COUNT(8, 1),
|
HID_RI_REPORT_COUNT(8, 1),
|
||||||
HID_RI_REPORT_SIZE(8, 16),
|
HID_RI_REPORT_SIZE(8, 16),
|
||||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
||||||
|
@ -179,10 +179,10 @@ const USB_Descriptor_HIDReport_Datatype_t PROGMEM SharedReport[] = {
|
||||||
HID_RI_USAGE(8, 0x01), // Consumer Control
|
HID_RI_USAGE(8, 0x01), // Consumer Control
|
||||||
HID_RI_COLLECTION(8, 0x01), // Application
|
HID_RI_COLLECTION(8, 0x01), // Application
|
||||||
HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
|
HID_RI_REPORT_ID(8, REPORT_ID_CONSUMER),
|
||||||
HID_RI_USAGE_MINIMUM(16, 0x0001), // Consumer Control
|
HID_RI_USAGE_MINIMUM(8, 0x01), // Consumer Control
|
||||||
HID_RI_USAGE_MAXIMUM(16, 0x029C), // AC Distribute Vertically
|
HID_RI_USAGE_MAXIMUM(16, 0x02A0), // AC Desktop Show All Applications
|
||||||
HID_RI_LOGICAL_MINIMUM(16, 0x0001),
|
HID_RI_LOGICAL_MINIMUM(8, 0x01),
|
||||||
HID_RI_LOGICAL_MAXIMUM(16, 0x029C),
|
HID_RI_LOGICAL_MAXIMUM(16, 0x02A0),
|
||||||
HID_RI_REPORT_COUNT(8, 1),
|
HID_RI_REPORT_COUNT(8, 1),
|
||||||
HID_RI_REPORT_SIZE(8, 16),
|
HID_RI_REPORT_SIZE(8, 16),
|
||||||
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
HID_RI_INPUT(8, HID_IOF_DATA | HID_IOF_ARRAY | HID_IOF_ABSOLUTE),
|
||||||
|
|
|
@ -129,7 +129,7 @@ static void send_extra(uint8_t report_id, uint16_t data) {
|
||||||
|
|
||||||
static void send_system(uint16_t data) {
|
static void send_system(uint16_t data) {
|
||||||
#ifdef EXTRAKEY_ENABLE
|
#ifdef EXTRAKEY_ENABLE
|
||||||
send_extra(REPORT_ID_SYSTEM, data - SYSTEM_POWER_DOWN + 1);
|
send_extra(REPORT_ID_SYSTEM, data);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,7 +251,9 @@ const PROGMEM uchar keyboard_hid_report[] = {
|
||||||
0xC0 // End Collection
|
0xC0 // End Collection
|
||||||
};
|
};
|
||||||
|
|
||||||
const PROGMEM uchar mouse_hid_report[] = {
|
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||||
|
const PROGMEM uchar mouse_extra_hid_report[] = {
|
||||||
|
# ifdef MOUSE_ENABLE
|
||||||
// Mouse report descriptor
|
// Mouse report descriptor
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
0x09, 0x02, // Usage (Mouse)
|
0x09, 0x02, // Usage (Mouse)
|
||||||
|
@ -300,17 +302,18 @@ const PROGMEM uchar mouse_hid_report[] = {
|
||||||
0x81, 0x06, // Input (Data, Variable, Relative)
|
0x81, 0x06, // Input (Data, Variable, Relative)
|
||||||
0xC0, // End Collection
|
0xC0, // End Collection
|
||||||
0xC0, // End Collection
|
0xC0, // End Collection
|
||||||
|
# endif
|
||||||
|
|
||||||
#ifdef EXTRAKEY_ENABLE
|
# ifdef EXTRAKEY_ENABLE
|
||||||
// Extrakeys report descriptor
|
// Extrakeys report descriptor
|
||||||
0x05, 0x01, // Usage Page (Generic Desktop)
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
||||||
0x09, 0x80, // Usage (System Control)
|
0x09, 0x80, // Usage (System Control)
|
||||||
0xA1, 0x01, // Collection (Application)
|
0xA1, 0x01, // Collection (Application)
|
||||||
0x85, REPORT_ID_SYSTEM, // Report ID
|
0x85, REPORT_ID_SYSTEM, // Report ID
|
||||||
0x1A, 0x81, 0x00, // Usage Minimum (System Power Down)
|
0x19, 0x01, // Usage Minimum (Pointer)
|
||||||
0x2A, 0x83, 0x00, // Usage Maximum (System Wake Up)
|
0x2A, 0xB7, 0x00, // Usage Maximum (System Display LCD Autoscale)
|
||||||
0x16, 0x01, 0x00, // Logical Minimum
|
0x15, 0x01, // Logical Minimum
|
||||||
0x26, 0x03, 0x00, // Logical Maximum
|
0x26, 0xB7, 0x00, // Logical Maximum
|
||||||
0x95, 0x01, // Report Count (1)
|
0x95, 0x01, // Report Count (1)
|
||||||
0x75, 0x10, // Report Size (16)
|
0x75, 0x10, // Report Size (16)
|
||||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
|
@ -320,16 +323,17 @@ const PROGMEM uchar mouse_hid_report[] = {
|
||||||
0x09, 0x01, // Usage (Consumer Control)
|
0x09, 0x01, // Usage (Consumer Control)
|
||||||
0xA1, 0x01, // Collection (Application)
|
0xA1, 0x01, // Collection (Application)
|
||||||
0x85, REPORT_ID_CONSUMER, // Report ID
|
0x85, REPORT_ID_CONSUMER, // Report ID
|
||||||
0x1A, 0x01, 0x00, // Usage Minimum (Consumer Control)
|
0x19, 0x01, // Usage Minimum (Consumer Control)
|
||||||
0x2A, 0x9C, 0x02, // Usage Maximum (AC Distribute Vertically)
|
0x2A, 0xA0, 0x02, // Usage Maximum (AC Desktop Show All Applications)
|
||||||
0x16, 0x01, 0x00, // Logical Minimum
|
0x15, 0x01, // Logical Minimum
|
||||||
0x26, 0x9C, 0x02, // Logical Maximum
|
0x26, 0xA0, 0x02, // Logical Maximum
|
||||||
0x95, 0x01, // Report Count (1)
|
0x95, 0x01, // Report Count (1)
|
||||||
0x75, 0x10, // Report Size (16)
|
0x75, 0x10, // Report Size (16)
|
||||||
0x81, 0x00, // Input (Data, Array, Absolute)
|
0x81, 0x00, // Input (Data, Array, Absolute)
|
||||||
0xC0 // End Collection
|
0xC0 // End Collection
|
||||||
#endif
|
# endif
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef USB_MAX_POWER_CONSUMPTION
|
#ifndef USB_MAX_POWER_CONSUMPTION
|
||||||
# define USB_MAX_POWER_CONSUMPTION 500
|
# define USB_MAX_POWER_CONSUMPTION 500
|
||||||
|
@ -350,10 +354,19 @@ const PROGMEM char usbDescriptorConfiguration[] = {
|
||||||
/* USB configuration descriptor */
|
/* USB configuration descriptor */
|
||||||
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
|
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
|
||||||
USBDESCR_CONFIG, /* descriptor type */
|
USBDESCR_CONFIG, /* descriptor type */
|
||||||
9 + (9 + 9 + 7) + (9 + 9 + 7), 0,
|
# if defined (MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||||
|
59, // 9 + (9 + 9 + 7) + (9 + 9 + 7)
|
||||||
|
#else
|
||||||
|
34, // 9 + (9 + 9 + 7)
|
||||||
|
# endif
|
||||||
|
0,
|
||||||
// 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 9, 0,
|
// 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 9, 0,
|
||||||
/* total length of data returned (including inlined descriptors) */
|
/* total length of data returned (including inlined descriptors) */
|
||||||
|
# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||||
2, /* number of interfaces in this configuration */
|
2, /* number of interfaces in this configuration */
|
||||||
|
# else
|
||||||
|
1,
|
||||||
|
#endif
|
||||||
1, /* index of this configuration */
|
1, /* index of this configuration */
|
||||||
0, /* configuration name string index */
|
0, /* configuration name string index */
|
||||||
# if USB_CFG_IS_SELF_POWERED
|
# if USB_CFG_IS_SELF_POWERED
|
||||||
|
@ -391,8 +404,9 @@ const PROGMEM char usbDescriptorConfiguration[] = {
|
||||||
USB_POLLING_INTERVAL_MS, /* in ms */
|
USB_POLLING_INTERVAL_MS, /* in ms */
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
|
# if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||||
/*
|
/*
|
||||||
* Mouse interface
|
* Mouse/extrakeys interface
|
||||||
*/
|
*/
|
||||||
/* Interface descriptor */
|
/* Interface descriptor */
|
||||||
9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
|
9, /* sizeof(usbDescrInterface): length of descriptor in bytes */
|
||||||
|
@ -411,7 +425,7 @@ const PROGMEM char usbDescriptorConfiguration[] = {
|
||||||
0x00, /* target country code */
|
0x00, /* target country code */
|
||||||
0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */
|
0x01, /* number of HID Report (or other HID class) Descriptor infos to follow */
|
||||||
0x22, /* descriptor type: report */
|
0x22, /* descriptor type: report */
|
||||||
sizeof(mouse_hid_report), 0, /* total length of report descriptor */
|
sizeof(mouse_extra_hid_report), 0, /* total length of report descriptor */
|
||||||
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
|
# if USB_CFG_HAVE_INTRIN_ENDPOINT3 /* endpoint descriptor for endpoint 3 */
|
||||||
/* Endpoint descriptor */
|
/* Endpoint descriptor */
|
||||||
7, /* sizeof(usbDescrEndpoint) */
|
7, /* sizeof(usbDescrEndpoint) */
|
||||||
|
@ -421,6 +435,7 @@ const PROGMEM char usbDescriptorConfiguration[] = {
|
||||||
8, 0, /* maximum packet size */
|
8, 0, /* maximum packet size */
|
||||||
USB_POLLING_INTERVAL_MS, /* in ms */
|
USB_POLLING_INTERVAL_MS, /* in ms */
|
||||||
# endif
|
# endif
|
||||||
|
# endif
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -448,10 +463,12 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
|
||||||
usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + 9);
|
usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + 9);
|
||||||
len = 9;
|
len = 9;
|
||||||
break;
|
break;
|
||||||
|
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||||
case 1:
|
case 1:
|
||||||
usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + (9 + 9 + 7) + 9);
|
usbMsgPtr = (unsigned char *)(usbDescriptorConfiguration + 9 + (9 + 9 + 7) + 9);
|
||||||
len = 9;
|
len = 9;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case USBDESCR_HID_REPORT:
|
case USBDESCR_HID_REPORT:
|
||||||
|
@ -461,10 +478,12 @@ USB_PUBLIC usbMsgLen_t usbFunctionDescriptor(struct usbRequest *rq) {
|
||||||
usbMsgPtr = (unsigned char *)keyboard_hid_report;
|
usbMsgPtr = (unsigned char *)keyboard_hid_report;
|
||||||
len = sizeof(keyboard_hid_report);
|
len = sizeof(keyboard_hid_report);
|
||||||
break;
|
break;
|
||||||
|
#if defined(MOUSE_ENABLE) || defined(EXTRAKEY_ENABLE)
|
||||||
case 1:
|
case 1:
|
||||||
usbMsgPtr = (unsigned char *)mouse_hid_report;
|
usbMsgPtr = (unsigned char *)mouse_extra_hid_report;
|
||||||
len = sizeof(mouse_hid_report);
|
len = sizeof(mouse_extra_hid_report);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue