Update UC3 platform driver support to use the bitmasks defined in the header files...
[pub/USBasp.git] / Demos / Device / Incomplete / TestAndMeasurement / TestAndMeasurement.c
index e174aa9..08c50c7 100644 (file)
@@ -1,13 +1,13 @@
 /*\r
              LUFA Library\r
-     Copyright (C) Dean Camera, 2010.\r
+     Copyright (C) Dean Camera, 2011.\r
               \r
   dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
+           www.lufa-lib.org\r
 */\r
 \r
 /*\r
-  Copyright 2010  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
 \r
   Permission to use, copy, modify, distribute, and sell this \r
   software and its documentation for any purpose is hereby granted\r
@@ -53,17 +53,19 @@ TMC_Capabilities_t Capabilities =
        };\r
 \r
 /** Current TMC control request that is being processed */\r
-uint8_t RequestInProgress = 0;\r
+static uint8_t RequestInProgress = 0;\r
 \r
 /** Stream callback abort flag for bulk IN data */\r
-bool IsTMCBulkINReset = false;\r
+static bool IsTMCBulkINReset = false;\r
 \r
 /** Stream callback abort flag for bulk OUT data */\r
-bool IsTMCBulkOUTReset = false;\r
+static bool IsTMCBulkOUTReset = false;\r
 \r
 /** Last used tag value for data transfers */\r
-uint8_t CurrentTransferTag = 0;\r
+static uint8_t CurrentTransferTag = 0;\r
 \r
+/** Length of last data transfer, for reporting to the host in case an in-progress transfer is aborted */\r
+static uint32_t LastTransferLength = 0;\r
 \r
 /** Main program entry point. This routine contains the overall program flow, including initial\r
  *  setup of all components and the main program loop.\r
@@ -118,36 +120,25 @@ void EVENT_USB_Device_Disconnect(void)
  */\r
 void EVENT_USB_Device_ConfigurationChanged(void)\r
 {\r
-       LEDs_SetAllLEDs(LEDMASK_USB_READY);\r
+       bool ConfigSuccess = true;\r
 \r
        /* Setup TMC In, Out and Notification Endpoints */\r
-       if (!(Endpoint_ConfigureEndpoint(TMC_IN_EPNUM, EP_TYPE_BULK,\r
-                                            ENDPOINT_DIR_IN, TMC_IO_EPSIZE,\r
-                                        ENDPOINT_BANK_SINGLE)))\r
-       {\r
-               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
-       }\r
-\r
-       if (!(Endpoint_ConfigureEndpoint(TMC_OUT_EPNUM, EP_TYPE_BULK,\r
-                                            ENDPOINT_DIR_OUT, TMC_IO_EPSIZE,\r
-                                        ENDPOINT_BANK_SINGLE)))\r
-       {\r
-               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
-       }\r
-\r
-       if (!(Endpoint_ConfigureEndpoint(TMC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT,\r
-                                            ENDPOINT_DIR_IN, TMC_NOTIFICATION_EPSIZE,\r
-                                        ENDPOINT_BANK_SINGLE)))\r
-       {\r
-               LEDs_SetAllLEDs(LEDMASK_USB_ERROR);\r
-       }\r
+       ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN,\r
+                                                   TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);\r
+       ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_IN_EPNUM,  EP_TYPE_BULK, ENDPOINT_DIR_IN,\r
+                                                   TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);\r
+       ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT,\r
+                                                   TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE);\r
+\r
+       /* Indicate endpoint configuration success or failure */\r
+       LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR);\r
 }\r
 \r
-/** Event handler for the USB_UnhandledControlRequest event. This is used to catch standard and class specific\r
- *  control requests that are not handled internally by the USB library (including the CDC control commands,\r
- *  which are all issued via the control endpoint), so that they can be handled appropriately for the application.\r
+/** Event handler for the USB_ControlRequest event. This is used to catch and process control requests sent to\r
+ *  the device from the USB host before passing along unhandled control requests to the library for processing\r
+ *  internally.\r
  */\r
