aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--usbdrv/asmcommon.inc26
-rw-r--r--usbdrv/usbconfig-prototype.h20
-rw-r--r--usbdrv/usbdrv.c29
-rw-r--r--usbdrv/usbdrv.h20
-rw-r--r--usbdrv/usbdrvasm.S4
5 files changed, 88 insertions, 11 deletions
diff --git a/usbdrv/asmcommon.inc b/usbdrv/asmcommon.inc
index d2a4f7c..906dc14 100644
--- a/usbdrv/asmcommon.inc
+++ b/usbdrv/asmcommon.inc
@@ -110,11 +110,17 @@ handleData:
breq doReturn ;[21]
lds x2, usbRxLen ;[22]
tst x2 ;[24]
- brne sendNakAndReti ;[25]
+; 2020-05-04 Following change is used to overcome branch +/- 64 word limit.
+ breq noBranchSendNakAndReti ; [25]
+ rjmp sendNakAndReti
+noBranchSendNakAndReti:
; 2006-03-11: The following two lines fix a problem where the device was not
; recognized if usbPoll() was called less frequently than once every 4 ms.
cpi cnt, 4 ;[26] zero sized data packets are status phase only -- ignore and ack
- brmi sendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP
+; 2020-05-04 Following change is used to overcome branch +/- 64 word limit.
+ brpl noBranchSendAckAndReti ;[27] keep rx buffer clean -- we must not NAK next SETUP
+ rjmp sendAckAndReti
+noBranchSendAckAndReti:
#if USB_CFG_CHECK_DATA_TOGGLING
sts usbCurrentDataToken, token ; store for checking by C code
#endif
@@ -166,6 +172,10 @@ handleIn1: ;[38]
cpi x3, USB_CFG_EP3_NUMBER;[38]
breq handleIn3 ;[39]
#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4
+ cpi x3, USB_CFG_EP4_NUMBER;[38]
+ breq handleIn4 ;[39]
+#endif
lds cnt, usbTxLen1 ;[40]
sbrc cnt, 4 ;[42] all handshake tokens have bit 4 set
rjmp sendCntAndReti ;[43] 47 + 16 = 63 until SOP
@@ -184,4 +194,16 @@ handleIn3:
ldi YH, hi8(usbTxBuf3) ;[48]
rjmp usbSendAndReti ;[49] 51 + 12 = 63 until SOP
#endif
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4
+handleIn4:
+ lds cnt, usbTxLen4 ;[41]
+ sbrc cnt, 4 ;[43]
+ rjmp sendCntAndReti ;[44] 49 + 16 = 65 until SOP
+ sts usbTxLen4, x1 ;[45] x1 == USBPID_NAK from above
+ ldi YL, lo8(usbTxBuf4) ;[47]
+ ldi YH, hi8(usbTxBuf4) ;[48]
+ rjmp usbSendAndReti ;[49] 51 + 12 = 63 until SOP
+#endif
+
#endif
diff --git a/usbdrv/usbconfig-prototype.h b/usbdrv/usbconfig-prototype.h
index 22dd9e8..43b9ba7 100644
--- a/usbdrv/usbconfig-prototype.h
+++ b/usbdrv/usbconfig-prototype.h
@@ -89,9 +89,19 @@ section at the end of this file).
/* If the so-called endpoint 3 is used, it can now be configured to any other
* endpoint number (except 0) with this macro. Default if undefined is 3.
*/
+#define USB_CFG_HAVE_INTRIN_ENDPOINT4 0
+/* Define this to 1 if you want to compile a version with three endpoints: The
+ * default control endpoint 0, an interrupt-in endpoint 4 (or the number
+ * configured below) and a catch-all default interrupt-in endpoint as above.
+ * You must also define USB_CFG_HAVE_INTRIN_ENDPOINT to 1 for this feature.
+ */
+#define USB_CFG_EP4_NUMBER 4
+/* If the so-called endpoint 4 is used, it can now be configured to any other
+ * endpoint number (except 0) with this macro. Default if undefined is 4.
+ */
/* #define USB_INITIAL_DATATOKEN USBPID_DATA1 */
/* The above macro defines the startup condition for data toggling on the
- * interrupt/bulk endpoints 1 and 3. Defaults to USBPID_DATA1.
+ * interrupt/bulk endpoints 1, 3 and 4. Defaults to USBPID_DATA1.
* Since the token is toggled BEFORE sending any data, the first packet is
* sent with the oposite value of this configuration!
*/
@@ -104,10 +114,10 @@ section at the end of this file).
#define USB_CFG_SUPPRESS_INTR_CODE 0
/* Define this to 1 if you want to declare interrupt-in endpoints, but don't
* want to send any data over them. If this macro is defined to 1, functions
- * usbSetInterrupt() and usbSetInterrupt3() are omitted. This is useful if
- * you need the interrupt-in endpoints in order to comply to an interface
- * (e.g. HID), but never want to send any data. This option saves a couple
- * of bytes in flash memory and the transmit buffers in RAM.
+ * usbSetInterrupt(), usbSetInterrupt3() and usbSetInterrupt4() are omitted.
+ * This is useful if you need the interrupt-in endpoints in order to comply
+ * to an interface (e.g. HID), but never want to send any data. This option
+ * saves a couple of bytes in flash memory and the transmit buffers in RAM.
*/
#define USB_CFG_INTR_POLL_INTERVAL 10
/* If you compile a version with endpoint 1 (interrupt-in), this is the poll
diff --git a/usbdrv/usbdrv.c b/usbdrv/usbdrv.c
index 1d80ac6..b0cb565 100644
--- a/usbdrv/usbdrv.c
+++ b/usbdrv/usbdrv.c
@@ -37,6 +37,9 @@ usbTxStatus_t usbTxStatus1;
# if USB_CFG_HAVE_INTRIN_ENDPOINT3
usbTxStatus_t usbTxStatus3;
# endif
+# if USB_CFG_HAVE_INTRIN_ENDPOINT4
+usbTxStatus_t usbTxStatus4;
+# endif
#endif
#if USB_CFG_CHECK_DATA_TOGGLING
uchar usbCurrentDataToken;/* when we check data toggling to ignore duplicate packets */
@@ -139,7 +142,7 @@ PROGMEM const char usbDescriptorDevice[] = { /* USB device descriptor */
PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
USBDESCR_CONFIG, /* descriptor type */
- 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 +
+ 18 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT3 + 7 * USB_CFG_HAVE_INTRIN_ENDPOINT4 +
(USB_CFG_DESCR_PROPS_HID & 0xff), 0,
/* total length of data returned (including inlined descriptors) */
1, /* number of interfaces in this configuration */
@@ -187,6 +190,14 @@ PROGMEM const char usbDescriptorConfiguration[] = { /* USB configuration desc
8, 0, /* maximum packet size */
USB_CFG_INTR_POLL_INTERVAL, /* in ms */
#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4 /* endpoint descriptor for endpoint 4 */
+ 7, /* sizeof(usbDescrEndpoint) */
+ USBDESCR_ENDPOINT, /* descriptor type = endpoint */
+ (char)(0x80 | USB_CFG_EP4_NUMBER), /* IN endpoint number 4 */
+ 0x03, /* attrib: Interrupt endpoint */
+ 8, 0, /* maximum packet size */
+ USB_CFG_INTR_POLL_INTERVAL, /* in ms */
+#endif
};
#endif
@@ -199,6 +210,9 @@ static inline void usbResetDataToggling(void)
# if USB_CFG_HAVE_INTRIN_ENDPOINT3
USB_SET_DATATOKEN3(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
# endif
+# if USB_CFG_HAVE_INTRIN_ENDPOINT4
+ USB_SET_DATATOKEN4(USB_INITIAL_DATATOKEN); /* reset data toggling for interrupt endpoint */
+# endif
#endif
}
@@ -209,6 +223,9 @@ static inline void usbResetStall(void)
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
usbTxLen3 = USBPID_NAK;
#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4
+ usbTxLen4 = USBPID_NAK;
+#endif
#endif
}
@@ -252,6 +269,13 @@ USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len)
usbGenericSetInterrupt(data, len, &usbTxStatus3);
}
#endif
+
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4
+USB_PUBLIC void usbSetInterrupt4(uchar *data, uchar len)
+{
+ usbGenericSetInterrupt(data, len, &usbTxStatus4);
+}
+#endif
#endif /* USB_CFG_SUPPRESS_INTR_CODE */
/* ------------------ utilities for code following below ------------------- */
@@ -628,6 +652,9 @@ USB_PUBLIC void usbInit(void)
#if USB_CFG_HAVE_INTRIN_ENDPOINT3
usbTxLen3 = USBPID_NAK;
#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4
+ usbTxLen4 = USBPID_NAK;
+#endif
#endif
}
diff --git a/usbdrv/usbdrv.h b/usbdrv/usbdrv.h
index f094120..7a44b6d 100644
--- a/usbdrv/usbdrv.h
+++ b/usbdrv/usbdrv.h
@@ -268,6 +268,11 @@ USB_PUBLIC void usbSetInterrupt3(uchar *data, uchar len);
#define usbInterruptIsReady3() (usbTxLen3 & 0x10)
/* Same as above for endpoint 3 */
#endif
+#if USB_CFG_HAVE_INTRIN_ENDPOINT4
+USB_PUBLIC void usbSetInterrupt4(uchar *data, uchar len);
+#define usbInterruptIsReady4() (usbTxLen4 & 0x10)
+/* Same as above for endpoint 4 */
+#endif
#endif /* USB_CFG_HAVE_INTRIN_ENDPOINT */
#if USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH /* simplified interface for backward compatibility */
#define usbHidReportDescriptor usbDescriptorHidReport
@@ -408,8 +413,9 @@ extern volatile schar usbRxLen;
#define USB_SET_DATATOKEN1(token) usbTxBuf1[0] = token
#define USB_SET_DATATOKEN3(token) usbTxBuf3[0] = token
+#define USB_SET_DATATOKEN4(token) usbTxBuf4[0] = token
/* These two macros can be used by application software to reset data toggling
- * for interrupt-in endpoints 1 and 3. Since the token is toggled BEFORE
+ * for interrupt-in endpoints 1, 3 and 4. Since the token is toggled BEFORE
* sending data, you must set the opposite value of the token which should come
* first.
*/
@@ -592,10 +598,18 @@ int usbDescriptorStringSerialNumber[];
#define USB_CFG_EP3_NUMBER 3
#endif
+#ifndef USB_CFG_EP4_NUMBER /* if not defined in usbconfig.h */
+#define USB_CFG_EP4_NUMBER 4
+#endif
+
#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT3
#define USB_CFG_HAVE_INTRIN_ENDPOINT3 0
#endif
+#ifndef USB_CFG_HAVE_INTRIN_ENDPOINT4
+#define USB_CFG_HAVE_INTRIN_ENDPOINT4 0
+#endif
+
#define USB_BUFSIZE 11 /* PID, 8 bytes data, 2 bytes CRC */
/* ----- Try to find registers and bits responsible for ext interrupt 0 ----- */
@@ -683,11 +697,13 @@ typedef struct usbTxStatus{
uchar buffer[USB_BUFSIZE];
}usbTxStatus_t;
-extern usbTxStatus_t usbTxStatus1, usbTxStatus3;
+extern usbTxStatus_t usbTxStatus1, usbTxStatus3, usbTxStatus4;
#define usbTxLen1 usbTxStatus1.len
#define usbTxBuf1 usbTxStatus1.buffer
#define usbTxLen3 usbTxStatus3.len
#define usbTxBuf3 usbTxStatus3.buffer
+#define usbTxLen4 usbTxStatus4.len
+#define usbTxBuf4 usbTxStatus4.buffer
typedef union usbWord{
diff --git a/usbdrv/usbdrvasm.S b/usbdrv/usbdrvasm.S
index 3bda63c..91a7abb 100644
--- a/usbdrv/usbdrvasm.S
+++ b/usbdrv/usbdrvasm.S
@@ -35,7 +35,7 @@ the file appropriate for the given clock rate.
#ifdef __IAR_SYSTEMS_ASM__
extern usbRxBuf, usbDeviceAddr, usbNewDeviceAddr, usbInputBufOffset
extern usbCurrentTok, usbRxLen, usbRxToken, usbTxLen
- extern usbTxBuf, usbTxStatus1, usbTxStatus3
+ extern usbTxBuf, usbTxStatus1, usbTxStatus3, usbTxStatus4
# if USB_COUNT_SOF
extern usbSofCount
# endif
@@ -82,6 +82,8 @@ the file appropriate for the given clock rate.
#define usbTxBuf1 (usbTxStatus1 + 1)
#define usbTxLen3 usbTxStatus3
#define usbTxBuf3 (usbTxStatus3 + 1)
+#define usbTxLen4 usbTxStatus4
+#define usbTxBuf4 (usbTxStatus4 + 1)
;----------------------------------------------------------------------------