initial usb
[rapper.git] / new_cmsis / usb / cdcuser.c
diff --git a/new_cmsis/usb/cdcuser.c b/new_cmsis/usb/cdcuser.c
new file mode 100755 (executable)
index 0000000..3b4f52f
--- /dev/null
@@ -0,0 +1,379 @@
+/*----------------------------------------------------------------------------\r
+ *      U S B  -  K e r n e l\r
+ *----------------------------------------------------------------------------\r
+ *      Name:    cdcuser.c\r
+ *      Purpose: USB Communication Device Class User module\r
+ *      Version: V1.10\r
+ *----------------------------------------------------------------------------\r
+*      This software is supplied "AS IS" without any warranties, express,\r
+ *      implied or statutory, including but not limited to the implied\r
+ *      warranties of fitness for purpose, satisfactory quality and\r
+ *      noninfringement. Keil extends you a royalty-free right to reproduce\r
+ *      and distribute executable files created using this software for use\r
+ *      on NXP Semiconductors LPC microcontroller devices only. Nothing else\r
+ *      gives you the right to use this software.\r
+ *\r
+ * Copyright (c) 2009 Keil - An ARM Company. All rights reserved.\r
+ *---------------------------------------------------------------------------*/\r
+\r
+#include "lpc_types.h"\r
+\r
+#include "usb.h"\r
+#include "usbhw.h"\r
+#include "usbcfg.h"\r
+#include "usbcore.h"\r
+#include "cdc.h"\r
+#include "cdcuser.h"\r
+#include "serial.h"\r
+\r
+\r
+unsigned char BulkBufIn  [USB_CDC_BUFSIZE];            // Buffer to store USB IN  packet\r
+unsigned char BulkBufOut [USB_CDC_BUFSIZE];            // Buffer to store USB OUT packet\r
+unsigned char NotificationBuf [10];\r
+\r
+CDC_LINE_CODING CDC_LineCoding  = {9600, 0, 0, 8};\r
+unsigned short  CDC_SerialState = 0x0000;\r
+unsigned short  CDC_DepInEmpty  = 1;                   // Data IN EP is empty\r
+\r
+/*----------------------------------------------------------------------------\r
+  We need a buffer for incomming data on USB port because USB receives\r
+  much faster than  UART transmits\r
+ *---------------------------------------------------------------------------*/\r
+/* Buffer masks */\r
+#define CDC_BUF_SIZE               (64)               // Output buffer in bytes (power 2)\r
+                                                       // large enough for file transfer\r
+#define CDC_BUF_MASK               (CDC_BUF_SIZE-1ul)\r
+\r
+/* Buffer read / write macros */\r
+#define CDC_BUF_RESET(cdcBuf)      (cdcBuf.rdIdx = cdcBuf.wrIdx = 0)\r
+#define CDC_BUF_WR(cdcBuf, dataIn) (cdcBuf.data[CDC_BUF_MASK & cdcBuf.wrIdx++] = (dataIn))\r
+#define CDC_BUF_RD(cdcBuf)         (cdcBuf.data[CDC_BUF_MASK & cdcBuf.rdIdx++])\r
+#define CDC_BUF_EMPTY(cdcBuf)      (cdcBuf.rdIdx == cdcBuf.wrIdx)\r
+#define CDC_BUF_FULL(cdcBuf)       (cdcBuf.rdIdx == cdcBuf.wrIdx+1)\r
+#define CDC_BUF_COUNT(cdcBuf)      (CDC_BUF_MASK & (cdcBuf.wrIdx - cdcBuf.rdIdx))\r
+\r
+\r
+// CDC output buffer\r
+typedef struct __CDC_BUF_T {\r
+  unsigned char data[CDC_BUF_SIZE];\r
+  unsigned int wrIdx;\r
+  unsigned int rdIdx;\r
+} CDC_BUF_T;\r
+\r
+CDC_BUF_T  CDC_OutBuf;                                 // buffer for all CDC Out data\r
+\r
+/*----------------------------------------------------------------------------\r
+  read data from CDC_OutBuf\r
+ *---------------------------------------------------------------------------*/\r
+int CDC_RdOutBuf (char *buffer, const int *length) {\r
+  int bytesToRead, bytesRead;\r
+\r
+  /* Read *length bytes, block if *bytes are not avaialable    */\r
+  bytesToRead = *length;\r
+  bytesToRead = (bytesToRead < (*length)) ? bytesToRead : (*length);\r
+  bytesRead = bytesToRead;\r
+\r
+\r
+  // ... add code to check for underrun\r
+\r
+  while (bytesToRead--) {\r
+    *buffer++ = CDC_BUF_RD(CDC_OutBuf);\r
+  }\r
+  return (bytesRead);\r
+}\r
+\r
+/*----------------------------------------------------------------------------\r
+  write data to CDC_OutBuf\r
+ *---------------------------------------------------------------------------*/\r
+int CDC_WrOutBuf (const char *buffer, int *length) {\r
+  int bytesToWrite, bytesWritten;\r
+\r
+  // Write *length bytes\r
+  bytesToWrite = *length;\r
+  bytesWritten = bytesToWrite;\r
+\r
+\r
+  // ... add code to check for overwrite\r
+\r
+  while (bytesToWrite) {\r
+      CDC_BUF_WR(CDC_OutBuf, *buffer++);           // Copy Data to buffer\r
+      bytesToWrite--;\r
+  }\r
+\r
+  return (bytesWritten);\r
+}\r
+\r
+/*----------------------------------------------------------------------------\r
+  check if character(s) are available at CDC_OutBuf\r
+ *---------------------------------------------------------------------------*/\r
+int CDC_OutBufAvailChar (int *availChar) {\r
+\r
+  *availChar = CDC_BUF_COUNT(CDC_OutBuf);\r
+\r
+  return (0);\r
+}\r
+/* end Buffer handling */\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC Initialisation\r
+  Initializes the data structures and serial port\r
+  Parameters:   None\r
+  Return Value: None\r
+ *---------------------------------------------------------------------------*/\r
+void CDC_Init (char portNum ) {\r
+\r
+  if ( portNum == 0 )\r
+  {\r
+       ser_OpenPort (0);\r
+       ser_InitPort0 (CDC_LineCoding.dwDTERate,\r
+                CDC_LineCoding.bDataBits,\r
+                CDC_LineCoding.bParityType,\r
+                CDC_LineCoding.bCharFormat);\r
+  }\r
+  else\r
+  {\r
+       ser_OpenPort (1);\r
+       ser_InitPort1 (CDC_LineCoding.dwDTERate,\r
+                CDC_LineCoding.bDataBits,\r
+                CDC_LineCoding.bParityType,\r
+                CDC_LineCoding.bCharFormat);\r
+  }\r
+  CDC_DepInEmpty  = 1;\r
+  CDC_SerialState = CDC_GetSerialState();\r
+\r
+  CDC_BUF_RESET(CDC_OutBuf);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC SendEncapsulatedCommand Request Callback\r
+  Called automatically on CDC SEND_ENCAPSULATED_COMMAND Request\r
+  Parameters:   None                          (global SetupPacket and EP0Buf)\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_SendEncapsulatedCommand (void) {\r
+\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC GetEncapsulatedResponse Request Callback\r
+  Called automatically on CDC Get_ENCAPSULATED_RESPONSE Request\r
+  Parameters:   None                          (global SetupPacket and EP0Buf)\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_GetEncapsulatedResponse (void) {\r
+\r
+  /* ... add code to handle request */\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC SetCommFeature Request Callback\r
+  Called automatically on CDC Set_COMM_FATURE Request\r
+  Parameters:   FeatureSelector\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_SetCommFeature (unsigned short wFeatureSelector) {\r
+\r
+  /* ... add code to handle request */\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC GetCommFeature Request Callback\r
+  Called automatically on CDC Get_COMM_FATURE Request\r
+  Parameters:   FeatureSelector\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_GetCommFeature (unsigned short wFeatureSelector) {\r
+\r
+  /* ... add code to handle request */\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC ClearCommFeature Request Callback\r
+  Called automatically on CDC CLEAR_COMM_FATURE Request\r
+  Parameters:   FeatureSelector\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_ClearCommFeature (unsigned short wFeatureSelector) {\r
+\r
+  /* ... add code to handle request */\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC SetLineCoding Request Callback\r
+  Called automatically on CDC SET_LINE_CODING Request\r
+  Parameters:   none                    (global SetupPacket and EP0Buf)\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_SetLineCoding (void) {\r
+\r
+  CDC_LineCoding.dwDTERate   =   (EP0Buf[0] <<  0)\r
+                               | (EP0Buf[1] <<  8)\r
+                               | (EP0Buf[2] << 16)\r
+                               | (EP0Buf[3] << 24);\r
+  CDC_LineCoding.bCharFormat =  EP0Buf[4];\r
+  CDC_LineCoding.bParityType =  EP0Buf[5];\r
+  CDC_LineCoding.bDataBits   =  EP0Buf[6];\r
+\r
+#if PORT_NUM\r
+  ser_ClosePort(1);\r
+  ser_OpenPort (1);\r
+  ser_InitPort1 (CDC_LineCoding.dwDTERate,\r
+                CDC_LineCoding.bDataBits,\r
+                CDC_LineCoding.bParityType,\r
+                CDC_LineCoding.bCharFormat);\r
+#else\r
+  ser_ClosePort(0);\r
+  ser_OpenPort (0);\r
+  ser_InitPort0 (CDC_LineCoding.dwDTERate,\r
+                CDC_LineCoding.bDataBits,\r
+                CDC_LineCoding.bParityType,\r
+                CDC_LineCoding.bCharFormat);\r
+#endif\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC GetLineCoding Request Callback\r
+  Called automatically on CDC GET_LINE_CODING Request\r
+  Parameters:   None                         (global SetupPacket and EP0Buf)\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_GetLineCoding (void) {\r
+\r
+  EP0Buf[0] = (CDC_LineCoding.dwDTERate >>  0) & 0xFF;\r
+  EP0Buf[1] = (CDC_LineCoding.dwDTERate >>  8) & 0xFF;\r
+  EP0Buf[2] = (CDC_LineCoding.dwDTERate >> 16) & 0xFF;\r
+  EP0Buf[3] = (CDC_LineCoding.dwDTERate >> 24) & 0xFF;\r
+  EP0Buf[4] =  CDC_LineCoding.bCharFormat;\r
+  EP0Buf[5] =  CDC_LineCoding.bParityType;\r
+  EP0Buf[6] =  CDC_LineCoding.bDataBits;\r
+\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC SetControlLineState Request Callback\r
+  Called automatically on CDC SET_CONTROL_LINE_STATE Request\r
+  Parameters:   ControlSignalBitmap\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_SetControlLineState (unsigned short wControlSignalBitmap) {\r
+\r
+  /* ... add code to handle request */\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC SendBreak Request Callback\r
+  Called automatically on CDC Set_COMM_FATURE Request\r
+  Parameters:   0xFFFF  start of Break\r
+                0x0000  stop  of Break\r
+                0x####  Duration of Break\r
+  Return Value: TRUE - Success, FALSE - Error\r
+ *---------------------------------------------------------------------------*/\r
+uint32_t CDC_SendBreak (unsigned short wDurationOfBreak) {\r
+\r
+  /* ... add code to handle request */\r
+  return (TRUE);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC_BulkIn call on DataIn Request\r
+  Parameters:   none\r
+  Return Value: none\r
+ *---------------------------------------------------------------------------*/\r
+void CDC_BulkIn(void) {\r
+  int numBytesRead, numBytesAvail;\r
+\r
+  ser_AvailChar (&numBytesAvail);\r
+\r
+  // ... add code to check for overwrite\r
+\r
+  numBytesRead = ser_Read ((char *)&BulkBufIn[0], &numBytesAvail);\r
+\r
+  // send over USB\r
+  if (numBytesRead > 0) {\r
+       USB_WriteEP (CDC_DEP_IN, &BulkBufIn[0], numBytesRead);\r
+  }\r
+  else {\r
+    CDC_DepInEmpty = 1;\r
+  }\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  CDC_BulkOut call on DataOut Request\r
+  Parameters:   none\r
+  Return Value: none\r
+ *---------------------------------------------------------------------------*/\r
+void CDC_BulkOut(void) {\r
+  int numBytesRead;\r
+\r
+  // get data from USB into intermediate buffer\r
+  numBytesRead = USB_ReadEP(CDC_DEP_OUT, &BulkBufOut[0]);\r
+\r
+  // ... add code to check for overwrite\r
+\r
+  // store data in a buffer to transmit it over serial interface\r
+  CDC_WrOutBuf ((char *)&BulkBufOut[0], &numBytesRead);\r
+\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  Get the SERIAL_STATE as defined in usbcdc11.pdf, 6.3.5, Table 69.\r
+  Parameters:   none\r
+  Return Value: SerialState as defined in usbcdc11.pdf\r
+ *---------------------------------------------------------------------------*/\r
+unsigned short CDC_GetSerialState (void) {\r
+  unsigned short temp;\r
+\r
+  CDC_SerialState = 0;\r
+  ser_LineState (&temp);\r
+\r
+  if (temp & 0x8000)  CDC_SerialState |= CDC_SERIAL_STATE_RX_CARRIER;\r
+  if (temp & 0x2000)  CDC_SerialState |= CDC_SERIAL_STATE_TX_CARRIER;\r
+  if (temp & 0x0010)  CDC_SerialState |= CDC_SERIAL_STATE_BREAK;\r
+  if (temp & 0x4000)  CDC_SerialState |= CDC_SERIAL_STATE_RING;\r
+  if (temp & 0x0008)  CDC_SerialState |= CDC_SERIAL_STATE_FRAMING;\r
+  if (temp & 0x0004)  CDC_SerialState |= CDC_SERIAL_STATE_PARITY;\r
+  if (temp & 0x0002)  CDC_SerialState |= CDC_SERIAL_STATE_OVERRUN;\r
+\r
+  return (CDC_SerialState);\r
+}\r
+\r
+\r
+/*----------------------------------------------------------------------------\r
+  Send the SERIAL_STATE notification as defined in usbcdc11.pdf, 6.3.5.\r
+ *---------------------------------------------------------------------------*/\r
+void CDC_NotificationIn (void) {\r
+\r
+  NotificationBuf[0] = 0xA1;                           // bmRequestType\r
+  NotificationBuf[1] = CDC_NOTIFICATION_SERIAL_STATE;  // bNotification (SERIAL_STATE)\r
+  NotificationBuf[2] = 0x00;                           // wValue\r
+  NotificationBuf[3] = 0x00;\r
+  NotificationBuf[4] = 0x00;                           // wIndex (Interface #, LSB first)\r
+  NotificationBuf[5] = 0x00;\r
+  NotificationBuf[6] = 0x02;                           // wLength (Data length = 2 bytes, LSB first)\r
+  NotificationBuf[7] = 0x00;\r
+  NotificationBuf[8] = (CDC_SerialState >>  0) & 0xFF; // UART State Bitmap (16bits, LSB first)\r
+  NotificationBuf[9] = (CDC_SerialState >>  8) & 0xFF;\r
+\r
+  USB_WriteEP (CDC_CEP_IN, &NotificationBuf[0], 10);   // send notification\r
+}\r