-void EVENT_USB_Device_UnhandledControlRequest(void)\r
+void EVENT_USB_Device_ControlRequest(void)\r
 {\r
        uint8_t TMCRequestStatus = TMC_STATUS_SUCCESS;\r
 \r
@@ -157,8 +148,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_InitiateAbortBulkOut:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
                                /* Check that no split transaction is already in progress and the data transfer tag is valid */\r
                                if (RequestInProgress != 0)\r
                                {\r
@@ -176,9 +165,11 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                                        /* Save the split request for later checking when a new request is received */\r
                                        RequestInProgress = Req_InitiateAbortBulkOut;\r
                                }\r
+\r
+                               Endpoint_ClearSETUP();\r
                                \r
                                /* Write the request response byte */\r
-                               Endpoint_Write_Byte(TMCRequestStatus);\r
+                               Endpoint_Write_8(TMCRequestStatus);\r
 \r
                                Endpoint_ClearIN();\r
                                Endpoint_ClearStatusStage();\r
@@ -188,20 +179,20 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_CheckAbortBulkOutStatus:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
                                /* Check that an ABORT BULK OUT transaction has been requested and that the request has completed */\r
                                if (RequestInProgress != Req_InitiateAbortBulkOut)\r
                                  TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;                          \r
                                else if (IsTMCBulkOUTReset)\r
                                  TMCRequestStatus = TMC_STATUS_PENDING;\r
                                else\r
-                                 RequestInProgress = 0;                        \r
-                               \r
+                                 RequestInProgress = 0;        \r
+\r
+                               Endpoint_ClearSETUP();\r
+                                                               \r
                                /* Write the request response bytes */\r
-                               Endpoint_Write_Byte(TMCRequestStatus);\r
-                               Endpoint_Write_Word_LE(0);\r
-                               Endpoint_Write_DWord_LE(0); // TODO - Last transfer length\r
+                               Endpoint_Write_8(TMCRequestStatus);\r
+                               Endpoint_Write_16_LE(0);\r
+                               Endpoint_Write_32_LE(LastTransferLength);\r
 \r
                                Endpoint_ClearIN();\r
                                Endpoint_ClearStatusStage();                            \r
@@ -211,8 +202,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_InitiateAbortBulkIn:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
                                /* Check that no split transaction is already in progress and the data transfer tag is valid */\r
                                if (RequestInProgress != 0)\r
                                {\r
@@ -230,10 +219,12 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                                        /* Save the split request for later checking when a new request is received */\r
                                        RequestInProgress = Req_InitiateAbortBulkIn;\r
                                }\r
+\r
+                               Endpoint_ClearSETUP();\r
                                \r
                                /* Write the request response bytes */\r
-                               Endpoint_Write_Byte(TMCRequestStatus);\r
-                               Endpoint_Write_Byte(CurrentTransferTag);\r
+                               Endpoint_Write_8(TMCRequestStatus);\r
+                               Endpoint_Write_8(CurrentTransferTag);\r
 \r
                                Endpoint_ClearIN();\r
                                Endpoint_ClearStatusStage();\r
@@ -243,8 +234,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_CheckAbortBulkInStatus:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
                                /* Check that an ABORT BULK IN transaction has been requested and that the request has completed */\r
                                if (RequestInProgress != Req_InitiateAbortBulkIn)\r
                                  TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;\r
@@ -252,11 +241,13 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                                  TMCRequestStatus = TMC_STATUS_PENDING;\r
                                else\r
                                  RequestInProgress = 0;\r
-                               \r
+\r
+                               Endpoint_ClearSETUP();\r
+                                                               \r
                                /* Write the request response bytes */\r
-                               Endpoint_Write_Byte(TMCRequestStatus);\r
-                               Endpoint_Write_Word_LE(0);\r
-                               Endpoint_Write_DWord_LE(0); // TODO - Last transfer length\r
+                               Endpoint_Write_8(TMCRequestStatus);\r
+                               Endpoint_Write_16_LE(0);\r
+                               Endpoint_Write_32_LE(LastTransferLength);\r
 \r
                                Endpoint_ClearIN();\r
                                Endpoint_ClearStatusStage();\r
@@ -266,12 +257,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_InitiateClear:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
                                /* Check that no split transaction is already in progress */\r
                                if (RequestInProgress != 0)\r
                                {\r
-                                       Endpoint_Write_Byte(TMC_STATUS_SPLIT_IN_PROGRESS);                              \r
+                                       Endpoint_Write_8(TMC_STATUS_SPLIT_IN_PROGRESS);                         \r
                                }\r
                                else\r
                                {\r
@@ -282,9 +271,11 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                                        /* Save the split request for later checking when a new request is received */\r
                                        RequestInProgress = Req_InitiateClear;\r
                                }\r
+\r
+                               Endpoint_ClearSETUP();\r
                                \r
                                /* Write the request response byte */\r
-                               Endpoint_Write_Byte(TMCRequestStatus);\r
+                               Endpoint_Write_8(TMCRequestStatus);\r
 \r
                                Endpoint_ClearIN();\r
                                Endpoint_ClearStatusStage();\r
@@ -294,8 +285,6 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_CheckClearStatus:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
                        {\r
-                               Endpoint_ClearSETUP();\r
-                               \r
                                /* Check that a CLEAR transaction has been requested and that the request has completed */\r
                                if (RequestInProgress != Req_InitiateClear)\r
                                  TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS;                          \r
@@ -303,10 +292,12 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                                  TMCRequestStatus = TMC_STATUS_PENDING;\r
                                else\r
                                  RequestInProgress = 0;\r
-                               \r
+\r
+                               Endpoint_ClearSETUP();\r
+\r
                                /* Write the request response bytes */\r
-                               Endpoint_Write_Byte(TMCRequestStatus);\r
-                               Endpoint_Write_Byte(0);\r
+                               Endpoint_Write_8(TMCRequestStatus);\r
+                               Endpoint_Write_8(0);\r
                                \r
                                Endpoint_ClearIN();\r
                                Endpoint_ClearStatusStage();                            \r
@@ -316,13 +307,10 @@ void EVENT_USB_Device_UnhandledControlRequest(void)
                case Req_GetCapabilities:\r
                        if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE))\r
                        {\r
-                               /* Acknowledge the SETUP packet, ready for data transfer */\r
                                Endpoint_ClearSETUP();\r
                                        \r
                                /* Write the device capabilities to the control endpoint */\r
-                               Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t));\r
-                               \r
-                               /* Finalize the stream transfer to send the last packet or clear the host abort */\r
+                               Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t));                            \r
                                Endpoint_ClearOUT();\r
                        }\r
                        \r
