From 6ad3acd15e9859ac9bc77c1eb04d67108dcc5a03 Mon Sep 17 00:00:00 2001 From: AJM Date: Sat, 24 Apr 2010 22:23:50 -0400 Subject: finally got TX working without any delay, there is some weird timing involved in what happens when the line state is toggled (host port disconnected) and theres still data waiting to go out, this will hang any while(txCount != 0) calls. similarly, sending data without checking txCount != 0 will hard fault the chip. This is all handled now by usbSendBytes, which returns -1 for unconnected, and 0 for simply 'waiting to send' --- core/usb/descriptors.c | 6 ++-- core/usb/descriptors.h | 6 ++-- core/usb/usb.c | 89 +++++++++++++++++++++++++++++++++++++++++++++--- core/usb/usb.h | 5 +++ core/usb/usb_callbacks.c | 54 +++++++++++++++++++++++------ core/usb/usb_callbacks.h | 8 +++++ core/usb/usb_config.h | 2 +- core/usb/usb_hardware.h | 2 ++ 8 files changed, 149 insertions(+), 23 deletions(-) (limited to 'core') diff --git a/core/usb/descriptors.c b/core/usb/descriptors.c index 7ff26a2..5038709 100644 --- a/core/usb/descriptors.c +++ b/core/usb/descriptors.c @@ -143,7 +143,7 @@ const USB_Descriptor_Config usbVcomDescriptor_Config = { which is 0x0409 for US English */ -uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = +const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = { USB_DESCRIPTOR_STRING_LEN(1), USB_DESCRIPTOR_TYPE_STRING, @@ -151,7 +151,7 @@ uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)] = 0x04 }; -uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = +const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = { USB_DESCRIPTOR_STRING_LEN(8), USB_DESCRIPTOR_TYPE_STRING, @@ -159,7 +159,7 @@ uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)] = 'L', 0, 'a', 0, 'b', 0, 's', 0 }; -uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)] = +const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)] = { USB_DESCRIPTOR_STRING_LEN(8), USB_DESCRIPTOR_TYPE_STRING, diff --git a/core/usb/descriptors.h b/core/usb/descriptors.h index f15221a..6e96024 100644 --- a/core/usb/descriptors.h +++ b/core/usb/descriptors.h @@ -191,9 +191,9 @@ typedef struct { extern const USB_Descriptor_Device usbVcomDescriptor_Device; extern const USB_Descriptor_Config usbVcomDescriptor_Config; -extern uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)]; -extern uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)]; -extern uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)]; +extern const uint8 usbVcomDescriptor_LangID[USB_DESCRIPTOR_STRING_LEN(1)]; +extern const uint8 usbVcomDescriptor_iManufacturer[USB_DESCRIPTOR_STRING_LEN(8)]; +extern const uint8 usbVcomDescriptor_iProduct[USB_DESCRIPTOR_STRING_LEN(8)]; #if defined(__cplusplus) } diff --git a/core/usb/usb.c b/core/usb/usb.c index 8ef8697..c8a27c2 100644 --- a/core/usb/usb.c +++ b/core/usb/usb.c @@ -334,10 +334,89 @@ if (wIstr & ISTR_CTR & wInterrupt_Mask) #endif } +/* copies data out of sendBuf into the packet memory for + usb, but waits until any previous usb transmissions have + completed before doing this. It returns without waiting + for its data to be sent. most efficient when 64 bytes are copied + at a time. users responsible for not overflowing sendbuf + with len! if > 64 bytes are being sent, then the function + will block at every 64 byte packet +*/ +int16 usbSendBytes(uint8* sendBuf, uint16 len) { +/* while (countTx != 0) { */ +/* if (reset_state == NDTR_NRTS) { */ +/* return 0; */ +/* } */ +/* }/\* wait for pipe to be clear *\/ */ + + if (reset_state == NDTR_NRTS) { + return -1; /* indicates to caller to stop trying, were not connected */ + } + + /* ideally we should wait here, but it gets stuck + for some reason. countTx wont decrement when + theres no host side port reading the data, this is + known, but even if we add the check for NDTR_NRTS it + still gets stuck...*/ + if (countTx != 0) { + return 0; /* indicated to caller to keep trying, were just busy */ + } + + uint16 sent = len; + + while (len > VCOM_TX_EPSIZE) { + countTx = VCOM_TX_EPSIZE; + + UserToPMABufferCopy(sendBuf,VCOM_TX_ADDR,VCOM_TX_EPSIZE); + _SetEPTxCount(VCOM_TX_ENDP,VCOM_TX_EPSIZE); + _SetEPTxValid(VCOM_TX_ENDP); + + while(countTx != 0); + len -= VCOM_TX_EPSIZE; + sendBuf += VCOM_TX_EPSIZE; + } + + if (len != 0) { + countTx = len; + UserToPMABufferCopy(sendBuf,VCOM_TX_ADDR,len); + _SetEPTxCount(VCOM_TX_ENDP,len); + _SetEPTxValid(VCOM_TX_ENDP); + } + + return sent; +} + +/* returns the number of available bytes are in the recv FIFO */ +uint8 usbBytesAvailable(void) { + return VCOM_RX_EPSIZE - maxNewBytes; +} + +/* copies len bytes from the local recieve FIFO (not + usb packet buffer) into recvBuf and deq's the fifo. + will only copy the minimum of len or the available + bytes. returns the number of bytes copied */ +uint8 usbReceiveBytes(uint8* recvBuf, uint8 len) { + uint8 bytesCopied; + + if (len > VCOM_RX_EPSIZE - maxNewBytes) { + len = VCOM_RX_EPSIZE - maxNewBytes; + } + + int i; + for (i=0;i