From 731236cf2099d1081a4fc9cd6be7ed93631b4ab1 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Sun, 30 Sep 2018 10:37:48 -0400 Subject: [PATCH] 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 --- src/avr/pgm.h | 2 ++ src/generic/pgm.h | 1 + src/generic/usb_cdc.c | 7 +++++-- src/generic/usb_cdc.h | 1 + 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 +#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);