@@ -338,6 +326,7 @@ void TMC_Task(void)
          return;\r
        \r
        TMC_MessageHeader_t MessageHeader;\r
+       uint16_t            BytesTransferred;\r
        \r
        /* Try to read in a TMC message from the interface, process if one is available */\r
        if (ReadTMCHeader(&MessageHeader))\r
@@ -348,16 +337,35 @@ void TMC_Task(void)
                switch (MessageHeader.MessageID)\r
                {\r
                        case TMC_MESSAGEID_DEV_DEP_MSG_OUT:\r
-                               Endpoint_Discard_Stream(MessageHeader.TransferSize, StreamCallback_AbortOUTOnRequest);\r
+                               BytesTransferred = 0;\r
+                               while (Endpoint_Discard_Stream(MessageHeader.TransferSize, &BytesTransferred) ==\r
+                                      ENDPOINT_RWSTREAM_IncompleteTransfer)\r
+                               {\r
+                                       if (IsTMCBulkOUTReset)\r
+                                         break;\r
+                               }\r
+                               LastTransferLength = BytesTransferred;\r
+                               \r
                                Endpoint_ClearOUT();\r
                                break;\r
                        case TMC_MESSAGEID_DEV_DEP_MSG_IN:\r
                                Endpoint_ClearOUT();\r
+                               \r
+                               char MessageData[] = "TMC Class Test";\r
 \r
-                               MessageHeader.TransferSize = 3;\r
+                               MessageHeader.TransferSize = strlen(MessageData);\r
+                               MessageHeader.MessageIDSpecific.DeviceOUT.LastMessageTransaction = true;\r
                                WriteTMCHeader(&MessageHeader);\r
 \r
-                               Endpoint_Write_Stream_LE("TMC", 3, StreamCallback_AbortINOnRequest);\r
+                               BytesTransferred = 0;\r
+                               while (Endpoint_Write_Stream_LE(MessageData, MessageHeader.TransferSize, &BytesTransferred) ==\r
+                                      ENDPOINT_RWSTREAM_IncompleteTransfer)\r
+                               {\r
+                                       if (IsTMCBulkINReset)\r
+                                         break;\r
+                               }\r
+                               LastTransferLength = BytesTransferred;\r
+\r
                                Endpoint_ClearIN();\r
                                break;\r
                        default:\r
@@ -381,6 +389,9 @@ void TMC_Task(void)
  */\r
 bool ReadTMCHeader(TMC_MessageHeader_t* const MessageHeader)\r
 {\r
+       uint16_t BytesTransferred;\r
+       uint8_t  ErrorCode;\r
+\r
        /* Select the Data Out endpoint */\r
        Endpoint_SelectEndpoint(TMC_OUT_EPNUM);\r
        \r
@@ -389,20 +400,25 @@ bool ReadTMCHeader(TMC_MessageHeader_t* const MessageHeader)
          return false;\r
        \r
        /* Read in the header of the command from the host */\r
-       Endpoint_Read_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), StreamCallback_AbortOUTOnRequest);\r
+       BytesTransferred = 0;\r
+       while ((ErrorCode = Endpoint_Read_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), &BytesTransferred)) ==\r
+              ENDPOINT_RWSTREAM_IncompleteTransfer)\r
+       {\r
+               if (IsTMCBulkOUTReset)\r
+                 break;\r
+       }\r
 \r
        /* Store the new command tag value for later use */\r
        CurrentTransferTag = MessageHeader->Tag;\r
        \r
        /* Indicate if the command has been aborted or not */\r
