aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin O'Connor <kevin@koconnor.net>2018-09-30 10:37:48 -0400
committerKevin O'Connor <kevin@koconnor.net>2018-09-30 22:32:19 -0400
commit731236cf2099d1081a4fc9cd6be7ed93631b4ab1 (patch)
treea25913be0e79ee1865eb3094b400cd497f1bb9f8
parent92aea93500c7938c4744501ce58f62a502efa690 (diff)
downloadkutter-731236cf2099d1081a4fc9cd6be7ed93631b4ab1.tar.gz
kutter-731236cf2099d1081a4fc9cd6be7ed93631b4ab1.tar.xz
kutter-731236cf2099d1081a4fc9cd6be7ed93631b4ab1.zip
usb_cdc: Add support for usb_send_ep0_progmem()
Add support for explicitly sending to the ep0 pipe from constant "progmem" memory on the AVR. Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
-rw-r--r--src/avr/pgm.h2
-rw-r--r--src/generic/pgm.h1
-rw-r--r--src/generic/usb_cdc.c7
-rw-r--r--src/generic/usb_cdc.h1
4 files changed, 9 insertions, 2 deletions
diff --git a/src/avr/pgm.h b/src/avr/pgm.h
index ba68d8f9..031ba079 100644
--- a/src/avr/pgm.h
+++ b/src/avr/pgm.h
@@ -5,6 +5,8 @@
#include <avr/pgmspace.h>
+#define NEED_PROGMEM 1
+
#define READP(VAR) ({ \
_Pragma("GCC diagnostic push"); \
_Pragma("GCC diagnostic ignored \"-Wint-to-pointer-cast\""); \
diff --git a/src/generic/pgm.h b/src/generic/pgm.h
index bbdc0ba3..80ef4d1d 100644
--- a/src/generic/pgm.h
+++ b/src/generic/pgm.h
@@ -3,6 +3,7 @@
// This header provides wrappers for the AVR specific "PROGMEM"
// declarations on non-avr platforms.
+#define NEED_PROGMEM 0
#define PROGMEM
#define PSTR(S) S
#define READP(VAR) VAR
diff --git a/src/generic/usb_cdc.c b/src/generic/usb_cdc.c
index 1e12f6a7..3899d7c3 100644
--- a/src/generic/usb_cdc.c
+++ b/src/generic/usb_cdc.c
@@ -290,7 +290,7 @@ static const struct descriptor_s {
// State tracking
enum {
- UX_READ = 1<<0, UX_SEND = 1<<1, UX_SEND_ZLP = 1<<2
+ UX_READ = 1<<0, UX_SEND = 1<<1, UX_SEND_PROGMEM = 1<<2, UX_SEND_ZLP = 1<<3
};
static void *usb_xfer_data;
@@ -315,6 +315,8 @@ usb_do_xfer(void *data, uint_fast8_t size, uint_fast8_t flags)
int_fast8_t ret;
if (flags & UX_READ)
ret = usb_read_ep0(data, xs);
+ else if (NEED_PROGMEM && flags & UX_SEND_PROGMEM)
+ ret = usb_send_ep0_progmem(data, xs);
else
ret = usb_send_ep0(data, xs);
if (ret == xs) {
@@ -359,7 +361,8 @@ usb_req_get_descriptor(struct usb_ctrlrequest *req)
const struct descriptor_s *d = &cdc_descriptors[i];
if (READP(d->wValue) == req->wValue
&& READP(d->wIndex) == req->wIndex) {
- uint_fast8_t size = READP(d->size), flags = UX_SEND;
+ uint_fast8_t size = READP(d->size);
+ uint_fast8_t flags = NEED_PROGMEM ? UX_SEND_PROGMEM : UX_SEND;
if (size > req->wLength)
size = req->wLength;
else if (size < req->wLength)
diff --git a/src/generic/usb_cdc.h b/src/generic/usb_cdc.h
index e152916d..21646900 100644
--- a/src/generic/usb_cdc.h
+++ b/src/generic/usb_cdc.h
@@ -16,6 +16,7 @@ int_fast8_t usb_read_bulk_out(void *data, uint_fast8_t max_len);
int_fast8_t usb_send_bulk_in(void *data, uint_fast8_t len);
int_fast8_t usb_read_ep0(void *data, uint_fast8_t max_len);
int_fast8_t usb_send_ep0(const void *data, uint_fast8_t len);
+int_fast8_t usb_send_ep0_progmem(const void *data, uint_fast8_t len);
void usb_stall_ep0(void);
void usb_set_address(uint_fast8_t addr);
void usb_set_configure(void);