aboutsummaryrefslogtreecommitdiffstats
path: root/libmaple/usb/usb_callbacks.c
diff options
context:
space:
mode:
authorAJM <poslathian@poslathian.(none)>2010-05-20 22:47:59 -0400
committerAJM <poslathian@poslathian.(none)>2010-05-20 22:47:59 -0400
commitdcc4c457f0cad15b9d60e8fc3afa913bacacdbc6 (patch)
treead805c404ec1414a330aad74fb833137a44ad136 /libmaple/usb/usb_callbacks.c
parent3d0c8c9b374a9a2e3e9fb296cf8a89239106eea2 (diff)
downloadlibrambutan-dcc4c457f0cad15b9d60e8fc3afa913bacacdbc6.tar.gz
librambutan-dcc4c457f0cad15b9d60e8fc3afa913bacacdbc6.zip
moved the usb directory to its proper home in ./libmaple
also, removed some old usb file, bootVect.h, which setup the static table for the runtime usb lib that no longer exists and was provided by the bootloader rev 1
Diffstat (limited to 'libmaple/usb/usb_callbacks.c')
-rw-r--r--libmaple/usb/usb_callbacks.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/libmaple/usb/usb_callbacks.c b/libmaple/usb/usb_callbacks.c
new file mode 100644
index 0000000..08d62c5
--- /dev/null
+++ b/libmaple/usb/usb_callbacks.c
@@ -0,0 +1,293 @@
+/* insert license */
+
+#include "usb_callbacks.h"
+#include "usb_lib.h"
+#include "descriptors.h"
+#include "usb_config.h"
+#include "usb.h"
+
+ONE_DESCRIPTOR Device_Descriptor = {
+ (uint8*)&usbVcomDescriptor_Device,
+ sizeof(USB_Descriptor_Device)
+};
+
+ONE_DESCRIPTOR Config_Descriptor = {
+ (uint8*)&usbVcomDescriptor_Config,
+ 0x43//sizeof(USB_Descriptor_Config)
+};
+
+ONE_DESCRIPTOR String_Descriptor[3] = {
+ {(uint8*)&usbVcomDescriptor_LangID, USB_DESCRIPTOR_STRING_LEN(1)},
+ {(uint8*)&usbVcomDescriptor_iManufacturer,USB_DESCRIPTOR_STRING_LEN(8)},
+ {(uint8*)&usbVcomDescriptor_iProduct, USB_DESCRIPTOR_STRING_LEN(8)}
+};
+
+uint8 last_request = 0;
+
+USB_Line_Coding line_coding = {
+ bitrate: 115200,
+ format: 0x00, /* stop bits-1 */
+ paritytype: 0x00,
+ datatype: 0x08
+};
+
+uint8 vcomBufferRx[VCOM_RX_EPSIZE];
+uint8 countTx = 0;
+uint8 recvBufIn = 0;
+uint8 recvBufOut = 0;
+uint8 maxNewBytes = VCOM_RX_EPSIZE;
+
+RESET_STATE reset_state = START;
+
+void vcomDataTxCb(void) {
+ /* do whatever after data has been sent to host */
+
+ /* allows usbSendBytes to stop blocking */
+
+
+ countTx = 0;
+}
+
+/* we could get arbitrarily complicated here for speed purposes
+ however, the simple scheme here is to implement a receive fifo
+ and always set the maximum to new bytes to the space remaining
+ in the fifo. this number will be reincremented after calls
+ to usbReceiveBytes */
+void vcomDataRxCb(void) {
+ /* do whatever after data has been received from host */
+
+ /* setEPRxCount on the previous cycle should garuntee
+ we havnt received more bytes than we can fit */
+ uint8 newBytes = GetEPRxCount(VCOM_RX_ENDP);
+ /* assert (newBytes <= maxNewBytes); */
+
+ if (recvBufIn + newBytes < VCOM_RX_EPSIZE) {
+ PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,newBytes);
+ recvBufIn += newBytes;
+ } else {
+ /* we have to copy the data in two chunks because we roll over
+ the edge of the circular buffer */
+ uint8 tailBytes = VCOM_RX_EPSIZE - recvBufIn;
+ uint8 remaining = newBytes - tailBytes;
+
+ PMAToUserBufferCopy(&vcomBufferRx[recvBufIn],VCOM_RX_ADDR,tailBytes);
+ PMAToUserBufferCopy(&vcomBufferRx[0], VCOM_RX_ADDR,remaining);
+
+ recvBufIn = (recvBufIn + newBytes ) % VCOM_RX_EPSIZE;
+ }
+
+ maxNewBytes -= newBytes;
+ SetEPRxCount(VCOM_RX_ENDP,maxNewBytes);
+ SetEPRxValid(VCOM_RX_ENDP);
+}
+
+void vcomManagementCb(void) {
+/* unused. This enpoint would callback if we had sent a linestate
+ changed notification */
+}
+
+u8* vcomGetSetLineCoding(uint16 length) {
+ if (length == 0) {
+ pInformation->Ctrl_Info.Usb_wLength = sizeof(USB_Line_Coding);
+ }
+ return (uint8*)&line_coding;
+}
+
+vcomSetLineState(void) {
+}
+
+void usbInit(void) {
+ pInformation->Current_Configuration = 0;
+ usbPowerOn();
+
+ _SetISTR(0);
+ wInterrupt_Mask = ISR_MSK;
+ _SetCNTR(wInterrupt_Mask);
+
+ usbEnbISR();
+ bDeviceState = UNCONNECTED;
+}
+
+void usbReset(void) {
+ pInformation->Current_Configuration = 0;
+
+ /* current feature is current bmAttributes */
+ pInformation->Current_Feature = (USB_CONFIG_ATTR_BUSPOWERED | USB_CONFIG_ATTR_SELF_POWERED);
+
+ _SetBTABLE(USB_BTABLE_ADDRESS);
+
+ /* setup control endpoint 0 */
+ _SetEPType(ENDP0, EP_CONTROL);
+ _SetEPTxStatus(ENDP0, EP_TX_STALL);
+ _SetEPRxAddr(ENDP0,VCOM_CTRL_RX_ADDR);
+ _SetEPTxAddr(ENDP0,VCOM_CTRL_TX_ADDR);
+ Clear_Status_Out(ENDP0);
+
+ SetEPRxCount(ENDP0, pProperty->MaxPacketSize);
+ SetEPRxValid(ENDP0);
+
+ /* setup management endpoint 1 */
+ SetEPType (VCOM_NOTIFICATION_ENDP, EP_INTERRUPT);
+ SetEPTxAddr (VCOM_NOTIFICATION_ENDP, VCOM_NOTIFICATION_ADDR);
+ SetEPTxStatus (VCOM_NOTIFICATION_ENDP, EP_TX_NAK);
+ SetEPRxStatus (VCOM_NOTIFICATION_ENDP, EP_RX_DIS);
+
+ /* setup data endpoint OUT (rx) */
+/* SetEPType (VCOM_RX_ENDP, EP_BULK); */
+/* SetEPRxAddr (VCOM_RX_ENDP, VCOM_RX_ADDR); */
+/* SetEPRxCount (VCOM_RX_ENDP, VCOM_RX_EPSIZE); */
+/* // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS); */
+/* SetEPRxStatus (VCOM_RX_ENDP, EP_RX_VALID); */
+
+ SetEPType (3, EP_BULK);
+ SetEPRxAddr (3, 0x110);
+ SetEPRxCount (3,64);
+ // SetEPTxStatus (VCOM_RX_ENDP, EP_TX_DIS);
+ SetEPRxStatus (3, EP_RX_VALID);
+
+ /* setup data endpoint IN (tx) */
+ SetEPType (VCOM_TX_ENDP, EP_BULK);
+ SetEPTxAddr (VCOM_TX_ENDP, VCOM_TX_ADDR);
+ SetEPTxStatus (VCOM_TX_ENDP, EP_TX_NAK);
+ SetEPRxStatus (VCOM_TX_ENDP, EP_RX_DIS);
+
+ bDeviceState = ATTACHED;
+ SetDeviceAddress(0);
+
+ /* reset the rx fifo */
+ recvBufIn = 0;
+ recvBufOut = 0;
+ maxNewBytes = VCOM_RX_EPSIZE;
+ countTx = 0;
+}
+
+
+void usbStatusIn(void) {
+ /* adjust the usart line coding
+ if we wish to couple the CDC line coding
+ with the real usart port */
+}
+
+void usbStatusOut(void) {
+}
+
+RESULT usbDataSetup(uint8 request) {
+ uint8 *(*CopyRoutine)(uint16);
+ CopyRoutine = NULL;
+
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
+ switch (request) {
+ case (GET_LINE_CODING):
+ CopyRoutine = vcomGetSetLineCoding;
+ last_request = GET_LINE_CODING;
+ break;
+ case (SET_LINE_CODING):
+ CopyRoutine = vcomGetSetLineCoding;
+ last_request = SET_LINE_CODING;
+ break;
+ default: break;
+ }
+ }
+
+ if (CopyRoutine == NULL) {
+ return USB_UNSUPPORT;
+ }
+
+ pInformation->Ctrl_Info.CopyData = CopyRoutine;
+ pInformation->Ctrl_Info.Usb_wOffset = 0;
+ (*CopyRoutine)(0);
+ return USB_SUCCESS;
+}
+
+RESULT usbNoDataSetup(u8 request) {
+ uint8 new_signal;
+
+ /* we support set com feature but dont handle it */
+ if (Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT)) {
+
+ switch (request) {
+ case (SET_COMM_FEATURE):
+ return USB_SUCCESS;
+ case (SET_CONTROL_LINE_STATE):
+ /* to reset the board, pull both dtr and rts low
+ then pulse dtr by itself */
+ new_signal = pInformation->USBwValues.bw.bb0 & (CONTROL_LINE_DTR | CONTROL_LINE_RTS);
+ switch (reset_state) {
+ /* no default, covered enum */
+ case START:
+ if (new_signal == 0) {
+ reset_state = NDTR_NRTS;
+ }
+ break;
+
+ case NDTR_NRTS:
+ if (new_signal == CONTROL_LINE_DTR) {
+ reset_state = DTR_NRTS;
+ } else if (new_signal == 0) {
+ reset_state = NDTR_NRTS;
+ } else {
+ reset_state = START;
+ }
+ break;
+
+ case DTR_NRTS:
+ if (new_signal == 0) {
+ /* dont reset here, otherwise
+ well likely crash the host! */
+ reset_state = RESET_NOW;
+ } else {
+ reset_state = START;
+ }
+ break;
+ case RESET_NEXT:
+ reset_state = RESET_NOW;
+ break;
+ case RESET_NOW:
+ /* do nothing, wait for reset */
+ break;
+ }
+ return USB_SUCCESS;
+ }
+ }
+ return USB_UNSUPPORT;
+}
+
+RESULT usbGetInterfaceSetting(uint8 interface, uint8 alt_setting) {
+ if (alt_setting > 0) {
+ return USB_UNSUPPORT;
+ } else if (interface > 1) {
+ return USB_UNSUPPORT;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+u8* usbGetDeviceDescriptor(u16 length) {
+ return Standard_GetDescriptorData(length, &Device_Descriptor);
+}
+
+u8* usbGetConfigDescriptor(u16 length) {
+ return Standard_GetDescriptorData(length, &Config_Descriptor);
+}
+
+u8* usbGetStringDescriptor(u16 length) {
+ uint8 wValue0 = pInformation->USBwValue0;
+
+ if (wValue0 > 2) {
+ return NULL;
+ }
+ return Standard_GetDescriptorData(length, &String_Descriptor[wValue0]);
+}
+
+/* internal callbacks to respond to standard requests */
+void usbSetConfiguration(void) {
+ if (pInformation->Current_Configuration != 0) {
+ bDeviceState = CONFIGURED;
+ }
+}
+
+void usbSetDeviceAddress(void) {
+ bDeviceState = ADDRESSED;
+}
+