-       return !(IsTMCBulkOUTReset);\r
+       return (!(IsTMCBulkOUTReset) && (ErrorCode == ENDPOINT_RWSTREAM_NoError));\r
 }\r
 \r
 bool WriteTMCHeader(TMC_MessageHeader_t* const MessageHeader)\r
 {\r
-       /* Compute the next transfer tag value, must be between 1 and 254 */\r
-       if (++CurrentTransferTag == 0xFF)\r
-         CurrentTransferTag = 1;\r
+       uint16_t BytesTransferred;\r
+       uint8_t  ErrorCode;\r
 \r
        /* Set the message tag of the command header */\r
        MessageHeader->Tag        =  CurrentTransferTag;\r
@@ -412,34 +428,14 @@ bool WriteTMCHeader(TMC_MessageHeader_t* const MessageHeader)
        Endpoint_SelectEndpoint(TMC_IN_EPNUM);\r
 \r
        /* Send the command header to the host */\r
-       Endpoint_Write_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), StreamCallback_AbortINOnRequest);\r
+       BytesTransferred = 0;\r
+       while ((ErrorCode = Endpoint_Write_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), &BytesTransferred)) ==\r
+              ENDPOINT_RWSTREAM_IncompleteTransfer)\r
+       {\r
+               if (IsTMCBulkINReset)\r
+                 break;\r
+       }\r
 \r
        /* Indicate if the command has been aborted or not */\r
-       return !(IsTMCBulkINReset);\r
-}\r
-\r
-/** Stream callback function for the Endpoint stream write functions. This callback will abort the current stream transfer\r
- *  if a TMC Abort Bulk IN request has been issued to the control endpoint.\r
- */\r
-uint8_t StreamCallback_AbortINOnRequest(void)\r
-{      \r
-       /* Abort if a TMC Bulk Data IN abort was received */\r
-       if (IsTMCBulkINReset)\r
-         return STREAMCALLBACK_Abort;\r
-       \r
-       /* Continue with the current stream operation */\r
-       return STREAMCALLBACK_Continue;\r
-}\r
-\r
-/** Stream callback function for the Endpoint stream read functions. This callback will abort the current stream transfer\r
- *  if a TMC Abort Bulk OUT request has been issued to the control endpoint.\r
- */\r
-uint8_t StreamCallback_AbortOUTOnRequest(void)\r
-{      \r
-       /* Abort if a TMC Bulk Data IN abort was received */\r
-       if (IsTMCBulkOUTReset)\r
-         return STREAMCALLBACK_Abort;\r
-       \r
-       /* Continue with the current stream operation */\r
-       return STREAMCALLBACK_Continue;\r
+       return (!(IsTMCBulkINReset) && (ErrorCode == ENDPOINT_RWSTREAM_NoError));\r
 }\r