X-Git-Url: http://git.linex4red.de/pub/USBasp.git/blobdiff_plain/0c2ad9eb349e1a5676468af3b407329dde4a53b4..0da99447d3e88e83f9977501bee56af5c7aa56c0:/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c diff --git a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c index 039736a28..027264ab5 100644 --- a/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c +++ b/Demos/Device/Incomplete/TestAndMeasurement/TestAndMeasurement.c @@ -1,21 +1,21 @@ /* LUFA Library - Copyright (C) Dean Camera, 2011. - + Copyright (C) Dean Camera, 2012. + dean [at] fourwalledcubicle [dot] com www.lufa-lib.org */ /* - Copyright 2011 Dean Camera (dean [at] fourwalledcubicle [dot] com) + Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) - Permission to use, copy, modify, distribute, and sell this + Permission to use, copy, modify, distribute, and sell this software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in + without fee, provided that the above copyright notice appear in all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the + permission notice and warranty disclaimer appear in supporting + documentation, and that the name of the author not be used in + advertising or publicity pertaining to distribution of the software without specific, written prior permission. The author disclaim all warranties with regard to this @@ -38,7 +38,7 @@ TMC_Capabilities_t Capabilities = { .Status = TMC_STATUS_SUCCESS, .TMCVersion = VERSION_BCD(1.00), - + .Interface = { .ListenOnly = false, @@ -65,7 +65,13 @@ static bool IsTMCBulkOUTReset = false; static uint8_t CurrentTransferTag = 0; /** Length of last data transfer, for reporting to the host in case an in-progress transfer is aborted */ -static uint32_t LastTransferLength = 0; +static uint16_t LastTransferLength = 0; + +/** Buffer to hold the next message to sent to the TMC host */ +static uint8_t NextResponseBuffer[64]; + +/** Indicates the length of the next response to send */ +static uint8_t NextResponseLen; /** Main program entry point. This routine contains the overall program flow, including initial * setup of all components and the main program loop. @@ -76,7 +82,7 @@ int main(void) LEDs_SetAllLEDs(LEDMASK_USB_NOTREADY); sei(); - + for (;;) { TMC_Task(); @@ -93,7 +99,7 @@ void SetupHardware(void) /* Disable clock division */ clock_prescale_set(clock_div_1); - + /* Hardware Initialization */ LEDs_Init(); USB_Init(); @@ -123,12 +129,9 @@ void EVENT_USB_Device_ConfigurationChanged(void) bool ConfigSuccess = true; /* Setup TMC In, Out and Notification Endpoints */ - ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_NOTIFICATION_EPNUM, EP_TYPE_INTERRUPT, ENDPOINT_DIR_IN, - TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE); - ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_IN_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_IN, - TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE); - ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_OUT_EPNUM, EP_TYPE_BULK, ENDPOINT_DIR_OUT, - TMC_IO_EPSIZE, ENDPOINT_BANK_SINGLE); + ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_NOTIFICATION_EPADDR, EP_TYPE_INTERRUPT, TMC_IO_EPSIZE, 1); + ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_IN_EPADDR, EP_TYPE_BULK, TMC_IO_EPSIZE, 1); + ConfigSuccess &= Endpoint_ConfigureEndpoint(TMC_OUT_EPADDR, EP_TYPE_BULK, TMC_IO_EPSIZE, 1); /* Indicate endpoint configuration success or failure */ LEDs_SetAllLEDs(ConfigSuccess ? LEDMASK_USB_READY : LEDMASK_USB_ERROR); @@ -161,43 +164,43 @@ void EVENT_USB_Device_ControlRequest(void) { /* Indicate that all in-progress/pending data OUT requests should be aborted */ IsTMCBulkOUTReset = true; - + /* Save the split request for later checking when a new request is received */ RequestInProgress = Req_InitiateAbortBulkOut; } Endpoint_ClearSETUP(); - + /* Write the request response byte */ Endpoint_Write_8(TMCRequestStatus); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } - + break; case Req_CheckAbortBulkOutStatus: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) { /* Check that an ABORT BULK OUT transaction has been requested and that the request has completed */ if (RequestInProgress != Req_InitiateAbortBulkOut) - TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; + TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; else if (IsTMCBulkOUTReset) TMCRequestStatus = TMC_STATUS_PENDING; else - RequestInProgress = 0; + RequestInProgress = 0; Endpoint_ClearSETUP(); - + /* Write the request response bytes */ Endpoint_Write_8(TMCRequestStatus); Endpoint_Write_16_LE(0); Endpoint_Write_32_LE(LastTransferLength); Endpoint_ClearIN(); - Endpoint_ClearStatusStage(); + Endpoint_ClearStatusStage(); } - + break; case Req_InitiateAbortBulkIn: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) @@ -205,7 +208,7 @@ void EVENT_USB_Device_ControlRequest(void) /* Check that no split transaction is already in progress and the data transfer tag is valid */ if (RequestInProgress != 0) { - TMCRequestStatus = TMC_STATUS_SPLIT_IN_PROGRESS; + TMCRequestStatus = TMC_STATUS_SPLIT_IN_PROGRESS; } else if (USB_ControlRequest.wValue != CurrentTransferTag) { @@ -215,13 +218,13 @@ void EVENT_USB_Device_ControlRequest(void) { /* Indicate that all in-progress/pending data IN requests should be aborted */ IsTMCBulkINReset = true; - + /* Save the split request for later checking when a new request is received */ RequestInProgress = Req_InitiateAbortBulkIn; } Endpoint_ClearSETUP(); - + /* Write the request response bytes */ Endpoint_Write_8(TMCRequestStatus); Endpoint_Write_8(CurrentTransferTag); @@ -229,7 +232,7 @@ void EVENT_USB_Device_ControlRequest(void) Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } - + break; case Req_CheckAbortBulkInStatus: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_ENDPOINT)) @@ -243,7 +246,7 @@ void EVENT_USB_Device_ControlRequest(void) RequestInProgress = 0; Endpoint_ClearSETUP(); - + /* Write the request response bytes */ Endpoint_Write_8(TMCRequestStatus); Endpoint_Write_16_LE(0); @@ -252,7 +255,7 @@ void EVENT_USB_Device_ControlRequest(void) Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } - + break; case Req_InitiateClear: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) @@ -260,34 +263,34 @@ void EVENT_USB_Device_ControlRequest(void) /* Check that no split transaction is already in progress */ if (RequestInProgress != 0) { - Endpoint_Write_8(TMC_STATUS_SPLIT_IN_PROGRESS); + Endpoint_Write_8(TMC_STATUS_SPLIT_IN_PROGRESS); } else { /* Indicate that all in-progress/pending data IN and OUT requests should be aborted */ IsTMCBulkINReset = true; IsTMCBulkOUTReset = true; - + /* Save the split request for later checking when a new request is received */ RequestInProgress = Req_InitiateClear; } Endpoint_ClearSETUP(); - + /* Write the request response byte */ Endpoint_Write_8(TMCRequestStatus); Endpoint_ClearIN(); Endpoint_ClearStatusStage(); } - + break; case Req_CheckClearStatus: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { /* Check that a CLEAR transaction has been requested and that the request has completed */ if (RequestInProgress != Req_InitiateClear) - TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; + TMCRequestStatus = TMC_STATUS_SPLIT_NOT_IN_PROGRESS; else if (IsTMCBulkINReset || IsTMCBulkOUTReset) TMCRequestStatus = TMC_STATUS_PENDING; else @@ -298,73 +301,92 @@ void EVENT_USB_Device_ControlRequest(void) /* Write the request response bytes */ Endpoint_Write_8(TMCRequestStatus); Endpoint_Write_8(0); - + Endpoint_ClearIN(); - Endpoint_ClearStatusStage(); + Endpoint_ClearStatusStage(); } - + break; case Req_GetCapabilities: if (USB_ControlRequest.bmRequestType == (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE)) { Endpoint_ClearSETUP(); - + /* Write the device capabilities to the control endpoint */ - Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t)); + Endpoint_Write_Control_Stream_LE(&Capabilities, sizeof(TMC_Capabilities_t)); Endpoint_ClearOUT(); } - + break; } } +void ProcessSentMessage(uint8_t* const Data, const uint8_t Length) +{ + if (strncmp((char*)Data, "*IDN?", 5) == 0) + strcpy((char*)NextResponseBuffer, "LUFA TMC DEMO"); + + NextResponseLen = strlen((char*)NextResponseBuffer); +} + +uint8_t GetNextMessage(uint8_t* const Data) +{ + strcpy((char*)NextResponseBuffer, "LUFA TMC DEMO"); + + NextResponseLen = strlen((char*)NextResponseBuffer); +// --- + uint8_t DataLen = MIN(NextResponseLen, 64); + + strlcpy((char*)Data, (char*)NextResponseBuffer, DataLen); + + return DataLen; +} + /** Function to manage TMC data transmission and reception to and from the host. */ void TMC_Task(void) { /* Device must be connected and configured for the task to run */ if (USB_DeviceState != DEVICE_STATE_Configured) return; - + TMC_MessageHeader_t MessageHeader; - uint16_t BytesTransferred; - + uint8_t MessagePayload[128]; + /* Try to read in a TMC message from the interface, process if one is available */ if (ReadTMCHeader(&MessageHeader)) { /* Indicate busy */ LEDs_SetAllLEDs(LEDMASK_USB_BUSY); - + switch (MessageHeader.MessageID) { case TMC_MESSAGEID_DEV_DEP_MSG_OUT: - BytesTransferred = 0; - while (Endpoint_Discard_Stream(MessageHeader.TransferSize, &BytesTransferred) == + LastTransferLength = 0; + while (Endpoint_Read_Stream_LE(MessagePayload, MIN(MessageHeader.TransferSize, sizeof(MessagePayload)), &LastTransferLength) == ENDPOINT_RWSTREAM_IncompleteTransfer) { if (IsTMCBulkOUTReset) break; } - LastTransferLength = BytesTransferred; - + Endpoint_ClearOUT(); + + ProcessSentMessage(MessagePayload, LastTransferLength); break; case TMC_MESSAGEID_DEV_DEP_MSG_IN: Endpoint_ClearOUT(); - - char MessageData[] = "TMC Class Test"; - MessageHeader.TransferSize = strlen(MessageData); + MessageHeader.TransferSize = GetNextMessage(MessagePayload); MessageHeader.MessageIDSpecific.DeviceOUT.LastMessageTransaction = true; WriteTMCHeader(&MessageHeader); - BytesTransferred = 0; - while (Endpoint_Write_Stream_LE(MessageData, MessageHeader.TransferSize, &BytesTransferred) == + LastTransferLength = 0; + while (Endpoint_Write_Stream_LE(MessagePayload, MessageHeader.TransferSize, &LastTransferLength) == ENDPOINT_RWSTREAM_IncompleteTransfer) { if (IsTMCBulkINReset) break; } - LastTransferLength = BytesTransferred; Endpoint_ClearIN(); break; @@ -375,7 +397,7 @@ void TMC_Task(void) LEDs_SetAllLEDs(LEDMASK_USB_READY); } - + /* All pending data has been processed - reset the data abort flags */ IsTMCBulkINReset = false; IsTMCBulkOUTReset = false; @@ -393,12 +415,12 @@ bool ReadTMCHeader(TMC_MessageHeader_t* const MessageHeader) uint8_t ErrorCode; /* Select the Data Out endpoint */ - Endpoint_SelectEndpoint(TMC_OUT_EPNUM); - + Endpoint_SelectEndpoint(TMC_OUT_EPADDR); + /* Abort if no command has been sent from the host */ if (!(Endpoint_IsOUTReceived())) return false; - + /* Read in the header of the command from the host */ BytesTransferred = 0; while ((ErrorCode = Endpoint_Read_Stream_LE(MessageHeader, sizeof(TMC_MessageHeader_t), &BytesTransferred)) == @@ -410,7 +432,7 @@ bool ReadTMCHeader(TMC_MessageHeader_t* const MessageHeader) /* Store the new command tag value for later use */ CurrentTransferTag = MessageHeader->Tag; - + /* Indicate if the command has been aborted or not */ return (!(IsTMCBulkOUTReset) && (ErrorCode == ENDPOINT_RWSTREAM_NoError)); } @@ -425,7 +447,7 @@ bool WriteTMCHeader(TMC_MessageHeader_t* const MessageHeader) MessageHeader->InverseTag = ~CurrentTransferTag; /* Select the Data In endpoint */ - Endpoint_SelectEndpoint(TMC_IN_EPNUM); + Endpoint_SelectEndpoint(TMC_IN_EPADDR); /* Send the command header to the host */ BytesTransferred = 0; @@ -439,3 +461,4 @@ bool WriteTMCHeader(TMC_MessageHeader_t* const MessageHeader) /* Indicate if the command has been aborted or not */ return (!(IsTMCBulkINReset) && (ErrorCode == ENDPOINT_RWSTREAM_NoError)); } +