diff --git a/cpu/arm/at91sam7s/Makefile.at91sam7s b/cpu/arm/at91sam7s/Makefile.at91sam7s index 91b406296..ad2b62cd6 100644 --- a/cpu/arm/at91sam7s/Makefile.at91sam7s +++ b/cpu/arm/at91sam7s/Makefile.at91sam7s @@ -190,4 +190,11 @@ ocd_reset: $(OBJECTDIR)/elfloader.o: echo -n >$@ +clean: clean_cpu + +.PHONY: clean_cpu + +clean_cpu: + -rm -rf $(BUILTSRCDIR) + .PRECIOUS: %-nosyms.$(TARGET) diff --git a/cpu/arm/at91sam7s/usb-arch.c b/cpu/arm/at91sam7s/usb-arch.c index 52bd1de12..da733a2f1 100644 --- a/cpu/arm/at91sam7s/usb-arch.c +++ b/cpu/arm/at91sam7s/usb-arch.c @@ -5,7 +5,7 @@ #include -/* #define DEBUG */ +/* #define DEBUG */ #ifdef DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else @@ -340,7 +340,7 @@ static unsigned int get_receive_capacity(USBBuffer *buffer) { unsigned int capacity = 0; - while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP))) { + while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP|USB_BUFFER_HALT))) { capacity += buffer->left; buffer = buffer->next; } @@ -494,6 +494,16 @@ start_transmit(USBEndpoint *ep) if (!(ep_flags & USB_EP_FLAGS_ENABLED) || !buffer) return USB_WRITE_BLOCK; switch(ep_flags & USB_EP_FLAGS_TYPE_MASK) { case USB_EP_FLAGS_TYPE_BULK: + if (buffer->flags & USB_BUFFER_HALT) { + if (ep->status & 0x01) return USB_WRITE_BLOCK; + ep->status |= 0x01; + if (!(ep->flags & USB_EP_FLAGS_TRANSMITTING)) { + UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep], + AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL); + PRINTF("HALT IN\n"); + } + return USB_WRITE_BLOCK; + } case USB_EP_FLAGS_TYPE_ISO: if (!(ep->flags & USB_EP_FLAGS_TRANSMITTING)) { if (AT91C_UDP_CSR[hw_ep] & AT91C_UDP_TXPKTRDY) return USB_WRITE_BLOCK; @@ -518,8 +528,6 @@ start_transmit(USBEndpoint *ep) if (buffer->left == 0) { if (buffer->flags & USB_BUFFER_SHORT_END) { if (len == 0) { - /* Avoid endless loop */ - buffer->flags &= ~USB_BUFFER_SHORT_END; /* Send zero length packet. */ break; } else { @@ -554,7 +562,19 @@ start_transfer(USBEndpoint *ep) { unsigned int hw_ep = EP_HW_NUM(ep->addr); int res; - while (ep->flags & USB_EP_FLAGS_RECV_PENDING) { + while (1) { + if (!(ep->addr & 0x80)) { + if (ep->buffer && (ep->buffer->flags & USB_BUFFER_HALT)) { + if (ep->status & 0x01) return ; + ep->status |= 0x01; + UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[EP_HW_NUM(ep->addr)], + AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL); + PRINTF("HALT OUT\n"); + *AT91C_UDP_IDR = 1<flags & USB_EP_FLAGS_RECV_PENDING)) break; res = handle_pending_receive(ep); if (res & USB_READ_NOTIFY) { notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION); @@ -609,7 +629,7 @@ start_transfer(USBEndpoint *ep) if (ep->buffer) { if (ep->buffer->flags & USB_BUFFER_IN) { res = start_transmit(ep); - if (res & USB_READ_NOTIFY) { + if (res & USB_WRITE_NOTIFY) { notify_ep_process(ep, USB_EP_EVENT_NOTIFICATION); } } else { @@ -658,6 +678,7 @@ usb_arch_transfer_complete(unsigned int hw_ep) if (ep->status & 0x01) { UDP_SET_EP_CTRL_FLAGS(&AT91C_UDP_CSR[hw_ep], AT91C_UDP_FORCESTALL, AT91C_UDP_FORCESTALL); + PRINTF("HALT IN\n"); } else { start_transfer(ep); } @@ -807,7 +828,16 @@ usb_arch_halt_endpoint(unsigned char ep_addr, int halt) 0, AT91C_UDP_FORCESTALL); *AT91C_UDP_RSTEP = 1<buffer && (ep->buffer->flags & USB_BUFFER_HALT)) { + ep->buffer->flags &= ~USB_BUFFER_SUBMITTED; + if (ep->buffer->flags & USB_BUFFER_NOTIFY) { + notify_ep_process(ep,USB_EP_EVENT_NOTIFICATION); + } + ep->buffer = ep->buffer->next; + } + /* Restart transmission */ start_transfer(&usb_endpoints[EP_INDEX(ep_addr)]); } diff --git a/cpu/arm/common/dbg-io/dbg-printf.c b/cpu/arm/common/dbg-io/dbg-printf.c index dfb865f60..9bd09c1ac 100644 --- a/cpu/arm/common/dbg-io/dbg-printf.c +++ b/cpu/arm/common/dbg-io/dbg-printf.c @@ -6,7 +6,7 @@ static StrFormatResult write_str(void *user_data, const char *data, unsigned int len) { - dbg_send_bytes((unsigned char*)data, len); + if (len > 0) dbg_send_bytes((unsigned char*)data, len); return STRFORMAT_OK; } diff --git a/cpu/arm/common/usb/Makefile.usb b/cpu/arm/common/usb/Makefile.usb index b58b2a9a2..ba3935b59 100644 --- a/cpu/arm/common/usb/Makefile.usb +++ b/cpu/arm/common/usb/Makefile.usb @@ -4,6 +4,8 @@ ifeq (${wildcard $(BUILTSRCDIR)},) DUMMY := ${shell mkdir $(BUILTSRCDIR)} endif +STRUCTGEN = structgen + PROJECTDIRS += $(BUILTSRCDIR) USB_STRING_DESCRIPTORS ?= $(CONTIKI_CPU_ARM)/common/usb/cdc-acm/string-descriptors.xml @@ -26,7 +28,7 @@ endif ifdef USB_MASS_STORAGE_CLASS CONTIKI_CPU_DIRS += ../common/usb/msc -USB += usb-msc-bulk.c usb-rbc.c msc-descriptors.c msc-string-descriptors.c +USB += usb-msc-bulk.c usb-rbc.c msc-descriptors-consts.c msc-descriptors.c XMLDIRS += $(CONTIKI_CPU_ARM)/common/usb/msc endif @@ -42,7 +44,17 @@ USB += usb-msc-bulk.c usb-streaming.c msc-scsi-transparent-descriptors.c msc-str XMLDIRS += $(CONTIKI_CPU_ARM)/common/usb/msc endif +ifdef USB_MTP_CLASS +CONTIKI_CPU_DIRS += ../common/usb/mtp +USB += usb-mtp.c mtp-descriptors-consts.c mtp-descriptors.c +STRUCTGENDIRS += $(CONTIKI_CPU_ARM)/common/usb/mtp +endif + vpath %.xml $(XMLDIRS) +vpath %.gen.c $(STRUCTGENDIRS) %.c: %.xml $(XSLTPROC) $(CONTIKI_CPU_ARM)/common/usb/string-descriptors.xslt $^ >$(BUILTSRCDIR)/$@ + +%-consts.c: %.gen.c + $(CPP) -I$(CFLAGS) $< | $(STRUCTGEN) --output $(BUILTSRCDIR)/$*-consts.c \ No newline at end of file diff --git a/cpu/arm/common/usb/descriptors.h b/cpu/arm/common/usb/descriptors.h index c8bc72745..30808f744 100644 --- a/cpu/arm/common/usb/descriptors.h +++ b/cpu/arm/common/usb/descriptors.h @@ -1,7 +1,9 @@ #ifndef __DESCRIPTORS_H__RPFUB8O7OV__ #define __DESCRIPTORS_H__RPFUB8O7OV__ +#ifndef STRUCTGEN #include "usb.h" +#endif extern const struct usb_st_device_descriptor device_descriptor; extern const struct usb_st_configuration_descriptor const *configuration_head; diff --git a/cpu/arm/common/usb/msc/usb-msc-bulk.c b/cpu/arm/common/usb/msc/usb-msc-bulk.c index 65f650340..fc62831c9 100644 --- a/cpu/arm/common/usb/msc/usb-msc-bulk.c +++ b/cpu/arm/common/usb/msc/usb-msc-bulk.c @@ -5,7 +5,7 @@ #include #include -#define DEBUG +#define DEBUG #ifdef DEBUG #define PRINTF(...) printf(__VA_ARGS__) @@ -65,13 +65,14 @@ usb_msc_send_data_buf_flags(const uint8_t *data, unsigned int len, } state.cmd_data_submitted += len; buf_free = NEXT_BUF(buf_free); -/* PRINTF("usb_msc_send_data: %d\n", len); */ + /* PRINTF("usb_msc_send_data: %d\n", len); */ if (flags & USB_MSC_DATA_SEND) { usb_submit_xmit_buffer(BULK_IN, &data_usb_buffer[buf_first]); buf_first = buf_free; -/* PRINTF("usb_msc_send_data: sent\n"); */ + /* PRINTF("usb_msc_send_data: sent\n"); */ } else if (flags & USB_MSC_DATA_LAST) { /* Cancel transmission */ + PRINTF("Send last\n"); buf_first = buf_free; process_poll(&usb_mass_bulk_process); } @@ -89,7 +90,7 @@ usb_msc_receive_data_buf_flags(uint8_t *data, unsigned int len, { USBBuffer *buffer = &data_usb_buffer[buf_free]; if (buffer->id != USB_BUFFER_ID_UNUSED) { - printf("Data IN buffer busy\n"); + printf("Data OUT buffer busy\n"); return; } buffer->flags = USB_BUFFER_NOTIFY | buf_flags; @@ -363,6 +364,7 @@ PROCESS_THREAD(usb_mass_bulk_request_process, ev , data) uint8_t id = 0; /* Wait for any data to be sent */ while (buf_submitted == buf_free) { + PRINTF("Wait data\n"); PROCESS_WAIT_EVENT(); } #if 0 @@ -379,7 +381,7 @@ PROCESS_THREAD(usb_mass_bulk_request_process, ev , data) } while (!(data_usb_buffer[buf_submitted].flags & USB_BUFFER_SUBMITTED)) { id = data_usb_buffer[buf_submitted].id; - /* PRINTF("id: %02x\n", id); */ + /* PRINTF("id: %02x\n", id); */ if (id == USB_BUFFER_ID_UNUSED) break; state.cmd_data_transfered += buffer_lengths[buf_submitted]; data_usb_buffer[buf_submitted].id = USB_BUFFER_ID_UNUSED; diff --git a/cpu/arm/common/usb/msc/usb-msc-bulk.h b/cpu/arm/common/usb/msc/usb-msc-bulk.h index 0d2a7464b..68f05c654 100644 --- a/cpu/arm/common/usb/msc/usb-msc-bulk.h +++ b/cpu/arm/common/usb/msc/usb-msc-bulk.h @@ -3,39 +3,10 @@ #include #include +#include -#define USB_MSC_BUFFERS 4 +#define USB_MSC_BUFFERS 16 -/* Communication Class */ -/* Class code */ -#define MASS_STORAGE 0x08 - -/* Interface subclass codes */ -#define MASS_RBC 0x01 -#define MASS_SFF_8020i 0x02 -#define MASS_MMC_2 0x02 -#define MASS_QIC_157 0x03 -#define MASS_UFI 0x04 -#define MASS_SFF_8070i 0x05 -#define MASS_SCSI_TRANSP 0x06 - -/* Protocols */ -#define MASS_CBI_COMPLETION 0x00 -#define MASS_CBI_NO_COMPLETION 0x01 -#define MASS_BULK_ONLY 0x50 - -/* Requests */ -#define MASS_BULK_RESET 0xff -#define MASS_BULK_GET_MAX_LUN 0xfe - -#define MASS_BULK_CBW_SIGNATURE 0x43425355 -#define MASS_BULK_CSW_SIGNATURE 0x53425355 - -#define MASS_BULK_CBW_FLAG_IN 0x80 - -#define MASS_BULK_CSW_STATUS_PASSED 0x00 -#define MASS_BULK_CSW_STATUS_FAILED 0x01 -#define MASS_BULK_CSW_STATUS_PHASE_ERROR 0x02 struct usb_msc_bulk_cbw { diff --git a/cpu/arm/common/usb/string-descriptors.h b/cpu/arm/common/usb/string-descriptors.h index 6d0ffea5f..dac3ce535 100644 --- a/cpu/arm/common/usb/string-descriptors.h +++ b/cpu/arm/common/usb/string-descriptors.h @@ -1,16 +1,23 @@ +#ifndef STRUCTGEN #include "usb.h" +#endif +#include + struct usb_st_string_language_map { - Uint16 lang_id; + uint16_t lang_id; const struct usb_st_string_descriptor * const *descriptors; }; struct usb_st_string_languages { - Uchar num_lang; - Uchar max_index; + uint8_t num_lang; + uint8_t max_index; const struct usb_st_language_descriptor *lang_descr; const struct usb_st_string_language_map map[1]; }; extern const struct usb_st_string_languages * const string_languages; + +const uint8_t * +usb_class_get_string_descriptor(uint16_t lang, uint8_t index); diff --git a/cpu/arm/common/usb/usb-api.h b/cpu/arm/common/usb/usb-api.h index 45a67e29f..9286879f9 100644 --- a/cpu/arm/common/usb/usb-api.h +++ b/cpu/arm/common/usb/usb-api.h @@ -37,7 +37,7 @@ struct _USBBuffer /* HALT the endpoint at this point. Only valid for bulk and interrupt endpoints */ -#define USB_BUFFER_HALT 0x20 +#define USB_BUFFER_HALT 0x100 /* Flags set by system */ @@ -78,6 +78,9 @@ struct USBRequestHandlerHook void usb_register_request_handler(struct USBRequestHandlerHook *hook); +void +usb_prepend_request_handler(struct USBRequestHandlerHook *hook); + void usb_setup_bulk_endpoint(uint8_t addr); void diff --git a/cpu/arm/common/usb/usb-core.c b/cpu/arm/common/usb/usb-core.c index 4fae45aaa..662ec95a0 100644 --- a/cpu/arm/common/usb/usb-core.c +++ b/cpu/arm/common/usb/usb-core.c @@ -8,7 +8,7 @@ #include #include -/* #define DEBUG */ +#define DEBUG #ifdef DEBUG #define PRINTF(...) printf(__VA_ARGS__) #else @@ -25,8 +25,8 @@ static USBBuffer ctrl_buffer; #define STATUS_OUT_ID 4 #define STATUS_IN_ID 5 -static unsigned short usb_device_status; -static unsigned char usb_configuration_value; +static uint16_t usb_device_status; +static uint8_t usb_configuration_value; static struct USBRequestHandlerHook *usb_request_handler_hooks = NULL; @@ -35,11 +35,6 @@ static const unsigned short zero_word = 0; static unsigned char usb_flags = 0; #define USB_FLAG_ADDRESS_PENDING 0x01 -#define USB_FLAG_RECEIVING_CTRL 0x04 -#define USB_FLAG_SEND_ZLP 0x08 /* If the last packet has max length, - then it needs to be followed by a - zero length packet to mark the - end. */ static struct process *global_user_event_pocess = NULL; static unsigned int global_user_events = 0; @@ -74,6 +69,9 @@ usb_send_ctrl_response(const uint8_t *data, unsigned int len) len = usb_setup_buffer.wLength; /* Truncate if too long */ } ctrl_buffer.flags = USB_BUFFER_NOTIFY | USB_BUFFER_IN; + if (len < usb_setup_buffer.wLength) { + ctrl_buffer.flags |= USB_BUFFER_SHORT_END; + } ctrl_buffer.next = NULL; ctrl_buffer.data = (uint8_t*)data; ctrl_buffer.left = len; @@ -81,9 +79,12 @@ usb_send_ctrl_response(const uint8_t *data, unsigned int len) usb_submit_xmit_buffer(0,&ctrl_buffer); } +static uint8_t error_stall = 0; + void usb_error_stall() { + error_stall = 1; usb_arch_control_stall(0); } @@ -137,12 +138,13 @@ get_device_descriptor() static void get_string_descriptor() { +#if OLD_STRING_DESCR if (LOW_BYTE(usb_setup_buffer.wValue) == 0) { usb_send_ctrl_response((const unsigned char*)string_languages->lang_descr, string_languages->lang_descr->bLength); } else { - unsigned char l; const struct usb_st_string_descriptor *descriptor; + unsigned char l; const struct usb_st_string_descriptor * const *table; const struct usb_st_string_language_map *map; if (LOW_BYTE(usb_setup_buffer.wValue) > string_languages->max_index) { @@ -165,6 +167,18 @@ get_string_descriptor() usb_send_ctrl_response((const unsigned char*)descriptor, descriptor->bLength); } +#else + const struct usb_st_string_descriptor *descriptor; + descriptor = (struct usb_st_string_descriptor*) + usb_class_get_string_descriptor(usb_setup_buffer.wIndex, + LOW_BYTE(usb_setup_buffer.wValue)); + if (!descriptor) { + usb_error_stall(); + return; + } + usb_send_ctrl_response((const unsigned char*)descriptor, + descriptor->bLength); +#endif } static void @@ -478,6 +492,11 @@ PROCESS_THREAD(usb_process, ev , data) usb_setup_buffer.bmRequestType, usb_setup_buffer.bRequest, usb_setup_buffer.wValue, usb_setup_buffer.wIndex, usb_setup_buffer.wLength); + } + /* Check if any handler stalled the pipe, if so prepare for + next setup */ + if (error_stall) { + error_stall = 0; submit_setup(); } } else { @@ -542,6 +561,13 @@ usb_register_request_handler(struct USBRequestHandlerHook *hook) hook->next = NULL; } +void +usb_prepend_request_handler(struct USBRequestHandlerHook *hook) +{ + hook->next = usb_request_handler_hooks; + usb_request_handler_hooks = hook; +} + unsigned int usb_get_current_configuration(void) diff --git a/cpu/arm/stm32f103/gpio.h b/cpu/arm/stm32f103/gpio.h index 3e79d8779..3469e8015 100644 --- a/cpu/arm/stm32f103/gpio.h +++ b/cpu/arm/stm32f103/gpio.h @@ -66,4 +66,64 @@ _GPIO_OUTPUT_SPEED_##speed(_GPIO_CONF_BIT_REG_##bit(GPIO_,_MODE##bit##_1),\ #define AFIO_REMAP(mask,value) \ MODIFY_REG(AFIO->MAPR, AFIO_MAPR_SWJ_CFG | mask, AFIO_MAPR_SWJ_CFG_VALUE | value); +#define GPIO_CM0 0x000000000000000fLL +#define GPIO_CM1 0x00000000000000f0LL +#define GPIO_CM2 0x0000000000000f00LL +#define GPIO_CM3 0x000000000000f000LL +#define GPIO_CM4 0x00000000000f0000LL +#define GPIO_CM5 0x0000000000f00000LL +#define GPIO_CM6 0x000000000f000000LL +#define GPIO_CM7 0x00000000f0000000LL +#define GPIO_CM8 0x0000000f00000000LL +#define GPIO_CM9 0x000000f000000000LL +#define GPIO_CM10 0x00000f0000000000LL +#define GPIO_CM11 0x0000f00000000000LL +#define GPIO_CM12 0x000f000000000000LL +#define GPIO_CM13 0x00f0000000000000LL +#define GPIO_CM14 0x0f00000000000000LL +#define GPIO_CM15 0xf000000000000000LL + +#define _GPIO_CONF_INPUT_MASK(port, mask , mode) \ + MODIFY_REG(GPIO##port ->CRH,((mask)>>32), (mode & ((mask)>>32))); \ + MODIFY_REG(GPIO##port ->CRL,((mask)&0xffffffff), (mode & ((mask)&0xffffffff))) + +#define GPIO_CONF_INPUT_ANALOG(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x00000000) + +#define GPIO_CONF_INPUT_FLOATING(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x44444444) + +#define GPIO_CONF_INPUT_PU_PD(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x88888888) + +#define GPIO_CONF_OUTPUT_PUSH_PULL_50(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x22222222) +#define GPIO_CONF_OUTPUT_PUSH_PULL_10(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x33333333) +#define GPIO_CONF_OUTPUT_PUSH_PULL_2(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x11111111) + +#define GPIO_CONF_OUTPUT_OPEN_DRAIN_50(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x77777777) +#define GPIO_CONF_OUTPUT_OPEN_DRAIN_10(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x55555555) +#define GPIO_CONF_OUTPUT_OPEN_DRAIN_2(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x66666666) + +#define GPIO_CONF_OUTPUT_ALT_PUSH_PULL_50(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0xbbbbbbbb) +#define GPIO_CONF_OUTPUT_ALT_PUSH_PULL_10(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0x99999999) +#define GPIO_CONF_OUTPUT_ALT_PUSH_PULL_2(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0xaaaaaaaa) + +#define GPIO_CONF_OUTPUT_ALT_OPEN_DRAIN_50(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0xffffffff) +#define GPIO_CONF_OUTPUT_ALT_OPEN_DRAIN_10(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0xdddddddd) +#define GPIO_CONF_OUTPUT_ALT_OPEN_DRAIN_2(port, mask) \ + _GPIO_CONF_INPUT_MASK(port, mask, 0xeeeeeeee) + + + #endif /* __GPIO_H__LK7NAD1HN8__ */ diff --git a/cpu/arm/stm32f103/stm32f10x_conf.h b/cpu/arm/stm32f103/stm32f10x_conf.h index 34213bcea..c29b798fd 100644 --- a/cpu/arm/stm32f103/stm32f10x_conf.h +++ b/cpu/arm/stm32f103/stm32f10x_conf.h @@ -3,14 +3,20 @@ #define _GPIOA #define _GPIOB #define _GPIOC +#define _GPIOD +#define _GPIOE #define _BKP #define _AFIO #define _USART1 #define _NVIC #define _SysTick #define _USB +#define _TIM1 #define _TIM2 #define _TIM3 +#define _TIM4 +#define _I2C1 +#define _I2C2 #define _DMA1_Channel1 #define _DMA1_Channel2 #define _DMA1_Channel3 diff --git a/cpu/arm/stm32f103/usb-arch.c b/cpu/arm/stm32f103/usb-arch.c index c7bbd802c..cf85f35db 100644 --- a/cpu/arm/stm32f103/usb-arch.c +++ b/cpu/arm/stm32f103/usb-arch.c @@ -522,7 +522,7 @@ read_hw_buffer(USBBuffer *buffer, unsigned int offset, unsigned int len) #define USB_WRITE_BLOCK 0x01 #define USB_WRITE_NOTIFY 0x02 -static void +void write_hw_buffer(USBBuffer *buffer,unsigned int offset, unsigned int len) { #ifdef USB_STM32F103_ENABLE_ALT_COPY @@ -531,8 +531,11 @@ write_hw_buffer(USBBuffer *buffer,unsigned int offset, unsigned int len) } else #endif { - const uint8_t *data = buffer->data; - uint32_t *hw_data = ((u32*)USB_MEM_BASE) + offset/2; + const uint8_t *data; + uint32_t *hw_data; + if (len == 0) return; + data = buffer->data; + hw_data = ((u32*)USB_MEM_BASE) + offset/2; buffer->data += len; if (offset & 1) { *hw_data = (*hw_data & 0xff) | (*data++ << 8); @@ -554,7 +557,7 @@ static unsigned int get_receive_capacity(USBBuffer *buffer) { unsigned int capacity = 0; - while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP))) { + while(buffer && !(buffer->flags & (USB_BUFFER_IN| USB_BUFFER_SETUP|USB_BUFFER_HALT))) { capacity += buffer->left; buffer = buffer->next; } @@ -761,10 +764,10 @@ start_transmit(USBEndpoint *ep) break; case USB_EP_FLAGS_TYPE_BULK: if (buffer->flags & USB_BUFFER_HALT) { - if (ep->status & 0x01) return USB_READ_BLOCK; + if (ep->status & 0x01) return USB_WRITE_BLOCK; ep->status |= 0x01; stall_bulk_in(hw_ep); - return USB_READ_BLOCK; + return USB_WRITE_BLOCK; } if (USB->EPR[hw_ep] & USB_EPxR_SW_BUF_TX) { hw_offset = buf_desc->ADDR_TX_1; @@ -790,10 +793,8 @@ start_transmit(USBEndpoint *ep) if (buffer->left == 0) { if (buffer->flags & USB_BUFFER_SHORT_END) { if (len == 0) { - /* Avoid endless loop */ - buffer->flags &= ~USB_BUFFER_SHORT_END; /* Send zero length packet. */ - break; + break; /* Leave without moving to next buffer */ } else { len = 0; }