Moved out each demos' functionality library files (e.g. Ring Buffer library) to ...
authorDean Camera <dean@fourwalledcubicle.com>
Fri, 22 May 2009 06:17:57 +0000 (06:17 +0000)
committerDean Camera <dean@fourwalledcubicle.com>
Fri, 22 May 2009 06:17:57 +0000 (06:17 +0000)
90 files changed:
Demos/Device/MassStorage/DataflashManager.c [deleted file]
Demos/Device/MassStorage/DataflashManager.h [deleted file]
Demos/Device/MassStorage/Lib/DataflashManager.c [new file with mode: 0644]
Demos/Device/MassStorage/Lib/DataflashManager.h [new file with mode: 0644]
Demos/Device/MassStorage/Lib/SCSI.c [new file with mode: 0644]
Demos/Device/MassStorage/Lib/SCSI.h [new file with mode: 0644]
Demos/Device/MassStorage/Lib/SCSI_Codes.h [new file with mode: 0644]
Demos/Device/MassStorage/MassStorage.h
Demos/Device/MassStorage/SCSI.c [deleted file]
Demos/Device/MassStorage/SCSI.h [deleted file]
Demos/Device/MassStorage/SCSI_Codes.h [deleted file]
Demos/Device/MassStorage/makefile
Demos/Device/RNDISEthernet/ARP.c [deleted file]
Demos/Device/RNDISEthernet/ARP.h [deleted file]
Demos/Device/RNDISEthernet/DHCP.c [deleted file]
Demos/Device/RNDISEthernet/DHCP.h [deleted file]
Demos/Device/RNDISEthernet/Ethernet.c [deleted file]
Demos/Device/RNDISEthernet/Ethernet.h [deleted file]
Demos/Device/RNDISEthernet/EthernetProtocols.h [deleted file]
Demos/Device/RNDISEthernet/ICMP.c [deleted file]
Demos/Device/RNDISEthernet/ICMP.h [deleted file]
Demos/Device/RNDISEthernet/IP.c [deleted file]
Demos/Device/RNDISEthernet/IP.h [deleted file]
Demos/Device/RNDISEthernet/Lib/ARP.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/ARP.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/DHCP.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/DHCP.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/Ethernet.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/Ethernet.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/ICMP.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/ICMP.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/IP.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/IP.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/ProtocolDecoders.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/ProtocolDecoders.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/RNDIS.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/RNDIS.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/RNDISConstants.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/TCP.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/TCP.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/UDP.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/UDP.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/Webserver.c [new file with mode: 0644]
Demos/Device/RNDISEthernet/Lib/Webserver.h [new file with mode: 0644]
Demos/Device/RNDISEthernet/ProtocolDecoders.c [deleted file]
Demos/Device/RNDISEthernet/ProtocolDecoders.h [deleted file]
Demos/Device/RNDISEthernet/RNDIS.c [deleted file]
Demos/Device/RNDISEthernet/RNDIS.h [deleted file]
Demos/Device/RNDISEthernet/RNDISConstants.h [deleted file]
Demos/Device/RNDISEthernet/RNDISEthernet.h
Demos/Device/RNDISEthernet/TCP.c [deleted file]
Demos/Device/RNDISEthernet/TCP.h [deleted file]
Demos/Device/RNDISEthernet/UDP.c [deleted file]
Demos/Device/RNDISEthernet/UDP.h [deleted file]
Demos/Device/RNDISEthernet/Webserver.c [deleted file]
Demos/Device/RNDISEthernet/Webserver.h [deleted file]
Demos/Device/RNDISEthernet/makefile
Demos/Device/USBtoSerial/Lib/RingBuff.c [new file with mode: 0644]
Demos/Device/USBtoSerial/Lib/RingBuff.h [new file with mode: 0644]
Demos/Device/USBtoSerial/RingBuff.c [deleted file]
Demos/Device/USBtoSerial/RingBuff.h [deleted file]
Demos/Device/USBtoSerial/USBtoSerial.h
Demos/Device/USBtoSerial/makefile
Demos/Host/MassStorageHost/Lib/MassStoreCommands.c [new file with mode: 0644]
Demos/Host/MassStorageHost/Lib/MassStoreCommands.h [new file with mode: 0644]
Demos/Host/MassStorageHost/Lib/SCSI_Codes.h [new file with mode: 0644]
Demos/Host/MassStorageHost/MassStorageHost.h
Demos/Host/MassStorageHost/MassStoreCommands.c [deleted file]
Demos/Host/MassStorageHost/MassStoreCommands.h [deleted file]
Demos/Host/MassStorageHost/SCSI_Codes.h [deleted file]
Demos/Host/MassStorageHost/makefile
Demos/Host/StillImageHost/Lib/PIMACodes.h [new file with mode: 0644]
Demos/Host/StillImageHost/Lib/StillImageCommands.c [new file with mode: 0644]
Demos/Host/StillImageHost/Lib/StillImageCommands.h [new file with mode: 0644]
Demos/Host/StillImageHost/PIMACodes.h [deleted file]
Demos/Host/StillImageHost/StillImageCommands.c [deleted file]
Demos/Host/StillImageHost/StillImageCommands.h [deleted file]
Demos/Host/StillImageHost/StillImageHost.h
Demos/Host/StillImageHost/makefile
LUFA.pnproj
LUFA/ChangeLog.txt
Projects/Magstripe/CircularBitBuffer.c [deleted file]
Projects/Magstripe/CircularBitBuffer.h [deleted file]
Projects/Magstripe/Lib/CircularBitBuffer.c [new file with mode: 0644]
Projects/Magstripe/Lib/CircularBitBuffer.h [new file with mode: 0644]
Projects/Magstripe/Lib/MagstripeHW.h [new file with mode: 0644]
Projects/Magstripe/Magstripe.h
Projects/Magstripe/MagstripeHW.h [deleted file]
Projects/Magstripe/makefile

diff --git a/Demos/Device/MassStorage/DataflashManager.c b/Demos/Device/MassStorage/DataflashManager.c
deleted file mode 100644 (file)
index 4b62419..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Functions to manage the physical dataflash media, including reading and writing of\r
- *  blocks of data. These functions are called by the SCSI layer when data must be stored\r
- *  or retrieved to/from the physical storage media. If a different media is used (such\r
- *  as a SD card or EEPROM), functions similar to these will need to be generated.\r
- */\r
-\r
-#define  INCLUDE_FROM_DATAFLASHMANAGER_C\r
-#include "DataflashManager.h"\r
-\r
-/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from\r
- *  the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes\r
- *  them to the dataflash in Dataflash page sized blocks.\r
- *\r
- *  \param BlockAddress  Data block starting address for the write sequence\r
- *  \param TotalBlocks   Number of blocks of data to write\r
- */\r
-void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)\r
-{\r
-       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
-       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
-       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
-\r
-       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
-       Dataflash_SelectChipFromPage(CurrDFPage);\r
-       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
-       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-       Dataflash_WaitWhileBusy();\r
-\r
-       /* Send the dataflash buffer write command */\r
-       Dataflash_ToggleSelectedChipCS();\r
-       Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
-       Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
-\r
-       /* Wait until endpoint is ready before continuing */\r
-       while (!(Endpoint_IsReadWriteAllowed()));\r
-\r
-       while (TotalBlocks)\r
-       {\r
-               uint8_t BytesInBlockDiv16 = 0;\r
-               \r
-               /* Write an endpoint packet sized data block to the dataflash */\r
-               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
-               {\r
-                       /* Check if the endpoint is currently empty */\r
-                       if (!(Endpoint_IsReadWriteAllowed()))\r
-                       {\r
-                               /* Clear the current endpoint bank */\r
-                               Endpoint_ClearOUT();\r
-                               \r
-                               /* Wait until the host has sent another packet */\r
-                               while (!(Endpoint_IsReadWriteAllowed()));\r
-                       }\r
-\r
-                       /* Check if end of dataflash page reached */\r
-                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
-                       {\r
-                               /* Write the dataflash buffer contents back to the dataflash page */\r
-                               Dataflash_ToggleSelectedChipCS();\r
-                               Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
-                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-\r
-                               /* Reset the dataflash buffer counter, increment the page counter */\r
-                               CurrDFPageByteDiv16 = 0;\r
-                               CurrDFPage++;\r
-\r
-                               /* Select the next dataflash chip based on the new dataflash page index */\r
-                               Dataflash_SelectChipFromPage(CurrDFPage);\r
-                               Dataflash_WaitWhileBusy();\r
-\r
-#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
-                               /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */\r
-                               if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))\r
-                               {\r
-                                       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
-                                       Dataflash_ToggleSelectedChipCS();\r
-                                       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
-                                       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-                                       Dataflash_WaitWhileBusy();\r
-                               }\r
-#endif\r
-\r
-                               /* Send the dataflash buffer write command */\r
-                               Dataflash_ToggleSelectedChipCS();\r
-                               Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
-                               Dataflash_SendAddressBytes(0, 0);\r
-                       }\r
-\r
-                       /* Write one 16-byte chunk of data to the dataflash */\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       Dataflash_SendByte(Endpoint_Read_Byte());\r
-                       \r
-                       /* Increment the dataflash page 16 byte block counter */\r
-                       CurrDFPageByteDiv16++;\r
-\r
-                       /* Increment the block 16 byte block counter */\r
-                       BytesInBlockDiv16++;\r
-\r
-                       /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
-                         return;                       \r
-               }\r
-                       \r
-               /* Decrement the blocks remaining counter and reset the sub block counter */\r
-               TotalBlocks--;\r
-       }\r
-\r
-       /* Write the dataflash buffer contents back to the dataflash page */\r
-       Dataflash_ToggleSelectedChipCS();\r
-       Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
-       Dataflash_SendAddressBytes(CurrDFPage, 0x00);\r
-       Dataflash_WaitWhileBusy();\r
-\r
-       /* If the endpoint is empty, clear it ready for the next packet from the host */\r
-       if (!(Endpoint_IsReadWriteAllowed()))\r
-         Endpoint_ClearOUT();\r
-\r
-       /* Deselect all dataflash chips */\r
-       Dataflash_DeselectChip();\r
-}\r
-\r
-/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into\r
- *  the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash\r
- *  and writes them in OS sized blocks to the endpoint.\r
- *\r
- *  \param BlockAddress  Data block starting address for the read sequence\r
- *  \param TotalBlocks   Number of blocks of data to read\r
- */\r
-void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)\r
-{\r
-       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
-       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
-       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
-\r
-       /* Send the dataflash main memory page read command */\r
-       Dataflash_SelectChipFromPage(CurrDFPage);\r
-       Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
-       Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
-       Dataflash_SendByte(0x00);\r
-       Dataflash_SendByte(0x00);\r
-       Dataflash_SendByte(0x00);\r
-       Dataflash_SendByte(0x00);\r
-       \r
-       /* Wait until endpoint is ready before continuing */\r
-       while (!(Endpoint_IsReadWriteAllowed()));\r
-       \r
-       while (TotalBlocks)\r
-       {\r
-               uint8_t BytesInBlockDiv16 = 0;\r
-               \r
-               /* Write an endpoint packet sized data block to the dataflash */\r
-               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
-               {\r
-                       /* Check if the endpoint is currently full */\r
-                       if (!(Endpoint_IsReadWriteAllowed()))\r
-                       {\r
-                               /* Clear the endpoint bank to send its contents to the host */\r
-                               Endpoint_ClearIN();\r
-                               \r
-                               /* Wait until the endpoint is ready for more data */\r
-                               while (!(Endpoint_IsReadWriteAllowed()));\r
-                       }\r
-                       \r
-                       /* Check if end of dataflash page reached */\r
-                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
-                       {\r
-                               /* Reset the dataflash buffer counter, increment the page counter */\r
-                               CurrDFPageByteDiv16 = 0;\r
-                               CurrDFPage++;\r
-\r
-                               /* Select the next dataflash chip based on the new dataflash page index */\r
-                               Dataflash_SelectChipFromPage(CurrDFPage);\r
-                               \r
-                               /* Send the dataflash main memory page read command */\r
-                               Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
-                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-                               Dataflash_SendByte(0x00);\r
-                               Dataflash_SendByte(0x00);\r
-                               Dataflash_SendByte(0x00);\r
-                               Dataflash_SendByte(0x00);\r
-                       }       \r
-\r
-                       /* Read one 16-byte chunk of data from the dataflash */\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
-                       \r
-                       /* Increment the dataflash page 16 byte block counter */\r
-                       CurrDFPageByteDiv16++;\r
-                       \r
-                       /* Increment the block 16 byte block counter */\r
-                       BytesInBlockDiv16++;\r
-\r
-                       /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
-                         return;\r
-               }\r
-               \r
-               /* Decrement the blocks remaining counter */\r
-               TotalBlocks--;\r
-       }\r
-       \r
-       /* If the endpoint is full, send its contents to the host */\r
-       if (!(Endpoint_IsReadWriteAllowed()))\r
-         Endpoint_ClearIN();\r
-\r
-       /* Deselect all dataflash chips */\r
-       Dataflash_DeselectChip();\r
-}\r
-\r
-/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from\r
- *  the a given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the\r
- *  dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the\r
- *  dataflash.\r
- *\r
- *  \param BlockAddress  Data block starting address for the write sequence\r
- *  \param TotalBlocks   Number of blocks of data to write\r
- *  \param BufferPtr     Pointer to the data source RAM buffer\r
- */\r
-void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)\r
-{\r
-       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
-       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
-       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
-\r
-       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
-       Dataflash_SelectChipFromPage(CurrDFPage);\r
-       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
-       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-       Dataflash_WaitWhileBusy();\r
-\r
-       /* Send the dataflash buffer write command */\r
-       Dataflash_ToggleSelectedChipCS();\r
-       Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
-       Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
-\r
-       while (TotalBlocks)\r
-       {\r
-               uint8_t BytesInBlockDiv16 = 0;\r
-               \r
-               /* Write an endpoint packet sized data block to the dataflash */\r
-               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
-               {\r
-                       /* Check if end of dataflash page reached */\r
-                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
-                       {\r
-                               /* Write the dataflash buffer contents back to the dataflash page */\r
-                               Dataflash_ToggleSelectedChipCS();\r
-                               Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
-                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-\r
-                               /* Reset the dataflash buffer counter, increment the page counter */\r
-                               CurrDFPageByteDiv16 = 0;\r
-                               CurrDFPage++;\r
-\r
-                               /* Select the next dataflash chip based on the new dataflash page index */\r
-                               Dataflash_SelectChipFromPage(CurrDFPage);\r
-                               Dataflash_WaitWhileBusy();\r
-\r
-#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
-                               /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */\r
-                               if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))\r
-                               {\r
-                                       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
-                                       Dataflash_ToggleSelectedChipCS();\r
-                                       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
-                                       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-                                       Dataflash_WaitWhileBusy();\r
-                               }\r
-#endif\r
-\r
-                               /* Send the dataflash buffer write command */\r
-                               Dataflash_ToggleSelectedChipCS();\r
-                               Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
-                               Dataflash_SendAddressBytes(0, 0);\r
-                       }\r
-                       \r
-                       /* Write one 16-byte chunk of data to the dataflash */\r
-                       for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)\r
-                         Dataflash_SendByte(*(BufferPtr++));\r
-                       \r
-                       /* Increment the dataflash page 16 byte block counter */\r
-                       CurrDFPageByteDiv16++;\r
-\r
-                       /* Increment the block 16 byte block counter */\r
-                       BytesInBlockDiv16++;\r
-\r
-                       /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
-                         return;                       \r
-               }\r
-                       \r
-               /* Decrement the blocks remaining counter and reset the sub block counter */\r
-               TotalBlocks--;\r
-       }\r
-\r
-       /* Write the dataflash buffer contents back to the dataflash page */\r
-       Dataflash_ToggleSelectedChipCS();\r
-       Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
-       Dataflash_SendAddressBytes(CurrDFPage, 0x00);\r
-       Dataflash_WaitWhileBusy();\r
-\r
-       /* Deselect all dataflash chips */\r
-       Dataflash_DeselectChip();\r
-}\r
-\r
-/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into\r
- *  the a preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash\r
- *  and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read\r
- *  the files stored on the dataflash.\r
- *\r
- *  \param BlockAddress  Data block starting address for the read sequence\r
- *  \param TotalBlocks   Number of blocks of data to read\r
- *  \param BufferPtr     Pointer to the data destination RAM buffer\r
- */\r
-void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)\r
-{\r
-       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
-       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
-       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
-\r
-       /* Send the dataflash main memory page read command */\r
-       Dataflash_SelectChipFromPage(CurrDFPage);\r
-       Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
-       Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
-       Dataflash_SendByte(0x00);\r
-       Dataflash_SendByte(0x00);\r
-       Dataflash_SendByte(0x00);\r
-       Dataflash_SendByte(0x00);\r
-\r
-       while (TotalBlocks)\r
-       {\r
-               uint8_t BytesInBlockDiv16 = 0;\r
-               \r
-               /* Write an endpoint packet sized data block to the dataflash */\r
-               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
-               {\r
-                       /* Check if end of dataflash page reached */\r
-                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
-                       {\r
-                               /* Reset the dataflash buffer counter, increment the page counter */\r
-                               CurrDFPageByteDiv16 = 0;\r
-                               CurrDFPage++;\r
-\r
-                               /* Select the next dataflash chip based on the new dataflash page index */\r
-                               Dataflash_SelectChipFromPage(CurrDFPage);\r
-                               \r
-                               /* Send the dataflash main memory page read command */\r
-                               Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
-                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
-                               Dataflash_SendByte(0x00);\r
-                               Dataflash_SendByte(0x00);\r
-                               Dataflash_SendByte(0x00);\r
-                               Dataflash_SendByte(0x00);\r
-                       }       \r
-\r
-                       /* Read one 16-byte chunk of data from the dataflash */\r
-                       for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)\r
-                         *(BufferPtr++) = Dataflash_ReceiveByte();\r
-                       \r
-                       /* Increment the dataflash page 16 byte block counter */\r
-                       CurrDFPageByteDiv16++;\r
-                       \r
-                       /* Increment the block 16 byte block counter */\r
-                       BytesInBlockDiv16++;\r
-\r
-                       /* Check if the current command is being aborted by the host */\r
-                       if (IsMassStoreReset)\r
-                         return;\r
-               }\r
-               \r
-               /* Decrement the blocks remaining counter */\r
-               TotalBlocks--;\r
-       }\r
-\r
-       /* Deselect all dataflash chips */\r
-       Dataflash_DeselectChip();\r
-}\r
-\r
-/** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */\r
-void DataflashManager_ResetDataflashProtections(void)\r
-{\r
-       /* Select first dataflash chip, send the read status register command */\r
-       Dataflash_SelectChip(DATAFLASH_CHIP1);\r
-       Dataflash_SendByte(DF_CMD_GETSTATUS);\r
-       \r
-       /* Check if sector protection is enabled */\r
-       if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)\r
-       {\r
-               Dataflash_ToggleSelectedChipCS();\r
-\r
-               /* Send the commands to disable sector protection */\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);\r
-       }\r
-       \r
-       /* Select second dataflash chip (if present on selected board), send read status register command */\r
-       #if (DATAFLASH_TOTALCHIPS == 2)\r
-       Dataflash_SelectChip(DATAFLASH_CHIP2);\r
-       Dataflash_SendByte(DF_CMD_GETSTATUS);\r
-       \r
-       /* Check if sector protection is enabled */\r
-       if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)\r
-       {\r
-               Dataflash_ToggleSelectedChipCS();\r
-\r
-               /* Send the commands to disable sector protection */\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);\r
-               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);\r
-       }\r
-       #endif\r
-       \r
-       /* Deselect current dataflash chip */\r
-       Dataflash_DeselectChip();\r
-}\r
diff --git a/Demos/Device/MassStorage/DataflashManager.h b/Demos/Device/MassStorage/DataflashManager.h
deleted file mode 100644 (file)
index 1332fd3..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for DataflashManager.c.\r
- */\r
\r
-#ifndef _DATAFLASH_MANAGER_H\r
-#define _DATAFLASH_MANAGER_H\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               \r
-               #include "MassStorage.h"\r
-               #include "Descriptors.h"\r
-\r
-               #include <LUFA/Common/Common.h>              // Function Attribute, Atomic, Debug and ISR Macros\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/Dataflash.h>    // Dataflash chip driver\r
-\r
-       /* Preprocessor Checks: */\r
-               #if (DATAFLASH_PAGE_SIZE % 16)\r
-                       #error Dataflash page size must be a multiple of 16 bytes.\r
-               #endif\r
-\r
-       /* Defines: */\r
-               /** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */\r
-               #define VIRTUAL_MEMORY_BYTES                ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)\r
-\r
-               /** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying\r
-                *  storage media (Dataflash) using a different native block size.\r
-                */\r
-               #define VIRTUAL_MEMORY_BLOCK_SIZE           512\r
-               \r
-               /** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. */\r
-               #define VIRTUAL_MEMORY_BLOCKS               (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)\r
-               \r
-       /* Function Prototypes: */\r
-               void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
-               void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
-               void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
-                                                     uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
-               void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
-                                                    uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
-               void DataflashManager_ResetDataflashProtections(void);\r
-               \r
-#endif\r
diff --git a/Demos/Device/MassStorage/Lib/DataflashManager.c b/Demos/Device/MassStorage/Lib/DataflashManager.c
new file mode 100644 (file)
index 0000000..4b62419
--- /dev/null
@@ -0,0 +1,477 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Functions to manage the physical dataflash media, including reading and writing of\r
+ *  blocks of data. These functions are called by the SCSI layer when data must be stored\r
+ *  or retrieved to/from the physical storage media. If a different media is used (such\r
+ *  as a SD card or EEPROM), functions similar to these will need to be generated.\r
+ */\r
+\r
+#define  INCLUDE_FROM_DATAFLASHMANAGER_C\r
+#include "DataflashManager.h"\r
+\r
+/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from\r
+ *  the pre-selected data OUT endpoint. This routine reads in OS sized blocks from the endpoint and writes\r
+ *  them to the dataflash in Dataflash page sized blocks.\r
+ *\r
+ *  \param BlockAddress  Data block starting address for the write sequence\r
+ *  \param TotalBlocks   Number of blocks of data to write\r
+ */\r
+void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)\r
+{\r
+       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
+       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
+       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
+\r
+       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+       Dataflash_SelectChipFromPage(CurrDFPage);\r
+       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
+       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+       Dataflash_WaitWhileBusy();\r
+\r
+       /* Send the dataflash buffer write command */\r
+       Dataflash_ToggleSelectedChipCS();\r
+       Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
+       Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
+\r
+       /* Wait until endpoint is ready before continuing */\r
+       while (!(Endpoint_IsReadWriteAllowed()));\r
+\r
+       while (TotalBlocks)\r
+       {\r
+               uint8_t BytesInBlockDiv16 = 0;\r
+               \r
+               /* Write an endpoint packet sized data block to the dataflash */\r
+               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
+               {\r
+                       /* Check if the endpoint is currently empty */\r
+                       if (!(Endpoint_IsReadWriteAllowed()))\r
+                       {\r
+                               /* Clear the current endpoint bank */\r
+                               Endpoint_ClearOUT();\r
+                               \r
+                               /* Wait until the host has sent another packet */\r
+                               while (!(Endpoint_IsReadWriteAllowed()));\r
+                       }\r
+\r
+                       /* Check if end of dataflash page reached */\r
+                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
+                       {\r
+                               /* Write the dataflash buffer contents back to the dataflash page */\r
+                               Dataflash_ToggleSelectedChipCS();\r
+                               Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
+                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+\r
+                               /* Reset the dataflash buffer counter, increment the page counter */\r
+                               CurrDFPageByteDiv16 = 0;\r
+                               CurrDFPage++;\r
+\r
+                               /* Select the next dataflash chip based on the new dataflash page index */\r
+                               Dataflash_SelectChipFromPage(CurrDFPage);\r
+                               Dataflash_WaitWhileBusy();\r
+\r
+#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
+                               /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */\r
+                               if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))\r
+                               {\r
+                                       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+                                       Dataflash_ToggleSelectedChipCS();\r
+                                       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
+                                       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+                                       Dataflash_WaitWhileBusy();\r
+                               }\r
+#endif\r
+\r
+                               /* Send the dataflash buffer write command */\r
+                               Dataflash_ToggleSelectedChipCS();\r
+                               Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
+                               Dataflash_SendAddressBytes(0, 0);\r
+                       }\r
+\r
+                       /* Write one 16-byte chunk of data to the dataflash */\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       Dataflash_SendByte(Endpoint_Read_Byte());\r
+                       \r
+                       /* Increment the dataflash page 16 byte block counter */\r
+                       CurrDFPageByteDiv16++;\r
+\r
+                       /* Increment the block 16 byte block counter */\r
+                       BytesInBlockDiv16++;\r
+\r
+                       /* Check if the current command is being aborted by the host */\r
+                       if (IsMassStoreReset)\r
+                         return;                       \r
+               }\r
+                       \r
+               /* Decrement the blocks remaining counter and reset the sub block counter */\r
+               TotalBlocks--;\r
+       }\r
+\r
+       /* Write the dataflash buffer contents back to the dataflash page */\r
+       Dataflash_ToggleSelectedChipCS();\r
+       Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
+       Dataflash_SendAddressBytes(CurrDFPage, 0x00);\r
+       Dataflash_WaitWhileBusy();\r
+\r
+       /* If the endpoint is empty, clear it ready for the next packet from the host */\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearOUT();\r
+\r
+       /* Deselect all dataflash chips */\r
+       Dataflash_DeselectChip();\r
+}\r
+\r
+/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into\r
+ *  the pre-selected data IN endpoint. This routine reads in Dataflash page sized blocks from the Dataflash\r
+ *  and writes them in OS sized blocks to the endpoint.\r
+ *\r
+ *  \param BlockAddress  Data block starting address for the read sequence\r
+ *  \param TotalBlocks   Number of blocks of data to read\r
+ */\r
+void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks)\r
+{\r
+       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
+       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
+       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
+\r
+       /* Send the dataflash main memory page read command */\r
+       Dataflash_SelectChipFromPage(CurrDFPage);\r
+       Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
+       Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       \r
+       /* Wait until endpoint is ready before continuing */\r
+       while (!(Endpoint_IsReadWriteAllowed()));\r
+       \r
+       while (TotalBlocks)\r
+       {\r
+               uint8_t BytesInBlockDiv16 = 0;\r
+               \r
+               /* Write an endpoint packet sized data block to the dataflash */\r
+               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
+               {\r
+                       /* Check if the endpoint is currently full */\r
+                       if (!(Endpoint_IsReadWriteAllowed()))\r
+                       {\r
+                               /* Clear the endpoint bank to send its contents to the host */\r
+                               Endpoint_ClearIN();\r
+                               \r
+                               /* Wait until the endpoint is ready for more data */\r
+                               while (!(Endpoint_IsReadWriteAllowed()));\r
+                       }\r
+                       \r
+                       /* Check if end of dataflash page reached */\r
+                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
+                       {\r
+                               /* Reset the dataflash buffer counter, increment the page counter */\r
+                               CurrDFPageByteDiv16 = 0;\r
+                               CurrDFPage++;\r
+\r
+                               /* Select the next dataflash chip based on the new dataflash page index */\r
+                               Dataflash_SelectChipFromPage(CurrDFPage);\r
+                               \r
+                               /* Send the dataflash main memory page read command */\r
+                               Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
+                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                       }       \r
+\r
+                       /* Read one 16-byte chunk of data from the dataflash */\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       Endpoint_Write_Byte(Dataflash_ReceiveByte());\r
+                       \r
+                       /* Increment the dataflash page 16 byte block counter */\r
+                       CurrDFPageByteDiv16++;\r
+                       \r
+                       /* Increment the block 16 byte block counter */\r
+                       BytesInBlockDiv16++;\r
+\r
+                       /* Check if the current command is being aborted by the host */\r
+                       if (IsMassStoreReset)\r
+                         return;\r
+               }\r
+               \r
+               /* Decrement the blocks remaining counter */\r
+               TotalBlocks--;\r
+       }\r
+       \r
+       /* If the endpoint is full, send its contents to the host */\r
+       if (!(Endpoint_IsReadWriteAllowed()))\r
+         Endpoint_ClearIN();\r
+\r
+       /* Deselect all dataflash chips */\r
+       Dataflash_DeselectChip();\r
+}\r
+\r
+/** Writes blocks (OS blocks, not Dataflash pages) to the storage medium, the board dataflash IC(s), from\r
+ *  the a given RAM buffer. This routine reads in OS sized blocks from the buffer and writes them to the\r
+ *  dataflash in Dataflash page sized blocks. This can be linked to FAT libraries to write files to the\r
+ *  dataflash.\r
+ *\r
+ *  \param BlockAddress  Data block starting address for the write sequence\r
+ *  \param TotalBlocks   Number of blocks of data to write\r
+ *  \param BufferPtr     Pointer to the data source RAM buffer\r
+ */\r
+void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)\r
+{\r
+       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
+       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
+       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
+\r
+       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+       Dataflash_SelectChipFromPage(CurrDFPage);\r
+       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
+       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+       Dataflash_WaitWhileBusy();\r
+\r
+       /* Send the dataflash buffer write command */\r
+       Dataflash_ToggleSelectedChipCS();\r
+       Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
+       Dataflash_SendAddressBytes(0, CurrDFPageByte);\r
+\r
+       while (TotalBlocks)\r
+       {\r
+               uint8_t BytesInBlockDiv16 = 0;\r
+               \r
+               /* Write an endpoint packet sized data block to the dataflash */\r
+               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
+               {\r
+                       /* Check if end of dataflash page reached */\r
+                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
+                       {\r
+                               /* Write the dataflash buffer contents back to the dataflash page */\r
+                               Dataflash_ToggleSelectedChipCS();\r
+                               Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
+                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+\r
+                               /* Reset the dataflash buffer counter, increment the page counter */\r
+                               CurrDFPageByteDiv16 = 0;\r
+                               CurrDFPage++;\r
+\r
+                               /* Select the next dataflash chip based on the new dataflash page index */\r
+                               Dataflash_SelectChipFromPage(CurrDFPage);\r
+                               Dataflash_WaitWhileBusy();\r
+\r
+#if (DATAFLASH_PAGE_SIZE > VIRTUAL_MEMORY_BLOCK_SIZE)\r
+                               /* If less than one dataflash page remaining, copy over the existing page to preserve trailing data */\r
+                               if ((TotalBlocks * (VIRTUAL_MEMORY_BLOCK_SIZE >> 4)) < (DATAFLASH_PAGE_SIZE >> 4))\r
+                               {\r
+                                       /* Copy selected dataflash's current page contents to the dataflash buffer */\r
+                                       Dataflash_ToggleSelectedChipCS();\r
+                                       Dataflash_SendByte(DF_CMD_MAINMEMTOBUFF1);\r
+                                       Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+                                       Dataflash_WaitWhileBusy();\r
+                               }\r
+#endif\r
+\r
+                               /* Send the dataflash buffer write command */\r
+                               Dataflash_ToggleSelectedChipCS();\r
+                               Dataflash_SendByte(DF_CMD_BUFF1WRITE);\r
+                               Dataflash_SendAddressBytes(0, 0);\r
+                       }\r
+                       \r
+                       /* Write one 16-byte chunk of data to the dataflash */\r
+                       for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)\r
+                         Dataflash_SendByte(*(BufferPtr++));\r
+                       \r
+                       /* Increment the dataflash page 16 byte block counter */\r
+                       CurrDFPageByteDiv16++;\r
+\r
+                       /* Increment the block 16 byte block counter */\r
+                       BytesInBlockDiv16++;\r
+\r
+                       /* Check if the current command is being aborted by the host */\r
+                       if (IsMassStoreReset)\r
+                         return;                       \r
+               }\r
+                       \r
+               /* Decrement the blocks remaining counter and reset the sub block counter */\r
+               TotalBlocks--;\r
+       }\r
+\r
+       /* Write the dataflash buffer contents back to the dataflash page */\r
+       Dataflash_ToggleSelectedChipCS();\r
+       Dataflash_SendByte(DF_CMD_BUFF1TOMAINMEMWITHERASE);\r
+       Dataflash_SendAddressBytes(CurrDFPage, 0x00);\r
+       Dataflash_WaitWhileBusy();\r
+\r
+       /* Deselect all dataflash chips */\r
+       Dataflash_DeselectChip();\r
+}\r
+\r
+/** Reads blocks (OS blocks, not Dataflash pages) from the storage medium, the board dataflash IC(s), into\r
+ *  the a preallocated RAM buffer. This routine reads in Dataflash page sized blocks from the Dataflash\r
+ *  and writes them in OS sized blocks to the given buffer. This can be linked to FAT libraries to read\r
+ *  the files stored on the dataflash.\r
+ *\r
+ *  \param BlockAddress  Data block starting address for the read sequence\r
+ *  \param TotalBlocks   Number of blocks of data to read\r
+ *  \param BufferPtr     Pointer to the data destination RAM buffer\r
+ */\r
+void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks, uint8_t* BufferPtr)\r
+{\r
+       uint16_t CurrDFPage          = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) / DATAFLASH_PAGE_SIZE);\r
+       uint16_t CurrDFPageByte      = ((BlockAddress * VIRTUAL_MEMORY_BLOCK_SIZE) % DATAFLASH_PAGE_SIZE);\r
+       uint8_t  CurrDFPageByteDiv16 = (CurrDFPageByte >> 4);\r
+\r
+       /* Send the dataflash main memory page read command */\r
+       Dataflash_SelectChipFromPage(CurrDFPage);\r
+       Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
+       Dataflash_SendAddressBytes(CurrDFPage, CurrDFPageByte);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+       Dataflash_SendByte(0x00);\r
+\r
+       while (TotalBlocks)\r
+       {\r
+               uint8_t BytesInBlockDiv16 = 0;\r
+               \r
+               /* Write an endpoint packet sized data block to the dataflash */\r
+               while (BytesInBlockDiv16 < (VIRTUAL_MEMORY_BLOCK_SIZE >> 4))\r
+               {\r
+                       /* Check if end of dataflash page reached */\r
+                       if (CurrDFPageByteDiv16 == (DATAFLASH_PAGE_SIZE >> 4))\r
+                       {\r
+                               /* Reset the dataflash buffer counter, increment the page counter */\r
+                               CurrDFPageByteDiv16 = 0;\r
+                               CurrDFPage++;\r
+\r
+                               /* Select the next dataflash chip based on the new dataflash page index */\r
+                               Dataflash_SelectChipFromPage(CurrDFPage);\r
+                               \r
+                               /* Send the dataflash main memory page read command */\r
+                               Dataflash_SendByte(DF_CMD_MAINMEMPAGEREAD);\r
+                               Dataflash_SendAddressBytes(CurrDFPage, 0);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                               Dataflash_SendByte(0x00);\r
+                       }       \r
+\r
+                       /* Read one 16-byte chunk of data from the dataflash */\r
+                       for (uint8_t ByteNum = 0; ByteNum < 16; ByteNum++)\r
+                         *(BufferPtr++) = Dataflash_ReceiveByte();\r
+                       \r
+                       /* Increment the dataflash page 16 byte block counter */\r
+                       CurrDFPageByteDiv16++;\r
+                       \r
+                       /* Increment the block 16 byte block counter */\r
+                       BytesInBlockDiv16++;\r
+\r
+                       /* Check if the current command is being aborted by the host */\r
+                       if (IsMassStoreReset)\r
+                         return;\r
+               }\r
+               \r
+               /* Decrement the blocks remaining counter */\r
+               TotalBlocks--;\r
+       }\r
+\r
+       /* Deselect all dataflash chips */\r
+       Dataflash_DeselectChip();\r
+}\r
+\r
+/** Disables the dataflash memory write protection bits on the board Dataflash ICs, if enabled. */\r
+void DataflashManager_ResetDataflashProtections(void)\r
+{\r
+       /* Select first dataflash chip, send the read status register command */\r
+       Dataflash_SelectChip(DATAFLASH_CHIP1);\r
+       Dataflash_SendByte(DF_CMD_GETSTATUS);\r
+       \r
+       /* Check if sector protection is enabled */\r
+       if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)\r
+       {\r
+               Dataflash_ToggleSelectedChipCS();\r
+\r
+               /* Send the commands to disable sector protection */\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);\r
+       }\r
+       \r
+       /* Select second dataflash chip (if present on selected board), send read status register command */\r
+       #if (DATAFLASH_TOTALCHIPS == 2)\r
+       Dataflash_SelectChip(DATAFLASH_CHIP2);\r
+       Dataflash_SendByte(DF_CMD_GETSTATUS);\r
+       \r
+       /* Check if sector protection is enabled */\r
+       if (Dataflash_ReceiveByte() & DF_STATUS_SECTORPROTECTION_ON)\r
+       {\r
+               Dataflash_ToggleSelectedChipCS();\r
+\r
+               /* Send the commands to disable sector protection */\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[0]);\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[1]);\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[2]);\r
+               Dataflash_SendByte(DF_CMD_SECTORPROTECTIONOFF[3]);\r
+       }\r
+       #endif\r
+       \r
+       /* Deselect current dataflash chip */\r
+       Dataflash_DeselectChip();\r
+}\r
diff --git a/Demos/Device/MassStorage/Lib/DataflashManager.h b/Demos/Device/MassStorage/Lib/DataflashManager.h
new file mode 100644 (file)
index 0000000..1332fd3
--- /dev/null
@@ -0,0 +1,75 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for DataflashManager.c.\r
+ */\r
\r
+#ifndef _DATAFLASH_MANAGER_H\r
+#define _DATAFLASH_MANAGER_H\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               \r
+               #include "MassStorage.h"\r
+               #include "Descriptors.h"\r
+\r
+               #include <LUFA/Common/Common.h>              // Function Attribute, Atomic, Debug and ISR Macros\r
+               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
+               #include <LUFA/Drivers/Board/Dataflash.h>    // Dataflash chip driver\r
+\r
+       /* Preprocessor Checks: */\r
+               #if (DATAFLASH_PAGE_SIZE % 16)\r
+                       #error Dataflash page size must be a multiple of 16 bytes.\r
+               #endif\r
+\r
+       /* Defines: */\r
+               /** Total number of bytes of the storage medium, comprised of one or more dataflash ICs. */\r
+               #define VIRTUAL_MEMORY_BYTES                ((uint32_t)DATAFLASH_PAGES * DATAFLASH_PAGE_SIZE * DATAFLASH_TOTALCHIPS)\r
+\r
+               /** Block size of the device. This is kept at 512 to remain compatible with the OS despite the underlying\r
+                *  storage media (Dataflash) using a different native block size.\r
+                */\r
+               #define VIRTUAL_MEMORY_BLOCK_SIZE           512\r
+               \r
+               /** Total number of blocks of the virtual memory for reporting to the host as the device's total capacity. */\r
+               #define VIRTUAL_MEMORY_BLOCKS               (VIRTUAL_MEMORY_BYTES / VIRTUAL_MEMORY_BLOCK_SIZE)\r
+               \r
+       /* Function Prototypes: */\r
+               void DataflashManager_WriteBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
+               void DataflashManager_ReadBlocks(const uint32_t BlockAddress, uint16_t TotalBlocks);\r
+               void DataflashManager_WriteBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
+                                                     uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
+               void DataflashManager_ReadBlocks_RAM(const uint32_t BlockAddress, uint16_t TotalBlocks,\r
+                                                    uint8_t* BufferPtr) ATTR_NON_NULL_PTR_ARG(3);\r
+               void DataflashManager_ResetDataflashProtections(void);\r
+               \r
+#endif\r
diff --git a/Demos/Device/MassStorage/Lib/SCSI.c b/Demos/Device/MassStorage/Lib/SCSI.c
new file mode 100644 (file)
index 0000000..5993a54
--- /dev/null
@@ -0,0 +1,350 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  SCSI command processing routines, for SCSI commands issued by the host. Mass Storage\r
+ *  devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,\r
+ *  which wrap around standard SCSI device commands for controlling the actual storage medium.\r
+ */\r
\r
+#define  INCLUDE_FROM_SCSI_C\r
+#include "SCSI.h"\r
+\r
+/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's\r
+ *  features and capabilities.\r
+ */\r
+SCSI_Inquiry_Response_t InquiryData = \r
+       {\r
+               .DeviceType          = DEVICE_TYPE_BLOCK,\r
+               .PeripheralQualifier = 0,\r
+                       \r
+               .Removable           = true,\r
+                       \r
+               .Version             = 0,\r
+                       \r
+               .ResponseDataFormat  = 2,\r
+               .NormACA             = false,\r
+               .TrmTsk              = false,\r
+               .AERC                = false,\r
+\r
+               .AdditionalLength    = 0x1F,\r
+                       \r
+               .SoftReset           = false,\r
+               .CmdQue              = false,\r
+               .Linked              = false,\r
+               .Sync                = false,\r
+               .WideBus16Bit        = false,\r
+               .WideBus32Bit        = false,\r
+               .RelAddr             = false,\r
+               \r
+               .VendorID            = "LUFA",\r
+               .ProductID           = "Dataflash Disk",\r
+               .RevisionID          = {'0','.','0','0'},\r
+       };\r
+\r
+/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE\r
+ *  command is issued. This gives information on exactly why the last command failed to complete.\r
+ */\r
+SCSI_Request_Sense_Response_t SenseData =\r
+       {\r
+               .ResponseCode        = 0x70,\r
+               .AdditionalLength    = 0x0A,\r
+       };\r
+\r
+\r
+/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches\r
+ *  to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns\r
+ *  a command failure due to a ILLEGAL REQUEST.\r
+ */\r
+void SCSI_DecodeSCSICommand(void)\r
+{\r
+       bool CommandSuccess = false;\r
+\r
+       /* Run the appropriate SCSI command hander function based on the passed command */\r
+       switch (CommandBlock.SCSICommandData[0])\r
+       {\r
+               case SCSI_CMD_INQUIRY:\r
+                       CommandSuccess = SCSI_Command_Inquiry();                        \r
+                       break;\r
+               case SCSI_CMD_REQUEST_SENSE:\r
+                       CommandSuccess = SCSI_Command_Request_Sense();\r
+                       break;\r
+               case SCSI_CMD_READ_CAPACITY_10:\r
+                       CommandSuccess = SCSI_Command_Read_Capacity_10();                       \r
+                       break;\r
+               case SCSI_CMD_SEND_DIAGNOSTIC:\r
+                       CommandSuccess = SCSI_Command_Send_Diagnostic();\r
+                       break;\r
+               case SCSI_CMD_WRITE_10:\r
+                       CommandSuccess = SCSI_Command_ReadWrite_10(DATA_WRITE);\r
+                       break;\r
+               case SCSI_CMD_READ_10:\r
+                       CommandSuccess = SCSI_Command_ReadWrite_10(DATA_READ);\r
+                       break;\r
+               case SCSI_CMD_TEST_UNIT_READY:\r
+               case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:\r
+               case SCSI_CMD_VERIFY_10:\r
+                       /* These commands should just succeed, no handling required */\r
+                       CommandSuccess = true;\r
+                       CommandBlock.DataTransferLength = 0;\r
+                       break;\r
+               default:\r
+                       /* Update the SENSE key to reflect the invalid command */\r
+                       SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
+                                  SCSI_ASENSE_INVALID_COMMAND,\r
+                                  SCSI_ASENSEQ_NO_QUALIFIER);\r
+                       break;\r
+       }\r
+       \r
+       /* Check if command was successfully processed */\r
+       if (CommandSuccess)\r
+       {\r
+               /* Command succeeded - set the CSW status and update the SENSE key */\r
+               CommandStatus.Status = Command_Pass;\r
+               \r
+               SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,\r
+                              SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);                                         \r
+       }\r
+       else\r
+       {\r
+               /* Command failed - set the CSW status - failed command function updates the SENSE key */\r
+               CommandStatus.Status = Command_Fail;\r
+       }\r
+}\r
+\r
+/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features\r
+ *  and capabilities to the host.\r
+ *\r
+ *  \return Boolean true if the command completed successfully, false otherwise.\r
+ */\r
+static bool SCSI_Command_Inquiry(void)\r
+{\r
+       uint16_t AllocationLength  = (((uint16_t)CommandBlock.SCSICommandData[3] << 8) |\r
+                                                CommandBlock.SCSICommandData[4]);\r
+       uint16_t BytesTransferred  = (AllocationLength < sizeof(InquiryData))? AllocationLength :\r
+                                                                              sizeof(InquiryData);\r
+\r
+       /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */\r
+       if ((CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||\r
+            CommandBlock.SCSICommandData[2])\r
+       {\r
+               /* Optional but unsupported bits set - update the SENSE key and fail the request */\r
+               SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
+                              SCSI_ASENSE_INVALID_FIELD_IN_CDB,\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);\r
+\r
+               return false;\r
+       }\r
+\r
+       /* Write the INQUIRY data to the endpoint */\r
+       Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);\r
+\r
+       uint8_t PadBytes[AllocationLength - BytesTransferred];\r
+       \r
+       /* Pad out remaining bytes with 0x00 */\r
+       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);\r
+\r
+       /* Finalize the stream transfer to send the last packet */\r
+       Endpoint_ClearIN();\r
+\r
+       /* Succeed the command and update the bytes transferred counter */\r
+       CommandBlock.DataTransferLength -= BytesTransferred;\r
+       \r
+       return true;\r
+}\r
+\r
+/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,\r
+ *  including the error code and additional error information so that the host can determine why a command failed to complete.\r
+ *\r
+ *  \return Boolean true if the command completed successfully, false otherwise.\r
+ */\r
+static bool SCSI_Command_Request_Sense(void)\r
+{\r
+       uint8_t  AllocationLength = CommandBlock.SCSICommandData[4];\r
+       uint8_t  BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);\r
+       \r
+       /* Send the SENSE data - this indicates to the host the status of the last command */\r
+       Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);\r
+       \r
+       uint8_t PadBytes[AllocationLength - BytesTransferred];\r
+       \r
+       /* Pad out remaining bytes with 0x00 */\r
+       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);\r
+\r
+       /* Finalize the stream transfer to send the last packet */\r
+       Endpoint_ClearIN();\r
+\r
+       /* Succeed the command and update the bytes transferred counter */\r
+       CommandBlock.DataTransferLength -= BytesTransferred;\r
+\r
+       return true;\r
+}\r
+\r
+/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity\r
+ *  on the selected Logical Unit (drive), as a number of OS-sized blocks.\r
+ *\r
+ *  \return Boolean true if the command completed successfully, false otherwise.\r
+ */\r
+static bool SCSI_Command_Read_Capacity_10(void)\r
+{\r
+       /* Send the total number of logical blocks in the current LUN */\r
+       Endpoint_Write_DWord_BE(LUN_MEDIA_BLOCKS - 1);\r
+\r
+       /* Send the logical block size of the device (must be 512 bytes) */\r
+       Endpoint_Write_DWord_BE(VIRTUAL_MEMORY_BLOCK_SIZE);\r
+\r
+       /* Check if the current command is being aborted by the host */\r
+       if (IsMassStoreReset)\r
+         return false;\r
+\r
+       /* Send the endpoint data packet to the host */\r
+       Endpoint_ClearIN();\r
+\r
+       /* Succeed the command and update the bytes transferred counter */\r
+       CommandBlock.DataTransferLength -= 8;\r
+       \r
+       return true;\r
+}\r
+\r
+/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the\r
+ *  board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is\r
+ *  supported.\r
+ *\r
+ *  \return Boolean true if the command completed successfully, false otherwise.\r
+ */\r
+static bool SCSI_Command_Send_Diagnostic(void)\r
+{\r
+       uint8_t ReturnByte;\r
+\r
+       /* Check to see if the SELF TEST bit is not set */\r
+       if (!(CommandBlock.SCSICommandData[1] & (1 << 2)))\r
+       {\r
+               /* Only self-test supported - update SENSE key and fail the command */\r
+               SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
+                              SCSI_ASENSE_INVALID_FIELD_IN_CDB,\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);\r
+\r
+               return false;\r
+       }\r
+       \r
+       /* Test first Dataflash IC is present and responding to commands */\r
+       Dataflash_SelectChip(DATAFLASH_CHIP1);\r
+       Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);\r
+       ReturnByte = Dataflash_ReceiveByte();\r
+       Dataflash_DeselectChip();\r
+\r
+       /* If returned data is invalid, fail the command */\r
+       if (ReturnByte != DF_MANUFACTURER_ATMEL)\r
+       {\r
+               /* Update SENSE key with a hardware error condition and return command fail */\r
+               SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,\r
+                              SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);      \r
+       \r
+               return false;\r
+       }\r
+\r
+       #if (DATAFLASH_TOTALCHIPS == 2)\r
+       /* Test second Dataflash IC is present and responding to commands */\r
+       Dataflash_SelectChip(DATAFLASH_CHIP2);\r
+       Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);\r
+       ReturnByte = Dataflash_ReceiveByte();\r
+       Dataflash_DeselectChip();\r
+\r
+       /* If returned data is invalid, fail the command */\r
+       if (ReturnByte != DF_MANUFACTURER_ATMEL)\r
+       {\r
+               /* Update SENSE key with a hardware error condition and return command fail */\r
+               SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,\r
+                              SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);      \r
+       \r
+               return false;\r
+       }\r
+       #endif\r
+       \r
+       /* Succeed the command and update the bytes transferred counter */\r
+       CommandBlock.DataTransferLength = 0;\r
+       \r
+       return true;\r
+}\r
+\r
+/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address\r
+ *  and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual\r
+ *  reading and writing of the data.\r
+ *\r
+ *  \param IsDataRead  Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)\r
+ *\r
+ *  \return Boolean true if the command completed successfully, false otherwise.\r
+ */\r
+static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)\r
+{\r
+       uint32_t BlockAddress;\r
+       uint16_t TotalBlocks;\r
+       \r
+       /* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */\r
+       ((uint8_t*)&BlockAddress)[3] = CommandBlock.SCSICommandData[2];\r
+       ((uint8_t*)&BlockAddress)[2] = CommandBlock.SCSICommandData[3];\r
+       ((uint8_t*)&BlockAddress)[1] = CommandBlock.SCSICommandData[4];\r
+       ((uint8_t*)&BlockAddress)[0] = CommandBlock.SCSICommandData[5];\r
+\r
+       /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */\r
+       ((uint8_t*)&TotalBlocks)[1]  = CommandBlock.SCSICommandData[7];\r
+       ((uint8_t*)&TotalBlocks)[0]  = CommandBlock.SCSICommandData[8];\r
+       \r
+       /* Check if the block address is outside the maximum allowable value for the LUN */\r
+       if (BlockAddress >= LUN_MEDIA_BLOCKS)\r
+       {\r
+               /* Block address is invalid, update SENSE key and return command fail */\r
+               SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
+                              SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,\r
+                              SCSI_ASENSEQ_NO_QUALIFIER);\r
+\r
+               return false;\r
+       }\r
+\r
+       #if (TOTAL_LUNS > 1)\r
+       /* Adjust the given block address to the real media address based on the selected LUN */\r
+       BlockAddress += ((uint32_t)CommandBlock.LUN * LUN_MEDIA_BLOCKS);\r
+       #endif\r
+       \r
+       /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */\r
+       if (IsDataRead == DATA_READ)\r
+         DataflashManager_ReadBlocks(BlockAddress, TotalBlocks);\r
+       else\r
+         DataflashManager_WriteBlocks(BlockAddress, TotalBlocks);\r
+\r
+       /* Update the bytes transferred counter and succeed the command */\r
+       CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);\r
+       \r
+       return true;\r
+}\r
diff --git a/Demos/Device/MassStorage/Lib/SCSI.h b/Demos/Device/MassStorage/Lib/SCSI.h
new file mode 100644 (file)
index 0000000..d7693ca
--- /dev/null
@@ -0,0 +1,149 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for SCSI.c.\r
+ */\r
\r
+#ifndef _SCSI_H_\r
+#define _SCSI_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <avr/pgmspace.h>\r
+\r
+               #include <LUFA/Common/Common.h>              // Function Attribute, Atomic, Debug and ISR Macros\r
+               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
+               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
+\r
+               #include "MassStorage.h"\r
+               #include "Descriptors.h"\r
+               #include "DataflashManager.h"\r
+               #include "SCSI_Codes.h"\r
+       \r
+       /* Macros: */\r
+               /** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This\r
+                *  is for convenience, as it allows for all three sense values (returned upon request to the host to give information about\r
+                *  the last command failure) in a quick and easy manner.\r
+                *\r
+                *  \param key    New SCSI sense key to set the sense code to\r
+                *  \param acode  New SCSI additional sense key to set the additional sense code to\r
+                *  \param aqual  New SCSI additional sense key qualifier to set the additional sense qualifier code to\r
+                */\r
+               #define SCSI_SET_SENSE(key, acode, aqual)  MACROS{ SenseData.SenseKey = key;              \\r
+                                                                  SenseData.AdditionalSenseCode = acode; \\r
+                                                                  SenseData.AdditionalSenseQualifier = aqual; }MACROE\r
+\r
+               /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */\r
+               #define DATA_READ      true\r
+\r
+               /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */\r
+               #define DATA_WRITE     false\r
+\r
+               /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */\r
+               #define DEVICE_TYPE_BLOCK 0x00\r
+               \r
+               /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */\r
+               #define DEVICE_TYPE_CDROM 0x05\r
+\r
+       /* Type Defines: */\r
+               /** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the\r
+                *  structure contents, refer to the SCSI specifications.\r
+                */\r
+               typedef struct\r
+               {\r
+                       unsigned char DeviceType          : 5;\r
+                       unsigned char PeripheralQualifier : 3;\r
+                       \r
+                       unsigned char _RESERVED1          : 7;\r
+                       unsigned char Removable           : 1;\r
+                       \r
+                       uint8_t      Version;\r
+                       \r
+                       unsigned char ResponseDataFormat  : 4;\r
+                       unsigned char _RESERVED2          : 1;\r
+                       unsigned char NormACA             : 1;\r
+                       unsigned char TrmTsk              : 1;\r
+                       unsigned char AERC                : 1;\r
+\r
+                       uint8_t      AdditionalLength;\r
+                       uint8_t      _RESERVED3[2];\r
+\r
+                       unsigned char SoftReset           : 1;\r
+                       unsigned char CmdQue              : 1;\r
+                       unsigned char _RESERVED4          : 1;\r
+                       unsigned char Linked              : 1;\r
+                       unsigned char Sync                : 1;\r
+                       unsigned char WideBus16Bit        : 1;\r
+                       unsigned char WideBus32Bit        : 1;\r
+                       unsigned char RelAddr             : 1;\r
+                       \r
+                       uint8_t      VendorID[8];\r
+                       uint8_t      ProductID[16];\r
+                       uint8_t      RevisionID[4];\r
+               } SCSI_Inquiry_Response_t;\r
+               \r
+               /** Type define for a SCSI sense structure to a SCSI REQUEST SENSE command. For details of the\r
+                *  structure contents, refer to the SCSI specifications.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint8_t       ResponseCode;\r
+                       \r
+                       uint8_t       SegmentNumber;\r
+                       \r
+                       unsigned char SenseKey            : 4;\r
+                       unsigned char _RESERVED1          : 1;\r
+                       unsigned char ILI                 : 1;\r
+                       unsigned char EOM                 : 1;\r
+                       unsigned char FileMark            : 1;\r
+                       \r
+                       uint8_t      Information[4];\r
+                       uint8_t      AdditionalLength;\r
+                       uint8_t      CmdSpecificInformation[4];\r
+                       uint8_t      AdditionalSenseCode;\r
+                       uint8_t      AdditionalSenseQualifier;\r
+                       uint8_t      FieldReplaceableUnitCode;\r
+                       uint8_t      SenseKeySpecific[3];\r
+               } SCSI_Request_Sense_Response_t;\r
+               \r
+       /* Function Prototypes: */\r
+               void SCSI_DecodeSCSICommand(void);\r
+               \r
+               #if defined(INCLUDE_FROM_SCSI_C)\r
+                       static bool SCSI_Command_Inquiry(void);\r
+                       static bool SCSI_Command_Request_Sense(void);\r
+                       static bool SCSI_Command_Read_Capacity_10(void);\r
+                       static bool SCSI_Command_Send_Diagnostic(void);\r
+                       static bool SCSI_Command_ReadWrite_10(const bool IsDataRead);\r
+               #endif\r
+               \r
+#endif\r
diff --git a/Demos/Device/MassStorage/Lib/SCSI_Codes.h b/Demos/Device/MassStorage/Lib/SCSI_Codes.h
new file mode 100644 (file)
index 0000000..2b2213d
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header containing macros for possible SCSI commands and SENSE data. Refer to\r
+ *  the SCSI standard documentation for more information on each SCSI command and\r
+ *  the SENSE data.\r
+ */\r
\r
+#ifndef _SCSI_CODES_H_\r
+#define _SCSI_CODES_H_\r
+\r
+       /* Macros: */\r
+               #define SCSI_CMD_INQUIRY                               0x12\r
+               #define SCSI_CMD_REQUEST_SENSE                         0x03\r
+               #define SCSI_CMD_TEST_UNIT_READY                       0x00\r
+               #define SCSI_CMD_READ_CAPACITY_10                      0x25\r
+               #define SCSI_CMD_SEND_DIAGNOSTIC                       0x1D\r
+               #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL          0x1E\r
+               #define SCSI_CMD_WRITE_10                              0x2A\r
+               #define SCSI_CMD_READ_10                               0x28\r
+               #define SCSI_CMD_WRITE_6                               0x0A\r
+               #define SCSI_CMD_READ_6                                0x08\r
+               #define SCSI_CMD_VERIFY_10                             0x2F\r
+               #define SCSI_CMD_MODE_SENSE_6                          0x1A\r
+               #define SCSI_CMD_MODE_SENSE_10                         0x5A\r
+\r
+               #define SCSI_SENSE_KEY_GOOD                            0x00\r
+               #define SCSI_SENSE_KEY_RECOVERED_ERROR                 0x01\r
+               #define SCSI_SENSE_KEY_NOT_READY                       0x02\r
+               #define SCSI_SENSE_KEY_MEDIUM_ERROR                    0x03\r
+               #define SCSI_SENSE_KEY_HARDWARE_ERROR                  0x04\r
+               #define SCSI_SENSE_KEY_ILLEGAL_REQUEST                 0x05\r
+               #define SCSI_SENSE_KEY_UNIT_ATTENTION                  0x06\r
+               #define SCSI_SENSE_KEY_DATA_PROTECT                    0x07\r
+               #define SCSI_SENSE_KEY_BLANK_CHECK                     0x08\r
+               #define SCSI_SENSE_KEY_VENDOR_SPECIFIC                 0x09\r
+               #define SCSI_SENSE_KEY_COPY_ABORTED                    0x0A\r
+               #define SCSI_SENSE_KEY_ABORTED_COMMAND                 0x0B\r
+               #define SCSI_SENSE_KEY_VOLUME_OVERFLOW                 0x0D\r
+               #define SCSI_SENSE_KEY_MISCOMPARE                      0x0E\r
+\r
+               #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION          0x00\r
+               #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY             0x04\r
+               #define SCSI_ASENSE_INVALID_FIELD_IN_CDB               0x24\r
+               #define SCSI_ASENSE_WRITE_PROTECTED                    0x27\r
+               #define SCSI_ASENSE_FORMAT_ERROR                       0x31\r
+               #define SCSI_ASENSE_INVALID_COMMAND                    0x20\r
+               #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21\r
+               #define SCSI_ASENSE_MEDIUM_NOT_PRESENT                 0x3A\r
+\r
+               #define SCSI_ASENSEQ_NO_QUALIFIER                      0x00\r
+               #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED             0x01\r
+               #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED     0x02\r
+               #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS             0x07\r
+\r
+#endif\r
index afe9872..cbd3cd9 100644 (file)
@@ -42,8 +42,9 @@
                #include <avr/power.h>\r
 \r
                #include "Descriptors.h"\r
-               #include "SCSI.h"\r
-               #include "DataflashManager.h"\r
+\r
+               #include "Lib/SCSI.h"\r
+               #include "Lib/DataflashManager.h"\r
 \r
                #include <LUFA/Version.h>                    // Library Version Information\r
                #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
diff --git a/Demos/Device/MassStorage/SCSI.c b/Demos/Device/MassStorage/SCSI.c
deleted file mode 100644 (file)
index 5993a54..0000000
+++ /dev/null
@@ -1,350 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  SCSI command processing routines, for SCSI commands issued by the host. Mass Storage\r
- *  devices use a thin "Bulk-Only Transport" protocol for issuing commands and status information,\r
- *  which wrap around standard SCSI device commands for controlling the actual storage medium.\r
- */\r
\r
-#define  INCLUDE_FROM_SCSI_C\r
-#include "SCSI.h"\r
-\r
-/** Structure to hold the SCSI response data to a SCSI INQUIRY command. This gives information about the device's\r
- *  features and capabilities.\r
- */\r
-SCSI_Inquiry_Response_t InquiryData = \r
-       {\r
-               .DeviceType          = DEVICE_TYPE_BLOCK,\r
-               .PeripheralQualifier = 0,\r
-                       \r
-               .Removable           = true,\r
-                       \r
-               .Version             = 0,\r
-                       \r
-               .ResponseDataFormat  = 2,\r
-               .NormACA             = false,\r
-               .TrmTsk              = false,\r
-               .AERC                = false,\r
-\r
-               .AdditionalLength    = 0x1F,\r
-                       \r
-               .SoftReset           = false,\r
-               .CmdQue              = false,\r
-               .Linked              = false,\r
-               .Sync                = false,\r
-               .WideBus16Bit        = false,\r
-               .WideBus32Bit        = false,\r
-               .RelAddr             = false,\r
-               \r
-               .VendorID            = "LUFA",\r
-               .ProductID           = "Dataflash Disk",\r
-               .RevisionID          = {'0','.','0','0'},\r
-       };\r
-\r
-/** Structure to hold the sense data for the last issued SCSI command, which is returned to the host after a SCSI REQUEST SENSE\r
- *  command is issued. This gives information on exactly why the last command failed to complete.\r
- */\r
-SCSI_Request_Sense_Response_t SenseData =\r
-       {\r
-               .ResponseCode        = 0x70,\r
-               .AdditionalLength    = 0x0A,\r
-       };\r
-\r
-\r
-/** Main routine to process the SCSI command located in the Command Block Wrapper read from the host. This dispatches\r
- *  to the appropriate SCSI command handling routine if the issued command is supported by the device, else it returns\r
- *  a command failure due to a ILLEGAL REQUEST.\r
- */\r
-void SCSI_DecodeSCSICommand(void)\r
-{\r
-       bool CommandSuccess = false;\r
-\r
-       /* Run the appropriate SCSI command hander function based on the passed command */\r
-       switch (CommandBlock.SCSICommandData[0])\r
-       {\r
-               case SCSI_CMD_INQUIRY:\r
-                       CommandSuccess = SCSI_Command_Inquiry();                        \r
-                       break;\r
-               case SCSI_CMD_REQUEST_SENSE:\r
-                       CommandSuccess = SCSI_Command_Request_Sense();\r
-                       break;\r
-               case SCSI_CMD_READ_CAPACITY_10:\r
-                       CommandSuccess = SCSI_Command_Read_Capacity_10();                       \r
-                       break;\r
-               case SCSI_CMD_SEND_DIAGNOSTIC:\r
-                       CommandSuccess = SCSI_Command_Send_Diagnostic();\r
-                       break;\r
-               case SCSI_CMD_WRITE_10:\r
-                       CommandSuccess = SCSI_Command_ReadWrite_10(DATA_WRITE);\r
-                       break;\r
-               case SCSI_CMD_READ_10:\r
-                       CommandSuccess = SCSI_Command_ReadWrite_10(DATA_READ);\r
-                       break;\r
-               case SCSI_CMD_TEST_UNIT_READY:\r
-               case SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL:\r
-               case SCSI_CMD_VERIFY_10:\r
-                       /* These commands should just succeed, no handling required */\r
-                       CommandSuccess = true;\r
-                       CommandBlock.DataTransferLength = 0;\r
-                       break;\r
-               default:\r
-                       /* Update the SENSE key to reflect the invalid command */\r
-                       SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
-                                  SCSI_ASENSE_INVALID_COMMAND,\r
-                                  SCSI_ASENSEQ_NO_QUALIFIER);\r
-                       break;\r
-       }\r
-       \r
-       /* Check if command was successfully processed */\r
-       if (CommandSuccess)\r
-       {\r
-               /* Command succeeded - set the CSW status and update the SENSE key */\r
-               CommandStatus.Status = Command_Pass;\r
-               \r
-               SCSI_SET_SENSE(SCSI_SENSE_KEY_GOOD,\r
-                              SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);                                         \r
-       }\r
-       else\r
-       {\r
-               /* Command failed - set the CSW status - failed command function updates the SENSE key */\r
-               CommandStatus.Status = Command_Fail;\r
-       }\r
-}\r
-\r
-/** Command processing for an issued SCSI INQUIRY command. This command returns information about the device's features\r
- *  and capabilities to the host.\r
- *\r
- *  \return Boolean true if the command completed successfully, false otherwise.\r
- */\r
-static bool SCSI_Command_Inquiry(void)\r
-{\r
-       uint16_t AllocationLength  = (((uint16_t)CommandBlock.SCSICommandData[3] << 8) |\r
-                                                CommandBlock.SCSICommandData[4]);\r
-       uint16_t BytesTransferred  = (AllocationLength < sizeof(InquiryData))? AllocationLength :\r
-                                                                              sizeof(InquiryData);\r
-\r
-       /* Only the standard INQUIRY data is supported, check if any optional INQUIRY bits set */\r
-       if ((CommandBlock.SCSICommandData[1] & ((1 << 0) | (1 << 1))) ||\r
-            CommandBlock.SCSICommandData[2])\r
-       {\r
-               /* Optional but unsupported bits set - update the SENSE key and fail the request */\r
-               SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
-                              SCSI_ASENSE_INVALID_FIELD_IN_CDB,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);\r
-\r
-               return false;\r
-       }\r
-\r
-       /* Write the INQUIRY data to the endpoint */\r
-       Endpoint_Write_Stream_LE(&InquiryData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);\r
-\r
-       uint8_t PadBytes[AllocationLength - BytesTransferred];\r
-       \r
-       /* Pad out remaining bytes with 0x00 */\r
-       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);\r
-\r
-       /* Finalize the stream transfer to send the last packet */\r
-       Endpoint_ClearIN();\r
-\r
-       /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength -= BytesTransferred;\r
-       \r
-       return true;\r
-}\r
-\r
-/** Command processing for an issued SCSI REQUEST SENSE command. This command returns information about the last issued command,\r
- *  including the error code and additional error information so that the host can determine why a command failed to complete.\r
- *\r
- *  \return Boolean true if the command completed successfully, false otherwise.\r
- */\r
-static bool SCSI_Command_Request_Sense(void)\r
-{\r
-       uint8_t  AllocationLength = CommandBlock.SCSICommandData[4];\r
-       uint8_t  BytesTransferred = (AllocationLength < sizeof(SenseData))? AllocationLength : sizeof(SenseData);\r
-       \r
-       /* Send the SENSE data - this indicates to the host the status of the last command */\r
-       Endpoint_Write_Stream_LE(&SenseData, BytesTransferred, StreamCallback_AbortOnMassStoreReset);\r
-       \r
-       uint8_t PadBytes[AllocationLength - BytesTransferred];\r
-       \r
-       /* Pad out remaining bytes with 0x00 */\r
-       Endpoint_Write_Stream_LE(&PadBytes, (AllocationLength - BytesTransferred), StreamCallback_AbortOnMassStoreReset);\r
-\r
-       /* Finalize the stream transfer to send the last packet */\r
-       Endpoint_ClearIN();\r
-\r
-       /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength -= BytesTransferred;\r
-\r
-       return true;\r
-}\r
-\r
-/** Command processing for an issued SCSI READ CAPACITY (10) command. This command returns information about the device's capacity\r
- *  on the selected Logical Unit (drive), as a number of OS-sized blocks.\r
- *\r
- *  \return Boolean true if the command completed successfully, false otherwise.\r
- */\r
-static bool SCSI_Command_Read_Capacity_10(void)\r
-{\r
-       /* Send the total number of logical blocks in the current LUN */\r
-       Endpoint_Write_DWord_BE(LUN_MEDIA_BLOCKS - 1);\r
-\r
-       /* Send the logical block size of the device (must be 512 bytes) */\r
-       Endpoint_Write_DWord_BE(VIRTUAL_MEMORY_BLOCK_SIZE);\r
-\r
-       /* Check if the current command is being aborted by the host */\r
-       if (IsMassStoreReset)\r
-         return false;\r
-\r
-       /* Send the endpoint data packet to the host */\r
-       Endpoint_ClearIN();\r
-\r
-       /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength -= 8;\r
-       \r
-       return true;\r
-}\r
-\r
-/** Command processing for an issued SCSI SEND DIAGNOSTIC command. This command performs a quick check of the Dataflash ICs on the\r
- *  board, and indicates if they are present and functioning correctly. Only the Self-Test portion of the diagnostic command is\r
- *  supported.\r
- *\r
- *  \return Boolean true if the command completed successfully, false otherwise.\r
- */\r
-static bool SCSI_Command_Send_Diagnostic(void)\r
-{\r
-       uint8_t ReturnByte;\r
-\r
-       /* Check to see if the SELF TEST bit is not set */\r
-       if (!(CommandBlock.SCSICommandData[1] & (1 << 2)))\r
-       {\r
-               /* Only self-test supported - update SENSE key and fail the command */\r
-               SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
-                              SCSI_ASENSE_INVALID_FIELD_IN_CDB,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);\r
-\r
-               return false;\r
-       }\r
-       \r
-       /* Test first Dataflash IC is present and responding to commands */\r
-       Dataflash_SelectChip(DATAFLASH_CHIP1);\r
-       Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);\r
-       ReturnByte = Dataflash_ReceiveByte();\r
-       Dataflash_DeselectChip();\r
-\r
-       /* If returned data is invalid, fail the command */\r
-       if (ReturnByte != DF_MANUFACTURER_ATMEL)\r
-       {\r
-               /* Update SENSE key with a hardware error condition and return command fail */\r
-               SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,\r
-                              SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);      \r
-       \r
-               return false;\r
-       }\r
-\r
-       #if (DATAFLASH_TOTALCHIPS == 2)\r
-       /* Test second Dataflash IC is present and responding to commands */\r
-       Dataflash_SelectChip(DATAFLASH_CHIP2);\r
-       Dataflash_SendByte(DF_CMD_READMANUFACTURERDEVICEINFO);\r
-       ReturnByte = Dataflash_ReceiveByte();\r
-       Dataflash_DeselectChip();\r
-\r
-       /* If returned data is invalid, fail the command */\r
-       if (ReturnByte != DF_MANUFACTURER_ATMEL)\r
-       {\r
-               /* Update SENSE key with a hardware error condition and return command fail */\r
-               SCSI_SET_SENSE(SCSI_SENSE_KEY_HARDWARE_ERROR,\r
-                              SCSI_ASENSE_NO_ADDITIONAL_INFORMATION,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);      \r
-       \r
-               return false;\r
-       }\r
-       #endif\r
-       \r
-       /* Succeed the command and update the bytes transferred counter */\r
-       CommandBlock.DataTransferLength = 0;\r
-       \r
-       return true;\r
-}\r
-\r
-/** Command processing for an issued SCSI READ (10) or WRITE (10) command. This command reads in the block start address\r
- *  and total number of blocks to process, then calls the appropriate low-level dataflash routine to handle the actual\r
- *  reading and writing of the data.\r
- *\r
- *  \param IsDataRead  Indicates if the command is a READ (10) command or WRITE (10) command (DATA_READ or DATA_WRITE)\r
- *\r
- *  \return Boolean true if the command completed successfully, false otherwise.\r
- */\r
-static bool SCSI_Command_ReadWrite_10(const bool IsDataRead)\r
-{\r
-       uint32_t BlockAddress;\r
-       uint16_t TotalBlocks;\r
-       \r
-       /* Load in the 32-bit block address (SCSI uses big-endian, so have to do it byte-by-byte) */\r
-       ((uint8_t*)&BlockAddress)[3] = CommandBlock.SCSICommandData[2];\r
-       ((uint8_t*)&BlockAddress)[2] = CommandBlock.SCSICommandData[3];\r
-       ((uint8_t*)&BlockAddress)[1] = CommandBlock.SCSICommandData[4];\r
-       ((uint8_t*)&BlockAddress)[0] = CommandBlock.SCSICommandData[5];\r
-\r
-       /* Load in the 16-bit total blocks (SCSI uses big-endian, so have to do it byte-by-byte) */\r
-       ((uint8_t*)&TotalBlocks)[1]  = CommandBlock.SCSICommandData[7];\r
-       ((uint8_t*)&TotalBlocks)[0]  = CommandBlock.SCSICommandData[8];\r
-       \r
-       /* Check if the block address is outside the maximum allowable value for the LUN */\r
-       if (BlockAddress >= LUN_MEDIA_BLOCKS)\r
-       {\r
-               /* Block address is invalid, update SENSE key and return command fail */\r
-               SCSI_SET_SENSE(SCSI_SENSE_KEY_ILLEGAL_REQUEST,\r
-                              SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE,\r
-                              SCSI_ASENSEQ_NO_QUALIFIER);\r
-\r
-               return false;\r
-       }\r
-\r
-       #if (TOTAL_LUNS > 1)\r
-       /* Adjust the given block address to the real media address based on the selected LUN */\r
-       BlockAddress += ((uint32_t)CommandBlock.LUN * LUN_MEDIA_BLOCKS);\r
-       #endif\r
-       \r
-       /* Determine if the packet is a READ (10) or WRITE (10) command, call appropriate function */\r
-       if (IsDataRead == DATA_READ)\r
-         DataflashManager_ReadBlocks(BlockAddress, TotalBlocks);\r
-       else\r
-         DataflashManager_WriteBlocks(BlockAddress, TotalBlocks);\r
-\r
-       /* Update the bytes transferred counter and succeed the command */\r
-       CommandBlock.DataTransferLength -= ((uint32_t)TotalBlocks * VIRTUAL_MEMORY_BLOCK_SIZE);\r
-       \r
-       return true;\r
-}\r
diff --git a/Demos/Device/MassStorage/SCSI.h b/Demos/Device/MassStorage/SCSI.h
deleted file mode 100644 (file)
index d7693ca..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for SCSI.c.\r
- */\r
\r
-#ifndef _SCSI_H_\r
-#define _SCSI_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <avr/pgmspace.h>\r
-\r
-               #include <LUFA/Common/Common.h>              // Function Attribute, Atomic, Debug and ISR Macros\r
-               #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
-               #include <LUFA/Drivers/Board/LEDs.h>         // LEDs driver\r
-\r
-               #include "MassStorage.h"\r
-               #include "Descriptors.h"\r
-               #include "DataflashManager.h"\r
-               #include "SCSI_Codes.h"\r
-       \r
-       /* Macros: */\r
-               /** Macro to set the current SCSI sense data to the given key, additional sense code and additional sense qualifier. This\r
-                *  is for convenience, as it allows for all three sense values (returned upon request to the host to give information about\r
-                *  the last command failure) in a quick and easy manner.\r
-                *\r
-                *  \param key    New SCSI sense key to set the sense code to\r
-                *  \param acode  New SCSI additional sense key to set the additional sense code to\r
-                *  \param aqual  New SCSI additional sense key qualifier to set the additional sense qualifier code to\r
-                */\r
-               #define SCSI_SET_SENSE(key, acode, aqual)  MACROS{ SenseData.SenseKey = key;              \\r
-                                                                  SenseData.AdditionalSenseCode = acode; \\r
-                                                                  SenseData.AdditionalSenseQualifier = aqual; }MACROE\r
-\r
-               /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be read from the storage medium. */\r
-               #define DATA_READ      true\r
-\r
-               /** Macro for the SCSI_Command_ReadWrite_10() function, to indicate that data is to be written to the storage medium. */\r
-               #define DATA_WRITE     false\r
-\r
-               /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a Block Media device. */\r
-               #define DEVICE_TYPE_BLOCK 0x00\r
-               \r
-               /** Value for the DeviceType entry in the SCSI_Inquiry_Response_t enum, indicating a CD-ROM device. */\r
-               #define DEVICE_TYPE_CDROM 0x05\r
-\r
-       /* Type Defines: */\r
-               /** Type define for a SCSI response structure to a SCSI INQUIRY command. For details of the\r
-                *  structure contents, refer to the SCSI specifications.\r
-                */\r
-               typedef struct\r
-               {\r
-                       unsigned char DeviceType          : 5;\r
-                       unsigned char PeripheralQualifier : 3;\r
-                       \r
-                       unsigned char _RESERVED1          : 7;\r
-                       unsigned char Removable           : 1;\r
-                       \r
-                       uint8_t      Version;\r
-                       \r
-                       unsigned char ResponseDataFormat  : 4;\r
-                       unsigned char _RESERVED2          : 1;\r
-                       unsigned char NormACA             : 1;\r
-                       unsigned char TrmTsk              : 1;\r
-                       unsigned char AERC                : 1;\r
-\r
-                       uint8_t      AdditionalLength;\r
-                       uint8_t      _RESERVED3[2];\r
-\r
-                       unsigned char SoftReset           : 1;\r
-                       unsigned char CmdQue              : 1;\r
-                       unsigned char _RESERVED4          : 1;\r
-                       unsigned char Linked              : 1;\r
-                       unsigned char Sync                : 1;\r
-                       unsigned char WideBus16Bit        : 1;\r
-                       unsigned char WideBus32Bit        : 1;\r
-                       unsigned char RelAddr             : 1;\r
-                       \r
-                       uint8_t      VendorID[8];\r
-                       uint8_t      ProductID[16];\r
-                       uint8_t      RevisionID[4];\r
-               } SCSI_Inquiry_Response_t;\r
-               \r
-               /** Type define for a SCSI sense structure to a SCSI REQUEST SENSE command. For details of the\r
-                *  structure contents, refer to the SCSI specifications.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint8_t       ResponseCode;\r
-                       \r
-                       uint8_t       SegmentNumber;\r
-                       \r
-                       unsigned char SenseKey            : 4;\r
-                       unsigned char _RESERVED1          : 1;\r
-                       unsigned char ILI                 : 1;\r
-                       unsigned char EOM                 : 1;\r
-                       unsigned char FileMark            : 1;\r
-                       \r
-                       uint8_t      Information[4];\r
-                       uint8_t      AdditionalLength;\r
-                       uint8_t      CmdSpecificInformation[4];\r
-                       uint8_t      AdditionalSenseCode;\r
-                       uint8_t      AdditionalSenseQualifier;\r
-                       uint8_t      FieldReplaceableUnitCode;\r
-                       uint8_t      SenseKeySpecific[3];\r
-               } SCSI_Request_Sense_Response_t;\r
-               \r
-       /* Function Prototypes: */\r
-               void SCSI_DecodeSCSICommand(void);\r
-               \r
-               #if defined(INCLUDE_FROM_SCSI_C)\r
-                       static bool SCSI_Command_Inquiry(void);\r
-                       static bool SCSI_Command_Request_Sense(void);\r
-                       static bool SCSI_Command_Read_Capacity_10(void);\r
-                       static bool SCSI_Command_Send_Diagnostic(void);\r
-                       static bool SCSI_Command_ReadWrite_10(const bool IsDataRead);\r
-               #endif\r
-               \r
-#endif\r
diff --git a/Demos/Device/MassStorage/SCSI_Codes.h b/Demos/Device/MassStorage/SCSI_Codes.h
deleted file mode 100644 (file)
index 2b2213d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header containing macros for possible SCSI commands and SENSE data. Refer to\r
- *  the SCSI standard documentation for more information on each SCSI command and\r
- *  the SENSE data.\r
- */\r
\r
-#ifndef _SCSI_CODES_H_\r
-#define _SCSI_CODES_H_\r
-\r
-       /* Macros: */\r
-               #define SCSI_CMD_INQUIRY                               0x12\r
-               #define SCSI_CMD_REQUEST_SENSE                         0x03\r
-               #define SCSI_CMD_TEST_UNIT_READY                       0x00\r
-               #define SCSI_CMD_READ_CAPACITY_10                      0x25\r
-               #define SCSI_CMD_SEND_DIAGNOSTIC                       0x1D\r
-               #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL          0x1E\r
-               #define SCSI_CMD_WRITE_10                              0x2A\r
-               #define SCSI_CMD_READ_10                               0x28\r
-               #define SCSI_CMD_WRITE_6                               0x0A\r
-               #define SCSI_CMD_READ_6                                0x08\r
-               #define SCSI_CMD_VERIFY_10                             0x2F\r
-               #define SCSI_CMD_MODE_SENSE_6                          0x1A\r
-               #define SCSI_CMD_MODE_SENSE_10                         0x5A\r
-\r
-               #define SCSI_SENSE_KEY_GOOD                            0x00\r
-               #define SCSI_SENSE_KEY_RECOVERED_ERROR                 0x01\r
-               #define SCSI_SENSE_KEY_NOT_READY                       0x02\r
-               #define SCSI_SENSE_KEY_MEDIUM_ERROR                    0x03\r
-               #define SCSI_SENSE_KEY_HARDWARE_ERROR                  0x04\r
-               #define SCSI_SENSE_KEY_ILLEGAL_REQUEST                 0x05\r
-               #define SCSI_SENSE_KEY_UNIT_ATTENTION                  0x06\r
-               #define SCSI_SENSE_KEY_DATA_PROTECT                    0x07\r
-               #define SCSI_SENSE_KEY_BLANK_CHECK                     0x08\r
-               #define SCSI_SENSE_KEY_VENDOR_SPECIFIC                 0x09\r
-               #define SCSI_SENSE_KEY_COPY_ABORTED                    0x0A\r
-               #define SCSI_SENSE_KEY_ABORTED_COMMAND                 0x0B\r
-               #define SCSI_SENSE_KEY_VOLUME_OVERFLOW                 0x0D\r
-               #define SCSI_SENSE_KEY_MISCOMPARE                      0x0E\r
-\r
-               #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION          0x00\r
-               #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY             0x04\r
-               #define SCSI_ASENSE_INVALID_FIELD_IN_CDB               0x24\r
-               #define SCSI_ASENSE_WRITE_PROTECTED                    0x27\r
-               #define SCSI_ASENSE_FORMAT_ERROR                       0x31\r
-               #define SCSI_ASENSE_INVALID_COMMAND                    0x20\r
-               #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21\r
-               #define SCSI_ASENSE_MEDIUM_NOT_PRESENT                 0x3A\r
-\r
-               #define SCSI_ASENSEQ_NO_QUALIFIER                      0x00\r
-               #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED             0x01\r
-               #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED     0x02\r
-               #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS             0x07\r
-\r
-#endif\r
index 78abcfd..93f8957 100644 (file)
@@ -125,8 +125,8 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         SCSI.c                                                      \\r
-         DataflashManager.c                                          \\r
+         Lib/SCSI.c                                                  \\r
+         Lib/DataflashManager.c                                      \\r
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
diff --git a/Demos/Device/RNDISEthernet/ARP.c b/Demos/Device/RNDISEthernet/ARP.c
deleted file mode 100644 (file)
index 0f108c2..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Address Resolution Protocol (ARP) packet handling routines. This protocol handles the\r
- *  conversion of physical MAC addresses to protocol IP addresses between the host and the\r
- *  device.\r
- */\r
\r
-#include "ARP.h"\r
-\r
-/** Processes an ARP packet inside an Ethernet frame, and writes the appropriate response\r
- *  to the output Ethernet frame if the host is requesting the IP or MAC address of the\r
- *  virtual server device on the network.\r
- *\r
- *  \param InDataStart   Pointer to the start of the incoming packet's ARP header\r
- *  \param OutDataStart  Pointer to the start of the outgoing packet's ARP header\r
- *\r
- *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
- */\r
-int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart)\r
-{\r
-       DecodeARPHeader(InDataStart);\r
-\r
-       ARP_Header_t* ARPHeaderIN  = (ARP_Header_t*)InDataStart;\r
-       ARP_Header_t* ARPHeaderOUT = (ARP_Header_t*)OutDataStart;\r
-\r
-       /* Ensure that the ARP request is a IPv4 request packet */\r
-       if ((SwapEndian_16(ARPHeaderIN->ProtocolType) == ETHERTYPE_IPV4) &&\r
-           (SwapEndian_16(ARPHeaderIN->Operation) == ARP_OPERATION_REQUEST))\r
-       {\r
-               /* If the ARP packet is requesting the MAC or IP of the virtual webserver, return the response */\r
-               if (IP_COMPARE(&ARPHeaderIN->TPA, &ServerIPAddress) || \r
-                   MAC_COMPARE(&ARPHeaderIN->THA, &ServerMACAddress))\r
-               {\r
-                       /* Fill out the ARP response header */\r
-                       ARPHeaderOUT->HardwareType = ARPHeaderIN->HardwareType;\r
-                       ARPHeaderOUT->ProtocolType = ARPHeaderIN->ProtocolType;\r
-                       ARPHeaderOUT->HLEN         = ARPHeaderIN->HLEN;\r
-                       ARPHeaderOUT->PLEN         = ARPHeaderIN->PLEN;\r
-                       ARPHeaderOUT->Operation    = SwapEndian_16(ARP_OPERATION_REPLY);\r
-\r
-                       /* Copy over the sender MAC/IP to the target fields for the response */\r
-                       ARPHeaderOUT->THA = ARPHeaderIN->SHA;\r
-                       ARPHeaderOUT->TPA = ARPHeaderIN->SPA;\r
-\r
-                       /* Copy over the new sender MAC/IP - MAC and IP addresses of the virtual webserver */\r
-                       ARPHeaderOUT->SHA = ServerMACAddress;\r
-                       ARPHeaderOUT->SPA = ServerIPAddress;\r
-\r
-                       /* Return the size of the response so far */\r
-                       return sizeof(ARP_Header_t);\r
-               }\r
-       }\r
-       \r
-       return NO_RESPONSE;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/ARP.h b/Demos/Device/RNDISEthernet/ARP.h
deleted file mode 100644 (file)
index 8551df8..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for ARP.c.\r
- */\r
\r
-#ifndef _ARP_H_\r
-#define _ARP_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <string.h>\r
-               \r
-               #include <LUFA/Scheduler/Scheduler.h>\r
-               \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               #include "ProtocolDecoders.h"\r
-               \r
-       /* Macros: */\r
-               /** ARP header operation constant, indicating a request from a host for an address translation */\r
-               #define ARP_OPERATION_REQUEST            1\r
-\r
-               /** ARP header operation constant, indicating a reply from a host giving an address translation */\r
-               #define ARP_OPERATION_REPLY              2\r
-\r
-       /* Type Defines: */\r
-               /** Type define for an ARP packet inside an Ethernet frame. */\r
-               typedef struct\r
-               {\r
-                       uint16_t      HardwareType; /**< Hardware type constant, indicating the hardware used */\r
-                       uint16_t      ProtocolType; /**< Protocol being resolved, usually ETHERTYPE_IPV4 */\r
-                       \r
-                       uint8_t       HLEN; /**< Length in bytes of the source/destination hardware addresses */\r
-                       uint8_t       PLEN; /**< Length in bytes of the source/destination protocol addresses */\r
-                       uint16_t      Operation; /**< Type of operation, either ARP_OPERATION_REQUEST or ARP_OPERATION_REPLY */\r
-                       \r
-                       MAC_Address_t SHA; /**< Sender's hardware address */\r
-                       IP_Address_t  SPA; /**< Sender's protocol address */\r
-                       MAC_Address_t THA; /**< Target's hardware address */\r
-                       IP_Address_t  TPA; /**< Target's protocol address */\r
-               } ARP_Header_t;\r
-               \r
-       /* Function Prototypes: */\r
-               int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart);\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/DHCP.c b/Demos/Device/RNDISEthernet/DHCP.c
deleted file mode 100644 (file)
index 76711fb..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Dynamic Host Configuration Protocol (DHCP) packet handling routines. This protocol\r
- *  handles the automatic IP negotiation to the host, so that the host will use the provided\r
- *  IP address given to it by the device.\r
- */\r
\r
-#include "DHCP.h"\r
-\r
-/** Processes a DHCP packet inside an Ethernet frame, and writes the appropriate response\r
- *  to the output Ethernet frame if the host is requesting or accepting an IP address.\r
- *\r
- *  \param IPHeaderInStart     Pointer to the start of the incoming packet's IP header\r
- *  \param DHCPHeaderInStart   Pointer to the start of the incoming packet's DHCP header\r
- *  \param DHCPHeaderOutStart  Pointer to the start of the outgoing packet's DHCP header\r
- *\r
- *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
- */\r
-int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart)\r
-{\r
-       IP_Header_t*   IPHeaderIN    = (IP_Header_t*)IPHeaderInStart;\r
-       DHCP_Header_t* DHCPHeaderIN  = (DHCP_Header_t*)DHCPHeaderInStart;\r
-       DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart;\r
-       \r
-       uint8_t* DHCPOptionsINStart  = (uint8_t*)(DHCPHeaderInStart  + sizeof(DHCP_Header_t));\r
-       uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t));\r
-\r
-       DecodeDHCPHeader(DHCPHeaderInStart);\r
-\r
-       /* Zero out the response DHCP packet, as much of it legacy and left at 0 */\r
-       memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t));\r
-\r
-       /* Fill out the response DHCP packet */\r
-       DHCPHeaderOUT->HardwareType          = DHCPHeaderIN->HardwareType;\r
-       DHCPHeaderOUT->Operation             = DHCP_OP_BOOTREPLY;\r
-       DHCPHeaderOUT->HardwareAddressLength = DHCPHeaderIN->HardwareAddressLength;\r
-       DHCPHeaderOUT->Hops                  = 0;\r
-       DHCPHeaderOUT->TransactionID         = DHCPHeaderIN->TransactionID;\r
-       DHCPHeaderOUT->ElapsedSeconds        = 0;\r
-       DHCPHeaderOUT->Flags                 = DHCPHeaderIN->Flags;\r
-       DHCPHeaderOUT->YourIP                = ClientIPAddress;\r
-       memcpy(&DHCPHeaderOUT->ClientHardwareAddress, &DHCPHeaderIN->ClientHardwareAddress, sizeof(MAC_Address_t));\r
-       DHCPHeaderOUT->Cookie                = SwapEndian_32(DHCP_MAGIC_COOKIE);\r
-       \r
-       /* Alter the incoming IP packet header so that the corrected IP source and destinations are used - this means that\r
-          when the response IP header is generated, it will use the corrected addresses and not the null/broatcast addresses */\r
-       IPHeaderIN->SourceAddress      = ClientIPAddress;\r
-       IPHeaderIN->DestinationAddress = ServerIPAddress;\r
-\r
-       /* Process the incoming DHCP packet options */\r
-       while (DHCPOptionsINStart[0] != DHCP_OPTION_END)\r
-       {       \r
-               /* Find the Message Type DHCP option, to determine the type of DHCP packet */\r
-               if (DHCPOptionsINStart[0] == DHCP_OPTION_MESSAGETYPE)\r
-               {\r
-                       if ((DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) || (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_REQUEST))\r
-                       {\r
-                               /* Fill out the response DHCP packet options for a DHCP OFFER or ACK response */\r
-\r
-                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_MESSAGETYPE;\r
-                               *(DHCPOptionsOUTStart++) = 1;\r
-                               *(DHCPOptionsOUTStart++) = (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) ? DHCP_MESSAGETYPE_OFFER\r
-                                                                                                                                                                                               : DHCP_MESSAGETYPE_ACK;\r
-\r
-                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_SUBNETMASK;\r
-                               *(DHCPOptionsOUTStart++) = 4;\r
-                               *(DHCPOptionsOUTStart++) = 0xFF;\r
-                               *(DHCPOptionsOUTStart++) = 0xFF;\r
-                               *(DHCPOptionsOUTStart++) = 0xFF;\r
-                               *(DHCPOptionsOUTStart++) = 0x00;\r
-\r
-                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_DHCPSERVER;\r
-                               *(DHCPOptionsOUTStart++) = sizeof(IP_Address_t);\r
-                               memcpy(DHCPOptionsOUTStart, &ServerIPAddress, sizeof(IP_Address_t));\r
-                               DHCPOptionsOUTStart     += sizeof(IP_Address_t);\r
-\r
-                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_END;\r
-                               \r
-                               return (sizeof(DHCP_Header_t) + 12 + sizeof(IP_Address_t));\r
-                       }\r
-               }\r
-               \r
-               /* Go to the next DHCP option - skip one byte if option is a padding byte, else skip the complete option's size */\r
-               DHCPOptionsINStart += ((DHCPOptionsINStart[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptionsINStart[1] + 2));\r
-       }\r
-       \r
-       return NO_RESPONSE;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/DHCP.h b/Demos/Device/RNDISEthernet/DHCP.h
deleted file mode 100644 (file)
index f0e68b9..0000000
+++ /dev/null
@@ -1,125 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for DHCP.c.\r
- */\r
\r
-#ifndef _DHCP_H_\r
-#define _DHCP_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <string.h>\r
-       \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               #include "ProtocolDecoders.h"\r
-\r
-       /* Macros: */\r
-               /** DHCP operation constant, indicating a request from a host to a DHCP server */\r
-               #define DHCP_OP_BOOTREQUEST       0x01\r
-\r
-               /** DHCP operation constant, indicating a reply from a DHCP server to a host */\r
-               #define DHCP_OP_BOOTREPLY         0x02\r
-               \r
-               /** Hardware type constant, indicating Ethernet as a carrier */\r
-               #define DHCP_HTYPE_ETHERNET       0x01\r
-               \r
-               /** Magic boot protocol "cookie", inserted into all BOOTP packets (BOOTP is the carrier of DHCP) */\r
-               #define DHCP_MAGIC_COOKIE         0x63825363\r
-               \r
-               /** DHCP option list entry header, indicating that a subnet mask will follow */\r
-               #define DHCP_OPTION_SUBNETMASK    1\r
-\r
-               /** DHCP option list entry header, indicating that the DHCP message type constant will follow */\r
-               #define DHCP_OPTION_MESSAGETYPE   53\r
-\r
-               /** DHCP option list entry header, indicating that the IP address of the DHCP server will follow */\r
-               #define DHCP_OPTION_DHCPSERVER    54\r
-\r
-               /** DHCP option list entry header, used to pad out option data */\r
-               #define DHCP_OPTION_PAD           0\r
-\r
-               /** DHCP option list entry header, indicating the end of option data */\r
-               #define DHCP_OPTION_END           255\r
-                       \r
-               /** Message type constant, used in the DHCP option data field, requesting that a DHCP server offer an IP address */\r
-               #define DHCP_MESSAGETYPE_DISCOVER 1\r
-\r
-               /** Message type constant, used in the DHCP option data field, indicating that a DHCP server is offering an IP address */\r
-               #define DHCP_MESSAGETYPE_OFFER    2\r
-\r
-               /** Message type constant, used in the DHCP option data field, requesting that a DHCP server lease a given IP address */\r
-               #define DHCP_MESSAGETYPE_REQUEST  3\r
-\r
-               /** Message type constant, used in the DHCP option data field, declining an offered DHCP server IP address lease */\r
-               #define DHCP_MESSAGETYPE_DECLINE  4\r
-\r
-               /** Message type constant, used in the DHCP option data field, ACKing a host IP lease request */\r
-               #define DHCP_MESSAGETYPE_ACK      5\r
-\r
-               /** Message type constant, used in the DHCP option data field, NACKing a host IP lease request */\r
-               #define DHCP_MESSAGETYPE_NACK     6\r
-\r
-               /** Message type constant, used in the DHCP option data field, indicating that a host is releasing a leased IP address */\r
-               #define DHCP_MESSAGETYPE_RELEASE  7\r
-\r
-       /* Type Defines: */\r
-               /** Type define for a DHCP packet inside an Ethernet frame. */\r
-               typedef struct\r
-               {\r
-                       uint8_t  Operation; /**< DHCP operation, either DHCP_OP_BOOTREQUEST or DHCP_OP_BOOTREPLY */\r
-                       uint8_t  HardwareType; /**< Hardware carrier type constant */\r
-                       uint8_t  HardwareAddressLength;  /**< Length in bytes of a hardware (MAC) address on the network */\r
-                       uint8_t  Hops; /**< Number of hops required to reach the server, unused */\r
-\r
-                       uint32_t TransactionID; /**< Unique ID of the DHCP packet, for positive matching between sent and received packets */\r
-\r
-                       uint16_t ElapsedSeconds; /**< Elapsed seconds since the request was made */\r
-                       uint16_t Flags; /**< BOOTP packet flags */\r
-                       \r
-                       IP_Address_t ClientIP; /**< Client IP address, if already leased an IP */\r
-                       IP_Address_t YourIP; /**< Client IP address */\r
-                       IP_Address_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */\r
-                       IP_Address_t RelayAgentIP; /**< Legacy BOOTP protocol field, unused for DHCP */\r
-                       \r
-                       uint8_t ClientHardwareAddress[16]; /**< Hardware (MAC) address of the client making a request to the DHCP server */\r
-                       uint8_t ServerHostnameString[64]; /**< Legacy BOOTP protocol field, unused for DHCP */\r
-                       uint8_t BootFileName[128]; /**< Legacy BOOTP protocol field, unused for DHCP */\r
-                       \r
-                       uint32_t Cookie; /**< Magic BOOTP protocol cookie to indicate a valid packet */\r
-               } DHCP_Header_t;\r
-\r
-       /* Function Prototypes: */\r
-               int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart);\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/Ethernet.c b/Demos/Device/RNDISEthernet/Ethernet.c
deleted file mode 100644 (file)
index 3d34f71..0000000
+++ /dev/null
@@ -1,136 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Ethernet frame packet handling routines. This protocol handles the processing of raw Ethernet\r
- *  frames sent and received, deferring the processing of subpacket protocols to the appropriate\r
- *  protocol handlers, such as DHCP or ARP.\r
- */\r
\r
-#include "Ethernet.h"\r
-\r
-/* Global Variables: */\r
-/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */\r
-Ethernet_Frame_Info_t FrameIN;\r
-\r
-/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */\r
-Ethernet_Frame_Info_t FrameOUT;\r
-\r
-/** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */\r
-const MAC_Address_t ServerMACAddress    = {SERVER_MAC_ADDRESS};\r
-\r
-/** Constant for convenience when checking against or setting an IP address to the virtual server IP address. */\r
-const IP_Address_t  ServerIPAddress     = {SERVER_IP_ADDRESS};\r
-\r
-/** Constant for convenience when checking against or setting a MAC address to the broadcast MAC address. */\r
-const MAC_Address_t BroadcastMACAddress = {BROADCAST_MAC_ADDRESS};\r
-\r
-/** Constant for convenience when checking against or setting a IP address to the broadcast IP address. */\r
-const IP_Address_t  BroadcastIPAddress  = {BROADCAST_IP_ADDRESS};\r
-\r
-/** Constant for convenience when checking against or setting an IP address to the client (host) IP address. */\r
-const IP_Address_t  ClientIPAddress     = {CLIENT_IP_ADDRESS};\r
-\r
-\r
-/** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet\r
- *  frame buffer if the sub protocol handlers create a valid response.\r
- */\r
-void Ethernet_ProcessPacket(void)\r
-{\r
-       DecodeEthernetFrameHeader(FrameIN.FrameData);\r
-\r
-       /* Cast the incoming Ethernet frame to the Ethernet header type */\r
-       Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;\r
-       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
-       \r
-       int16_t                  RetSize        = NO_RESPONSE;\r
-       \r
-       /* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */\r
-       if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||\r
-            MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&\r
-               (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))\r
-       {\r
-               /* Process the packet depending on its protocol */\r
-               switch (SwapEndian_16(FrameINHeader->EtherType))\r
-               {\r
-                       case ETHERTYPE_ARP:\r
-                               RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
-                                                              &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
-                               break;          \r
-                       case ETHERTYPE_IPV4:\r
-                               RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
-                                                            &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
-                               break;\r
-               }\r
-               \r
-               /* Protocol processing routine has filled a response, complete the ethernet frame header */\r
-               if (RetSize > 0)\r
-               {\r
-                       /* Fill out the response Ethernet frame header */\r
-                       FrameOUTHeader->Source          = ServerMACAddress;\r
-                       FrameOUTHeader->Destination     = FrameINHeader->Source;\r
-                       FrameOUTHeader->EtherType       = FrameINHeader->EtherType;\r
-                       \r
-                       /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
-                       FrameOUT.FrameLength            = (sizeof(Ethernet_Frame_Header_t) + RetSize);\r
-                       FrameOUT.FrameInBuffer          = true;\r
-               }\r
-       }\r
-\r
-       /* Check if the packet was processed */\r
-       if (RetSize != NO_PROCESS)\r
-       {\r
-               /* Clear the frame buffer */\r
-               FrameIN.FrameInBuffer = false;\r
-       }\r
-}\r
-\r
-/** Calculates the appropriate ethernet checksum, consisting of the addition of the one's\r
- *  compliment of each word, complimented.\r
- *\r
- *  \param Data   Pointer to the packet buffer data whose checksum must be calculated\r
- *  \param Bytes  Number of bytes in the data buffer to process\r
- *\r
- *  \return A 16-bit Ethernet checksum value\r
- */\r
-uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes)\r
-{\r
-       uint16_t* Words    = (uint16_t*)Data;\r
-       uint32_t  Checksum = 0;\r
-\r
-       for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)\r
-         Checksum += Words[CurrWord];\r
-         \r
-       while (Checksum & 0xFFFF0000)\r
-         Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));\r
-       \r
-       return ~Checksum;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/Ethernet.h b/Demos/Device/RNDISEthernet/Ethernet.h
deleted file mode 100644 (file)
index b360f07..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for Ethernet.c.\r
- */\r
\r
-#ifndef _ETHERNET_H_\r
-#define _ETHERNET_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <string.h>\r
-\r
-               #include "EthernetProtocols.h"\r
-               #include "ProtocolDecoders.h"\r
-               #include "ICMP.h"\r
-               #include "TCP.h"\r
-               #include "UDP.h"\r
-               #include "DHCP.h"\r
-               #include "ARP.h"\r
-               #include "IP.h"\r
-               \r
-       /* Macros: */\r
-               /** Physical MAC address of the virtual server on the network */\r
-               #define SERVER_MAC_ADDRESS               {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}           \r
-\r
-               /** Physical MAC address of the network broadcast address */\r
-               #define BROADCAST_MAC_ADDRESS            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}\r
-       \r
-               /** Performs a comparison between two MAC addresses, indicating if they are identical.\r
-                *  \r
-                *  \param MAC1  First MAC address\r
-                *  \param MAC2  Second MAC address\r
-                *\r
-                *  \return True if the addresses match, false otherwise\r
-                */\r
-               #define MAC_COMPARE(MAC1, MAC2)          (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)\r
-\r
-               /** Maximum size of an incoming or outgoing Ethernet frame in bytes */\r
-               #define ETHERNET_FRAME_SIZE_MAX          1500\r
-               \r
-               /** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */\r
-               #define ETHERNET_VER2_MINSIZE            0x0600\r
-               \r
-               /** Return value for all sub protocol handling routines, indicating that no response packet has been generated */\r
-               #define NO_RESPONSE                      0              \r
-\r
-               /** Return value for all sub protocol handling routines, indicating that the packet has not yet been handled */\r
-               #define NO_PROCESS                       -1\r
-\r
-       /* Type Defines: */\r
-               /** Type define for an Ethernet frame buffer. */\r
-               typedef struct\r
-               {\r
-                       uint8_t       FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */\r
-                       uint16_t      FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */\r
-                       bool          FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */\r
-               } Ethernet_Frame_Info_t;\r
-\r
-               /** Type define for an Ethernet frame header */\r
-               typedef struct\r
-               {\r
-                       MAC_Address_t Destination; /**< Physical MAC address of the packet recipient */\r
-                       MAC_Address_t Source; /**< Physics MAC address of the packet source */\r
-                       \r
-                       union\r
-                       {\r
-                               uint16_t  EtherType; /**< Ethernet packet subprotocol type, for Ethernet V2 packets */\r
-                               uint16_t  Length; /**< Ethernet frame length, for Ethernet V1 packets */\r
-                       };\r
-               } Ethernet_Frame_Header_t;\r
-               \r
-       /* External Variables: */\r
-               extern Ethernet_Frame_Info_t FrameIN;\r
-               extern Ethernet_Frame_Info_t FrameOUT;\r
-\r
-               extern const MAC_Address_t ServerMACAddress;\r
-               extern const IP_Address_t  ServerIPAddress;\r
-               extern const MAC_Address_t BroadcastMACAddress;\r
-               extern const IP_Address_t  BroadcastIPAddress;\r
-               extern const IP_Address_t  ClientIPAddress;\r
-               \r
-       /* Function Prototypes: */\r
-               void     Ethernet_ProcessPacket(void);\r
-               uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);\r
-               \r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/EthernetProtocols.h b/Demos/Device/RNDISEthernet/EthernetProtocols.h
deleted file mode 100644 (file)
index 3ff3433..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  General Ethernet protocol constants and type defines, for use by\r
- *  all network protocol portions of the TCP/IP stack.\r
- */\r
-\r
-#ifndef _ETHERNET_PROTOCOLS_H_\r
-#define _ETHERNET_PROTOCOLS_H_\r
-\r
-       /* Macros: */\r
-               #define ETHERTYPE_IPV4                   0x0800\r
-               #define ETHERTYPE_ARP                    0x0806\r
-               #define ETHERTYPE_RARP                   0x8035\r
-               #define ETHERTYPE_APPLETALK              0x809b\r
-               #define ETHERTYPE_APPLETALKARP           0x80f3\r
-               #define ETHERTYPE_IEEE8021Q              0x8100\r
-               #define ETHERTYPE_NOVELLIPX              0x8137\r
-               #define ETHERTYPE_NOVELL                 0x8138\r
-               #define ETHERTYPE_IPV6                   0x86DD\r
-               #define ETHERTYPE_COBRANET               0x8819\r
-               #define ETHERTYPE_PROVIDERBRIDGING       0x88a8\r
-               #define ETHERTYPE_MPLSUNICAST            0x8847\r
-               #define ETHERTYPE_MPLSMULTICAST          0x8848\r
-               #define ETHERTYPE_PPPoEDISCOVERY         0x8863\r
-               #define ETHERTYPE_PPPoESESSION           0x8864\r
-               #define ETHERTYPE_EAPOVERLAN             0x888E\r
-               #define ETHERTYPE_HYPERSCSI              0x889A\r
-               #define ETHERTYPE_ATAOVERETHERNET        0x88A2\r
-               #define ETHERTYPE_ETHERCAT               0x88A4\r
-               #define ETHERTYPE_SERCOSIII              0x88CD\r
-               #define ETHERTYPE_CESoE                  0x88D8\r
-               #define ETHERTYPE_MACSECURITY            0x88E5\r
-               #define ETHERTYPE_FIBRECHANNEL           0x8906\r
-               #define ETHERTYPE_QINQ                   0x9100\r
-               #define ETHERTYPE_VLLT                   0xCAFE\r
-               \r
-               #define PROTOCOL_ICMP                    1\r
-               #define PROTOCOL_IGMP                    2\r
-               #define PROTOCOL_TCP                     6\r
-               #define PROTOCOL_UDP                     17\r
-               #define PROTOCOL_OSPF                    89\r
-               #define PROTOCOL_SCTP                    132\r
-\r
-       /* Type Defines: */\r
-               /** Type define for a physical MAC address of a device on a network */\r
-               typedef struct\r
-               {\r
-                       uint8_t       Octets[6]; /**< Individual bytes of a MAC address */\r
-               } MAC_Address_t;\r
-               \r
-               /** Type define for a protocol IP address of a device on a network */\r
-               typedef struct\r
-               {\r
-                       uint8_t       Octets[4]; /**< Individual bytes of an IP address */\r
-               } IP_Address_t;\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/ICMP.c b/Demos/Device/RNDISEthernet/ICMP.c
deleted file mode 100644 (file)
index da4ffcf..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Internet Control Message Protocol (ICMP) packet handling routines. This protocol handles\r
- *  Echo requests from the host, to indicate a successful network connection between the host\r
- *  and the virtual server.\r
- */\r
\r
-#include "ICMP.h"\r
-\r
-/** Processes an ICMP packet inside an Ethernet frame, and writes the appropriate response\r
- *  to the output Ethernet frame if the host is issuing a ICMP ECHO request.\r
- *\r
- *  \param InDataStart   Pointer to the start of the incoming packet's ICMP header\r
- *  \param OutDataStart  Pointer to the start of the outgoing packet's ICMP header\r
- *\r
- *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
- */\r
-int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)\r
-{\r
-       ICMP_Header_t* ICMPHeaderIN  = (ICMP_Header_t*)InDataStart;\r
-       ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;\r
-\r
-       DecodeICMPHeader(InDataStart);\r
-\r
-       /* Determine if the ICMP packet is an echo request (ping) */\r
-       if (ICMPHeaderIN->Type == ICMP_TYPE_ECHOREQUEST)\r
-       {\r
-               /* Fill out the ICMP response packet */\r
-               ICMPHeaderOUT->Type     = ICMP_TYPE_ECHOREPLY;\r
-               ICMPHeaderOUT->Code     = 0;\r
-               ICMPHeaderOUT->Checksum = 0;\r
-               ICMPHeaderOUT->Id       = ICMPHeaderIN->Id;\r
-               ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;\r
-               \r
-               uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));\r
-               \r
-               /* Copy the remaining payload to the response - echo requests should echo back any sent data */\r
-               memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],\r
-                      &((uint8_t*)InDataStart)[sizeof(ICMP_Header_t)],\r
-                          DataSize);\r
-\r
-               ICMPHeaderOUT->Checksum = Ethernet_Checksum16(ICMPHeaderOUT, (DataSize + sizeof(ICMP_Header_t)));\r
-\r
-               /* Return the size of the response so far */\r
-               return (DataSize + sizeof(ICMP_Header_t));\r
-       }\r
-       \r
-       return NO_RESPONSE;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/ICMP.h b/Demos/Device/RNDISEthernet/ICMP.h
deleted file mode 100644 (file)
index b20a557..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for ICMP.c.\r
- */\r
-\r
-#ifndef _ICMP_H_\r
-#define _ICMP_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <string.h>\r
-               \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               #include "ProtocolDecoders.h"\r
-       \r
-       /* Macros: */\r
-               /** ICMP message type constant, indicating an ICMP ECHO Reply message */\r
-               #define ICMP_TYPE_ECHOREPLY              0\r
-\r
-               /** ICMP message type constant, indicating a packet destination is unreachable */\r
-               #define ICMP_TYPE_DESTINATIONUNREACHABLE 3\r
-               \r
-               /** ICMP message type constant, indicating an ICMP Source Quench message */\r
-               #define ICMP_TYPE_SOURCEQUENCH           4\r
-\r
-               /** ICMP message type constant, indicating an ICMP Redirect message */\r
-               #define ICMP_TYPE_REDIRECTMESSAGE        5\r
-\r
-               /** ICMP message type constant, indicating an ICMP ECHO Request message */\r
-               #define ICMP_TYPE_ECHOREQUEST            8\r
-\r
-               /** ICMP message type constant, indicating an ICMP Time Exceeded message */\r
-               #define ICMP_TYPE_TIMEEXCEEDED           11\r
-       \r
-       /* Type Defines: */\r
-               /** Type define for an ICMP message header. */\r
-               typedef struct\r
-               {\r
-                       uint8_t       Type; /**< ICMP message type, a ICMP_TYPE_* constant */\r
-                       uint8_t       Code; /**< ICMP message code, indicating the message value */\r
-                       uint16_t      Checksum; /**< Ethernet checksum of the ICMP message */\r
-                       uint16_t      Id; /**< Id of the ICMP message */\r
-                       uint16_t      Sequence; /**< Sequence number of the ICMP message, to link together message responses */\r
-               } ICMP_Header_t;\r
-               \r
-       /* Function Prototypes: */\r
-               int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/IP.c b/Demos/Device/RNDISEthernet/IP.c
deleted file mode 100644 (file)
index 8fb0b44..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Internet Protocol (IP) packet handling routines. This protocol handles IP packets from the\r
- *  host which typically encapsulate other protocols such as ICMP, UDP and TCP.\r
- */\r
\r
-#include "IP.h"\r
-\r
-/** Processes an IP packet inside an Ethernet frame, and writes the appropriate response\r
- *  to the output Ethernet frame if one is created by a subprotocol handler.\r
- *\r
- *  \param InDataStart   Pointer to the start of the incoming packet's IP header\r
- *  \param OutDataStart  Pointer to the start of the outgoing packet's IP header\r
- *\r
- *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no\r
- *           response was generated, NO_PROCESS if the packet processing was deferred until the\r
- *           next Ethernet packet handler iteration\r
- */\r
-int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)\r
-{\r
-       DecodeIPHeader(InDataStart);\r
-\r
-       IP_Header_t* IPHeaderIN  = (IP_Header_t*)InDataStart;\r
-       IP_Header_t* IPHeaderOUT = (IP_Header_t*)OutDataStart;\r
-\r
-       /* Header length is specified in number of longs in the packet header, convert to bytes */\r
-       uint16_t HeaderLengthBytes = (IPHeaderIN->HeaderLength * sizeof(uint32_t));\r
-\r
-       int16_t  RetSize = NO_RESPONSE;\r
-\r
-       /* Check to ensure the IP packet is addressed to the virtual webserver's IP or the broadcast IP address */\r
-       if (!(IP_COMPARE(&IPHeaderIN->DestinationAddress, &ServerIPAddress)) &&\r
-           !(IP_COMPARE(&IPHeaderIN->DestinationAddress, &BroadcastIPAddress)))\r
-       {\r
-               return NO_RESPONSE;\r
-       }\r
-       \r
-       /* Pass off the IP payload to the appropriate protocol processing routine */\r
-       switch (IPHeaderIN->Protocol)\r
-       {\r
-               case PROTOCOL_ICMP:\r
-                       RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],\r
-                                                        &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);\r
-                       break;\r
-               case PROTOCOL_TCP:\r
-                       RetSize = TCP_ProcessTCPPacket(InDataStart,\r
-                                                      &((uint8_t*)InDataStart)[HeaderLengthBytes],\r
-                                                      &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);         \r
-                       break;\r
-               case PROTOCOL_UDP:\r
-                       RetSize = UDP_ProcessUDPPacket(InDataStart,\r
-                                                      &((uint8_t*)InDataStart)[HeaderLengthBytes],\r
-                                                      &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);         \r
-                       break;\r
-       }\r
-       \r
-       /* Check to see if the protocol processing routine has filled out a response */\r
-       if (RetSize > 0)\r
-       {\r
-               /* Fill out the response IP packet header */\r
-               IPHeaderOUT->TotalLength        = SwapEndian_16(sizeof(IP_Header_t) + RetSize);\r
-               IPHeaderOUT->TypeOfService      = 0;\r
-               IPHeaderOUT->HeaderLength       = (sizeof(IP_Header_t) / sizeof(uint32_t));\r
-               IPHeaderOUT->Version            = 4;\r
-               IPHeaderOUT->Flags              = 0;\r
-               IPHeaderOUT->FragmentOffset     = 0;\r
-               IPHeaderOUT->Identification     = 0;\r
-               IPHeaderOUT->HeaderChecksum     = 0;\r
-               IPHeaderOUT->Protocol           = IPHeaderIN->Protocol;\r
-               IPHeaderOUT->TTL                = DEFAULT_TTL;\r
-               IPHeaderOUT->SourceAddress      = IPHeaderIN->DestinationAddress;\r
-               IPHeaderOUT->DestinationAddress = IPHeaderIN->SourceAddress;\r
-               \r
-               IPHeaderOUT->HeaderChecksum     = Ethernet_Checksum16(IPHeaderOUT, sizeof(IP_Header_t));\r
-                                               \r
-               /* Return the size of the response so far */\r
-               return (sizeof(IP_Header_t) + RetSize);\r
-       }\r
-       \r
-       return RetSize;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/IP.h b/Demos/Device/RNDISEthernet/IP.h
deleted file mode 100644 (file)
index fc1a46a..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for IP.c.\r
- */\r
\r
-#ifndef _IP_H_\r
-#define _IP_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <string.h>\r
-               \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               #include "ProtocolDecoders.h"\r
-       \r
-       /* Macros: */\r
-               /** Protocol IP address of the host (client) machine, once assigned by DHCP */\r
-               #define CLIENT_IP_ADDRESS                { 10,     0,    0,    1}\r
-\r
-               /** Protocol IP address of the virtual server machine */\r
-               #define SERVER_IP_ADDRESS                { 10,     0,    0,    2}\r
-\r
-               /** Protocol IP address of the broadcast address */\r
-               #define BROADCAST_IP_ADDRESS             {0xFF, 0xFF, 0xFF, 0xFF}\r
-\r
-               /** Default Time To Live (TTL) value for sent packets, indicating the maximum allowable hops until their destination is reached */\r
-               #define DEFAULT_TTL                      128\r
-               \r
-               /** Performs a comparison between two IP addresses, indicating if they are identical.\r
-                *  \r
-                *  \param IP1  First IP address\r
-                *  \param IP2  Second IP address\r
-                *\r
-                *  \return True if the addresses match, false otherwise\r
-                */\r
-               #define IP_COMPARE(IP1, IP2)             (memcmp(IP1, IP2, sizeof(IP_Address_t)) == 0)\r
-               \r
-       /* Type Defines: */\r
-               /** Type define of an IP packet header. */\r
-               typedef struct\r
-               {\r
-                       unsigned char  HeaderLength   : 4; /**< Total length of the packet header, in 4-byte blocks */\r
-                       unsigned char  Version        : 4; /**< IP protocol version */\r
-                       uint8_t        TypeOfService; /**< Special service type identifier, indicating delay/throughput/reliability levels */\r
-                       uint16_t       TotalLength; /**< Total length of the IP packet, in bytes */\r
-\r
-                       uint16_t       Identification; /**< Identification value for identifying fragmented packets */\r
-                       unsigned int   FragmentOffset : 13; /**< Offset of this IP fragment */\r
-                       unsigned int   Flags          : 3; /**< Fragment flags, to indicate if a packet is fragmented */\r
-\r
-                       uint8_t        TTL; /**< Maximum allowable number of hops to reach the packet destination */\r
-                       uint8_t        Protocol; /**< Encapsulated protocol type */\r
-                       uint16_t       HeaderChecksum; /**< Ethernet checksum of the IP header */\r
-                       \r
-                       IP_Address_t  SourceAddress; /**< Source protocol IP address of the packet */\r
-                       IP_Address_t  DestinationAddress; /**< Destination protocol IP address of the packet */\r
-               } IP_Header_t;\r
-               \r
-       /* Function Prototypes: */\r
-               int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/ARP.c b/Demos/Device/RNDISEthernet/Lib/ARP.c
new file mode 100644 (file)
index 0000000..0f108c2
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Address Resolution Protocol (ARP) packet handling routines. This protocol handles the\r
+ *  conversion of physical MAC addresses to protocol IP addresses between the host and the\r
+ *  device.\r
+ */\r
\r
+#include "ARP.h"\r
+\r
+/** Processes an ARP packet inside an Ethernet frame, and writes the appropriate response\r
+ *  to the output Ethernet frame if the host is requesting the IP or MAC address of the\r
+ *  virtual server device on the network.\r
+ *\r
+ *  \param InDataStart   Pointer to the start of the incoming packet's ARP header\r
+ *  \param OutDataStart  Pointer to the start of the outgoing packet's ARP header\r
+ *\r
+ *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
+ */\r
+int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart)\r
+{\r
+       DecodeARPHeader(InDataStart);\r
+\r
+       ARP_Header_t* ARPHeaderIN  = (ARP_Header_t*)InDataStart;\r
+       ARP_Header_t* ARPHeaderOUT = (ARP_Header_t*)OutDataStart;\r
+\r
+       /* Ensure that the ARP request is a IPv4 request packet */\r
+       if ((SwapEndian_16(ARPHeaderIN->ProtocolType) == ETHERTYPE_IPV4) &&\r
+           (SwapEndian_16(ARPHeaderIN->Operation) == ARP_OPERATION_REQUEST))\r
+       {\r
+               /* If the ARP packet is requesting the MAC or IP of the virtual webserver, return the response */\r
+               if (IP_COMPARE(&ARPHeaderIN->TPA, &ServerIPAddress) || \r
+                   MAC_COMPARE(&ARPHeaderIN->THA, &ServerMACAddress))\r
+               {\r
+                       /* Fill out the ARP response header */\r
+                       ARPHeaderOUT->HardwareType = ARPHeaderIN->HardwareType;\r
+                       ARPHeaderOUT->ProtocolType = ARPHeaderIN->ProtocolType;\r
+                       ARPHeaderOUT->HLEN         = ARPHeaderIN->HLEN;\r
+                       ARPHeaderOUT->PLEN         = ARPHeaderIN->PLEN;\r
+                       ARPHeaderOUT->Operation    = SwapEndian_16(ARP_OPERATION_REPLY);\r
+\r
+                       /* Copy over the sender MAC/IP to the target fields for the response */\r
+                       ARPHeaderOUT->THA = ARPHeaderIN->SHA;\r
+                       ARPHeaderOUT->TPA = ARPHeaderIN->SPA;\r
+\r
+                       /* Copy over the new sender MAC/IP - MAC and IP addresses of the virtual webserver */\r
+                       ARPHeaderOUT->SHA = ServerMACAddress;\r
+                       ARPHeaderOUT->SPA = ServerIPAddress;\r
+\r
+                       /* Return the size of the response so far */\r
+                       return sizeof(ARP_Header_t);\r
+               }\r
+       }\r
+       \r
+       return NO_RESPONSE;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/ARP.h b/Demos/Device/RNDISEthernet/Lib/ARP.h
new file mode 100644 (file)
index 0000000..8551df8
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for ARP.c.\r
+ */\r
\r
+#ifndef _ARP_H_\r
+#define _ARP_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <string.h>\r
+               \r
+               #include <LUFA/Scheduler/Scheduler.h>\r
+               \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               #include "ProtocolDecoders.h"\r
+               \r
+       /* Macros: */\r
+               /** ARP header operation constant, indicating a request from a host for an address translation */\r
+               #define ARP_OPERATION_REQUEST            1\r
+\r
+               /** ARP header operation constant, indicating a reply from a host giving an address translation */\r
+               #define ARP_OPERATION_REPLY              2\r
+\r
+       /* Type Defines: */\r
+               /** Type define for an ARP packet inside an Ethernet frame. */\r
+               typedef struct\r
+               {\r
+                       uint16_t      HardwareType; /**< Hardware type constant, indicating the hardware used */\r
+                       uint16_t      ProtocolType; /**< Protocol being resolved, usually ETHERTYPE_IPV4 */\r
+                       \r
+                       uint8_t       HLEN; /**< Length in bytes of the source/destination hardware addresses */\r
+                       uint8_t       PLEN; /**< Length in bytes of the source/destination protocol addresses */\r
+                       uint16_t      Operation; /**< Type of operation, either ARP_OPERATION_REQUEST or ARP_OPERATION_REPLY */\r
+                       \r
+                       MAC_Address_t SHA; /**< Sender's hardware address */\r
+                       IP_Address_t  SPA; /**< Sender's protocol address */\r
+                       MAC_Address_t THA; /**< Target's hardware address */\r
+                       IP_Address_t  TPA; /**< Target's protocol address */\r
+               } ARP_Header_t;\r
+               \r
+       /* Function Prototypes: */\r
+               int16_t ARP_ProcessARPPacket(void* InDataStart, void* OutDataStart);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/DHCP.c b/Demos/Device/RNDISEthernet/Lib/DHCP.c
new file mode 100644 (file)
index 0000000..76711fb
--- /dev/null
@@ -0,0 +1,118 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Dynamic Host Configuration Protocol (DHCP) packet handling routines. This protocol\r
+ *  handles the automatic IP negotiation to the host, so that the host will use the provided\r
+ *  IP address given to it by the device.\r
+ */\r
\r
+#include "DHCP.h"\r
+\r
+/** Processes a DHCP packet inside an Ethernet frame, and writes the appropriate response\r
+ *  to the output Ethernet frame if the host is requesting or accepting an IP address.\r
+ *\r
+ *  \param IPHeaderInStart     Pointer to the start of the incoming packet's IP header\r
+ *  \param DHCPHeaderInStart   Pointer to the start of the incoming packet's DHCP header\r
+ *  \param DHCPHeaderOutStart  Pointer to the start of the outgoing packet's DHCP header\r
+ *\r
+ *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
+ */\r
+int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart)\r
+{\r
+       IP_Header_t*   IPHeaderIN    = (IP_Header_t*)IPHeaderInStart;\r
+       DHCP_Header_t* DHCPHeaderIN  = (DHCP_Header_t*)DHCPHeaderInStart;\r
+       DHCP_Header_t* DHCPHeaderOUT = (DHCP_Header_t*)DHCPHeaderOutStart;\r
+       \r
+       uint8_t* DHCPOptionsINStart  = (uint8_t*)(DHCPHeaderInStart  + sizeof(DHCP_Header_t));\r
+       uint8_t* DHCPOptionsOUTStart = (uint8_t*)(DHCPHeaderOutStart + sizeof(DHCP_Header_t));\r
+\r
+       DecodeDHCPHeader(DHCPHeaderInStart);\r
+\r
+       /* Zero out the response DHCP packet, as much of it legacy and left at 0 */\r
+       memset(DHCPHeaderOUT, 0, sizeof(DHCP_Header_t));\r
+\r
+       /* Fill out the response DHCP packet */\r
+       DHCPHeaderOUT->HardwareType          = DHCPHeaderIN->HardwareType;\r
+       DHCPHeaderOUT->Operation             = DHCP_OP_BOOTREPLY;\r
+       DHCPHeaderOUT->HardwareAddressLength = DHCPHeaderIN->HardwareAddressLength;\r
+       DHCPHeaderOUT->Hops                  = 0;\r
+       DHCPHeaderOUT->TransactionID         = DHCPHeaderIN->TransactionID;\r
+       DHCPHeaderOUT->ElapsedSeconds        = 0;\r
+       DHCPHeaderOUT->Flags                 = DHCPHeaderIN->Flags;\r
+       DHCPHeaderOUT->YourIP                = ClientIPAddress;\r
+       memcpy(&DHCPHeaderOUT->ClientHardwareAddress, &DHCPHeaderIN->ClientHardwareAddress, sizeof(MAC_Address_t));\r
+       DHCPHeaderOUT->Cookie                = SwapEndian_32(DHCP_MAGIC_COOKIE);\r
+       \r
+       /* Alter the incoming IP packet header so that the corrected IP source and destinations are used - this means that\r
+          when the response IP header is generated, it will use the corrected addresses and not the null/broatcast addresses */\r
+       IPHeaderIN->SourceAddress      = ClientIPAddress;\r
+       IPHeaderIN->DestinationAddress = ServerIPAddress;\r
+\r
+       /* Process the incoming DHCP packet options */\r
+       while (DHCPOptionsINStart[0] != DHCP_OPTION_END)\r
+       {       \r
+               /* Find the Message Type DHCP option, to determine the type of DHCP packet */\r
+               if (DHCPOptionsINStart[0] == DHCP_OPTION_MESSAGETYPE)\r
+               {\r
+                       if ((DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) || (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_REQUEST))\r
+                       {\r
+                               /* Fill out the response DHCP packet options for a DHCP OFFER or ACK response */\r
+\r
+                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_MESSAGETYPE;\r
+                               *(DHCPOptionsOUTStart++) = 1;\r
+                               *(DHCPOptionsOUTStart++) = (DHCPOptionsINStart[2] == DHCP_MESSAGETYPE_DISCOVER) ? DHCP_MESSAGETYPE_OFFER\r
+                                                                                                                                                                                               : DHCP_MESSAGETYPE_ACK;\r
+\r
+                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_SUBNETMASK;\r
+                               *(DHCPOptionsOUTStart++) = 4;\r
+                               *(DHCPOptionsOUTStart++) = 0xFF;\r
+                               *(DHCPOptionsOUTStart++) = 0xFF;\r
+                               *(DHCPOptionsOUTStart++) = 0xFF;\r
+                               *(DHCPOptionsOUTStart++) = 0x00;\r
+\r
+                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_DHCPSERVER;\r
+                               *(DHCPOptionsOUTStart++) = sizeof(IP_Address_t);\r
+                               memcpy(DHCPOptionsOUTStart, &ServerIPAddress, sizeof(IP_Address_t));\r
+                               DHCPOptionsOUTStart     += sizeof(IP_Address_t);\r
+\r
+                               *(DHCPOptionsOUTStart++) = DHCP_OPTION_END;\r
+                               \r
+                               return (sizeof(DHCP_Header_t) + 12 + sizeof(IP_Address_t));\r
+                       }\r
+               }\r
+               \r
+               /* Go to the next DHCP option - skip one byte if option is a padding byte, else skip the complete option's size */\r
+               DHCPOptionsINStart += ((DHCPOptionsINStart[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptionsINStart[1] + 2));\r
+       }\r
+       \r
+       return NO_RESPONSE;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/DHCP.h b/Demos/Device/RNDISEthernet/Lib/DHCP.h
new file mode 100644 (file)
index 0000000..f0e68b9
--- /dev/null
@@ -0,0 +1,125 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for DHCP.c.\r
+ */\r
\r
+#ifndef _DHCP_H_\r
+#define _DHCP_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <string.h>\r
+       \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               #include "ProtocolDecoders.h"\r
+\r
+       /* Macros: */\r
+               /** DHCP operation constant, indicating a request from a host to a DHCP server */\r
+               #define DHCP_OP_BOOTREQUEST       0x01\r
+\r
+               /** DHCP operation constant, indicating a reply from a DHCP server to a host */\r
+               #define DHCP_OP_BOOTREPLY         0x02\r
+               \r
+               /** Hardware type constant, indicating Ethernet as a carrier */\r
+               #define DHCP_HTYPE_ETHERNET       0x01\r
+               \r
+               /** Magic boot protocol "cookie", inserted into all BOOTP packets (BOOTP is the carrier of DHCP) */\r
+               #define DHCP_MAGIC_COOKIE         0x63825363\r
+               \r
+               /** DHCP option list entry header, indicating that a subnet mask will follow */\r
+               #define DHCP_OPTION_SUBNETMASK    1\r
+\r
+               /** DHCP option list entry header, indicating that the DHCP message type constant will follow */\r
+               #define DHCP_OPTION_MESSAGETYPE   53\r
+\r
+               /** DHCP option list entry header, indicating that the IP address of the DHCP server will follow */\r
+               #define DHCP_OPTION_DHCPSERVER    54\r
+\r
+               /** DHCP option list entry header, used to pad out option data */\r
+               #define DHCP_OPTION_PAD           0\r
+\r
+               /** DHCP option list entry header, indicating the end of option data */\r
+               #define DHCP_OPTION_END           255\r
+                       \r
+               /** Message type constant, used in the DHCP option data field, requesting that a DHCP server offer an IP address */\r
+               #define DHCP_MESSAGETYPE_DISCOVER 1\r
+\r
+               /** Message type constant, used in the DHCP option data field, indicating that a DHCP server is offering an IP address */\r
+               #define DHCP_MESSAGETYPE_OFFER    2\r
+\r
+               /** Message type constant, used in the DHCP option data field, requesting that a DHCP server lease a given IP address */\r
+               #define DHCP_MESSAGETYPE_REQUEST  3\r
+\r
+               /** Message type constant, used in the DHCP option data field, declining an offered DHCP server IP address lease */\r
+               #define DHCP_MESSAGETYPE_DECLINE  4\r
+\r
+               /** Message type constant, used in the DHCP option data field, ACKing a host IP lease request */\r
+               #define DHCP_MESSAGETYPE_ACK      5\r
+\r
+               /** Message type constant, used in the DHCP option data field, NACKing a host IP lease request */\r
+               #define DHCP_MESSAGETYPE_NACK     6\r
+\r
+               /** Message type constant, used in the DHCP option data field, indicating that a host is releasing a leased IP address */\r
+               #define DHCP_MESSAGETYPE_RELEASE  7\r
+\r
+       /* Type Defines: */\r
+               /** Type define for a DHCP packet inside an Ethernet frame. */\r
+               typedef struct\r
+               {\r
+                       uint8_t  Operation; /**< DHCP operation, either DHCP_OP_BOOTREQUEST or DHCP_OP_BOOTREPLY */\r
+                       uint8_t  HardwareType; /**< Hardware carrier type constant */\r
+                       uint8_t  HardwareAddressLength;  /**< Length in bytes of a hardware (MAC) address on the network */\r
+                       uint8_t  Hops; /**< Number of hops required to reach the server, unused */\r
+\r
+                       uint32_t TransactionID; /**< Unique ID of the DHCP packet, for positive matching between sent and received packets */\r
+\r
+                       uint16_t ElapsedSeconds; /**< Elapsed seconds since the request was made */\r
+                       uint16_t Flags; /**< BOOTP packet flags */\r
+                       \r
+                       IP_Address_t ClientIP; /**< Client IP address, if already leased an IP */\r
+                       IP_Address_t YourIP; /**< Client IP address */\r
+                       IP_Address_t NextServerIP; /**< Legacy BOOTP protocol field, unused for DHCP */\r
+                       IP_Address_t RelayAgentIP; /**< Legacy BOOTP protocol field, unused for DHCP */\r
+                       \r
+                       uint8_t ClientHardwareAddress[16]; /**< Hardware (MAC) address of the client making a request to the DHCP server */\r
+                       uint8_t ServerHostnameString[64]; /**< Legacy BOOTP protocol field, unused for DHCP */\r
+                       uint8_t BootFileName[128]; /**< Legacy BOOTP protocol field, unused for DHCP */\r
+                       \r
+                       uint32_t Cookie; /**< Magic BOOTP protocol cookie to indicate a valid packet */\r
+               } DHCP_Header_t;\r
+\r
+       /* Function Prototypes: */\r
+               int16_t DHCP_ProcessDHCPPacket(void* IPHeaderInStart, void* DHCPHeaderInStart, void* DHCPHeaderOutStart);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/Ethernet.c b/Demos/Device/RNDISEthernet/Lib/Ethernet.c
new file mode 100644 (file)
index 0000000..3d34f71
--- /dev/null
@@ -0,0 +1,136 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Ethernet frame packet handling routines. This protocol handles the processing of raw Ethernet\r
+ *  frames sent and received, deferring the processing of subpacket protocols to the appropriate\r
+ *  protocol handlers, such as DHCP or ARP.\r
+ */\r
\r
+#include "Ethernet.h"\r
+\r
+/* Global Variables: */\r
+/** Ethernet Frame buffer structure, to hold the incoming Ethernet frame from the host. */\r
+Ethernet_Frame_Info_t FrameIN;\r
+\r
+/** Ethernet Frame buffer structure, to hold the outgoing Ethernet frame to the host. */\r
+Ethernet_Frame_Info_t FrameOUT;\r
+\r
+/** Constant for convenience when checking against or setting a MAC address to the virtual server MAC address. */\r
+const MAC_Address_t ServerMACAddress    = {SERVER_MAC_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting an IP address to the virtual server IP address. */\r
+const IP_Address_t  ServerIPAddress     = {SERVER_IP_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting a MAC address to the broadcast MAC address. */\r
+const MAC_Address_t BroadcastMACAddress = {BROADCAST_MAC_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting a IP address to the broadcast IP address. */\r
+const IP_Address_t  BroadcastIPAddress  = {BROADCAST_IP_ADDRESS};\r
+\r
+/** Constant for convenience when checking against or setting an IP address to the client (host) IP address. */\r
+const IP_Address_t  ClientIPAddress     = {CLIENT_IP_ADDRESS};\r
+\r
+\r
+/** Processes an incoming Ethernet frame, and writes the appropriate response to the output Ethernet\r
+ *  frame buffer if the sub protocol handlers create a valid response.\r
+ */\r
+void Ethernet_ProcessPacket(void)\r
+{\r
+       DecodeEthernetFrameHeader(FrameIN.FrameData);\r
+\r
+       /* Cast the incoming Ethernet frame to the Ethernet header type */\r
+       Ethernet_Frame_Header_t* FrameINHeader  = (Ethernet_Frame_Header_t*)&FrameIN.FrameData;\r
+       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
+       \r
+       int16_t                  RetSize        = NO_RESPONSE;\r
+       \r
+       /* Ensure frame is addressed to either all (broadcast) or the virtual webserver, and is a type II frame */\r
+       if ((MAC_COMPARE(&FrameINHeader->Destination, &ServerMACAddress) ||\r
+            MAC_COMPARE(&FrameINHeader->Destination, &BroadcastMACAddress)) &&\r
+               (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE))\r
+       {\r
+               /* Process the packet depending on its protocol */\r
+               switch (SwapEndian_16(FrameINHeader->EtherType))\r
+               {\r
+                       case ETHERTYPE_ARP:\r
+                               RetSize = ARP_ProcessARPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
+                                                              &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
+                               break;          \r
+                       case ETHERTYPE_IPV4:\r
+                               RetSize = IP_ProcessIPPacket(&FrameIN.FrameData[sizeof(Ethernet_Frame_Header_t)],\r
+                                                            &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)]);\r
+                               break;\r
+               }\r
+               \r
+               /* Protocol processing routine has filled a response, complete the ethernet frame header */\r
+               if (RetSize > 0)\r
+               {\r
+                       /* Fill out the response Ethernet frame header */\r
+                       FrameOUTHeader->Source          = ServerMACAddress;\r
+                       FrameOUTHeader->Destination     = FrameINHeader->Source;\r
+                       FrameOUTHeader->EtherType       = FrameINHeader->EtherType;\r
+                       \r
+                       /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
+                       FrameOUT.FrameLength            = (sizeof(Ethernet_Frame_Header_t) + RetSize);\r
+                       FrameOUT.FrameInBuffer          = true;\r
+               }\r
+       }\r
+\r
+       /* Check if the packet was processed */\r
+       if (RetSize != NO_PROCESS)\r
+       {\r
+               /* Clear the frame buffer */\r
+               FrameIN.FrameInBuffer = false;\r
+       }\r
+}\r
+\r
+/** Calculates the appropriate ethernet checksum, consisting of the addition of the one's\r
+ *  compliment of each word, complimented.\r
+ *\r
+ *  \param Data   Pointer to the packet buffer data whose checksum must be calculated\r
+ *  \param Bytes  Number of bytes in the data buffer to process\r
+ *\r
+ *  \return A 16-bit Ethernet checksum value\r
+ */\r
+uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes)\r
+{\r
+       uint16_t* Words    = (uint16_t*)Data;\r
+       uint32_t  Checksum = 0;\r
+\r
+       for (uint8_t CurrWord = 0; CurrWord < (Bytes >> 1); CurrWord++)\r
+         Checksum += Words[CurrWord];\r
+         \r
+       while (Checksum & 0xFFFF0000)\r
+         Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));\r
+       \r
+       return ~Checksum;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/Ethernet.h b/Demos/Device/RNDISEthernet/Lib/Ethernet.h
new file mode 100644 (file)
index 0000000..b360f07
--- /dev/null
@@ -0,0 +1,116 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for Ethernet.c.\r
+ */\r
\r
+#ifndef _ETHERNET_H_\r
+#define _ETHERNET_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <string.h>\r
+\r
+               #include "EthernetProtocols.h"\r
+               #include "ProtocolDecoders.h"\r
+               #include "ICMP.h"\r
+               #include "TCP.h"\r
+               #include "UDP.h"\r
+               #include "DHCP.h"\r
+               #include "ARP.h"\r
+               #include "IP.h"\r
+               \r
+       /* Macros: */\r
+               /** Physical MAC address of the virtual server on the network */\r
+               #define SERVER_MAC_ADDRESS               {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}           \r
+\r
+               /** Physical MAC address of the network broadcast address */\r
+               #define BROADCAST_MAC_ADDRESS            {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}\r
+       \r
+               /** Performs a comparison between two MAC addresses, indicating if they are identical.\r
+                *  \r
+                *  \param MAC1  First MAC address\r
+                *  \param MAC2  Second MAC address\r
+                *\r
+                *  \return True if the addresses match, false otherwise\r
+                */\r
+               #define MAC_COMPARE(MAC1, MAC2)          (memcmp(MAC1, MAC2, sizeof(MAC_Address_t)) == 0)\r
+\r
+               /** Maximum size of an incoming or outgoing Ethernet frame in bytes */\r
+               #define ETHERNET_FRAME_SIZE_MAX          1500\r
+               \r
+               /** Minimum size of an Ethernet packet in bytes, to conform to the Ethernet V2 packet standard */\r
+               #define ETHERNET_VER2_MINSIZE            0x0600\r
+               \r
+               /** Return value for all sub protocol handling routines, indicating that no response packet has been generated */\r
+               #define NO_RESPONSE                      0              \r
+\r
+               /** Return value for all sub protocol handling routines, indicating that the packet has not yet been handled */\r
+               #define NO_PROCESS                       -1\r
+\r
+       /* Type Defines: */\r
+               /** Type define for an Ethernet frame buffer. */\r
+               typedef struct\r
+               {\r
+                       uint8_t       FrameData[ETHERNET_FRAME_SIZE_MAX]; /**< Ethernet frame contents */\r
+                       uint16_t      FrameLength; /**< Length in bytes of the Ethernet frame stored in the buffer */\r
+                       bool          FrameInBuffer; /**< Indicates if a frame is currently stored in the buffer */\r
+               } Ethernet_Frame_Info_t;\r
+\r
+               /** Type define for an Ethernet frame header */\r
+               typedef struct\r
+               {\r
+                       MAC_Address_t Destination; /**< Physical MAC address of the packet recipient */\r
+                       MAC_Address_t Source; /**< Physics MAC address of the packet source */\r
+                       \r
+                       union\r
+                       {\r
+                               uint16_t  EtherType; /**< Ethernet packet subprotocol type, for Ethernet V2 packets */\r
+                               uint16_t  Length; /**< Ethernet frame length, for Ethernet V1 packets */\r
+                       };\r
+               } Ethernet_Frame_Header_t;\r
+               \r
+       /* External Variables: */\r
+               extern Ethernet_Frame_Info_t FrameIN;\r
+               extern Ethernet_Frame_Info_t FrameOUT;\r
+\r
+               extern const MAC_Address_t ServerMACAddress;\r
+               extern const IP_Address_t  ServerIPAddress;\r
+               extern const MAC_Address_t BroadcastMACAddress;\r
+               extern const IP_Address_t  BroadcastIPAddress;\r
+               extern const IP_Address_t  ClientIPAddress;\r
+               \r
+       /* Function Prototypes: */\r
+               void     Ethernet_ProcessPacket(void);\r
+               uint16_t Ethernet_Checksum16(void* Data, uint16_t Bytes);\r
+               \r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h b/Demos/Device/RNDISEthernet/Lib/EthernetProtocols.h
new file mode 100644 (file)
index 0000000..3ff3433
--- /dev/null
@@ -0,0 +1,87 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  General Ethernet protocol constants and type defines, for use by\r
+ *  all network protocol portions of the TCP/IP stack.\r
+ */\r
+\r
+#ifndef _ETHERNET_PROTOCOLS_H_\r
+#define _ETHERNET_PROTOCOLS_H_\r
+\r
+       /* Macros: */\r
+               #define ETHERTYPE_IPV4                   0x0800\r
+               #define ETHERTYPE_ARP                    0x0806\r
+               #define ETHERTYPE_RARP                   0x8035\r
+               #define ETHERTYPE_APPLETALK              0x809b\r
+               #define ETHERTYPE_APPLETALKARP           0x80f3\r
+               #define ETHERTYPE_IEEE8021Q              0x8100\r
+               #define ETHERTYPE_NOVELLIPX              0x8137\r
+               #define ETHERTYPE_NOVELL                 0x8138\r
+               #define ETHERTYPE_IPV6                   0x86DD\r
+               #define ETHERTYPE_COBRANET               0x8819\r
+               #define ETHERTYPE_PROVIDERBRIDGING       0x88a8\r
+               #define ETHERTYPE_MPLSUNICAST            0x8847\r
+               #define ETHERTYPE_MPLSMULTICAST          0x8848\r
+               #define ETHERTYPE_PPPoEDISCOVERY         0x8863\r
+               #define ETHERTYPE_PPPoESESSION           0x8864\r
+               #define ETHERTYPE_EAPOVERLAN             0x888E\r
+               #define ETHERTYPE_HYPERSCSI              0x889A\r
+               #define ETHERTYPE_ATAOVERETHERNET        0x88A2\r
+               #define ETHERTYPE_ETHERCAT               0x88A4\r
+               #define ETHERTYPE_SERCOSIII              0x88CD\r
+               #define ETHERTYPE_CESoE                  0x88D8\r
+               #define ETHERTYPE_MACSECURITY            0x88E5\r
+               #define ETHERTYPE_FIBRECHANNEL           0x8906\r
+               #define ETHERTYPE_QINQ                   0x9100\r
+               #define ETHERTYPE_VLLT                   0xCAFE\r
+               \r
+               #define PROTOCOL_ICMP                    1\r
+               #define PROTOCOL_IGMP                    2\r
+               #define PROTOCOL_TCP                     6\r
+               #define PROTOCOL_UDP                     17\r
+               #define PROTOCOL_OSPF                    89\r
+               #define PROTOCOL_SCTP                    132\r
+\r
+       /* Type Defines: */\r
+               /** Type define for a physical MAC address of a device on a network */\r
+               typedef struct\r
+               {\r
+                       uint8_t       Octets[6]; /**< Individual bytes of a MAC address */\r
+               } MAC_Address_t;\r
+               \r
+               /** Type define for a protocol IP address of a device on a network */\r
+               typedef struct\r
+               {\r
+                       uint8_t       Octets[4]; /**< Individual bytes of an IP address */\r
+               } IP_Address_t;\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/ICMP.c b/Demos/Device/RNDISEthernet/Lib/ICMP.c
new file mode 100644 (file)
index 0000000..da4ffcf
--- /dev/null
@@ -0,0 +1,79 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Internet Control Message Protocol (ICMP) packet handling routines. This protocol handles\r
+ *  Echo requests from the host, to indicate a successful network connection between the host\r
+ *  and the virtual server.\r
+ */\r
\r
+#include "ICMP.h"\r
+\r
+/** Processes an ICMP packet inside an Ethernet frame, and writes the appropriate response\r
+ *  to the output Ethernet frame if the host is issuing a ICMP ECHO request.\r
+ *\r
+ *  \param InDataStart   Pointer to the start of the incoming packet's ICMP header\r
+ *  \param OutDataStart  Pointer to the start of the outgoing packet's ICMP header\r
+ *\r
+ *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
+ */\r
+int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart)\r
+{\r
+       ICMP_Header_t* ICMPHeaderIN  = (ICMP_Header_t*)InDataStart;\r
+       ICMP_Header_t* ICMPHeaderOUT = (ICMP_Header_t*)OutDataStart;\r
+\r
+       DecodeICMPHeader(InDataStart);\r
+\r
+       /* Determine if the ICMP packet is an echo request (ping) */\r
+       if (ICMPHeaderIN->Type == ICMP_TYPE_ECHOREQUEST)\r
+       {\r
+               /* Fill out the ICMP response packet */\r
+               ICMPHeaderOUT->Type     = ICMP_TYPE_ECHOREPLY;\r
+               ICMPHeaderOUT->Code     = 0;\r
+               ICMPHeaderOUT->Checksum = 0;\r
+               ICMPHeaderOUT->Id       = ICMPHeaderIN->Id;\r
+               ICMPHeaderOUT->Sequence = ICMPHeaderIN->Sequence;\r
+               \r
+               uint16_t DataSize = FrameIN.FrameLength - ((((uint16_t)InDataStart + sizeof(ICMP_Header_t)) - (uint16_t)FrameIN.FrameData));\r
+               \r
+               /* Copy the remaining payload to the response - echo requests should echo back any sent data */\r
+               memcpy(&((uint8_t*)OutDataStart)[sizeof(ICMP_Header_t)],\r
+                      &((uint8_t*)InDataStart)[sizeof(ICMP_Header_t)],\r
+                          DataSize);\r
+\r
+               ICMPHeaderOUT->Checksum = Ethernet_Checksum16(ICMPHeaderOUT, (DataSize + sizeof(ICMP_Header_t)));\r
+\r
+               /* Return the size of the response so far */\r
+               return (DataSize + sizeof(ICMP_Header_t));\r
+       }\r
+       \r
+       return NO_RESPONSE;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/ICMP.h b/Demos/Device/RNDISEthernet/Lib/ICMP.h
new file mode 100644 (file)
index 0000000..b20a557
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for ICMP.c.\r
+ */\r
+\r
+#ifndef _ICMP_H_\r
+#define _ICMP_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <string.h>\r
+               \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               #include "ProtocolDecoders.h"\r
+       \r
+       /* Macros: */\r
+               /** ICMP message type constant, indicating an ICMP ECHO Reply message */\r
+               #define ICMP_TYPE_ECHOREPLY              0\r
+\r
+               /** ICMP message type constant, indicating a packet destination is unreachable */\r
+               #define ICMP_TYPE_DESTINATIONUNREACHABLE 3\r
+               \r
+               /** ICMP message type constant, indicating an ICMP Source Quench message */\r
+               #define ICMP_TYPE_SOURCEQUENCH           4\r
+\r
+               /** ICMP message type constant, indicating an ICMP Redirect message */\r
+               #define ICMP_TYPE_REDIRECTMESSAGE        5\r
+\r
+               /** ICMP message type constant, indicating an ICMP ECHO Request message */\r
+               #define ICMP_TYPE_ECHOREQUEST            8\r
+\r
+               /** ICMP message type constant, indicating an ICMP Time Exceeded message */\r
+               #define ICMP_TYPE_TIMEEXCEEDED           11\r
+       \r
+       /* Type Defines: */\r
+               /** Type define for an ICMP message header. */\r
+               typedef struct\r
+               {\r
+                       uint8_t       Type; /**< ICMP message type, a ICMP_TYPE_* constant */\r
+                       uint8_t       Code; /**< ICMP message code, indicating the message value */\r
+                       uint16_t      Checksum; /**< Ethernet checksum of the ICMP message */\r
+                       uint16_t      Id; /**< Id of the ICMP message */\r
+                       uint16_t      Sequence; /**< Sequence number of the ICMP message, to link together message responses */\r
+               } ICMP_Header_t;\r
+               \r
+       /* Function Prototypes: */\r
+               int16_t ICMP_ProcessICMPPacket(void* InDataStart, void* OutDataStart);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/IP.c b/Demos/Device/RNDISEthernet/Lib/IP.c
new file mode 100644 (file)
index 0000000..8fb0b44
--- /dev/null
@@ -0,0 +1,111 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Internet Protocol (IP) packet handling routines. This protocol handles IP packets from the\r
+ *  host which typically encapsulate other protocols such as ICMP, UDP and TCP.\r
+ */\r
\r
+#include "IP.h"\r
+\r
+/** Processes an IP packet inside an Ethernet frame, and writes the appropriate response\r
+ *  to the output Ethernet frame if one is created by a subprotocol handler.\r
+ *\r
+ *  \param InDataStart   Pointer to the start of the incoming packet's IP header\r
+ *  \param OutDataStart  Pointer to the start of the outgoing packet's IP header\r
+ *\r
+ *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no\r
+ *           response was generated, NO_PROCESS if the packet processing was deferred until the\r
+ *           next Ethernet packet handler iteration\r
+ */\r
+int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart)\r
+{\r
+       DecodeIPHeader(InDataStart);\r
+\r
+       IP_Header_t* IPHeaderIN  = (IP_Header_t*)InDataStart;\r
+       IP_Header_t* IPHeaderOUT = (IP_Header_t*)OutDataStart;\r
+\r
+       /* Header length is specified in number of longs in the packet header, convert to bytes */\r
+       uint16_t HeaderLengthBytes = (IPHeaderIN->HeaderLength * sizeof(uint32_t));\r
+\r
+       int16_t  RetSize = NO_RESPONSE;\r
+\r
+       /* Check to ensure the IP packet is addressed to the virtual webserver's IP or the broadcast IP address */\r
+       if (!(IP_COMPARE(&IPHeaderIN->DestinationAddress, &ServerIPAddress)) &&\r
+           !(IP_COMPARE(&IPHeaderIN->DestinationAddress, &BroadcastIPAddress)))\r
+       {\r
+               return NO_RESPONSE;\r
+       }\r
+       \r
+       /* Pass off the IP payload to the appropriate protocol processing routine */\r
+       switch (IPHeaderIN->Protocol)\r
+       {\r
+               case PROTOCOL_ICMP:\r
+                       RetSize = ICMP_ProcessICMPPacket(&((uint8_t*)InDataStart)[HeaderLengthBytes],\r
+                                                        &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);\r
+                       break;\r
+               case PROTOCOL_TCP:\r
+                       RetSize = TCP_ProcessTCPPacket(InDataStart,\r
+                                                      &((uint8_t*)InDataStart)[HeaderLengthBytes],\r
+                                                      &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);         \r
+                       break;\r
+               case PROTOCOL_UDP:\r
+                       RetSize = UDP_ProcessUDPPacket(InDataStart,\r
+                                                      &((uint8_t*)InDataStart)[HeaderLengthBytes],\r
+                                                      &((uint8_t*)OutDataStart)[sizeof(IP_Header_t)]);         \r
+                       break;\r
+       }\r
+       \r
+       /* Check to see if the protocol processing routine has filled out a response */\r
+       if (RetSize > 0)\r
+       {\r
+               /* Fill out the response IP packet header */\r
+               IPHeaderOUT->TotalLength        = SwapEndian_16(sizeof(IP_Header_t) + RetSize);\r
+               IPHeaderOUT->TypeOfService      = 0;\r
+               IPHeaderOUT->HeaderLength       = (sizeof(IP_Header_t) / sizeof(uint32_t));\r
+               IPHeaderOUT->Version            = 4;\r
+               IPHeaderOUT->Flags              = 0;\r
+               IPHeaderOUT->FragmentOffset     = 0;\r
+               IPHeaderOUT->Identification     = 0;\r
+               IPHeaderOUT->HeaderChecksum     = 0;\r
+               IPHeaderOUT->Protocol           = IPHeaderIN->Protocol;\r
+               IPHeaderOUT->TTL                = DEFAULT_TTL;\r
+               IPHeaderOUT->SourceAddress      = IPHeaderIN->DestinationAddress;\r
+               IPHeaderOUT->DestinationAddress = IPHeaderIN->SourceAddress;\r
+               \r
+               IPHeaderOUT->HeaderChecksum     = Ethernet_Checksum16(IPHeaderOUT, sizeof(IP_Header_t));\r
+                                               \r
+               /* Return the size of the response so far */\r
+               return (sizeof(IP_Header_t) + RetSize);\r
+       }\r
+       \r
+       return RetSize;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/IP.h b/Demos/Device/RNDISEthernet/Lib/IP.h
new file mode 100644 (file)
index 0000000..fc1a46a
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for IP.c.\r
+ */\r
\r
+#ifndef _IP_H_\r
+#define _IP_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <string.h>\r
+               \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               #include "ProtocolDecoders.h"\r
+       \r
+       /* Macros: */\r
+               /** Protocol IP address of the host (client) machine, once assigned by DHCP */\r
+               #define CLIENT_IP_ADDRESS                { 10,     0,    0,    1}\r
+\r
+               /** Protocol IP address of the virtual server machine */\r
+               #define SERVER_IP_ADDRESS                { 10,     0,    0,    2}\r
+\r
+               /** Protocol IP address of the broadcast address */\r
+               #define BROADCAST_IP_ADDRESS             {0xFF, 0xFF, 0xFF, 0xFF}\r
+\r
+               /** Default Time To Live (TTL) value for sent packets, indicating the maximum allowable hops until their destination is reached */\r
+               #define DEFAULT_TTL                      128\r
+               \r
+               /** Performs a comparison between two IP addresses, indicating if they are identical.\r
+                *  \r
+                *  \param IP1  First IP address\r
+                *  \param IP2  Second IP address\r
+                *\r
+                *  \return True if the addresses match, false otherwise\r
+                */\r
+               #define IP_COMPARE(IP1, IP2)             (memcmp(IP1, IP2, sizeof(IP_Address_t)) == 0)\r
+               \r
+       /* Type Defines: */\r
+               /** Type define of an IP packet header. */\r
+               typedef struct\r
+               {\r
+                       unsigned char  HeaderLength   : 4; /**< Total length of the packet header, in 4-byte blocks */\r
+                       unsigned char  Version        : 4; /**< IP protocol version */\r
+                       uint8_t        TypeOfService; /**< Special service type identifier, indicating delay/throughput/reliability levels */\r
+                       uint16_t       TotalLength; /**< Total length of the IP packet, in bytes */\r
+\r
+                       uint16_t       Identification; /**< Identification value for identifying fragmented packets */\r
+                       unsigned int   FragmentOffset : 13; /**< Offset of this IP fragment */\r
+                       unsigned int   Flags          : 3; /**< Fragment flags, to indicate if a packet is fragmented */\r
+\r
+                       uint8_t        TTL; /**< Maximum allowable number of hops to reach the packet destination */\r
+                       uint8_t        Protocol; /**< Encapsulated protocol type */\r
+                       uint16_t       HeaderChecksum; /**< Ethernet checksum of the IP header */\r
+                       \r
+                       IP_Address_t  SourceAddress; /**< Source protocol IP address of the packet */\r
+                       IP_Address_t  DestinationAddress; /**< Destination protocol IP address of the packet */\r
+               } IP_Header_t;\r
+               \r
+       /* Function Prototypes: */\r
+               int16_t IP_ProcessIPPacket(void* InDataStart, void* OutDataStart);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/ProtocolDecoders.c b/Demos/Device/RNDISEthernet/Lib/ProtocolDecoders.c
new file mode 100644 (file)
index 0000000..add0333
--- /dev/null
@@ -0,0 +1,280 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/* Protocol decoders for Ethernet, TCP, IP, ICMP and ARP. Each of these routines\r
+   accepts a header to the appropriate protocol and prints out pertinent information\r
+   on the packet through the serial port.\r
+   \r
+   To disable printing of a specific protocol, define the token NO_DECODE_{Protocol}\r
+   in the project makefile, and pass it to the compiler using the -D switch.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Protocol decoding routines, for the plain-text decoding of Ethernet frames for debugging purposes.\r
+ *  Enabled protocol decoders will print incoming Ethernet frame contents through the USART in a human\r
+ *  readable format.\r
+ *\r
+ *  Note that the USART is a slow transmission medium, and will slow down packet processing considerably.\r
+ *  Packet decoding routines can be disabled by defining NO_DECODE_{Protocol Name} in the project makefile\r
+ *  and passing it to the compiler via the -D switch.\r
+ */\r
\r
+#include "ProtocolDecoders.h"\r
+\r
+/** Decodes an Ethernet frame header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of an Ethernet frame header\r
+ */\r
+void DecodeEthernetFrameHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_ETHERNET)\r
+       Ethernet_Frame_Header_t* FrameHeader = (Ethernet_Frame_Header_t*)InDataStart;\r
+       \r
+       printf_P(PSTR("\r\n"));\r
+       \r
+       printf_P(PSTR("  ETHERNET\r\n"));\r
+       printf_P(PSTR("  + Frame Size: %u\r\n"), FrameIN.FrameLength);\r
+\r
+       if (!(MAC_COMPARE(&FrameHeader->Destination, &ServerMACAddress)) &&\r
+           !(MAC_COMPARE(&FrameHeader->Destination, &BroadcastMACAddress)))\r
+       {\r
+               printf_P(PSTR("  + NOT ADDRESSED TO DEVICE\r\n"));\r
+               return;\r
+       }\r
+\r
+       printf_P(PSTR("  + MAC Source : %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Source.Octets[0],\r
+                                                                            FrameHeader->Source.Octets[1],\r
+                                                                            FrameHeader->Source.Octets[2],\r
+                                                                            FrameHeader->Source.Octets[3],\r
+                                                                            FrameHeader->Source.Octets[4],\r
+                                                                            FrameHeader->Source.Octets[5]);\r
+\r
+       printf_P(PSTR("  + MAC Dest: %02X:%02X:%02X:%02X:%02X:%02X\r\n"),    FrameHeader->Destination.Octets[0],\r
+                                                                            FrameHeader->Destination.Octets[1],\r
+                                                                            FrameHeader->Destination.Octets[2],\r
+                                                                            FrameHeader->Destination.Octets[3],\r
+                                                                            FrameHeader->Destination.Octets[4],\r
+                                                                            FrameHeader->Destination.Octets[5]);\r
+\r
+       if (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE)\r
+         printf_P(PSTR("  + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));\r
+       else\r
+         printf_P(PSTR("  + Protocol: UNKNOWN E1\r\n"));\r
+       #endif\r
+}\r
+\r
+/** Decodes an ARP header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of an ARP packet header\r
+ */\r
+void DecodeARPHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_ARP)\r
+       ARP_Header_t* ARPHeader = (ARP_Header_t*)InDataStart;   \r
+\r
+       printf_P(PSTR("   \\\r\n    ARP\r\n"));\r
+\r
+       if (!(IP_COMPARE(&ARPHeader->TPA, &ServerIPAddress)) &&\r
+           !(MAC_COMPARE(&ARPHeader->THA, &ServerMACAddress)))\r
+       {\r
+               printf_P(PSTR("    + NOT ADDRESSED TO DEVICE\r\n"));\r
+               return;         \r
+       }\r
+\r
+       printf_P(PSTR("    + Protocol: %x\r\n"), SwapEndian_16(ARPHeader->ProtocolType));\r
+       printf_P(PSTR("    + Operation: %u\r\n"), SwapEndian_16(ARPHeader->Operation));\r
+       \r
+       if (SwapEndian_16(ARPHeader->ProtocolType) == ETHERTYPE_IPV4)\r
+       {\r
+               printf_P(PSTR("    + SHA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->SHA.Octets[0],\r
+                                                                                  ARPHeader->SHA.Octets[1],\r
+                                                                                  ARPHeader->SHA.Octets[2],\r
+                                                                                  ARPHeader->SHA.Octets[3],\r
+                                                                                  ARPHeader->SHA.Octets[4],\r
+                                                                                  ARPHeader->SHA.Octets[5]);\r
+\r
+               printf_P(PSTR("    + SPA IP: %u.%u.%u.%u\r\n"), ARPHeader->SPA.Octets[0],\r
+                                                               ARPHeader->SPA.Octets[1],\r
+                                                               ARPHeader->SPA.Octets[2],\r
+                                                               ARPHeader->SPA.Octets[3]);\r
+\r
+               printf_P(PSTR("    + THA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->THA.Octets[0],\r
+                                                                                  ARPHeader->THA.Octets[1],\r
+                                                                                  ARPHeader->THA.Octets[2],\r
+                                                                                  ARPHeader->THA.Octets[3],\r
+                                                                                  ARPHeader->THA.Octets[4],\r
+                                                                                  ARPHeader->THA.Octets[5]);\r
+\r
+               printf_P(PSTR("    + TPA IP: %u.%u.%u.%u\r\n"), ARPHeader->TPA.Octets[0],\r
+                                                               ARPHeader->TPA.Octets[1],\r
+                                                               ARPHeader->TPA.Octets[2],\r
+                                                               ARPHeader->TPA.Octets[3]);\r
+       }\r
+       #endif\r
+}\r
+\r
+/** Decodes an IP header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of an IP packet header\r
+ */\r
+void DecodeIPHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_IP)\r
+       IP_Header_t* IPHeader  = (IP_Header_t*)InDataStart;\r
+\r
+       uint16_t HeaderLengthBytes = (IPHeader->HeaderLength * sizeof(uint32_t));\r
+\r
+       printf_P(PSTR("   \\\r\n    IP\r\n"));\r
+\r
+       if (!(IP_COMPARE(&IPHeader->DestinationAddress, &ServerIPAddress)))\r
+       {\r
+               printf_P(PSTR("    + NOT ADDRESSED TO DEVICE\r\n"));\r
+               return;\r
+       }\r
+\r
+       printf_P(PSTR("    + Header Length: %u Bytes\r\n"), HeaderLengthBytes);\r
+       printf_P(PSTR("    + Packet Version: %u\r\n"), IPHeader->Version);\r
+       printf_P(PSTR("    + Total Length: %u\r\n"), SwapEndian_16(IPHeader->TotalLength));\r
+       \r
+       printf_P(PSTR("    + Protocol: %u\r\n"), IPHeader->Protocol);\r
+       printf_P(PSTR("    + TTL: %u\r\n"), IPHeader->TTL);\r
+       \r
+       printf_P(PSTR("    + IP Src: %u.%u.%u.%u\r\n"), IPHeader->SourceAddress.Octets[0],\r
+                                                       IPHeader->SourceAddress.Octets[1],\r
+                                                       IPHeader->SourceAddress.Octets[2],\r
+                                                       IPHeader->SourceAddress.Octets[3]);     \r
+\r
+       printf_P(PSTR("    + IP Dst: %u.%u.%u.%u\r\n"), IPHeader->DestinationAddress.Octets[0],\r
+                                                       IPHeader->DestinationAddress.Octets[1],\r
+                                                       IPHeader->DestinationAddress.Octets[2],\r
+                                                       IPHeader->DestinationAddress.Octets[3]);\r
+       #endif\r
+}\r
+\r
+/** Decodes an ICMP header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of an ICMP packet header\r
+ */\r
+void DecodeICMPHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_ICMP)\r
+       ICMP_Header_t* ICMPHeader  = (ICMP_Header_t*)InDataStart;\r
+\r
+       printf_P(PSTR("    \\\r\n     ICMP\r\n"));\r
+\r
+       printf_P(PSTR("     + Type: %u\r\n"), ICMPHeader->Type);\r
+       printf_P(PSTR("     + Code: %u\r\n"), ICMPHeader->Code);\r
+       #endif\r
+}\r
+\r
+/** Decodes a TCP header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of a TCP packet header\r
+ */\r
+void DecodeTCPHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_TCP)\r
+       TCP_Header_t* TCPHeader  = (TCP_Header_t*)InDataStart;\r
+\r
+       uint16_t               HeaderLengthBytes = (TCPHeader->DataOffset * sizeof(uint32_t));\r
+\r
+       printf_P(PSTR("    \\\r\n     TCP\r\n"));\r
+\r
+       printf_P(PSTR("     + Header Length: %u Bytes\r\n"), HeaderLengthBytes);\r
+\r
+       printf_P(PSTR("     + Source Port: %u\r\n"), SwapEndian_16(TCPHeader->SourcePort));\r
+       printf_P(PSTR("     + Destination Port: %u\r\n"), SwapEndian_16(TCPHeader->DestinationPort));\r
+\r
+       printf_P(PSTR("     + Sequence Number: %lu\r\n"), SwapEndian_32(TCPHeader->SequenceNumber));\r
+       printf_P(PSTR("     + Acknowledgment Number: %lu\r\n"), SwapEndian_32(TCPHeader->AcknowledgmentNumber));\r
+       \r
+       printf_P(PSTR("     + Flags: 0x%02X\r\n"), TCPHeader->Flags);\r
+       \r
+       if (TCP_GetPortState(TCPHeader->DestinationPort) == TCP_Port_Closed)\r
+         printf_P(PSTR("     + NOT LISTENING ON DESTINATION PORT\r\n"));\r
+       #endif\r
+}\r
+\r
+/** Decodes an UDP header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of a UDP packet header\r
+ */\r
+void DecodeUDPHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_UDP)\r
+       UDP_Header_t* UDPHeader = (UDP_Header_t*)InDataStart;\r
+\r
+       printf_P(PSTR("    \\\r\n     UDP\r\n"));\r
+\r
+       printf_P(PSTR("     + Source Port: %u\r\n"), SwapEndian_16(UDPHeader->SourcePort));\r
+       printf_P(PSTR("     + Destination Port: %u\r\n"), SwapEndian_16(UDPHeader->DestinationPort));\r
+\r
+       printf_P(PSTR("     + Data Length: %d\r\n"), SwapEndian_16(UDPHeader->Length));\r
+       #endif\r
+}\r
+\r
+/** Decodes an DHCP header and prints its contents to through the USART in a human readable format.\r
+ *\r
+ *  \param InDataStart  Pointer to the start of a DHCP packet header\r
+ */\r
+void DecodeDHCPHeader(void* InDataStart)\r
+{\r
+       #if !defined(NO_DECODE_DHCP)\r
+       uint8_t* DHCPOptions = (InDataStart + sizeof(DHCP_Header_t));\r
+\r
+       printf_P(PSTR("     \\\r\n      DHCP\r\n"));\r
+\r
+       while (DHCPOptions[0] != DHCP_OPTION_END)\r
+       {\r
+               if (DHCPOptions[0] == DHCP_OPTION_MESSAGETYPE)\r
+               {\r
+                       switch (DHCPOptions[2])\r
+                       {\r
+                               case DHCP_MESSAGETYPE_DISCOVER:\r
+                                       printf_P(PSTR("      + DISCOVER\r\n"));\r
+                                       break;\r
+                               case DHCP_MESSAGETYPE_REQUEST:\r
+                                       printf_P(PSTR("      + REQUEST\r\n"));\r
+                                       break;\r
+                               case DHCP_MESSAGETYPE_RELEASE:\r
+                                       printf_P(PSTR("      + RELEASE\r\n"));\r
+                                       break;\r
+                               case DHCP_MESSAGETYPE_DECLINE:\r
+                                       printf_P(PSTR("      + DECLINE\r\n"));\r
+                                       break;\r
+                       }\r
+               }\r
+               \r
+               DHCPOptions += ((DHCPOptions[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptions[1] + 2));\r
+       }\r
+\r
+       #endif\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/ProtocolDecoders.h b/Demos/Device/RNDISEthernet/Lib/ProtocolDecoders.h
new file mode 100644 (file)
index 0000000..fa0a869
--- /dev/null
@@ -0,0 +1,56 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for ProtocolDecoders.c.\r
+ */\r
+\r
+#ifndef _PROTOCOL_DECODERS_H_\r
+#define _PROTOCOL_DECODERS_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               \r
+               #include <LUFA/Drivers/Peripheral/SerialStream.h>\r
+               \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               \r
+       /* Function Prototypes: */\r
+               void DecodeEthernetFrameHeader(void* InDataStart);\r
+               void DecodeARPHeader(void* InDataStart);\r
+               void DecodeIPHeader(void* InDataStart);\r
+               void DecodeICMPHeader(void* InDataStart);\r
+               void DecodeTCPHeader(void* InDataStart);\r
+               void DecodeUDPHeader(void* InDataStart);\r
+               void DecodeDHCPHeader(void* InDataStart);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.c b/Demos/Device/RNDISEthernet/Lib/RNDIS.c
new file mode 100644 (file)
index 0000000..c5202bc
--- /dev/null
@@ -0,0 +1,394 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  RNDIS command handler functions. This handles RNDIS commands according to\r
+ *  the Microsoft RNDIS specification, creating a USB Ethernet network adapter.\r
+ */\r
\r
+#define  INCLUDE_FROM_RNDIS_C\r
+#include "RNDIS.h"\r
+\r
+/* Global Variables: */\r
+/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */\r
+static MAC_Address_t  PROGMEM AdapterMACAddress          = {ADAPTER_MAC_ADDRESS};\r
+\r
+/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for\r
+ *  the device, but may still be used by the OS in some circumstances.\r
+ */\r
+static char           PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";\r
+\r
+/** List of RNDIS OID commands supported by this adapter. */\r
+static const uint32_t PROGMEM AdapterSupportedOIDList[]  =\r
+                                                       {\r
+                                                               OID_GEN_SUPPORTED_LIST,\r
+                                                               OID_GEN_PHYSICAL_MEDIUM,\r
+                                                               OID_GEN_HARDWARE_STATUS,\r
+                                                               OID_GEN_MEDIA_SUPPORTED,\r
+                                                               OID_GEN_MEDIA_IN_USE,\r
+                                                               OID_GEN_MAXIMUM_FRAME_SIZE,\r
+                                                               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
+                                                               OID_GEN_LINK_SPEED,\r
+                                                               OID_GEN_TRANSMIT_BLOCK_SIZE,\r
+                                                               OID_GEN_RECEIVE_BLOCK_SIZE,\r
+                                                               OID_GEN_VENDOR_ID,\r
+                                                               OID_GEN_VENDOR_DESCRIPTION,\r
+                                                               OID_GEN_CURRENT_PACKET_FILTER,\r
+                                                               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
+                                                               OID_GEN_MEDIA_CONNECT_STATUS,\r
+                                                               OID_GEN_XMIT_OK,\r
+                                                               OID_GEN_RCV_OK,\r
+                                                               OID_GEN_XMIT_ERROR,\r
+                                                               OID_GEN_RCV_ERROR,\r
+                                                               OID_GEN_RCV_NO_BUFFER,\r
+                                                               OID_802_3_PERMANENT_ADDRESS,\r
+                                                               OID_802_3_CURRENT_ADDRESS,\r
+                                                               OID_802_3_MULTICAST_LIST,\r
+                                                               OID_802_3_MAXIMUM_LIST_SIZE,\r
+                                                               OID_802_3_RCV_ERROR_ALIGNMENT,\r
+                                                               OID_802_3_XMIT_ONE_COLLISION,\r
+                                                               OID_802_3_XMIT_MORE_COLLISIONS,\r
+                                                       };\r
+\r
+/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire\r
+ *  Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this\r
+ *  reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.\r
+ */\r
+uint8_t                 RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_QUERY_CMPLT_t)];\r
+\r
+/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */\r
+RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;\r
+\r
+/** Indicates if a RNDIS message response is ready to be sent back to the host. */\r
+bool                    ResponseReady               = false;\r
+\r
+/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */\r
+uint8_t                 CurrRNDISState              = RNDIS_Uninitialized;\r
+\r
+/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */\r
+uint32_t                CurrPacketFilter            = 0;                                                       \r
+\r
+\r
+/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is\r
+ *  created, the ResponseReady global is updated so that the response is written back to the host upon request.\r
+ */\r
+void ProcessRNDISControlMessage(void)\r
+{\r
+       /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of\r
+                this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */\r
+\r
+       switch (MessageHeader->MessageType)\r
+       {\r
+               case REMOTE_NDIS_INITIALIZE_MSG:\r
+                       /* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */\r
+\r
+                       ResponseReady = true;\r
+                       \r
+                       RNDIS_INITIALIZE_MSG_t*   INITIALIZE_Message  = (RNDIS_INITIALIZE_MSG_t*)&RNDISMessageBuffer;\r
+                       RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISMessageBuffer;\r
+                       \r
+                       INITIALIZE_Response->MessageType           = REMOTE_NDIS_INITIALIZE_CMPLT;\r
+                       INITIALIZE_Response->MessageLength         = sizeof(RNDIS_INITIALIZE_CMPLT_t);\r
+                       INITIALIZE_Response->RequestId             = INITIALIZE_Message->RequestId;\r
+                       INITIALIZE_Response->Status                = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       \r
+                       INITIALIZE_Response->MajorVersion          = REMOTE_NDIS_VERSION_MAJOR;\r
+                       INITIALIZE_Response->MinorVersion          = REMOTE_NDIS_VERSION_MINOR;                 \r
+                       INITIALIZE_Response->DeviceFlags           = REMOTE_NDIS_DF_CONNECTIONLESS;\r
+                       INITIALIZE_Response->Medium                = REMOTE_NDIS_MEDIUM_802_3;\r
+                       INITIALIZE_Response->MaxPacketsPerTransfer = 1;\r
+                       INITIALIZE_Response->MaxTransferSize       = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);\r
+                       INITIALIZE_Response->PacketAlignmentFactor = 0;\r
+                       INITIALIZE_Response->AFListOffset          = 0;\r
+                       INITIALIZE_Response->AFListSize            = 0;\r
+                       \r
+                       CurrRNDISState = RNDIS_Initialized;\r
+               \r
+                       break;\r
+               case REMOTE_NDIS_HALT_MSG:\r
+                       /* Halt the adapter, reset the adapter state - note that no response should be returned when completed */\r
+\r
+                       ResponseReady = false;\r
+                       MessageHeader->MessageLength = 0;\r
+\r
+                       CurrRNDISState = RNDIS_Uninitialized;\r
+\r
+                       break;\r
+               case REMOTE_NDIS_QUERY_MSG:\r
+                       /* Request for information about a parameter about the adapter, specified as an OID token */\r
+\r
+                       ResponseReady = true;\r
+                                               \r
+                       RNDIS_QUERY_MSG_t*   QUERY_Message  = (RNDIS_QUERY_MSG_t*)&RNDISMessageBuffer;\r
+                       RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISMessageBuffer;\r
+                       uint32_t             Query_Oid      = QUERY_Message->Oid;\r
+                                               \r
+                       void*     QueryData                 = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
+                                                                                 QUERY_Message->InformationBufferOffset];\r
+                       void*     ResponseData              = &RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];         \r
+                       uint16_t  ResponseSize;\r
+\r
+                       QUERY_Response->MessageType         = REMOTE_NDIS_QUERY_CMPLT;\r
+                       QUERY_Response->MessageLength       = sizeof(RNDIS_QUERY_CMPLT_t);\r
+                                               \r
+                       if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,\r
+                                            ResponseData, &ResponseSize))\r
+                       {\r
+                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_SUCCESS;\r
+                               QUERY_Response->MessageLength          += ResponseSize;\r
+                                                       \r
+                               QUERY_Response->InformationBufferLength = ResponseSize;\r
+                               QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));\r
+                       }\r
+                       else\r
+                       {                               \r
+                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
+\r
+                               QUERY_Response->InformationBufferLength = 0;\r
+                               QUERY_Response->InformationBufferOffset = 0;\r
+                       }\r
+                       \r
+                       break;\r
+               case REMOTE_NDIS_SET_MSG:\r
+                       /* Request to set a parameter of the adapter, specified as an OID token */\r
+               \r
+                       ResponseReady = true;\r
+                       \r
+                       RNDIS_SET_MSG_t*   SET_Message  = (RNDIS_SET_MSG_t*)&RNDISMessageBuffer;\r
+                       RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISMessageBuffer;\r
+                       uint32_t           SET_Oid      = SET_Message->Oid;\r
+\r
+                       SET_Response->MessageType       = REMOTE_NDIS_SET_CMPLT;\r
+                       SET_Response->MessageLength     = sizeof(RNDIS_SET_CMPLT_t);\r
+                       SET_Response->RequestId         = SET_Message->RequestId;\r
+\r
+                       void* SetData                   = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
+                                                                             SET_Message->InformationBufferOffset];\r
+                                               \r
+                       if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))\r
+                         SET_Response->Status        = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       else\r
+                         SET_Response->Status        = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
+\r
+                       break;\r
+               case REMOTE_NDIS_RESET_MSG:\r
+                       /* Soft reset the adapter */\r
+               \r
+                       ResponseReady = true;\r
+                       \r
+                       RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;\r
+\r
+                       RESET_Response->MessageType         = REMOTE_NDIS_RESET_CMPLT;\r
+                       RESET_Response->MessageLength       = sizeof(RNDIS_RESET_CMPLT_t);\r
+                       RESET_Response->Status              = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       RESET_Response->AddressingReset     = 0;\r
+\r
+                       break;\r
+               case REMOTE_NDIS_KEEPALIVE_MSG:\r
+                       /* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */\r
+               \r
+                       ResponseReady = true;\r
+                       \r
+                       RNDIS_KEEPALIVE_MSG_t*   KEEPALIVE_Message  = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;\r
+                       RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;\r
+\r
+                       KEEPALIVE_Response->MessageType     = REMOTE_NDIS_KEEPALIVE_CMPLT;\r
+                       KEEPALIVE_Response->MessageLength   = sizeof(RNDIS_KEEPALIVE_CMPLT_t);\r
+                       KEEPALIVE_Response->RequestId       = KEEPALIVE_Message->RequestId;\r
+                       KEEPALIVE_Response->Status          = REMOTE_NDIS_STATUS_SUCCESS;\r
+                       \r
+                       break;\r
+       }\r
+}\r
+\r
+/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested\r
+ *  parameter is given as an OID value.\r
+ *\r
+ *  \param OId           OId value of the parameter being queried\r
+ *  \param QueryData     Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer\r
+ *  \param QuerySize     Size in bytes of the extra query data being sent by the host\r
+ *  \param ResponseData  Pointer to the start of the query response inside the RNDIS message buffer\r
+ *  \param ResponseSize  Pointer to the size in bytes of the response data being sent to the host\r
+ *\r
+ *  \return Boolean true if the query was handled, false otherwise\r
+ */\r
+static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,\r
+                             void* ResponseData, uint16_t* ResponseSize)\r
+{\r
+       /* Handler for REMOTE_NDIS_QUERY_MSG messages */\r
+\r
+       switch (OId)\r
+       {\r
+               case OID_GEN_SUPPORTED_LIST:\r
+                       *ResponseSize = sizeof(AdapterSupportedOIDList);\r
+                       \r
+                       /* Copy the list of supported NDIS OID tokens to the response buffer */\r
+                       memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));\r
+                       \r
+                       return true;\r
+               case OID_GEN_PHYSICAL_MEDIUM:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate that the device is a true ethernet link */\r
+                       *((uint32_t*)ResponseData) = 0;\r
+                       \r
+                       return true;\r
+               case OID_GEN_HARDWARE_STATUS:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Always indicate hardware ready */\r
+                       *((uint32_t*)ResponseData) = NdisHardwareStatusReady;\r
+                       \r
+                       return true;\r
+               case OID_GEN_MEDIA_SUPPORTED:\r
+               case OID_GEN_MEDIA_IN_USE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate 802.3 (Ethernet) supported by the adapter */\r
+                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;\r
+                       \r
+                       return true;\r
+               case OID_GEN_VENDOR_ID:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */\r
+                       *((uint32_t*)ResponseData) = 0x00FFFFFF;\r
+                       \r
+                       return true;\r
+               case OID_GEN_MAXIMUM_FRAME_SIZE:\r
+               case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
+               case OID_GEN_RECEIVE_BLOCK_SIZE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate that the maximum frame size is the size of the ethernet frame buffer */\r
+                       *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;\r
+                       \r
+                       return true;\r
+               case OID_GEN_VENDOR_DESCRIPTION:\r
+                       *ResponseSize = sizeof(AdapterVendorDescription);\r
+                       \r
+                       /* Copy vendor description string to the response buffer */\r
+                       memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));\r
+                       \r
+                       return true;\r
+               case OID_GEN_MEDIA_CONNECT_STATUS:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Always indicate that the adapter is connected to a network */\r
+                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;\r
+                       \r
+                       return true;\r
+               case OID_GEN_LINK_SPEED:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate 10Mb/s link speed */\r
+                       *((uint32_t*)ResponseData) = 100000;\r
+\r
+                       return true;\r
+               case OID_802_3_PERMANENT_ADDRESS:\r
+               case OID_802_3_CURRENT_ADDRESS:\r
+                       *ResponseSize = sizeof(MAC_Address_t);\r
+                       \r
+                       /* Copy over the fixed adapter MAC to the response buffer */\r
+                       memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));\r
+\r
+                       return true;\r
+               case OID_802_3_MAXIMUM_LIST_SIZE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate only one multicast address supported */\r
+                       *((uint32_t*)ResponseData) = 1;\r
+               \r
+                       return true;\r
+               case OID_GEN_CURRENT_PACKET_FILTER:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate the current packet filter mask */\r
+                       *((uint32_t*)ResponseData) = CurrPacketFilter;\r
+               \r
+                       return true;                    \r
+               case OID_GEN_XMIT_OK:\r
+               case OID_GEN_RCV_OK:\r
+               case OID_GEN_XMIT_ERROR:\r
+               case OID_GEN_RCV_ERROR:\r
+               case OID_GEN_RCV_NO_BUFFER:\r
+               case OID_802_3_RCV_ERROR_ALIGNMENT:\r
+               case OID_802_3_XMIT_ONE_COLLISION:\r
+               case OID_802_3_XMIT_MORE_COLLISIONS:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Unused statistic OIDs - always return 0 for each */\r
+                       *((uint32_t*)ResponseData) = 0;\r
+               \r
+                       return true;\r
+               case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
+                       *ResponseSize = sizeof(uint32_t);\r
+                       \r
+                       /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */\r
+                       *((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);\r
+               \r
+                       return true;\r
+               default:\r
+                       return false;\r
+       }\r
+}\r
+\r
+/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given \r
+ *  as an OID value.\r
+ *\r
+ *  \param OId      OId value of the parameter being set\r
+ *  \param SetData  Pointer to the parameter value in the RNDIS message buffer\r
+ *  \param SetSize  Size in bytes of the parameter value being sent by the host\r
+ *\r
+ *  \return Boolean true if the set was handled, false otherwise\r
+ */\r
+static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)\r
+{\r
+       /* Handler for REMOTE_NDIS_SET_MSG messages */\r
+\r
+       switch (OId)\r
+       {\r
+               case OID_GEN_CURRENT_PACKET_FILTER:\r
+                       /* Save the packet filter mask in case the host queries it again later */\r
+                       CurrPacketFilter = *((uint32_t*)SetData);\r
+               \r
+                       /* Set the RNDIS state to initialized if the packet filter is non-zero */\r
+                       CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);\r
+                       \r
+                       return true;\r
+               case OID_802_3_MULTICAST_LIST:\r
+                       /* Do nothing - throw away the value from the host as it is unused */\r
+               \r
+                       return true;\r
+               default:\r
+                       return false;\r
+       }\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDIS.h b/Demos/Device/RNDISEthernet/Lib/RNDIS.h
new file mode 100644 (file)
index 0000000..88c9a9e
--- /dev/null
@@ -0,0 +1,226 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for RNDIS.c.\r
+ */\r
+\r
+#ifndef _RNDIS_H_\r
+#define _RNDIS_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <stdbool.h>\r
+               \r
+               #include "RNDISEthernet.h"\r
+               #include "RNDISConstants.h"\r
+               #include "Ethernet.h"\r
+\r
+       /* Macros: */\r
+               /** Physical MAC Address of the USB network adapter */\r
+               #define ADAPTER_MAC_ADDRESS                   {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}\r
+       \r
+               /** Implemented RNDIS Version Major */\r
+               #define REMOTE_NDIS_VERSION_MAJOR             0x01\r
+\r
+               /** Implemented RNDIS Version Minor */\r
+               #define REMOTE_NDIS_VERSION_MINOR             0x00\r
+       \r
+               /** RNDIS request to issue a host-to-device NDIS command */\r
+               #define REQ_SendEncapsulatedCommand           0x00\r
+\r
+               /** RNDIS request to issue a device-to-host NDIS response */\r
+               #define REQ_GetEncapsulatedResponse           0x01\r
+               \r
+       /* Enums: */\r
+               /** Enum for the possible NDIS adapter states. */\r
+               enum RNDIS_States_t\r
+               {\r
+                       RNDIS_Uninitialized    = 0, /**< Adapter currently uninitialized */\r
+                       RNDIS_Initialized      = 1, /**< Adapter currently initialized but not ready for data transfers */\r
+                       RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */\r
+               };\r
+\r
+               /** Enum for the NDIS hardware states */\r
+               enum NDIS_Hardware_Status_t\r
+               {\r
+                       NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */\r
+                       NdisHardwareStatusInitializing, /**< Hardware busy initializing */\r
+                       NdisHardwareStatusReset, /**< Hardware reset */\r
+                       NdisHardwareStatusClosing, /**< Hardware currently closing */\r
+                       NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */\r
+               };\r
+\r
+       /* Type Defines: */\r
+               /** Type define for a RNDIS message header, sent before RNDIS messages */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */\r
+                       uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */\r
+               } RNDIS_Message_Header_t;\r
+\r
+               /** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t DataOffset;\r
+                       uint32_t DataLength;\r
+                       uint32_t OOBDataOffset;\r
+                       uint32_t OOBDataLength;\r
+                       uint32_t NumOOBDataElements;\r
+                       uint32_t PerPacketInfoOffset;\r
+                       uint32_t PerPacketInfoLength;\r
+                       uint32_t VcHandle;\r
+                       uint32_t Reserved;\r
+               } RNDIS_PACKET_MSG_t;\r
+       \r
+               /** Type define for a RNDIS Initialize command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       \r
+                       uint32_t MajorVersion;\r
+                       uint32_t MinorVersion;\r
+                       uint32_t MaxTransferSize;\r
+               } RNDIS_INITIALIZE_MSG_t;\r
+               \r
+               /** Type define for a RNDIS Initialize complete response message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+                       \r
+                       uint32_t MajorVersion;\r
+                       uint32_t MinorVersion;\r
+                       uint32_t DeviceFlags;\r
+                       uint32_t Medium;\r
+                       uint32_t MaxPacketsPerTransfer;\r
+                       uint32_t MaxTransferSize;\r
+                       uint32_t PacketAlignmentFactor;\r
+                       uint32_t AFListOffset;\r
+                       uint32_t AFListSize;\r
+               } RNDIS_INITIALIZE_CMPLT_t;\r
+               \r
+               /** Type define for a RNDIS Keepalive command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+               } RNDIS_KEEPALIVE_MSG_t;\r
+\r
+               /** Type define for a RNDIS Keepalive complete message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+               } RNDIS_KEEPALIVE_CMPLT_t;\r
+\r
+               /** Type define for a RNDIS Reset complete message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t Status;\r
+\r
+                       uint32_t AddressingReset;\r
+               } RNDIS_RESET_CMPLT_t;\r
+               \r
+               /** Type define for a RNDIS Set command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       \r
+                       uint32_t Oid;\r
+                       uint32_t InformationBufferLength;\r
+                       uint32_t InformationBufferOffset;\r
+                       uint32_t DeviceVcHandle;\r
+               } RNDIS_SET_MSG_t;\r
+\r
+               /** Type define for a RNDIS Set complete response message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+               } RNDIS_SET_CMPLT_t;\r
+               \r
+               /** Type define for a RNDIS Query command message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       \r
+                       uint32_t Oid;\r
+                       uint32_t InformationBufferLength;\r
+                       uint32_t InformationBufferOffset;\r
+                       uint32_t DeviceVcHandle;\r
+               } RNDIS_QUERY_MSG_t;\r
+               \r
+               /** Type define for a RNDIS Query complete response message */\r
+               typedef struct\r
+               {\r
+                       uint32_t MessageType;\r
+                       uint32_t MessageLength;\r
+                       uint32_t RequestId;\r
+                       uint32_t Status;\r
+                       \r
+                       uint32_t InformationBufferLength;\r
+                       uint32_t InformationBufferOffset;\r
+               } RNDIS_QUERY_CMPLT_t;\r
+               \r
+       /* External Variables: */\r
+               extern uint8_t                 RNDISMessageBuffer[];\r
+               extern RNDIS_Message_Header_t* MessageHeader;\r
+               extern bool                    ResponseReady;\r
+               extern uint8_t                 CurrRNDISState;\r
+\r
+       /* Function Prototypes: */\r
+               void ProcessRNDISControlMessage(void);\r
+\r
+               #if defined(INCLUDE_FROM_RNDIS_C)\r
+                       static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,\r
+                                                                                void* ResponseData, uint16_t* ResponseSize);\r
+                       static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);      \r
+               #endif\r
+               \r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h b/Demos/Device/RNDISEthernet/Lib/RNDISConstants.h
new file mode 100644 (file)
index 0000000..ad66f62
--- /dev/null
@@ -0,0 +1,99 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  RNDIS specification related constants. For more information on these\r
+ *  constants, please refer to the Microsoft RNDIS specification.\r
+ */\r
\r
+#ifndef _RNDIS_CONSTANTS_H_\r
+#define _RNDIS_CONSTANTS_H_\r
+\r
+       /* Macros: */\r
+               #define REMOTE_NDIS_PACKET_MSG                0x00000001UL\r
+               #define REMOTE_NDIS_INITIALIZE_MSG            0x00000002UL\r
+               #define REMOTE_NDIS_HALT_MSG                  0x00000003UL\r
+               #define REMOTE_NDIS_QUERY_MSG                 0x00000004UL\r
+               #define REMOTE_NDIS_SET_MSG                   0x00000005UL\r
+               #define REMOTE_NDIS_RESET_MSG                 0x00000006UL\r
+               #define REMOTE_NDIS_INDICATE_STATUS_MSG       0x00000007UL\r
+               #define REMOTE_NDIS_KEEPALIVE_MSG             0x00000008UL\r
+\r
+               #define REMOTE_NDIS_INITIALIZE_CMPLT          0x80000002UL\r
+               #define REMOTE_NDIS_QUERY_CMPLT               0x80000004UL\r
+               #define REMOTE_NDIS_SET_CMPLT                 0x80000005UL\r
+               #define REMOTE_NDIS_RESET_CMPLT               0x80000006UL\r
+               #define REMOTE_NDIS_KEEPALIVE_CMPLT           0x80000008UL\r
+               \r
+               #define REMOTE_NDIS_STATUS_SUCCESS            0x00000000UL\r
+               #define REMOTE_NDIS_STATUS_FAILURE            0xC0000001UL\r
+               #define REMOTE_NDIS_STATUS_INVALID_DATA       0xC0010015UL\r
+               #define REMOTE_NDIS_STATUS_NOT_SUPPORTED      0xC00000BBUL\r
+               #define REMOTE_NDIS_STATUS_MEDIA_CONNECT      0x4001000BUL\r
+               #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT   0x4001000CUL\r
+               \r
+               #define REMOTE_NDIS_MEDIA_STATE_CONNECTED     0x00000000UL\r
+               #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED  0x00000001UL\r
+               \r
+               #define REMOTE_NDIS_MEDIUM_802_3              0x00000000UL\r
+               \r
+               #define REMOTE_NDIS_DF_CONNECTIONLESS         0x00000001UL\r
+               #define REMOTE_NDIS_DF_CONNECTION_ORIENTED    0x00000002UL\r
+               \r
+               #define OID_GEN_SUPPORTED_LIST                0x00010101UL\r
+               #define OID_GEN_HARDWARE_STATUS               0x00010102UL\r
+               #define OID_GEN_MEDIA_SUPPORTED               0x00010103UL\r
+               #define OID_GEN_MEDIA_IN_USE                  0x00010104UL\r
+               #define OID_GEN_MAXIMUM_FRAME_SIZE            0x00010106UL\r
+               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
+               #define OID_GEN_LINK_SPEED                    0x00010107UL\r
+               #define OID_GEN_TRANSMIT_BLOCK_SIZE           0x0001010AUL\r
+               #define OID_GEN_RECEIVE_BLOCK_SIZE            0x0001010BUL\r
+               #define OID_GEN_VENDOR_ID                     0x0001010CUL\r
+               #define OID_GEN_VENDOR_DESCRIPTION            0x0001010DUL\r
+               #define OID_GEN_CURRENT_PACKET_FILTER         0x0001010EUL\r
+               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
+               #define OID_GEN_MEDIA_CONNECT_STATUS          0x00010114UL\r
+               #define OID_GEN_PHYSICAL_MEDIUM               0x00010202UL\r
+               #define OID_GEN_XMIT_OK                       0x00020101UL\r
+               #define OID_GEN_RCV_OK                        0x00020102UL\r
+               #define OID_GEN_XMIT_ERROR                    0x00020103UL\r
+               #define OID_GEN_RCV_ERROR                     0x00020104UL\r
+               #define OID_GEN_RCV_NO_BUFFER                 0x00020105UL\r
+               #define OID_802_3_PERMANENT_ADDRESS           0x01010101UL\r
+               #define OID_802_3_CURRENT_ADDRESS             0x01010102UL\r
+               #define OID_802_3_MULTICAST_LIST              0x01010103UL\r
+               #define OID_802_3_MAXIMUM_LIST_SIZE           0x01010104UL\r
+               #define OID_802_3_RCV_ERROR_ALIGNMENT         0x01020101UL\r
+               #define OID_802_3_XMIT_ONE_COLLISION          0x01020102UL\r
+               #define OID_802_3_XMIT_MORE_COLLISIONS        0x01020103UL\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/TCP.c b/Demos/Device/RNDISEthernet/Lib/TCP.c
new file mode 100644 (file)
index 0000000..f259aad
--- /dev/null
@@ -0,0 +1,614 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Transmission Control Protocol (TCP) packet handling routines. This protocol handles the reliable in-order transmission\r
+ *  and reception of packets to and from devices on a network, to "ports" on the device. It is used in situations where data\r
+ *  delivery must be reliable and correct, e.g. HTTP, TELNET and most other non-streaming protocols.\r
+ */\r
\r
+#define  INCLUDE_FROM_TCP_C\r
+#include "TCP.h"\r
+\r
+/* Global Variables: */\r
+/** Port state table array. This contains the current status of TCP ports in the device. To save on space, only open ports are\r
+ *  stored - closed ports may be overwritten at any time, and the system will assume any ports not present in the array are closed. This\r
+ *  allows for MAX_OPEN_TCP_PORTS to be less than the number of ports used by the application if desired.\r
+ */\r
+TCP_PortState_t        PortStateTable[MAX_OPEN_TCP_PORTS];\r
+\r
+/** Connection state table array. This contains the current status of TCP connections in the device. To save on space, only active\r
+ *  (non-closed) connections are stored - closed connections may be overwritten at any time, and the system will assume any connections\r
+ *  not present in the array are closed.\r
+ */\r
+TCP_ConnectionState_t  ConnectionStateTable[MAX_TCP_CONNECTIONS];\r
+\r
+\r
+/** Task to handle the calling of each registered application's callback function, to process and generate TCP packets at the application\r
+ *  level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT\r
+ *  buffer for later transmission.\r
+ */\r
+TASK(TCP_Task)\r
+{\r
+       /* Task to hand off TCP packets to and from the listening applications. */\r
+\r
+       /* Run each application in sequence, to process incoming and generate outgoing packets */\r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+       {\r
+               /* Find the corresponding port entry in the port table */\r
+               for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
+               {\r
+                       /* Run the application handler for the port */\r
+                       if ((PortStateTable[PTableEntry].Port  == ConnectionStateTable[CSTableEntry].Port) && \r
+                           (PortStateTable[PTableEntry].State == TCP_Port_Open))\r
+                       {\r
+                               PortStateTable[PTableEntry].ApplicationHandler(&ConnectionStateTable[CSTableEntry], &ConnectionStateTable[CSTableEntry].Info.Buffer);\r
+                       }\r
+               }\r
+       }\r
+       \r
+       /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */\r
+       if (FrameOUT.FrameInBuffer)\r
+         return;\r
+       \r
+       /* Send response packets from each application as the TCP packet buffers are filled by the applications */\r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+       {\r
+               /* For each completely received packet, pass it along to the listening application */\r
+               if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&\r
+                   (ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))\r
+               {\r
+                       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
+                       IP_Header_t*             IPHeaderOUT    = (IP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];\r
+                       TCP_Header_t*            TCPHeaderOUT   = (TCP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
+                                                                                                    sizeof(IP_Header_t)];                                              \r
+                       void*                    TCPDataOUT     = &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
+                                                                                     sizeof(IP_Header_t) +\r
+                                                                                     sizeof(TCP_Header_t)];\r
+\r
+                       uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;\r
+\r
+                       /* Fill out the TCP data */\r
+                       TCPHeaderOUT->SourcePort           = ConnectionStateTable[CSTableEntry].Port;\r
+                       TCPHeaderOUT->DestinationPort      = ConnectionStateTable[CSTableEntry].RemotePort;\r
+                       TCPHeaderOUT->SequenceNumber       = SwapEndian_32(ConnectionStateTable[CSTableEntry].Info.SequenceNumberOut);\r
+                       TCPHeaderOUT->AcknowledgmentNumber = SwapEndian_32(ConnectionStateTable[CSTableEntry].Info.SequenceNumberIn);\r
+                       TCPHeaderOUT->DataOffset           = (sizeof(TCP_Header_t) / sizeof(uint32_t));\r
+                       TCPHeaderOUT->WindowSize           = SwapEndian_16(TCP_WINDOW_SIZE);\r
+\r
+                       TCPHeaderOUT->Flags                = TCP_FLAG_ACK;\r
+                       TCPHeaderOUT->UrgentPointer        = 0;\r
+                       TCPHeaderOUT->Checksum             = 0;\r
+                       TCPHeaderOUT->Reserved             = 0;\r
+\r
+                       memcpy(TCPDataOUT, ConnectionStateTable[CSTableEntry].Info.Buffer.Data, PacketSize);\r
+                       \r
+                       ConnectionStateTable[CSTableEntry].Info.SequenceNumberOut += PacketSize;\r
+\r
+                       TCPHeaderOUT->Checksum             = TCP_Checksum16(TCPHeaderOUT, ServerIPAddress,\r
+                                                                           ConnectionStateTable[CSTableEntry].RemoteAddress,\r
+                                                                           (sizeof(TCP_Header_t) + PacketSize));\r
+\r
+                       PacketSize += sizeof(TCP_Header_t);\r
+\r
+                       /* Fill out the response IP header */\r
+                       IPHeaderOUT->TotalLength        = SwapEndian_16(sizeof(IP_Header_t) + PacketSize);\r
+                       IPHeaderOUT->TypeOfService      = 0;\r
+                       IPHeaderOUT->HeaderLength       = (sizeof(IP_Header_t) / sizeof(uint32_t));\r
+                       IPHeaderOUT->Version            = 4;\r
+                       IPHeaderOUT->Flags              = 0;\r
+                       IPHeaderOUT->FragmentOffset     = 0;\r
+                       IPHeaderOUT->Identification     = 0;\r
+                       IPHeaderOUT->HeaderChecksum     = 0;\r
+                       IPHeaderOUT->Protocol           = PROTOCOL_TCP;\r
+                       IPHeaderOUT->TTL                = DEFAULT_TTL;\r
+                       IPHeaderOUT->SourceAddress      = ServerIPAddress;\r
+                       IPHeaderOUT->DestinationAddress = ConnectionStateTable[CSTableEntry].RemoteAddress;\r
+                       \r
+                       IPHeaderOUT->HeaderChecksum     = Ethernet_Checksum16(IPHeaderOUT, sizeof(IP_Header_t));\r
+               \r
+                       PacketSize += sizeof(IP_Header_t);\r
+               \r
+                       /* Fill out the response Ethernet frame header */\r
+                       FrameOUTHeader->Source          = ServerMACAddress;\r
+                       FrameOUTHeader->Destination     = (MAC_Address_t){{0x02, 0x00, 0x02, 0x00, 0x02, 0x00}};\r
+                       FrameOUTHeader->EtherType       = SwapEndian_16(ETHERTYPE_IPV4);\r
+\r
+                       PacketSize += sizeof(Ethernet_Frame_Header_t);\r
+\r
+                       /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
+                       FrameOUT.FrameLength            = PacketSize;\r
+                       FrameOUT.FrameInBuffer          = true;\r
+                       \r
+                       ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;\r
+                       \r
+                       break;\r
+               }\r
+       }\r
+}\r
+\r
+/** Initializes the TCP protocol handler, clearing the port and connection state tables. This must be called before TCP packets are\r
+ *  processed.\r
+ */\r
+void TCP_Init(void)\r
+{\r
+       /* Initialize the port state table with all CLOSED entries */\r
+       for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++)\r
+         PortStateTable[PTableEntry].State = TCP_Port_Closed;\r
+\r
+       /* Initialize the connection table with all CLOSED entries */\r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+         ConnectionStateTable[CSTableEntry].State = TCP_Connection_Closed;\r
+}\r
+\r
+/** Sets the state and callback handler of the given port, specified in big endian to the given state.\r
+ *\r
+ *  \param Port     Port whose state and callback function to set, specified in big endian\r
+ *  \param State    New state of the port, a value from the TCP_PortStates_t enum\r
+ *  \param Handler  Application callback handler for the port\r
+ *\r
+ *  \return Boolean true if the port state was set, false otherwise (no more space in the port state table)\r
+ */\r
+bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*))\r
+{\r
+       /* Note, Port number should be specified in BIG endian to simplify network code */\r
+\r
+       /* Check to see if the port entry is already in the port state table */\r
+       for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
+       {\r
+               /* Find existing entry for the port in the table, update it if found */\r
+               if (PortStateTable[PTableEntry].Port == Port)\r
+               {\r
+                       PortStateTable[PTableEntry].State = State;\r
+                       PortStateTable[PTableEntry].ApplicationHandler = Handler;\r
+                       return true;\r
+               }\r
+       }\r
+\r
+       /* Check if trying to open the port -- if so we need to find an unused (closed) entry and replace it */\r
+       if (State == TCP_Port_Open)\r
+       {\r
+               for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
+               {\r
+                       /* Find a closed port entry in the table, change it to the given port and state */\r
+                       if (PortStateTable[PTableEntry].State == TCP_Port_Closed)\r
+                       {\r
+                               PortStateTable[PTableEntry].Port  = Port;\r
+                               PortStateTable[PTableEntry].State = State;\r
+                               PortStateTable[PTableEntry].ApplicationHandler = Handler;\r
+                               return true;\r
+                       }\r
+               }\r
+               \r
+               /* Port not in table and no room to add it, return failure */\r
+               return false;\r
+       }\r
+       else\r
+       {\r
+               /* Port not in table but trying to close it, so operation successful */\r
+               return true;\r
+       }\r
+}\r
+\r
+/** Retrieves the current state of a given TCP port, specified in big endian.\r
+ *\r
+ *  \param Port  TCP port whose state is to be retrieved, given in big-endian\r
+ *\r
+ *  \return A value from the TCP_PortStates_t enum\r
+ */\r
+uint8_t TCP_GetPortState(uint16_t Port)\r
+{\r
+       /* Note, Port number should be specified in BIG endian to simplify network code */\r
+\r
+       for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
+       {\r
+               /* Find existing entry for the port in the table, return the port status if found */\r
+               if (PortStateTable[PTableEntry].Port == Port)\r
+                 return PortStateTable[PTableEntry].State;\r
+       }\r
+       \r
+       /* Port not in table, assume closed */\r
+       return TCP_Port_Closed;\r
+}\r
+\r
+/** Sets the connection state of the given port, remote address and remote port to the given TCP connection state. If the\r
+ *  connection exists in the connection state table it is updated, otherwise it is created if possible.\r
+ *\r
+ *  \param Port           TCP port of the connection on the device, specified in big endian\r
+ *  \param RemoteAddress  Remote protocol IP address of the connected device\r
+ *  \param RemotePort     TCP port of the remote device in the connection, specified in big endian\r
+ *  \param State          TCP connection state, a value from the TCP_ConnectionStates_t enum\r
+ *\r
+ *  \return Boolean true if the connection was updated or created, false otherwise (no more space in the connection state table)\r
+ */\r
+bool TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort, uint8_t State)\r
+{\r
+       /* Note, Port number should be specified in BIG endian to simplify network code */\r
+\r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+       {\r
+               /* Find port entry in the table */\r
+               if ((ConnectionStateTable[CSTableEntry].Port == Port) &&\r
+                    IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) &&\r
+                        ConnectionStateTable[CSTableEntry].RemotePort == RemotePort)\r
+               {\r
+                       ConnectionStateTable[CSTableEntry].State = State;\r
+                       return true;\r
+               }\r
+       }\r
+       \r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+       {\r
+               /* Find empty entry in the table */\r
+               if (ConnectionStateTable[CSTableEntry].State == TCP_Connection_Closed)\r
+               {\r
+                       ConnectionStateTable[CSTableEntry].Port          = Port;\r
+                       ConnectionStateTable[CSTableEntry].RemoteAddress = RemoteAddress;                       \r
+                       ConnectionStateTable[CSTableEntry].RemotePort    = RemotePort;\r
+                       ConnectionStateTable[CSTableEntry].State         = State;\r
+                       return true;\r
+               }\r
+       }\r
+       \r
+       return false;\r
+}\r
+\r
+/** Retrieves the current state of a given TCP connection to a host.\r
+ *\r
+ *  \param Port           TCP port on the device in the connection, specified in big endian\r
+ *  \param RemoteAddress  Remote protocol IP address of the connected host\r
+ *  \param RemotePort     Remote TCP port of the connected host, specified in big endian\r
+ *\r
+ *  \return A value from the TCP_ConnectionStates_t enum\r
+ */\r
+uint8_t TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort)\r
+{\r
+       /* Note, Port number should be specified in BIG endian to simplify network code */\r
+\r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+       {\r
+               /* Find port entry in the table */\r
+               if ((ConnectionStateTable[CSTableEntry].Port == Port) &&\r
+                    IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) &&\r
+                        ConnectionStateTable[CSTableEntry].RemotePort == RemotePort)\r
+                        \r
+               {\r
+                       return ConnectionStateTable[CSTableEntry].State;\r
+               }\r
+       }\r
+       \r
+       return TCP_Connection_Closed;\r
+}\r
+\r
+/** Retrieves the connection info structure of a given connection to a host.\r
+ *\r
+ *  \param Port           TCP port on the device in the connection, specified in big endian\r
+ *  \param RemoteAddress  Remote protocol IP address of the connected host\r
+ *  \param RemotePort     Remote TCP port of the connected host, specified in big endian\r
+ *\r
+ *  \return ConnectionInfo structure of the connection if found, NULL otherwise\r
+ */\r
+TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort)\r
+{\r
+       /* Note, Port number should be specified in BIG endian to simplify network code */\r
+\r
+       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
+       {\r
+               /* Find port entry in the table */\r
+               if ((ConnectionStateTable[CSTableEntry].Port == Port) &&\r
+                    IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) &&\r
+                        ConnectionStateTable[CSTableEntry].RemotePort == RemotePort)\r
+               {\r
+                       return &ConnectionStateTable[CSTableEntry].Info;\r
+               }\r
+       }\r
+       \r
+       return NULL;\r
+}\r
+\r
+/** Processes a TCP packet inside an Ethernet frame, and writes the appropriate response\r
+ *  to the output Ethernet frame if one is created by a application handler.\r
+ *\r
+ *  \param IPHeaderInStart    Pointer to the start of the incoming packet's IP header\r
+ *  \param TCPHeaderInStart   Pointer to the start of the incoming packet's TCP header\r
+ *  \param TCPHeaderOutStart  Pointer to the start of the outgoing packet's TCP header\r
+ *\r
+ *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no\r
+ *           response was generated, NO_PROCESS if the packet processing was deferred until the\r
+ *           next Ethernet packet handler iteration\r
+ */\r
+int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void* TCPHeaderOutStart)\r
+{\r
+       IP_Header_t*  IPHeaderIN   = (IP_Header_t*)IPHeaderInStart;\r
+       TCP_Header_t* TCPHeaderIN  = (TCP_Header_t*)TCPHeaderInStart;\r
+       TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)TCPHeaderOutStart;\r
+\r
+       TCP_ConnectionInfo_t* ConnectionInfo;\r
+       \r
+       DecodeTCPHeader(TCPHeaderInStart);\r
+\r
+       bool PacketResponse = false;\r
+               \r
+       /* Check if the destination port is open and allows incoming connections */\r
+       if (TCP_GetPortState(TCPHeaderIN->DestinationPort) == TCP_Port_Open)\r
+       {\r
+               /* Detect SYN from host to start a connection */\r
+               if (TCPHeaderIN->Flags & TCP_FLAG_SYN)\r
+                 TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Listen);\r
+\r
+               /* Detect RST from host to abort existing connection */\r
+               if (TCPHeaderIN->Flags & TCP_FLAG_RST)\r
+               {\r
+                       TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK);                            \r
+                       PacketResponse = true;\r
+                       \r
+                       TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                              TCPHeaderIN->SourcePort, TCP_Connection_Closed);                 \r
+               }\r
+               else\r
+               {\r
+                       /* Process the incoming TCP packet based on the current connection state for the sender and port */\r
+                       switch (TCP_GetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort))\r
+                       {\r
+                               case TCP_Connection_Listen:\r
+                                       if (TCPHeaderIN->Flags == TCP_FLAG_SYN)\r
+                                       {\r
+                                               /* SYN connection when closed starts a connection with a peer */\r
+\r
+                                               TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK);                            \r
+                                               PacketResponse      = true;\r
+                                                                       \r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort,\r
+                                                                                          TCP_Connection_SYNReceived);\r
+                                                                                          \r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort);\r
+\r
+                                               ConnectionInfo->SequenceNumberIn  = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1);\r
+                                               ConnectionInfo->SequenceNumberOut = 0;\r
+                                               ConnectionInfo->Buffer.InUse      = false;\r
+                                       }\r
+                                       \r
+                                       break;\r
+                               case TCP_Connection_SYNReceived:\r
+                                       if (TCPHeaderIN->Flags == TCP_FLAG_ACK)\r
+                                       {\r
+                                               /* ACK during the connection process completes the connection to a peer */\r
+\r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Established);\r
+\r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                                                          TCPHeaderIN->SourcePort);\r
+                                                                                                                          \r
+                                               ConnectionInfo->SequenceNumberOut++;\r
+                                       }\r
+                                       \r
+                                       break;\r
+                               case TCP_Connection_Established:\r
+                                       if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK))\r
+                                       {\r
+                                               /* FIN ACK when connected to a peer starts the finalization process */\r
+                                       \r
+                                               TCPHeaderOUT->Flags = (TCP_FLAG_FIN | TCP_FLAG_ACK);                            \r
+                                               PacketResponse      = true;\r
+                                               \r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_CloseWait);\r
+\r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                                                          TCPHeaderIN->SourcePort);\r
+\r
+                                               ConnectionInfo->SequenceNumberIn++;\r
+                                               ConnectionInfo->SequenceNumberOut++;\r
+                                       }\r
+                                       else if ((TCPHeaderIN->Flags == TCP_FLAG_ACK) || (TCPHeaderIN->Flags == (TCP_FLAG_ACK | TCP_FLAG_PSH)))\r
+                                       {\r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                                                          TCPHeaderIN->SourcePort);\r
+\r
+                                               /* Check if the buffer is currently in use either by a buffered data to send, or receive */             \r
+                                               if ((ConnectionInfo->Buffer.InUse == false) && (ConnectionInfo->Buffer.Ready == false))\r
+                                               {                                               \r
+                                                       ConnectionInfo->Buffer.Direction = TCP_PACKETDIR_IN;\r
+                                                       ConnectionInfo->Buffer.InUse     = true;\r
+                                                       ConnectionInfo->Buffer.Length    = 0;\r
+                                               }\r
+                                               \r
+                                               /* Check if the buffer has been claimed by us to read in data from the peer */\r
+                                               if ((ConnectionInfo->Buffer.Direction == TCP_PACKETDIR_IN) &&\r
+                                                       (ConnectionInfo->Buffer.Length != TCP_WINDOW_SIZE))\r
+                                               {\r
+                                                       uint16_t IPOffset   = (IPHeaderIN->HeaderLength * sizeof(uint32_t));\r
+                                                       uint16_t TCPOffset  = (TCPHeaderIN->DataOffset * sizeof(uint32_t));\r
+                                                       uint16_t DataLength = (SwapEndian_16(IPHeaderIN->TotalLength) - IPOffset - TCPOffset);\r
+\r
+                                                       /* Copy the packet data into the buffer */\r
+                                                       memcpy(&ConnectionInfo->Buffer.Data[ConnectionInfo->Buffer.Length],\r
+                                                                  &((uint8_t*)TCPHeaderInStart)[TCPOffset],\r
+                                                                  DataLength);\r
+\r
+                                                       ConnectionInfo->SequenceNumberIn += DataLength;\r
+                                                       ConnectionInfo->Buffer.Length    += DataLength;\r
+                                                       \r
+                                                       /* Check if the buffer is full or if the PSH flag is set, if so indicate buffer ready */\r
+                                                       if ((!(TCP_WINDOW_SIZE - ConnectionInfo->Buffer.Length)) || (TCPHeaderIN->Flags & TCP_FLAG_PSH))\r
+                                                       {\r
+                                                               ConnectionInfo->Buffer.InUse = false;\r
+                                                               ConnectionInfo->Buffer.Ready = true;\r
+\r
+                                                               TCPHeaderOUT->Flags = TCP_FLAG_ACK;\r
+                                                               PacketResponse      = true;\r
+                                                       }\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       /* Buffer is currently in use by the application, defer processing of the incoming packet */\r
+                                                       return NO_PROCESS;\r
+                                               }\r
+                                       }\r
+                                       \r
+                                       break;\r
+                               case TCP_Connection_Closing:\r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                                                          TCPHeaderIN->SourcePort);\r
+\r
+                                               TCPHeaderOUT->Flags = (TCP_FLAG_ACK | TCP_FLAG_FIN);\r
+                                               PacketResponse      = true;\r
+                                               \r
+                                               ConnectionInfo->Buffer.InUse = false;\r
+                                               \r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_FINWait1);\r
+\r
+                                       break;\r
+                               case TCP_Connection_FINWait1:\r
+                                       if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK))\r
+                                       {\r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                                                          TCPHeaderIN->SourcePort);\r
+\r
+                                               TCPHeaderOUT->Flags = TCP_FLAG_ACK;\r
+                                               PacketResponse      = true;\r
+\r
+                                               ConnectionInfo->SequenceNumberIn++;\r
+                                               ConnectionInfo->SequenceNumberOut++;\r
+                                               \r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Closed);\r
+                                       }\r
+                                       else if (TCPHeaderIN->Flags == TCP_FLAG_ACK)\r
+                                       {\r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_FINWait2);\r
+                                       }\r
+                                       \r
+                                       break;\r
+                               case TCP_Connection_FINWait2:\r
+                                       if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK))\r
+                                       {\r
+                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                                                          TCPHeaderIN->SourcePort);\r
+\r
+                                               TCPHeaderOUT->Flags = TCP_FLAG_ACK;\r
+                                               PacketResponse      = true;\r
+\r
+                                               ConnectionInfo->SequenceNumberIn++;\r
+                                               ConnectionInfo->SequenceNumberOut++;\r
+                                               \r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Closed);\r
+                                       }\r
+                               \r
+                                       break;\r
+                               case TCP_Connection_CloseWait:\r
+                                       if (TCPHeaderIN->Flags == TCP_FLAG_ACK)\r
+                                       {\r
+                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Closed);\r
+                                       }\r
+                                       \r
+                                       break;\r
+                       }\r
+               }\r
+       }\r
+       else\r
+       {\r
+               /* Port is not open, indicate via a RST/ACK response to the sender */\r
+               TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK);                            \r
+               PacketResponse      = true;\r
+       }\r
+       \r
+       /* Check if we need to respond to the sent packet */\r
+       if (PacketResponse)\r
+       {\r
+               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
+                                                      TCPHeaderIN->SourcePort);\r
+\r
+               TCPHeaderOUT->SourcePort           = TCPHeaderIN->DestinationPort;\r
+               TCPHeaderOUT->DestinationPort      = TCPHeaderIN->SourcePort;\r
+               TCPHeaderOUT->SequenceNumber       = SwapEndian_32(ConnectionInfo->SequenceNumberOut);\r
+               TCPHeaderOUT->AcknowledgmentNumber = SwapEndian_32(ConnectionInfo->SequenceNumberIn);\r
+               TCPHeaderOUT->DataOffset           = (sizeof(TCP_Header_t) / sizeof(uint32_t));\r
+               \r
+               if (!(ConnectionInfo->Buffer.InUse))\r
+                 TCPHeaderOUT->WindowSize         = SwapEndian_16(TCP_WINDOW_SIZE);\r
+               else\r
+                 TCPHeaderOUT->WindowSize         = SwapEndian_16(TCP_WINDOW_SIZE - ConnectionInfo->Buffer.Length);\r
+\r
+               TCPHeaderOUT->UrgentPointer        = 0;\r
+               TCPHeaderOUT->Checksum             = 0;\r
+               TCPHeaderOUT->Reserved             = 0;\r
+               \r
+               TCPHeaderOUT->Checksum             = TCP_Checksum16(TCPHeaderOUT, IPHeaderIN->DestinationAddress,\r
+                                                                   IPHeaderIN->SourceAddress, sizeof(TCP_Header_t));                                   \r
+\r
+               return sizeof(TCP_Header_t);    \r
+       }\r
+\r
+       return NO_RESPONSE;\r
+}\r
+\r
+/** Calculates the appropriate TCP checksum, consisting of the addition of the one's compliment of each word,\r
+ *  complimented.\r
+ *\r
+ *  \param TCPHeaderOutStart  Pointer to the start of the packet's outgoing TCP header\r
+ *  \param SourceAddress      Source protocol IP address of the outgoing IP header\r
+ *  \param SourceAddress      DestinationAddress protocol IP address of the outgoing IP header\r
+ *  \param TCPOutSize         Size in bytes of the TCP data header and payload\r
+ *\r
+ *  \return A 16-bit TCP checksum value\r
+ */\r
+static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddress,\r
+                               IP_Address_t DestinationAddress, uint16_t TCPOutSize)\r
+{\r
+       uint32_t Checksum = 0;\r
+       \r
+       /* TCP/IP checksums are the addition of the one's compliment of each word including the IP pseudo-header,\r
+          complimented */\r
+       \r
+       Checksum += ((uint16_t*)&SourceAddress)[0];\r
+       Checksum += ((uint16_t*)&SourceAddress)[1];\r
+       Checksum += ((uint16_t*)&DestinationAddress)[0];\r
+       Checksum += ((uint16_t*)&DestinationAddress)[1];\r
+       Checksum += SwapEndian_16(PROTOCOL_TCP);\r
+       Checksum += SwapEndian_16(TCPOutSize);\r
+\r
+       for (uint8_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++)\r
+         Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord];\r
+       \r
+       if (TCPOutSize & 0x01)\r
+         Checksum += (((uint16_t*)TCPHeaderOutStart)[TCPOutSize >> 1] & 0x00FF);\r
+         \r
+       while (Checksum & 0xFFFF0000)\r
+         Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));\r
+       \r
+       return ~Checksum;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/TCP.h b/Demos/Device/RNDISEthernet/Lib/TCP.h
new file mode 100644 (file)
index 0000000..d4b72a5
--- /dev/null
@@ -0,0 +1,253 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for TCP.c.\r
+ */\r
+\r
+#ifndef _TCP_H_\r
+#define _TCP_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <stdbool.h>\r
+               \r
+               #include <LUFA/Scheduler/Scheduler.h>\r
+               \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               #include "ProtocolDecoders.h"\r
+               \r
+       /* Macros: */\r
+               /** Maximum number of TCP ports which can be open at the one time */\r
+               #define MAX_OPEN_TCP_PORTS              1\r
+\r
+               /** Maximum number of TCP connections which can be sustained at the one time */\r
+               #define MAX_TCP_CONNECTIONS             1\r
+\r
+               /** TCP window size, giving the maximum number of bytes which can be buffered at the one time */\r
+               #define TCP_WINDOW_SIZE                 1024\r
+               \r
+               /** Port number for HTTP transmissions */\r
+               #define TCP_PORT_HTTP                   SwapEndian_16(80)\r
+               \r
+               /** Data direction indicator for a TCP application buffer, indicating data from host-to-device */\r
+               #define TCP_PACKETDIR_IN                false\r
+\r
+               /** Data direction indicator for a TCP application buffer, indicating data from device-to-host */\r
+               #define TCP_PACKETDIR_OUT               true\r
+               \r
+               /** Congestion Window Reduced TCP flag mask */\r
+               #define TCP_FLAG_CWR                    (1 << 7)\r
+\r
+               /** Explicit Congestion Notification TCP flag mask */\r
+               #define TCP_FLAG_ECE                    (1 << 6)\r
+\r
+               /** Urgent TCP flag mask */\r
+               #define TCP_FLAG_URG                    (1 << 5)\r
+\r
+               /** Data Acknowledge TCP flag mask */\r
+               #define TCP_FLAG_ACK                    (1 << 4)\r
+\r
+               /** Data Push TCP flag mask */\r
+               #define TCP_FLAG_PSH                    (1 << 3)\r
+\r
+               /** Reset TCP flag mask */\r
+               #define TCP_FLAG_RST                    (1 << 2)\r
+\r
+               /** Synchronize TCP flag mask */\r
+               #define TCP_FLAG_SYN                    (1 << 1)\r
+\r
+               /** Connection Finalize TCP flag mask */\r
+               #define TCP_FLAG_FIN                    (1 << 0)\r
+               \r
+               /** Application macro: Determines if the given application buffer contains a packet received from the host\r
+                *\r
+                *  \param Buffer  Application buffer to check\r
+                *\r
+                *  \return Boolean true if the buffer contains a packet from the host, false otherwise\r
+                */\r
+               #define TCP_APP_HAS_RECEIVED_PACKET(Buffer)  (Buffer->Ready && (Buffer->Direction == TCP_PACKETDIR_IN))\r
+\r
+               /** Application macro: Indicates if the application buffer is currently locked by the application for device-to-host transfers.\r
+                *\r
+                *  \param Buffer  Application buffer to check\r
+                *\r
+                *  \return Boolean true if the buffer has been captured by the application for device-to-host transmissions, false otherwise\r
+                */\r
+               #define TCP_APP_HAVE_CAPTURED_BUFFER(Buffer) (!(Buffer->Ready) && Buffer->InUse && \\r
+                                                             (Buffer->Direction == TCP_PACKETDIR_OUT))\r
+\r
+               /** Application macro: Indicates if the application can lock the buffer for multiple continued device-to-host transmissions.\r
+                *\r
+                *  \param Buffer  Application buffer to check\r
+                *\r
+                *  \return Boolean true if the buffer may be captured by the application for device-to-host transmissions, false otherwise\r
+                */\r
+               #define TCP_APP_CAN_CAPTURE_BUFFER(Buffer)   Buffer->InUse\r
+\r
+               /** Application macro: Captures the application buffer, locking it for device-to-host transmissions only. This should be\r
+                *  performed when the application needs to transmit several packets worth of data in succession with no interruptions from the host.\r
+                *\r
+                *  \note The application must check that the buffer can be locked first using TCP_APP_CAN_CAPTURE_BUFFER().\r
+                *\r
+                *  \param Buffer  Application buffer to lock\r
+                */\r
+               #define TCP_APP_CAPTURE_BUFFER(Buffer)       MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->InUse = true; }MACROE\r
+\r
+               /** Application macro: Releases a captured application buffer, allowing for host-to-device packets to be received.\r
+                *\r
+                *  \param Buffer  Application buffer to release\r
+                */\r
+               #define TCP_APP_RELEASE_BUFFER(Buffer)       MACROS{ Buffer->InUse = false; }MACROE\r
+\r
+               /** Application macro: Sends the contents of the given application buffer to the host.\r
+                *\r
+                *  \param Buffer  Application buffer to send\r
+                *  \param Len     Length of data contained in the buffer\r
+                */\r
+               #define TCP_APP_SEND_BUFFER(Buffer, Len)     MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->Length = Len; Buffer->Ready = true; }MACROE\r
+\r
+               /** Application macro: Clears the application buffer, ready for a packet to be written to it.\r
+                *\r
+                *  \param Buffer  Application buffer to clear\r
+                */\r
+               #define TCP_APP_CLEAR_BUFFER(Buffer)         MACROS{ Buffer->Ready = false; Buffer->Length = 0; }MACROE\r
+               \r
+               /** Application macro: Closes an open connection to a host.\r
+                *\r
+                *  \param Connection  Open TCP connection to close\r
+                */\r
+               #define TCP_APP_CLOSECONNECTION(Connection)  MACROS{ Connection->State = TCP_Connection_Closing;  }MACROE\r
+\r
+       /* Enums: */\r
+               /** Enum for possible TCP port states */\r
+               enum TCP_PortStates_t\r
+               {\r
+                       TCP_Port_Closed            = 0, /**< TCP port closed, no connections to a host may be made on this port. */\r
+                       TCP_Port_Open              = 1, /**< TCP port open, connections to a host may be made on this port. */\r
+               };\r
+       \r
+               /** Enum for possible TCP connection states */\r
+               enum TCP_ConnectionStates_t\r
+               {\r
+                       TCP_Connection_Listen      = 0, /**< Listening for a connection from a host */\r
+                       TCP_Connection_SYNSent     = 1, /**< Unused */\r
+                       TCP_Connection_SYNReceived = 2, /**< SYN received, waiting for ACK */\r
+                       TCP_Connection_Established = 3, /**< Connection established in both directions */\r
+                       TCP_Connection_FINWait1    = 4, /**< Closing, waiting for ACK */\r
+                       TCP_Connection_FINWait2    = 5, /**< Closing, waiting for FIN ACK */\r
+                       TCP_Connection_CloseWait   = 6, /**< Closing, waiting for ACK */\r
+                       TCP_Connection_Closing     = 7, /**< Unused */\r
+                       TCP_Connection_LastACK     = 8, /**< Unused */\r
+                       TCP_Connection_TimeWait    = 9, /**< Unused */\r
+                       TCP_Connection_Closed      = 10, /**< Connection closed in both directions */                   \r
+               };\r
+       \r
+       /* Type Defines: */\r
+               /** Type define for a TCP connection buffer structure, including size, data and direction */\r
+               typedef struct\r
+               {\r
+                       uint16_t               Length; /**< Length of data in the TCP application buffer */\r
+                       uint8_t                Data[TCP_WINDOW_SIZE]; /**< TCP application data buffer */\r
+                       bool                   Direction; /**< Buffer transmission direction, either TCP_PACKETDIR_IN  or TCP_PACKETDIR_OUT */\r
+                       bool                   Ready; /**< If data from host, indicates buffer ready to be read, otherwise indicates\r
+                                                      *   buffer ready to be sent to the host\r
+                                                      */\r
+                       bool                   InUse; /** Indicates if the buffer is locked to to the current direction, and cannot be changed */\r
+               } TCP_ConnectionBuffer_t;\r
+\r
+               /** Type define for a TCP connection information structure */\r
+               typedef struct\r
+               {\r
+                       uint32_t               SequenceNumberIn; /**< Current TCP sequence number for host-to-device */ \r
+                       uint32_t               SequenceNumberOut; /**< Current TCP sequence number for device-to-host */\r
+                       TCP_ConnectionBuffer_t Buffer; /**< Connection application data buffer */\r
+               } TCP_ConnectionInfo_t;\r
+\r
+               /** Type define for a complete TCP connection state */\r
+               typedef struct\r
+               {\r
+                       uint16_t               Port; /**< Connection port number on the device */\r
+                       uint16_t               RemotePort; /**< Connection port number on the host */\r
+                       IP_Address_t           RemoteAddress; /**< Connection protocol IP address of the host */\r
+                       TCP_ConnectionInfo_t   Info; /**< Connection information, including application buffer */\r
+                       uint8_t                State; /**< Current connection state, a value from the TCP_ConnectionStates_t enum */\r
+               } TCP_ConnectionState_t;\r
+\r
+               /** Type define for a TCP port state */\r
+               typedef struct\r
+               {\r
+                       uint16_t               Port; /**< TCP port number on the device */\r
+                       uint8_t                State; /**< Current port state, a value from the TCP_PortStates_t enum */\r
+                       void                   (*ApplicationHandler) (TCP_ConnectionState_t* ConnectionState,\r
+                                                                     TCP_ConnectionBuffer_t* Buffer); /**< Port application handler */\r
+               } TCP_PortState_t;\r
+\r
+               /** Type define for a TCP packet header */\r
+               typedef struct\r
+               {\r
+                       uint16_t               SourcePort; /**< Source port of the TCP packet */\r
+                       uint16_t               DestinationPort; /**< Destination port of the TCP packet */\r
+                       \r
+                       uint32_t               SequenceNumber; /**< Data sequence number of the packet */\r
+                       uint32_t               AcknowledgmentNumber; /**< Data acknowledgment number of the packet */\r
+                       \r
+                       unsigned char          Reserved : 4; /**< Reserved, must be all 0 */\r
+                       unsigned char          DataOffset : 4; /**< Offset of the data from the start of the header, in 4 byte chunks */\r
+                       uint8_t                Flags; /**< TCP packet flags */\r
+                       uint16_t               WindowSize; /**< Current data window size (bytes remaining in reception buffer) */\r
+                       \r
+                       uint16_t               Checksum; /**< TCP checksum */\r
+                       uint16_t               UrgentPointer; /**< Urgent data pointer */\r
+               } TCP_Header_t;\r
+\r
+       /* Tasks: */\r
+               TASK(TCP_Task);\r
+               \r
+       /* External Variables: */\r
+               TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];\r
+\r
+       /* Function Prototypes: */\r
+               void                  TCP_Init(void);\r
+               bool                  TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));\r
+               uint8_t               TCP_GetPortState(uint16_t Port);\r
+               bool                  TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort, uint8_t State);\r
+               uint8_t               TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);\r
+               TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);\r
+               int16_t               TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void* TCPHeaderOutStart);\r
+\r
+               #if defined(INCLUDE_FROM_TCP_C)\r
+                       static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddress,\r
+                                                                                  IP_Address_t DestinationAddress, uint16_t TCPOutSize);\r
+               #endif\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/UDP.c b/Demos/Device/RNDISEthernet/Lib/UDP.c
new file mode 100644 (file)
index 0000000..1f571c3
--- /dev/null
@@ -0,0 +1,80 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  User Datagram Protocol (UDP) packet handling routines. This protocol handles high throughput, low\r
+ *  reliability packets which are typically used to encapsulate streaming data.\r
+ */\r
\r
+#define  INCLUDE_FROM_UDP_C\r
+#include "UDP.h"\r
+\r
+/** Processes a UDP packet inside an Ethernet frame, and writes the appropriate response\r
+ *  to the output Ethernet frame if a subprotocol handler has created a response packet.\r
+ *\r
+ *  \param IPHeaderInStart    Pointer to the start of the incoming packet's IP header\r
+ *  \param UDPHeaderInStart   Pointer to the start of the incoming packet's UDP header\r
+ *  \param UDPHeaderOutStart  Pointer to the start of the outgoing packet's UDP header\r
+ *\r
+ *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
+ */\r
+int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart)\r
+{\r
+       UDP_Header_t* UDPHeaderIN  = (UDP_Header_t*)UDPHeaderInStart;\r
+       UDP_Header_t* UDPHeaderOUT = (UDP_Header_t*)UDPHeaderOutStart;\r
+       \r
+       int16_t RetSize = NO_RESPONSE;\r
+       \r
+       DecodeUDPHeader(UDPHeaderInStart);\r
+       \r
+       /* Check to see if the UDP packet is a DHCP packet */\r
+       if (SwapEndian_16(UDPHeaderIN->DestinationPort) == UDP_PORT_DHCP_REQUEST)\r
+       {\r
+               RetSize = DHCP_ProcessDHCPPacket(IPHeaderInStart,\r
+                                                &((uint8_t*)UDPHeaderInStart)[sizeof(UDP_Header_t)],\r
+                                            &((uint8_t*)UDPHeaderOutStart)[sizeof(UDP_Header_t)]);\r
+       }\r
+       \r
+       /* Check to see if the protocol processing routine has filled out a response */\r
+       if (RetSize > 0)\r
+       {\r
+               /* Fill out the response UDP packet header */\r
+               UDPHeaderOUT->SourcePort      = UDPHeaderIN->DestinationPort;\r
+               UDPHeaderOUT->DestinationPort = UDPHeaderIN->SourcePort;\r
+               UDPHeaderOUT->Checksum        = 0;\r
+               UDPHeaderOUT->Length          = SwapEndian_16(sizeof(UDP_Header_t) + RetSize);\r
+\r
+               /* Return the size of the response so far */\r
+               return (sizeof(UDP_Header_t) + RetSize);\r
+       }\r
+       \r
+       return NO_RESPONSE;\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/UDP.h b/Demos/Device/RNDISEthernet/Lib/UDP.h
new file mode 100644 (file)
index 0000000..60bbe21
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for IP.c.\r
+ */\r
+\r
+#ifndef _UDP_H_\r
+#define _UDP_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+       \r
+               #include "EthernetProtocols.h"\r
+               #include "Ethernet.h"\r
+               #include "ProtocolDecoders.h"\r
+       \r
+       /* Macros: */\r
+               /** Source UDP port for a DHCP request */\r
+               #define UDP_PORT_DHCP_REQUEST 67\r
+\r
+               /** Destination UDP port for a DHCP reply */\r
+               #define UDP_PORT_DHCP_REPLY   68\r
+                       \r
+       /* Type Defines: */\r
+               /** Type define for a UDP packet header */\r
+               typedef struct\r
+               {\r
+                       uint16_t SourcePort; /**< Packet source port */\r
+                       uint16_t DestinationPort; /**< Packet destination port */\r
+                       uint16_t Length; /**< Total packet length, in bytes */\r
+                       uint16_t Checksum; /**< Optional UDP packet checksum */\r
+               } UDP_Header_t;\r
+               \r
+       /* Function Prototypes: */\r
+               int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/Lib/Webserver.c b/Demos/Device/RNDISEthernet/Lib/Webserver.c
new file mode 100644 (file)
index 0000000..c07f2c8
--- /dev/null
@@ -0,0 +1,162 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Simple webserver application for demonstrating the RNDIS demo and TCP/IP stack. This\r
+ *  application will serve up a static HTTP webpage when requested by the host.\r
+ */\r
+\r
+#include "Webserver.h"\r
+\r
+/** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the\r
+ *  given location, and gives extra connection information.\r
+ */\r
+char PROGMEM HTTPHeader[] = "HTTP/1.1 200 OK\r\n"\r
+                            "Server: LUFA RNDIS\r\n"\r
+                            "Content-type: text/html\r\n"\r
+                            "Connection: close\r\n\r\n";\r
+\r
+/** HTTP page to serve to the host when a HTTP request is made. This page is too long for a single response, thus it is automatically\r
+ *  broken up into smaller blocks and sent as a series of packets each time the webserver application callback is run.\r
+ */\r
+char PROGMEM HTTPPage[]   = \r
+               "<html>"\r
+               "       <head>"\r
+               "               <title>"\r
+               "                       LUFA Webserver Demo"\r
+               "               </title>"\r
+               "       </head>"\r
+               "       <body>"\r
+               "               <h1>Hello from your USB AVR!</h1>"\r
+               "               <p>"\r
+               "                       Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack."\r
+               "                       <br /><br />"\r
+               "                       <small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>"\r
+               "                       <hr />"\r
+               "                       <i>LUFA Version: </i>" LUFA_VERSION_STRING\r
+               "               </p>"\r
+               "       </body>"\r
+               "</html>";\r
+\r
+\r
+/** Initializes the Webserver application, opening the appropriate HTTP port in the TCP handler and registering the application\r
+ *  callback routine for packets sent to the HTTP protocol port.\r
+ */\r
+void Webserver_Init(void)\r
+{\r
+       /* Open the HTTP port in the TCP protocol so that HTTP connections to the device can be established */\r
+       TCP_SetPortState(TCP_PORT_HTTP, TCP_Port_Open, Webserver_ApplicationCallback);\r
+}\r
+\r
+/** Indicates if a given request equals the given HTTP command.\r
+ *\r
+ *  \param RequestHeader  HTTP request made by the host\r
+ *  \param Command        HTTP command to compare the request to\r
+ *\r
+ *  \return Boolean true if the command matches the request, false otherwise\r
+ */\r
+static bool IsHTTPCommand(uint8_t* RequestHeader, char* Command)\r
+{\r
+       /* Returns true if the non null terminated string in RequestHeader matches the null terminated string Command */\r
+       return (strncmp((char*)RequestHeader, Command, strlen(Command)) == 0);\r
+}\r
+\r
+/** Application callback routine, executed each time the TCP processing task runs. This callback determines what request\r
+ *  has been made (if any), and serves up appropriate responses.\r
+ *\r
+ *  \param ConnectionState  Pointer to a TCP Connection State structure giving connection information\r
+ *  \param Buffer           Pointer to the application's send/receive packet buffer\r
+ */\r
+void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer)\r
+{\r
+       char*          BufferDataStr = (char*)Buffer->Data;\r
+       static uint8_t PageBlock     = 0;\r
+       \r
+       /* Check to see if a packet has been received on the HTTP port from a remote host */\r
+       if (TCP_APP_HAS_RECEIVED_PACKET(Buffer))\r
+       {\r
+               if (IsHTTPCommand(Buffer->Data, "GET"))\r
+               {\r
+                       PageBlock = 0;\r
+\r
+                       /* Copy the HTTP response header into the packet buffer */\r
+                       strcpy_P(BufferDataStr, HTTPHeader);\r
+                       \r
+                       /* Send the buffer contents to the host */\r
+                       TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));\r
+\r
+                       /* Lock the buffer to Device->Host transmissions only while we send the page contents */\r
+                       TCP_APP_CAPTURE_BUFFER(Buffer);\r
+               }\r
+               else if (IsHTTPCommand(Buffer->Data, "HEAD"))\r
+               {\r
+                       /* Copy the HTTP response header into the packet buffer */\r
+                       strcpy_P(BufferDataStr, HTTPHeader);\r
+\r
+                       /* Send the buffer contents to the host */\r
+                       TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));\r
+               }\r
+               else if (IsHTTPCommand(Buffer->Data, "TRACE"))\r
+               {\r
+                       /* Echo the host's query back to the host */\r
+                       TCP_APP_SEND_BUFFER(Buffer, Buffer->Length);\r
+               }\r
+               else\r
+               {\r
+                       /* Unknown request, just clear the buffer (drop the packet) */\r
+                       TCP_APP_CLEAR_BUFFER(Buffer);\r
+               }\r
+       }\r
+       else if (TCP_APP_HAVE_CAPTURED_BUFFER(Buffer))\r
+       {\r
+               uint16_t RemLength = strlen_P(&HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE]);\r
+               uint16_t Length;\r
+       \r
+               /* Determine the length of the loaded block */\r
+               Length = ((RemLength > HTTP_REPLY_BLOCK_SIZE) ? HTTP_REPLY_BLOCK_SIZE : RemLength);\r
+\r
+               /* Copy the next buffer sized block of the page to the packet buffer */\r
+               strncpy_P(BufferDataStr, &HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE], Length);\r
+               \r
+               /* Send the buffer contents to the host */\r
+               TCP_APP_SEND_BUFFER(Buffer, Length);\r
+\r
+               /* Check to see if the entire page has been sent */\r
+               if (PageBlock++ == (sizeof(HTTPPage) / HTTP_REPLY_BLOCK_SIZE))\r
+               {\r
+                       /* Unlock the buffer so that the host can fill it with future packets */\r
+                       TCP_APP_RELEASE_BUFFER(Buffer);\r
+                       \r
+                       /* Close the connection to the host */\r
+                       TCP_APP_CLOSECONNECTION(ConnectionState);\r
+               }\r
+       }\r
+}\r
diff --git a/Demos/Device/RNDISEthernet/Lib/Webserver.h b/Demos/Device/RNDISEthernet/Lib/Webserver.h
new file mode 100644 (file)
index 0000000..b2193ad
--- /dev/null
@@ -0,0 +1,55 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for Webserver.c.\r
+ */\r
\r
+#ifndef _WEBSERVER_H_\r
+#define _WEBSERVER_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <avr/pgmspace.h>\r
+               \r
+               #include <LUFA/Version.h>\r
+               \r
+               #include "TCP.h"\r
+       \r
+       /* Macros: */\r
+               /** Maximum size of a HTTP response per transmission */\r
+               #define  HTTP_REPLY_BLOCK_SIZE     128\r
+       \r
+       /* Function Prototypes: */\r
+               void Webserver_Init(void);\r
+               void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer);\r
+\r
+#endif\r
diff --git a/Demos/Device/RNDISEthernet/ProtocolDecoders.c b/Demos/Device/RNDISEthernet/ProtocolDecoders.c
deleted file mode 100644 (file)
index add0333..0000000
+++ /dev/null
@@ -1,280 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/* Protocol decoders for Ethernet, TCP, IP, ICMP and ARP. Each of these routines\r
-   accepts a header to the appropriate protocol and prints out pertinent information\r
-   on the packet through the serial port.\r
-   \r
-   To disable printing of a specific protocol, define the token NO_DECODE_{Protocol}\r
-   in the project makefile, and pass it to the compiler using the -D switch.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Protocol decoding routines, for the plain-text decoding of Ethernet frames for debugging purposes.\r
- *  Enabled protocol decoders will print incoming Ethernet frame contents through the USART in a human\r
- *  readable format.\r
- *\r
- *  Note that the USART is a slow transmission medium, and will slow down packet processing considerably.\r
- *  Packet decoding routines can be disabled by defining NO_DECODE_{Protocol Name} in the project makefile\r
- *  and passing it to the compiler via the -D switch.\r
- */\r
\r
-#include "ProtocolDecoders.h"\r
-\r
-/** Decodes an Ethernet frame header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of an Ethernet frame header\r
- */\r
-void DecodeEthernetFrameHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_ETHERNET)\r
-       Ethernet_Frame_Header_t* FrameHeader = (Ethernet_Frame_Header_t*)InDataStart;\r
-       \r
-       printf_P(PSTR("\r\n"));\r
-       \r
-       printf_P(PSTR("  ETHERNET\r\n"));\r
-       printf_P(PSTR("  + Frame Size: %u\r\n"), FrameIN.FrameLength);\r
-\r
-       if (!(MAC_COMPARE(&FrameHeader->Destination, &ServerMACAddress)) &&\r
-           !(MAC_COMPARE(&FrameHeader->Destination, &BroadcastMACAddress)))\r
-       {\r
-               printf_P(PSTR("  + NOT ADDRESSED TO DEVICE\r\n"));\r
-               return;\r
-       }\r
-\r
-       printf_P(PSTR("  + MAC Source : %02X:%02X:%02X:%02X:%02X:%02X\r\n"), FrameHeader->Source.Octets[0],\r
-                                                                            FrameHeader->Source.Octets[1],\r
-                                                                            FrameHeader->Source.Octets[2],\r
-                                                                            FrameHeader->Source.Octets[3],\r
-                                                                            FrameHeader->Source.Octets[4],\r
-                                                                            FrameHeader->Source.Octets[5]);\r
-\r
-       printf_P(PSTR("  + MAC Dest: %02X:%02X:%02X:%02X:%02X:%02X\r\n"),    FrameHeader->Destination.Octets[0],\r
-                                                                            FrameHeader->Destination.Octets[1],\r
-                                                                            FrameHeader->Destination.Octets[2],\r
-                                                                            FrameHeader->Destination.Octets[3],\r
-                                                                            FrameHeader->Destination.Octets[4],\r
-                                                                            FrameHeader->Destination.Octets[5]);\r
-\r
-       if (SwapEndian_16(FrameIN.FrameLength) > ETHERNET_VER2_MINSIZE)\r
-         printf_P(PSTR("  + Protocol: 0x%04x\r\n"), SwapEndian_16(FrameHeader->EtherType));\r
-       else\r
-         printf_P(PSTR("  + Protocol: UNKNOWN E1\r\n"));\r
-       #endif\r
-}\r
-\r
-/** Decodes an ARP header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of an ARP packet header\r
- */\r
-void DecodeARPHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_ARP)\r
-       ARP_Header_t* ARPHeader = (ARP_Header_t*)InDataStart;   \r
-\r
-       printf_P(PSTR("   \\\r\n    ARP\r\n"));\r
-\r
-       if (!(IP_COMPARE(&ARPHeader->TPA, &ServerIPAddress)) &&\r
-           !(MAC_COMPARE(&ARPHeader->THA, &ServerMACAddress)))\r
-       {\r
-               printf_P(PSTR("    + NOT ADDRESSED TO DEVICE\r\n"));\r
-               return;         \r
-       }\r
-\r
-       printf_P(PSTR("    + Protocol: %x\r\n"), SwapEndian_16(ARPHeader->ProtocolType));\r
-       printf_P(PSTR("    + Operation: %u\r\n"), SwapEndian_16(ARPHeader->Operation));\r
-       \r
-       if (SwapEndian_16(ARPHeader->ProtocolType) == ETHERTYPE_IPV4)\r
-       {\r
-               printf_P(PSTR("    + SHA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->SHA.Octets[0],\r
-                                                                                  ARPHeader->SHA.Octets[1],\r
-                                                                                  ARPHeader->SHA.Octets[2],\r
-                                                                                  ARPHeader->SHA.Octets[3],\r
-                                                                                  ARPHeader->SHA.Octets[4],\r
-                                                                                  ARPHeader->SHA.Octets[5]);\r
-\r
-               printf_P(PSTR("    + SPA IP: %u.%u.%u.%u\r\n"), ARPHeader->SPA.Octets[0],\r
-                                                               ARPHeader->SPA.Octets[1],\r
-                                                               ARPHeader->SPA.Octets[2],\r
-                                                               ARPHeader->SPA.Octets[3]);\r
-\r
-               printf_P(PSTR("    + THA MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n"), ARPHeader->THA.Octets[0],\r
-                                                                                  ARPHeader->THA.Octets[1],\r
-                                                                                  ARPHeader->THA.Octets[2],\r
-                                                                                  ARPHeader->THA.Octets[3],\r
-                                                                                  ARPHeader->THA.Octets[4],\r
-                                                                                  ARPHeader->THA.Octets[5]);\r
-\r
-               printf_P(PSTR("    + TPA IP: %u.%u.%u.%u\r\n"), ARPHeader->TPA.Octets[0],\r
-                                                               ARPHeader->TPA.Octets[1],\r
-                                                               ARPHeader->TPA.Octets[2],\r
-                                                               ARPHeader->TPA.Octets[3]);\r
-       }\r
-       #endif\r
-}\r
-\r
-/** Decodes an IP header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of an IP packet header\r
- */\r
-void DecodeIPHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_IP)\r
-       IP_Header_t* IPHeader  = (IP_Header_t*)InDataStart;\r
-\r
-       uint16_t HeaderLengthBytes = (IPHeader->HeaderLength * sizeof(uint32_t));\r
-\r
-       printf_P(PSTR("   \\\r\n    IP\r\n"));\r
-\r
-       if (!(IP_COMPARE(&IPHeader->DestinationAddress, &ServerIPAddress)))\r
-       {\r
-               printf_P(PSTR("    + NOT ADDRESSED TO DEVICE\r\n"));\r
-               return;\r
-       }\r
-\r
-       printf_P(PSTR("    + Header Length: %u Bytes\r\n"), HeaderLengthBytes);\r
-       printf_P(PSTR("    + Packet Version: %u\r\n"), IPHeader->Version);\r
-       printf_P(PSTR("    + Total Length: %u\r\n"), SwapEndian_16(IPHeader->TotalLength));\r
-       \r
-       printf_P(PSTR("    + Protocol: %u\r\n"), IPHeader->Protocol);\r
-       printf_P(PSTR("    + TTL: %u\r\n"), IPHeader->TTL);\r
-       \r
-       printf_P(PSTR("    + IP Src: %u.%u.%u.%u\r\n"), IPHeader->SourceAddress.Octets[0],\r
-                                                       IPHeader->SourceAddress.Octets[1],\r
-                                                       IPHeader->SourceAddress.Octets[2],\r
-                                                       IPHeader->SourceAddress.Octets[3]);     \r
-\r
-       printf_P(PSTR("    + IP Dst: %u.%u.%u.%u\r\n"), IPHeader->DestinationAddress.Octets[0],\r
-                                                       IPHeader->DestinationAddress.Octets[1],\r
-                                                       IPHeader->DestinationAddress.Octets[2],\r
-                                                       IPHeader->DestinationAddress.Octets[3]);\r
-       #endif\r
-}\r
-\r
-/** Decodes an ICMP header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of an ICMP packet header\r
- */\r
-void DecodeICMPHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_ICMP)\r
-       ICMP_Header_t* ICMPHeader  = (ICMP_Header_t*)InDataStart;\r
-\r
-       printf_P(PSTR("    \\\r\n     ICMP\r\n"));\r
-\r
-       printf_P(PSTR("     + Type: %u\r\n"), ICMPHeader->Type);\r
-       printf_P(PSTR("     + Code: %u\r\n"), ICMPHeader->Code);\r
-       #endif\r
-}\r
-\r
-/** Decodes a TCP header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of a TCP packet header\r
- */\r
-void DecodeTCPHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_TCP)\r
-       TCP_Header_t* TCPHeader  = (TCP_Header_t*)InDataStart;\r
-\r
-       uint16_t               HeaderLengthBytes = (TCPHeader->DataOffset * sizeof(uint32_t));\r
-\r
-       printf_P(PSTR("    \\\r\n     TCP\r\n"));\r
-\r
-       printf_P(PSTR("     + Header Length: %u Bytes\r\n"), HeaderLengthBytes);\r
-\r
-       printf_P(PSTR("     + Source Port: %u\r\n"), SwapEndian_16(TCPHeader->SourcePort));\r
-       printf_P(PSTR("     + Destination Port: %u\r\n"), SwapEndian_16(TCPHeader->DestinationPort));\r
-\r
-       printf_P(PSTR("     + Sequence Number: %lu\r\n"), SwapEndian_32(TCPHeader->SequenceNumber));\r
-       printf_P(PSTR("     + Acknowledgment Number: %lu\r\n"), SwapEndian_32(TCPHeader->AcknowledgmentNumber));\r
-       \r
-       printf_P(PSTR("     + Flags: 0x%02X\r\n"), TCPHeader->Flags);\r
-       \r
-       if (TCP_GetPortState(TCPHeader->DestinationPort) == TCP_Port_Closed)\r
-         printf_P(PSTR("     + NOT LISTENING ON DESTINATION PORT\r\n"));\r
-       #endif\r
-}\r
-\r
-/** Decodes an UDP header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of a UDP packet header\r
- */\r
-void DecodeUDPHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_UDP)\r
-       UDP_Header_t* UDPHeader = (UDP_Header_t*)InDataStart;\r
-\r
-       printf_P(PSTR("    \\\r\n     UDP\r\n"));\r
-\r
-       printf_P(PSTR("     + Source Port: %u\r\n"), SwapEndian_16(UDPHeader->SourcePort));\r
-       printf_P(PSTR("     + Destination Port: %u\r\n"), SwapEndian_16(UDPHeader->DestinationPort));\r
-\r
-       printf_P(PSTR("     + Data Length: %d\r\n"), SwapEndian_16(UDPHeader->Length));\r
-       #endif\r
-}\r
-\r
-/** Decodes an DHCP header and prints its contents to through the USART in a human readable format.\r
- *\r
- *  \param InDataStart  Pointer to the start of a DHCP packet header\r
- */\r
-void DecodeDHCPHeader(void* InDataStart)\r
-{\r
-       #if !defined(NO_DECODE_DHCP)\r
-       uint8_t* DHCPOptions = (InDataStart + sizeof(DHCP_Header_t));\r
-\r
-       printf_P(PSTR("     \\\r\n      DHCP\r\n"));\r
-\r
-       while (DHCPOptions[0] != DHCP_OPTION_END)\r
-       {\r
-               if (DHCPOptions[0] == DHCP_OPTION_MESSAGETYPE)\r
-               {\r
-                       switch (DHCPOptions[2])\r
-                       {\r
-                               case DHCP_MESSAGETYPE_DISCOVER:\r
-                                       printf_P(PSTR("      + DISCOVER\r\n"));\r
-                                       break;\r
-                               case DHCP_MESSAGETYPE_REQUEST:\r
-                                       printf_P(PSTR("      + REQUEST\r\n"));\r
-                                       break;\r
-                               case DHCP_MESSAGETYPE_RELEASE:\r
-                                       printf_P(PSTR("      + RELEASE\r\n"));\r
-                                       break;\r
-                               case DHCP_MESSAGETYPE_DECLINE:\r
-                                       printf_P(PSTR("      + DECLINE\r\n"));\r
-                                       break;\r
-                       }\r
-               }\r
-               \r
-               DHCPOptions += ((DHCPOptions[0] == DHCP_OPTION_PAD) ? 1 : (DHCPOptions[1] + 2));\r
-       }\r
-\r
-       #endif\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/ProtocolDecoders.h b/Demos/Device/RNDISEthernet/ProtocolDecoders.h
deleted file mode 100644 (file)
index fa0a869..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for ProtocolDecoders.c.\r
- */\r
-\r
-#ifndef _PROTOCOL_DECODERS_H_\r
-#define _PROTOCOL_DECODERS_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               \r
-               #include <LUFA/Drivers/Peripheral/SerialStream.h>\r
-               \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               \r
-       /* Function Prototypes: */\r
-               void DecodeEthernetFrameHeader(void* InDataStart);\r
-               void DecodeARPHeader(void* InDataStart);\r
-               void DecodeIPHeader(void* InDataStart);\r
-               void DecodeICMPHeader(void* InDataStart);\r
-               void DecodeTCPHeader(void* InDataStart);\r
-               void DecodeUDPHeader(void* InDataStart);\r
-               void DecodeDHCPHeader(void* InDataStart);\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/RNDIS.c b/Demos/Device/RNDISEthernet/RNDIS.c
deleted file mode 100644 (file)
index c5202bc..0000000
+++ /dev/null
@@ -1,394 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  RNDIS command handler functions. This handles RNDIS commands according to\r
- *  the Microsoft RNDIS specification, creating a USB Ethernet network adapter.\r
- */\r
\r
-#define  INCLUDE_FROM_RNDIS_C\r
-#include "RNDIS.h"\r
-\r
-/* Global Variables: */\r
-/** Physical MAC address of the network adapter, which becomes the MAC address of the host for packets sent to the adapter. */\r
-static MAC_Address_t  PROGMEM AdapterMACAddress          = {ADAPTER_MAC_ADDRESS};\r
-\r
-/** Vendor description of the adapter. This is overridden by the INF file required to install the appropriate RNDIS drivers for\r
- *  the device, but may still be used by the OS in some circumstances.\r
- */\r
-static char           PROGMEM AdapterVendorDescription[] = "LUFA RNDIS Adapter";\r
-\r
-/** List of RNDIS OID commands supported by this adapter. */\r
-static const uint32_t PROGMEM AdapterSupportedOIDList[]  =\r
-                                                       {\r
-                                                               OID_GEN_SUPPORTED_LIST,\r
-                                                               OID_GEN_PHYSICAL_MEDIUM,\r
-                                                               OID_GEN_HARDWARE_STATUS,\r
-                                                               OID_GEN_MEDIA_SUPPORTED,\r
-                                                               OID_GEN_MEDIA_IN_USE,\r
-                                                               OID_GEN_MAXIMUM_FRAME_SIZE,\r
-                                                               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
-                                                               OID_GEN_LINK_SPEED,\r
-                                                               OID_GEN_TRANSMIT_BLOCK_SIZE,\r
-                                                               OID_GEN_RECEIVE_BLOCK_SIZE,\r
-                                                               OID_GEN_VENDOR_ID,\r
-                                                               OID_GEN_VENDOR_DESCRIPTION,\r
-                                                               OID_GEN_CURRENT_PACKET_FILTER,\r
-                                                               OID_GEN_MAXIMUM_TOTAL_SIZE,\r
-                                                               OID_GEN_MEDIA_CONNECT_STATUS,\r
-                                                               OID_GEN_XMIT_OK,\r
-                                                               OID_GEN_RCV_OK,\r
-                                                               OID_GEN_XMIT_ERROR,\r
-                                                               OID_GEN_RCV_ERROR,\r
-                                                               OID_GEN_RCV_NO_BUFFER,\r
-                                                               OID_802_3_PERMANENT_ADDRESS,\r
-                                                               OID_802_3_CURRENT_ADDRESS,\r
-                                                               OID_802_3_MULTICAST_LIST,\r
-                                                               OID_802_3_MAXIMUM_LIST_SIZE,\r
-                                                               OID_802_3_RCV_ERROR_ALIGNMENT,\r
-                                                               OID_802_3_XMIT_ONE_COLLISION,\r
-                                                               OID_802_3_XMIT_MORE_COLLISIONS,\r
-                                                       };\r
-\r
-/** Buffer for RNDIS messages (as distinct from Ethernet frames sent through the adapter. This must be big enough to hold the entire\r
- *  Supported OID list, plus the response header. The buffer is half-duplex, and is written to as it is read to save on SRAM - for this\r
- *  reason, care must be taken when constructing RNDIS responses that unread data is not overwritten when writing in responses.\r
- */\r
-uint8_t                 RNDISMessageBuffer[sizeof(AdapterSupportedOIDList) + sizeof(RNDIS_QUERY_CMPLT_t)];\r
-\r
-/** Pointer to the RNDIS message header at the top of the RNDIS message buffer, for convenience. */\r
-RNDIS_Message_Header_t* MessageHeader = (RNDIS_Message_Header_t*)&RNDISMessageBuffer;\r
-\r
-/** Indicates if a RNDIS message response is ready to be sent back to the host. */\r
-bool                    ResponseReady               = false;\r
-\r
-/** Current RNDIS adapter state, a value from the RNDIS_States_t enum. */\r
-uint8_t                 CurrRNDISState              = RNDIS_Uninitialized;\r
-\r
-/** Current Ethernet packet filter mask. This is non-zero when the adapter is initialized, or zero when disabled. */\r
-uint32_t                CurrPacketFilter            = 0;                                                       \r
-\r
-\r
-/** Processes the RNDIS message received by the host and stored in the RNDISMessageBuffer global buffer. If a response is\r
- *  created, the ResponseReady global is updated so that the response is written back to the host upon request.\r
- */\r
-void ProcessRNDISControlMessage(void)\r
-{\r
-       /* Note: Only a single buffer is used for both the received message and its response to save SRAM. Because of\r
-                this, response bytes should be filled in order so that they do not clobber unread data in the buffer. */\r
-\r
-       switch (MessageHeader->MessageType)\r
-       {\r
-               case REMOTE_NDIS_INITIALIZE_MSG:\r
-                       /* Initialize the adapter - return information about the supported RNDIS version and buffer sizes */\r
-\r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_INITIALIZE_MSG_t*   INITIALIZE_Message  = (RNDIS_INITIALIZE_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_INITIALIZE_CMPLT_t* INITIALIZE_Response = (RNDIS_INITIALIZE_CMPLT_t*)&RNDISMessageBuffer;\r
-                       \r
-                       INITIALIZE_Response->MessageType           = REMOTE_NDIS_INITIALIZE_CMPLT;\r
-                       INITIALIZE_Response->MessageLength         = sizeof(RNDIS_INITIALIZE_CMPLT_t);\r
-                       INITIALIZE_Response->RequestId             = INITIALIZE_Message->RequestId;\r
-                       INITIALIZE_Response->Status                = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       \r
-                       INITIALIZE_Response->MajorVersion          = REMOTE_NDIS_VERSION_MAJOR;\r
-                       INITIALIZE_Response->MinorVersion          = REMOTE_NDIS_VERSION_MINOR;                 \r
-                       INITIALIZE_Response->DeviceFlags           = REMOTE_NDIS_DF_CONNECTIONLESS;\r
-                       INITIALIZE_Response->Medium                = REMOTE_NDIS_MEDIUM_802_3;\r
-                       INITIALIZE_Response->MaxPacketsPerTransfer = 1;\r
-                       INITIALIZE_Response->MaxTransferSize       = (sizeof(RNDIS_PACKET_MSG_t) + ETHERNET_FRAME_SIZE_MAX);\r
-                       INITIALIZE_Response->PacketAlignmentFactor = 0;\r
-                       INITIALIZE_Response->AFListOffset          = 0;\r
-                       INITIALIZE_Response->AFListSize            = 0;\r
-                       \r
-                       CurrRNDISState = RNDIS_Initialized;\r
-               \r
-                       break;\r
-               case REMOTE_NDIS_HALT_MSG:\r
-                       /* Halt the adapter, reset the adapter state - note that no response should be returned when completed */\r
-\r
-                       ResponseReady = false;\r
-                       MessageHeader->MessageLength = 0;\r
-\r
-                       CurrRNDISState = RNDIS_Uninitialized;\r
-\r
-                       break;\r
-               case REMOTE_NDIS_QUERY_MSG:\r
-                       /* Request for information about a parameter about the adapter, specified as an OID token */\r
-\r
-                       ResponseReady = true;\r
-                                               \r
-                       RNDIS_QUERY_MSG_t*   QUERY_Message  = (RNDIS_QUERY_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_QUERY_CMPLT_t* QUERY_Response = (RNDIS_QUERY_CMPLT_t*)&RNDISMessageBuffer;\r
-                       uint32_t             Query_Oid      = QUERY_Message->Oid;\r
-                                               \r
-                       void*     QueryData                 = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
-                                                                                 QUERY_Message->InformationBufferOffset];\r
-                       void*     ResponseData              = &RNDISMessageBuffer[sizeof(RNDIS_QUERY_CMPLT_t)];         \r
-                       uint16_t  ResponseSize;\r
-\r
-                       QUERY_Response->MessageType         = REMOTE_NDIS_QUERY_CMPLT;\r
-                       QUERY_Response->MessageLength       = sizeof(RNDIS_QUERY_CMPLT_t);\r
-                                               \r
-                       if (ProcessNDISQuery(Query_Oid, QueryData, QUERY_Message->InformationBufferLength,\r
-                                            ResponseData, &ResponseSize))\r
-                       {\r
-                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_SUCCESS;\r
-                               QUERY_Response->MessageLength          += ResponseSize;\r
-                                                       \r
-                               QUERY_Response->InformationBufferLength = ResponseSize;\r
-                               QUERY_Response->InformationBufferOffset = (sizeof(RNDIS_QUERY_CMPLT_t) - sizeof(RNDIS_Message_Header_t));\r
-                       }\r
-                       else\r
-                       {                               \r
-                               QUERY_Response->Status                  = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
-\r
-                               QUERY_Response->InformationBufferLength = 0;\r
-                               QUERY_Response->InformationBufferOffset = 0;\r
-                       }\r
-                       \r
-                       break;\r
-               case REMOTE_NDIS_SET_MSG:\r
-                       /* Request to set a parameter of the adapter, specified as an OID token */\r
-               \r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_SET_MSG_t*   SET_Message  = (RNDIS_SET_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_SET_CMPLT_t* SET_Response = (RNDIS_SET_CMPLT_t*)&RNDISMessageBuffer;\r
-                       uint32_t           SET_Oid      = SET_Message->Oid;\r
-\r
-                       SET_Response->MessageType       = REMOTE_NDIS_SET_CMPLT;\r
-                       SET_Response->MessageLength     = sizeof(RNDIS_SET_CMPLT_t);\r
-                       SET_Response->RequestId         = SET_Message->RequestId;\r
-\r
-                       void* SetData                   = &RNDISMessageBuffer[sizeof(RNDIS_Message_Header_t) +\r
-                                                                             SET_Message->InformationBufferOffset];\r
-                                               \r
-                       if (ProcessNDISSet(SET_Oid, SetData, SET_Message->InformationBufferLength))\r
-                         SET_Response->Status        = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       else\r
-                         SET_Response->Status        = REMOTE_NDIS_STATUS_NOT_SUPPORTED;\r
-\r
-                       break;\r
-               case REMOTE_NDIS_RESET_MSG:\r
-                       /* Soft reset the adapter */\r
-               \r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_RESET_CMPLT_t* RESET_Response = (RNDIS_RESET_CMPLT_t*)&RNDISMessageBuffer;\r
-\r
-                       RESET_Response->MessageType         = REMOTE_NDIS_RESET_CMPLT;\r
-                       RESET_Response->MessageLength       = sizeof(RNDIS_RESET_CMPLT_t);\r
-                       RESET_Response->Status              = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       RESET_Response->AddressingReset     = 0;\r
-\r
-                       break;\r
-               case REMOTE_NDIS_KEEPALIVE_MSG:\r
-                       /* Keep alive message sent to the adapter every 5 seconds when idle to ensure it is still responding */\r
-               \r
-                       ResponseReady = true;\r
-                       \r
-                       RNDIS_KEEPALIVE_MSG_t*   KEEPALIVE_Message  = (RNDIS_KEEPALIVE_MSG_t*)&RNDISMessageBuffer;\r
-                       RNDIS_KEEPALIVE_CMPLT_t* KEEPALIVE_Response = (RNDIS_KEEPALIVE_CMPLT_t*)&RNDISMessageBuffer;\r
-\r
-                       KEEPALIVE_Response->MessageType     = REMOTE_NDIS_KEEPALIVE_CMPLT;\r
-                       KEEPALIVE_Response->MessageLength   = sizeof(RNDIS_KEEPALIVE_CMPLT_t);\r
-                       KEEPALIVE_Response->RequestId       = KEEPALIVE_Message->RequestId;\r
-                       KEEPALIVE_Response->Status          = REMOTE_NDIS_STATUS_SUCCESS;\r
-                       \r
-                       break;\r
-       }\r
-}\r
-\r
-/** Processes RNDIS query commands, retrieving information from the adapter and reporting it back to the host. The requested\r
- *  parameter is given as an OID value.\r
- *\r
- *  \param OId           OId value of the parameter being queried\r
- *  \param QueryData     Pointer to any extra query data being sent by the host to the device inside the RNDIS message buffer\r
- *  \param QuerySize     Size in bytes of the extra query data being sent by the host\r
- *  \param ResponseData  Pointer to the start of the query response inside the RNDIS message buffer\r
- *  \param ResponseSize  Pointer to the size in bytes of the response data being sent to the host\r
- *\r
- *  \return Boolean true if the query was handled, false otherwise\r
- */\r
-static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,\r
-                             void* ResponseData, uint16_t* ResponseSize)\r
-{\r
-       /* Handler for REMOTE_NDIS_QUERY_MSG messages */\r
-\r
-       switch (OId)\r
-       {\r
-               case OID_GEN_SUPPORTED_LIST:\r
-                       *ResponseSize = sizeof(AdapterSupportedOIDList);\r
-                       \r
-                       /* Copy the list of supported NDIS OID tokens to the response buffer */\r
-                       memcpy_P(ResponseData, AdapterSupportedOIDList, sizeof(AdapterSupportedOIDList));\r
-                       \r
-                       return true;\r
-               case OID_GEN_PHYSICAL_MEDIUM:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate that the device is a true ethernet link */\r
-                       *((uint32_t*)ResponseData) = 0;\r
-                       \r
-                       return true;\r
-               case OID_GEN_HARDWARE_STATUS:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Always indicate hardware ready */\r
-                       *((uint32_t*)ResponseData) = NdisHardwareStatusReady;\r
-                       \r
-                       return true;\r
-               case OID_GEN_MEDIA_SUPPORTED:\r
-               case OID_GEN_MEDIA_IN_USE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate 802.3 (Ethernet) supported by the adapter */\r
-                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIUM_802_3;\r
-                       \r
-                       return true;\r
-               case OID_GEN_VENDOR_ID:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Vendor ID 0x0xFFFFFF is reserved for vendors who have not purchased a NDIS VID */\r
-                       *((uint32_t*)ResponseData) = 0x00FFFFFF;\r
-                       \r
-                       return true;\r
-               case OID_GEN_MAXIMUM_FRAME_SIZE:\r
-               case OID_GEN_TRANSMIT_BLOCK_SIZE:\r
-               case OID_GEN_RECEIVE_BLOCK_SIZE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate that the maximum frame size is the size of the ethernet frame buffer */\r
-                       *((uint32_t*)ResponseData) = ETHERNET_FRAME_SIZE_MAX;\r
-                       \r
-                       return true;\r
-               case OID_GEN_VENDOR_DESCRIPTION:\r
-                       *ResponseSize = sizeof(AdapterVendorDescription);\r
-                       \r
-                       /* Copy vendor description string to the response buffer */\r
-                       memcpy_P(ResponseData, AdapterVendorDescription, sizeof(AdapterVendorDescription));\r
-                       \r
-                       return true;\r
-               case OID_GEN_MEDIA_CONNECT_STATUS:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Always indicate that the adapter is connected to a network */\r
-                       *((uint32_t*)ResponseData) = REMOTE_NDIS_MEDIA_STATE_CONNECTED;\r
-                       \r
-                       return true;\r
-               case OID_GEN_LINK_SPEED:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate 10Mb/s link speed */\r
-                       *((uint32_t*)ResponseData) = 100000;\r
-\r
-                       return true;\r
-               case OID_802_3_PERMANENT_ADDRESS:\r
-               case OID_802_3_CURRENT_ADDRESS:\r
-                       *ResponseSize = sizeof(MAC_Address_t);\r
-                       \r
-                       /* Copy over the fixed adapter MAC to the response buffer */\r
-                       memcpy_P(ResponseData, &AdapterMACAddress, sizeof(MAC_Address_t));\r
-\r
-                       return true;\r
-               case OID_802_3_MAXIMUM_LIST_SIZE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate only one multicast address supported */\r
-                       *((uint32_t*)ResponseData) = 1;\r
-               \r
-                       return true;\r
-               case OID_GEN_CURRENT_PACKET_FILTER:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate the current packet filter mask */\r
-                       *((uint32_t*)ResponseData) = CurrPacketFilter;\r
-               \r
-                       return true;                    \r
-               case OID_GEN_XMIT_OK:\r
-               case OID_GEN_RCV_OK:\r
-               case OID_GEN_XMIT_ERROR:\r
-               case OID_GEN_RCV_ERROR:\r
-               case OID_GEN_RCV_NO_BUFFER:\r
-               case OID_802_3_RCV_ERROR_ALIGNMENT:\r
-               case OID_802_3_XMIT_ONE_COLLISION:\r
-               case OID_802_3_XMIT_MORE_COLLISIONS:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Unused statistic OIDs - always return 0 for each */\r
-                       *((uint32_t*)ResponseData) = 0;\r
-               \r
-                       return true;\r
-               case OID_GEN_MAXIMUM_TOTAL_SIZE:\r
-                       *ResponseSize = sizeof(uint32_t);\r
-                       \r
-                       /* Indicate maximum overall buffer (Ethernet frame and RNDIS header) the adapter can handle */\r
-                       *((uint32_t*)ResponseData) = (sizeof(RNDISMessageBuffer) + ETHERNET_FRAME_SIZE_MAX);\r
-               \r
-                       return true;\r
-               default:\r
-                       return false;\r
-       }\r
-}\r
-\r
-/** Processes RNDIS set commands, setting adapter parameters to values given by the host. The requested parameter is given \r
- *  as an OID value.\r
- *\r
- *  \param OId      OId value of the parameter being set\r
- *  \param SetData  Pointer to the parameter value in the RNDIS message buffer\r
- *  \param SetSize  Size in bytes of the parameter value being sent by the host\r
- *\r
- *  \return Boolean true if the set was handled, false otherwise\r
- */\r
-static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize)\r
-{\r
-       /* Handler for REMOTE_NDIS_SET_MSG messages */\r
-\r
-       switch (OId)\r
-       {\r
-               case OID_GEN_CURRENT_PACKET_FILTER:\r
-                       /* Save the packet filter mask in case the host queries it again later */\r
-                       CurrPacketFilter = *((uint32_t*)SetData);\r
-               \r
-                       /* Set the RNDIS state to initialized if the packet filter is non-zero */\r
-                       CurrRNDISState = ((CurrPacketFilter) ? RNDIS_Data_Initialized : RNDIS_Data_Initialized);\r
-                       \r
-                       return true;\r
-               case OID_802_3_MULTICAST_LIST:\r
-                       /* Do nothing - throw away the value from the host as it is unused */\r
-               \r
-                       return true;\r
-               default:\r
-                       return false;\r
-       }\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/RNDIS.h b/Demos/Device/RNDISEthernet/RNDIS.h
deleted file mode 100644 (file)
index 88c9a9e..0000000
+++ /dev/null
@@ -1,226 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for RNDIS.c.\r
- */\r
-\r
-#ifndef _RNDIS_H_\r
-#define _RNDIS_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               \r
-               #include "RNDISEthernet.h"\r
-               #include "RNDISConstants.h"\r
-               #include "Ethernet.h"\r
-\r
-       /* Macros: */\r
-               /** Physical MAC Address of the USB network adapter */\r
-               #define ADAPTER_MAC_ADDRESS                   {0x02, 0x00, 0x02, 0x00, 0x02, 0x00}\r
-       \r
-               /** Implemented RNDIS Version Major */\r
-               #define REMOTE_NDIS_VERSION_MAJOR             0x01\r
-\r
-               /** Implemented RNDIS Version Minor */\r
-               #define REMOTE_NDIS_VERSION_MINOR             0x00\r
-       \r
-               /** RNDIS request to issue a host-to-device NDIS command */\r
-               #define REQ_SendEncapsulatedCommand           0x00\r
-\r
-               /** RNDIS request to issue a device-to-host NDIS response */\r
-               #define REQ_GetEncapsulatedResponse           0x01\r
-               \r
-       /* Enums: */\r
-               /** Enum for the possible NDIS adapter states. */\r
-               enum RNDIS_States_t\r
-               {\r
-                       RNDIS_Uninitialized    = 0, /**< Adapter currently uninitialized */\r
-                       RNDIS_Initialized      = 1, /**< Adapter currently initialized but not ready for data transfers */\r
-                       RNDIS_Data_Initialized = 2, /**< Adapter currently initialized and ready for data transfers */\r
-               };\r
-\r
-               /** Enum for the NDIS hardware states */\r
-               enum NDIS_Hardware_Status_t\r
-               {\r
-                       NdisHardwareStatusReady, /**< Hardware Ready to accept commands from the host */\r
-                       NdisHardwareStatusInitializing, /**< Hardware busy initializing */\r
-                       NdisHardwareStatusReset, /**< Hardware reset */\r
-                       NdisHardwareStatusClosing, /**< Hardware currently closing */\r
-                       NdisHardwareStatusNotReady /**< Hardware not ready to accept commands from the host */\r
-               };\r
-\r
-       /* Type Defines: */\r
-               /** Type define for a RNDIS message header, sent before RNDIS messages */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType; /**< RNDIS message type, a REMOTE_NDIS_*_MSG constant */\r
-                       uint32_t MessageLength; /**< Total length of the RNDIS message, in bytes */\r
-               } RNDIS_Message_Header_t;\r
-\r
-               /** Type define for a RNDIS packet message, used to encapsulate Ethernet packets sent to and from the adapter */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t DataOffset;\r
-                       uint32_t DataLength;\r
-                       uint32_t OOBDataOffset;\r
-                       uint32_t OOBDataLength;\r
-                       uint32_t NumOOBDataElements;\r
-                       uint32_t PerPacketInfoOffset;\r
-                       uint32_t PerPacketInfoLength;\r
-                       uint32_t VcHandle;\r
-                       uint32_t Reserved;\r
-               } RNDIS_PACKET_MSG_t;\r
-       \r
-               /** Type define for a RNDIS Initialize command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       \r
-                       uint32_t MajorVersion;\r
-                       uint32_t MinorVersion;\r
-                       uint32_t MaxTransferSize;\r
-               } RNDIS_INITIALIZE_MSG_t;\r
-               \r
-               /** Type define for a RNDIS Initialize complete response message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-                       \r
-                       uint32_t MajorVersion;\r
-                       uint32_t MinorVersion;\r
-                       uint32_t DeviceFlags;\r
-                       uint32_t Medium;\r
-                       uint32_t MaxPacketsPerTransfer;\r
-                       uint32_t MaxTransferSize;\r
-                       uint32_t PacketAlignmentFactor;\r
-                       uint32_t AFListOffset;\r
-                       uint32_t AFListSize;\r
-               } RNDIS_INITIALIZE_CMPLT_t;\r
-               \r
-               /** Type define for a RNDIS Keepalive command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-               } RNDIS_KEEPALIVE_MSG_t;\r
-\r
-               /** Type define for a RNDIS Keepalive complete message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-               } RNDIS_KEEPALIVE_CMPLT_t;\r
-\r
-               /** Type define for a RNDIS Reset complete message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t Status;\r
-\r
-                       uint32_t AddressingReset;\r
-               } RNDIS_RESET_CMPLT_t;\r
-               \r
-               /** Type define for a RNDIS Set command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       \r
-                       uint32_t Oid;\r
-                       uint32_t InformationBufferLength;\r
-                       uint32_t InformationBufferOffset;\r
-                       uint32_t DeviceVcHandle;\r
-               } RNDIS_SET_MSG_t;\r
-\r
-               /** Type define for a RNDIS Set complete response message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-               } RNDIS_SET_CMPLT_t;\r
-               \r
-               /** Type define for a RNDIS Query command message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       \r
-                       uint32_t Oid;\r
-                       uint32_t InformationBufferLength;\r
-                       uint32_t InformationBufferOffset;\r
-                       uint32_t DeviceVcHandle;\r
-               } RNDIS_QUERY_MSG_t;\r
-               \r
-               /** Type define for a RNDIS Query complete response message */\r
-               typedef struct\r
-               {\r
-                       uint32_t MessageType;\r
-                       uint32_t MessageLength;\r
-                       uint32_t RequestId;\r
-                       uint32_t Status;\r
-                       \r
-                       uint32_t InformationBufferLength;\r
-                       uint32_t InformationBufferOffset;\r
-               } RNDIS_QUERY_CMPLT_t;\r
-               \r
-       /* External Variables: */\r
-               extern uint8_t                 RNDISMessageBuffer[];\r
-               extern RNDIS_Message_Header_t* MessageHeader;\r
-               extern bool                    ResponseReady;\r
-               extern uint8_t                 CurrRNDISState;\r
-\r
-       /* Function Prototypes: */\r
-               void ProcessRNDISControlMessage(void);\r
-\r
-               #if defined(INCLUDE_FROM_RNDIS_C)\r
-                       static bool ProcessNDISQuery(uint32_t OId, void* QueryData, uint16_t QuerySize,\r
-                                                                                void* ResponseData, uint16_t* ResponseSize);\r
-                       static bool ProcessNDISSet(uint32_t OId, void* SetData, uint16_t SetSize);      \r
-               #endif\r
-               \r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/RNDISConstants.h b/Demos/Device/RNDISEthernet/RNDISConstants.h
deleted file mode 100644 (file)
index ad66f62..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  RNDIS specification related constants. For more information on these\r
- *  constants, please refer to the Microsoft RNDIS specification.\r
- */\r
\r
-#ifndef _RNDIS_CONSTANTS_H_\r
-#define _RNDIS_CONSTANTS_H_\r
-\r
-       /* Macros: */\r
-               #define REMOTE_NDIS_PACKET_MSG                0x00000001UL\r
-               #define REMOTE_NDIS_INITIALIZE_MSG            0x00000002UL\r
-               #define REMOTE_NDIS_HALT_MSG                  0x00000003UL\r
-               #define REMOTE_NDIS_QUERY_MSG                 0x00000004UL\r
-               #define REMOTE_NDIS_SET_MSG                   0x00000005UL\r
-               #define REMOTE_NDIS_RESET_MSG                 0x00000006UL\r
-               #define REMOTE_NDIS_INDICATE_STATUS_MSG       0x00000007UL\r
-               #define REMOTE_NDIS_KEEPALIVE_MSG             0x00000008UL\r
-\r
-               #define REMOTE_NDIS_INITIALIZE_CMPLT          0x80000002UL\r
-               #define REMOTE_NDIS_QUERY_CMPLT               0x80000004UL\r
-               #define REMOTE_NDIS_SET_CMPLT                 0x80000005UL\r
-               #define REMOTE_NDIS_RESET_CMPLT               0x80000006UL\r
-               #define REMOTE_NDIS_KEEPALIVE_CMPLT           0x80000008UL\r
-               \r
-               #define REMOTE_NDIS_STATUS_SUCCESS            0x00000000UL\r
-               #define REMOTE_NDIS_STATUS_FAILURE            0xC0000001UL\r
-               #define REMOTE_NDIS_STATUS_INVALID_DATA       0xC0010015UL\r
-               #define REMOTE_NDIS_STATUS_NOT_SUPPORTED      0xC00000BBUL\r
-               #define REMOTE_NDIS_STATUS_MEDIA_CONNECT      0x4001000BUL\r
-               #define REMOTE_NDIS_STATUS_MEDIA_DISCONNECT   0x4001000CUL\r
-               \r
-               #define REMOTE_NDIS_MEDIA_STATE_CONNECTED     0x00000000UL\r
-               #define REMOTE_NDIS_MEDIA_STATE_DISCONNECTED  0x00000001UL\r
-               \r
-               #define REMOTE_NDIS_MEDIUM_802_3              0x00000000UL\r
-               \r
-               #define REMOTE_NDIS_DF_CONNECTIONLESS         0x00000001UL\r
-               #define REMOTE_NDIS_DF_CONNECTION_ORIENTED    0x00000002UL\r
-               \r
-               #define OID_GEN_SUPPORTED_LIST                0x00010101UL\r
-               #define OID_GEN_HARDWARE_STATUS               0x00010102UL\r
-               #define OID_GEN_MEDIA_SUPPORTED               0x00010103UL\r
-               #define OID_GEN_MEDIA_IN_USE                  0x00010104UL\r
-               #define OID_GEN_MAXIMUM_FRAME_SIZE            0x00010106UL\r
-               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
-               #define OID_GEN_LINK_SPEED                    0x00010107UL\r
-               #define OID_GEN_TRANSMIT_BLOCK_SIZE           0x0001010AUL\r
-               #define OID_GEN_RECEIVE_BLOCK_SIZE            0x0001010BUL\r
-               #define OID_GEN_VENDOR_ID                     0x0001010CUL\r
-               #define OID_GEN_VENDOR_DESCRIPTION            0x0001010DUL\r
-               #define OID_GEN_CURRENT_PACKET_FILTER         0x0001010EUL\r
-               #define OID_GEN_MAXIMUM_TOTAL_SIZE            0x00010111UL\r
-               #define OID_GEN_MEDIA_CONNECT_STATUS          0x00010114UL\r
-               #define OID_GEN_PHYSICAL_MEDIUM               0x00010202UL\r
-               #define OID_GEN_XMIT_OK                       0x00020101UL\r
-               #define OID_GEN_RCV_OK                        0x00020102UL\r
-               #define OID_GEN_XMIT_ERROR                    0x00020103UL\r
-               #define OID_GEN_RCV_ERROR                     0x00020104UL\r
-               #define OID_GEN_RCV_NO_BUFFER                 0x00020105UL\r
-               #define OID_802_3_PERMANENT_ADDRESS           0x01010101UL\r
-               #define OID_802_3_CURRENT_ADDRESS             0x01010102UL\r
-               #define OID_802_3_MULTICAST_LIST              0x01010103UL\r
-               #define OID_802_3_MAXIMUM_LIST_SIZE           0x01010104UL\r
-               #define OID_802_3_RCV_ERROR_ALIGNMENT         0x01020101UL\r
-               #define OID_802_3_XMIT_ONE_COLLISION          0x01020102UL\r
-               #define OID_802_3_XMIT_MORE_COLLISIONS        0x01020103UL\r
-\r
-#endif\r
index 7c3c8da..703af40 100644 (file)
                #include <stdio.h>\r
 \r
                #include "Descriptors.h"\r
-               #include "RNDIS.h"\r
-               #include "Ethernet.h"\r
-               #include "TCP.h"\r
-               #include "ARP.h"\r
-               #include "Webserver.h"\r
+\r
+               #include "Lib/RNDIS.h"\r
+               #include "Lib/Ethernet.h"\r
+               #include "Lib/TCP.h"\r
+               #include "Lib/ARP.h"\r
+               #include "Lib/Webserver.h"\r
 \r
                #include <LUFA/Version.h>                         // Library Version Information\r
                #include <LUFA/Drivers/USB/USB.h>                 // USB Functionality\r
diff --git a/Demos/Device/RNDISEthernet/TCP.c b/Demos/Device/RNDISEthernet/TCP.c
deleted file mode 100644 (file)
index f259aad..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Transmission Control Protocol (TCP) packet handling routines. This protocol handles the reliable in-order transmission\r
- *  and reception of packets to and from devices on a network, to "ports" on the device. It is used in situations where data\r
- *  delivery must be reliable and correct, e.g. HTTP, TELNET and most other non-streaming protocols.\r
- */\r
\r
-#define  INCLUDE_FROM_TCP_C\r
-#include "TCP.h"\r
-\r
-/* Global Variables: */\r
-/** Port state table array. This contains the current status of TCP ports in the device. To save on space, only open ports are\r
- *  stored - closed ports may be overwritten at any time, and the system will assume any ports not present in the array are closed. This\r
- *  allows for MAX_OPEN_TCP_PORTS to be less than the number of ports used by the application if desired.\r
- */\r
-TCP_PortState_t        PortStateTable[MAX_OPEN_TCP_PORTS];\r
-\r
-/** Connection state table array. This contains the current status of TCP connections in the device. To save on space, only active\r
- *  (non-closed) connections are stored - closed connections may be overwritten at any time, and the system will assume any connections\r
- *  not present in the array are closed.\r
- */\r
-TCP_ConnectionState_t  ConnectionStateTable[MAX_TCP_CONNECTIONS];\r
-\r
-\r
-/** Task to handle the calling of each registered application's callback function, to process and generate TCP packets at the application\r
- *  level. If an application produces a response, this task constructs the appropriate Ethernet frame and places it into the Ethernet OUT\r
- *  buffer for later transmission.\r
- */\r
-TASK(TCP_Task)\r
-{\r
-       /* Task to hand off TCP packets to and from the listening applications. */\r
-\r
-       /* Run each application in sequence, to process incoming and generate outgoing packets */\r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-       {\r
-               /* Find the corresponding port entry in the port table */\r
-               for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
-               {\r
-                       /* Run the application handler for the port */\r
-                       if ((PortStateTable[PTableEntry].Port  == ConnectionStateTable[CSTableEntry].Port) && \r
-                           (PortStateTable[PTableEntry].State == TCP_Port_Open))\r
-                       {\r
-                               PortStateTable[PTableEntry].ApplicationHandler(&ConnectionStateTable[CSTableEntry], &ConnectionStateTable[CSTableEntry].Info.Buffer);\r
-                       }\r
-               }\r
-       }\r
-       \r
-       /* Bail out early if there is already a frame waiting to be sent in the Ethernet OUT buffer */\r
-       if (FrameOUT.FrameInBuffer)\r
-         return;\r
-       \r
-       /* Send response packets from each application as the TCP packet buffers are filled by the applications */\r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-       {\r
-               /* For each completely received packet, pass it along to the listening application */\r
-               if ((ConnectionStateTable[CSTableEntry].Info.Buffer.Direction == TCP_PACKETDIR_OUT) &&\r
-                   (ConnectionStateTable[CSTableEntry].Info.Buffer.Ready))\r
-               {\r
-                       Ethernet_Frame_Header_t* FrameOUTHeader = (Ethernet_Frame_Header_t*)&FrameOUT.FrameData;\r
-                       IP_Header_t*             IPHeaderOUT    = (IP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t)];\r
-                       TCP_Header_t*            TCPHeaderOUT   = (TCP_Header_t*)&FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
-                                                                                                    sizeof(IP_Header_t)];                                              \r
-                       void*                    TCPDataOUT     = &FrameOUT.FrameData[sizeof(Ethernet_Frame_Header_t) +\r
-                                                                                     sizeof(IP_Header_t) +\r
-                                                                                     sizeof(TCP_Header_t)];\r
-\r
-                       uint16_t PacketSize = ConnectionStateTable[CSTableEntry].Info.Buffer.Length;\r
-\r
-                       /* Fill out the TCP data */\r
-                       TCPHeaderOUT->SourcePort           = ConnectionStateTable[CSTableEntry].Port;\r
-                       TCPHeaderOUT->DestinationPort      = ConnectionStateTable[CSTableEntry].RemotePort;\r
-                       TCPHeaderOUT->SequenceNumber       = SwapEndian_32(ConnectionStateTable[CSTableEntry].Info.SequenceNumberOut);\r
-                       TCPHeaderOUT->AcknowledgmentNumber = SwapEndian_32(ConnectionStateTable[CSTableEntry].Info.SequenceNumberIn);\r
-                       TCPHeaderOUT->DataOffset           = (sizeof(TCP_Header_t) / sizeof(uint32_t));\r
-                       TCPHeaderOUT->WindowSize           = SwapEndian_16(TCP_WINDOW_SIZE);\r
-\r
-                       TCPHeaderOUT->Flags                = TCP_FLAG_ACK;\r
-                       TCPHeaderOUT->UrgentPointer        = 0;\r
-                       TCPHeaderOUT->Checksum             = 0;\r
-                       TCPHeaderOUT->Reserved             = 0;\r
-\r
-                       memcpy(TCPDataOUT, ConnectionStateTable[CSTableEntry].Info.Buffer.Data, PacketSize);\r
-                       \r
-                       ConnectionStateTable[CSTableEntry].Info.SequenceNumberOut += PacketSize;\r
-\r
-                       TCPHeaderOUT->Checksum             = TCP_Checksum16(TCPHeaderOUT, ServerIPAddress,\r
-                                                                           ConnectionStateTable[CSTableEntry].RemoteAddress,\r
-                                                                           (sizeof(TCP_Header_t) + PacketSize));\r
-\r
-                       PacketSize += sizeof(TCP_Header_t);\r
-\r
-                       /* Fill out the response IP header */\r
-                       IPHeaderOUT->TotalLength        = SwapEndian_16(sizeof(IP_Header_t) + PacketSize);\r
-                       IPHeaderOUT->TypeOfService      = 0;\r
-                       IPHeaderOUT->HeaderLength       = (sizeof(IP_Header_t) / sizeof(uint32_t));\r
-                       IPHeaderOUT->Version            = 4;\r
-                       IPHeaderOUT->Flags              = 0;\r
-                       IPHeaderOUT->FragmentOffset     = 0;\r
-                       IPHeaderOUT->Identification     = 0;\r
-                       IPHeaderOUT->HeaderChecksum     = 0;\r
-                       IPHeaderOUT->Protocol           = PROTOCOL_TCP;\r
-                       IPHeaderOUT->TTL                = DEFAULT_TTL;\r
-                       IPHeaderOUT->SourceAddress      = ServerIPAddress;\r
-                       IPHeaderOUT->DestinationAddress = ConnectionStateTable[CSTableEntry].RemoteAddress;\r
-                       \r
-                       IPHeaderOUT->HeaderChecksum     = Ethernet_Checksum16(IPHeaderOUT, sizeof(IP_Header_t));\r
-               \r
-                       PacketSize += sizeof(IP_Header_t);\r
-               \r
-                       /* Fill out the response Ethernet frame header */\r
-                       FrameOUTHeader->Source          = ServerMACAddress;\r
-                       FrameOUTHeader->Destination     = (MAC_Address_t){{0x02, 0x00, 0x02, 0x00, 0x02, 0x00}};\r
-                       FrameOUTHeader->EtherType       = SwapEndian_16(ETHERTYPE_IPV4);\r
-\r
-                       PacketSize += sizeof(Ethernet_Frame_Header_t);\r
-\r
-                       /* Set the response length in the buffer and indicate that a response is ready to be sent */\r
-                       FrameOUT.FrameLength            = PacketSize;\r
-                       FrameOUT.FrameInBuffer          = true;\r
-                       \r
-                       ConnectionStateTable[CSTableEntry].Info.Buffer.Ready = false;\r
-                       \r
-                       break;\r
-               }\r
-       }\r
-}\r
-\r
-/** Initializes the TCP protocol handler, clearing the port and connection state tables. This must be called before TCP packets are\r
- *  processed.\r
- */\r
-void TCP_Init(void)\r
-{\r
-       /* Initialize the port state table with all CLOSED entries */\r
-       for (uint8_t PTableEntry = 0; PTableEntry < MAX_OPEN_TCP_PORTS; PTableEntry++)\r
-         PortStateTable[PTableEntry].State = TCP_Port_Closed;\r
-\r
-       /* Initialize the connection table with all CLOSED entries */\r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-         ConnectionStateTable[CSTableEntry].State = TCP_Connection_Closed;\r
-}\r
-\r
-/** Sets the state and callback handler of the given port, specified in big endian to the given state.\r
- *\r
- *  \param Port     Port whose state and callback function to set, specified in big endian\r
- *  \param State    New state of the port, a value from the TCP_PortStates_t enum\r
- *  \param Handler  Application callback handler for the port\r
- *\r
- *  \return Boolean true if the port state was set, false otherwise (no more space in the port state table)\r
- */\r
-bool TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*))\r
-{\r
-       /* Note, Port number should be specified in BIG endian to simplify network code */\r
-\r
-       /* Check to see if the port entry is already in the port state table */\r
-       for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
-       {\r
-               /* Find existing entry for the port in the table, update it if found */\r
-               if (PortStateTable[PTableEntry].Port == Port)\r
-               {\r
-                       PortStateTable[PTableEntry].State = State;\r
-                       PortStateTable[PTableEntry].ApplicationHandler = Handler;\r
-                       return true;\r
-               }\r
-       }\r
-\r
-       /* Check if trying to open the port -- if so we need to find an unused (closed) entry and replace it */\r
-       if (State == TCP_Port_Open)\r
-       {\r
-               for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
-               {\r
-                       /* Find a closed port entry in the table, change it to the given port and state */\r
-                       if (PortStateTable[PTableEntry].State == TCP_Port_Closed)\r
-                       {\r
-                               PortStateTable[PTableEntry].Port  = Port;\r
-                               PortStateTable[PTableEntry].State = State;\r
-                               PortStateTable[PTableEntry].ApplicationHandler = Handler;\r
-                               return true;\r
-                       }\r
-               }\r
-               \r
-               /* Port not in table and no room to add it, return failure */\r
-               return false;\r
-       }\r
-       else\r
-       {\r
-               /* Port not in table but trying to close it, so operation successful */\r
-               return true;\r
-       }\r
-}\r
-\r
-/** Retrieves the current state of a given TCP port, specified in big endian.\r
- *\r
- *  \param Port  TCP port whose state is to be retrieved, given in big-endian\r
- *\r
- *  \return A value from the TCP_PortStates_t enum\r
- */\r
-uint8_t TCP_GetPortState(uint16_t Port)\r
-{\r
-       /* Note, Port number should be specified in BIG endian to simplify network code */\r
-\r
-       for (uint8_t PTableEntry = 0; PTableEntry < MAX_TCP_CONNECTIONS; PTableEntry++)\r
-       {\r
-               /* Find existing entry for the port in the table, return the port status if found */\r
-               if (PortStateTable[PTableEntry].Port == Port)\r
-                 return PortStateTable[PTableEntry].State;\r
-       }\r
-       \r
-       /* Port not in table, assume closed */\r
-       return TCP_Port_Closed;\r
-}\r
-\r
-/** Sets the connection state of the given port, remote address and remote port to the given TCP connection state. If the\r
- *  connection exists in the connection state table it is updated, otherwise it is created if possible.\r
- *\r
- *  \param Port           TCP port of the connection on the device, specified in big endian\r
- *  \param RemoteAddress  Remote protocol IP address of the connected device\r
- *  \param RemotePort     TCP port of the remote device in the connection, specified in big endian\r
- *  \param State          TCP connection state, a value from the TCP_ConnectionStates_t enum\r
- *\r
- *  \return Boolean true if the connection was updated or created, false otherwise (no more space in the connection state table)\r
- */\r
-bool TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort, uint8_t State)\r
-{\r
-       /* Note, Port number should be specified in BIG endian to simplify network code */\r
-\r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-       {\r
-               /* Find port entry in the table */\r
-               if ((ConnectionStateTable[CSTableEntry].Port == Port) &&\r
-                    IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) &&\r
-                        ConnectionStateTable[CSTableEntry].RemotePort == RemotePort)\r
-               {\r
-                       ConnectionStateTable[CSTableEntry].State = State;\r
-                       return true;\r
-               }\r
-       }\r
-       \r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-       {\r
-               /* Find empty entry in the table */\r
-               if (ConnectionStateTable[CSTableEntry].State == TCP_Connection_Closed)\r
-               {\r
-                       ConnectionStateTable[CSTableEntry].Port          = Port;\r
-                       ConnectionStateTable[CSTableEntry].RemoteAddress = RemoteAddress;                       \r
-                       ConnectionStateTable[CSTableEntry].RemotePort    = RemotePort;\r
-                       ConnectionStateTable[CSTableEntry].State         = State;\r
-                       return true;\r
-               }\r
-       }\r
-       \r
-       return false;\r
-}\r
-\r
-/** Retrieves the current state of a given TCP connection to a host.\r
- *\r
- *  \param Port           TCP port on the device in the connection, specified in big endian\r
- *  \param RemoteAddress  Remote protocol IP address of the connected host\r
- *  \param RemotePort     Remote TCP port of the connected host, specified in big endian\r
- *\r
- *  \return A value from the TCP_ConnectionStates_t enum\r
- */\r
-uint8_t TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort)\r
-{\r
-       /* Note, Port number should be specified in BIG endian to simplify network code */\r
-\r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-       {\r
-               /* Find port entry in the table */\r
-               if ((ConnectionStateTable[CSTableEntry].Port == Port) &&\r
-                    IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) &&\r
-                        ConnectionStateTable[CSTableEntry].RemotePort == RemotePort)\r
-                        \r
-               {\r
-                       return ConnectionStateTable[CSTableEntry].State;\r
-               }\r
-       }\r
-       \r
-       return TCP_Connection_Closed;\r
-}\r
-\r
-/** Retrieves the connection info structure of a given connection to a host.\r
- *\r
- *  \param Port           TCP port on the device in the connection, specified in big endian\r
- *  \param RemoteAddress  Remote protocol IP address of the connected host\r
- *  \param RemotePort     Remote TCP port of the connected host, specified in big endian\r
- *\r
- *  \return ConnectionInfo structure of the connection if found, NULL otherwise\r
- */\r
-TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort)\r
-{\r
-       /* Note, Port number should be specified in BIG endian to simplify network code */\r
-\r
-       for (uint8_t CSTableEntry = 0; CSTableEntry < MAX_TCP_CONNECTIONS; CSTableEntry++)\r
-       {\r
-               /* Find port entry in the table */\r
-               if ((ConnectionStateTable[CSTableEntry].Port == Port) &&\r
-                    IP_COMPARE(&ConnectionStateTable[CSTableEntry].RemoteAddress, &RemoteAddress) &&\r
-                        ConnectionStateTable[CSTableEntry].RemotePort == RemotePort)\r
-               {\r
-                       return &ConnectionStateTable[CSTableEntry].Info;\r
-               }\r
-       }\r
-       \r
-       return NULL;\r
-}\r
-\r
-/** Processes a TCP packet inside an Ethernet frame, and writes the appropriate response\r
- *  to the output Ethernet frame if one is created by a application handler.\r
- *\r
- *  \param IPHeaderInStart    Pointer to the start of the incoming packet's IP header\r
- *  \param TCPHeaderInStart   Pointer to the start of the incoming packet's TCP header\r
- *  \param TCPHeaderOutStart  Pointer to the start of the outgoing packet's TCP header\r
- *\r
- *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE if no\r
- *           response was generated, NO_PROCESS if the packet processing was deferred until the\r
- *           next Ethernet packet handler iteration\r
- */\r
-int16_t TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void* TCPHeaderOutStart)\r
-{\r
-       IP_Header_t*  IPHeaderIN   = (IP_Header_t*)IPHeaderInStart;\r
-       TCP_Header_t* TCPHeaderIN  = (TCP_Header_t*)TCPHeaderInStart;\r
-       TCP_Header_t* TCPHeaderOUT = (TCP_Header_t*)TCPHeaderOutStart;\r
-\r
-       TCP_ConnectionInfo_t* ConnectionInfo;\r
-       \r
-       DecodeTCPHeader(TCPHeaderInStart);\r
-\r
-       bool PacketResponse = false;\r
-               \r
-       /* Check if the destination port is open and allows incoming connections */\r
-       if (TCP_GetPortState(TCPHeaderIN->DestinationPort) == TCP_Port_Open)\r
-       {\r
-               /* Detect SYN from host to start a connection */\r
-               if (TCPHeaderIN->Flags & TCP_FLAG_SYN)\r
-                 TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort, TCP_Connection_Listen);\r
-\r
-               /* Detect RST from host to abort existing connection */\r
-               if (TCPHeaderIN->Flags & TCP_FLAG_RST)\r
-               {\r
-                       TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK);                            \r
-                       PacketResponse = true;\r
-                       \r
-                       TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                              TCPHeaderIN->SourcePort, TCP_Connection_Closed);                 \r
-               }\r
-               else\r
-               {\r
-                       /* Process the incoming TCP packet based on the current connection state for the sender and port */\r
-                       switch (TCP_GetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort))\r
-                       {\r
-                               case TCP_Connection_Listen:\r
-                                       if (TCPHeaderIN->Flags == TCP_FLAG_SYN)\r
-                                       {\r
-                                               /* SYN connection when closed starts a connection with a peer */\r
-\r
-                                               TCPHeaderOUT->Flags = (TCP_FLAG_SYN | TCP_FLAG_ACK);                            \r
-                                               PacketResponse      = true;\r
-                                                                       \r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort,\r
-                                                                                          TCP_Connection_SYNReceived);\r
-                                                                                          \r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress, TCPHeaderIN->SourcePort);\r
-\r
-                                               ConnectionInfo->SequenceNumberIn  = (SwapEndian_32(TCPHeaderIN->SequenceNumber) + 1);\r
-                                               ConnectionInfo->SequenceNumberOut = 0;\r
-                                               ConnectionInfo->Buffer.InUse      = false;\r
-                                       }\r
-                                       \r
-                                       break;\r
-                               case TCP_Connection_SYNReceived:\r
-                                       if (TCPHeaderIN->Flags == TCP_FLAG_ACK)\r
-                                       {\r
-                                               /* ACK during the connection process completes the connection to a peer */\r
-\r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Established);\r
-\r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                                                          TCPHeaderIN->SourcePort);\r
-                                                                                                                          \r
-                                               ConnectionInfo->SequenceNumberOut++;\r
-                                       }\r
-                                       \r
-                                       break;\r
-                               case TCP_Connection_Established:\r
-                                       if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK))\r
-                                       {\r
-                                               /* FIN ACK when connected to a peer starts the finalization process */\r
-                                       \r
-                                               TCPHeaderOUT->Flags = (TCP_FLAG_FIN | TCP_FLAG_ACK);                            \r
-                                               PacketResponse      = true;\r
-                                               \r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_CloseWait);\r
-\r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                                                          TCPHeaderIN->SourcePort);\r
-\r
-                                               ConnectionInfo->SequenceNumberIn++;\r
-                                               ConnectionInfo->SequenceNumberOut++;\r
-                                       }\r
-                                       else if ((TCPHeaderIN->Flags == TCP_FLAG_ACK) || (TCPHeaderIN->Flags == (TCP_FLAG_ACK | TCP_FLAG_PSH)))\r
-                                       {\r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                                                          TCPHeaderIN->SourcePort);\r
-\r
-                                               /* Check if the buffer is currently in use either by a buffered data to send, or receive */             \r
-                                               if ((ConnectionInfo->Buffer.InUse == false) && (ConnectionInfo->Buffer.Ready == false))\r
-                                               {                                               \r
-                                                       ConnectionInfo->Buffer.Direction = TCP_PACKETDIR_IN;\r
-                                                       ConnectionInfo->Buffer.InUse     = true;\r
-                                                       ConnectionInfo->Buffer.Length    = 0;\r
-                                               }\r
-                                               \r
-                                               /* Check if the buffer has been claimed by us to read in data from the peer */\r
-                                               if ((ConnectionInfo->Buffer.Direction == TCP_PACKETDIR_IN) &&\r
-                                                       (ConnectionInfo->Buffer.Length != TCP_WINDOW_SIZE))\r
-                                               {\r
-                                                       uint16_t IPOffset   = (IPHeaderIN->HeaderLength * sizeof(uint32_t));\r
-                                                       uint16_t TCPOffset  = (TCPHeaderIN->DataOffset * sizeof(uint32_t));\r
-                                                       uint16_t DataLength = (SwapEndian_16(IPHeaderIN->TotalLength) - IPOffset - TCPOffset);\r
-\r
-                                                       /* Copy the packet data into the buffer */\r
-                                                       memcpy(&ConnectionInfo->Buffer.Data[ConnectionInfo->Buffer.Length],\r
-                                                                  &((uint8_t*)TCPHeaderInStart)[TCPOffset],\r
-                                                                  DataLength);\r
-\r
-                                                       ConnectionInfo->SequenceNumberIn += DataLength;\r
-                                                       ConnectionInfo->Buffer.Length    += DataLength;\r
-                                                       \r
-                                                       /* Check if the buffer is full or if the PSH flag is set, if so indicate buffer ready */\r
-                                                       if ((!(TCP_WINDOW_SIZE - ConnectionInfo->Buffer.Length)) || (TCPHeaderIN->Flags & TCP_FLAG_PSH))\r
-                                                       {\r
-                                                               ConnectionInfo->Buffer.InUse = false;\r
-                                                               ConnectionInfo->Buffer.Ready = true;\r
-\r
-                                                               TCPHeaderOUT->Flags = TCP_FLAG_ACK;\r
-                                                               PacketResponse      = true;\r
-                                                       }\r
-                                               }\r
-                                               else\r
-                                               {\r
-                                                       /* Buffer is currently in use by the application, defer processing of the incoming packet */\r
-                                                       return NO_PROCESS;\r
-                                               }\r
-                                       }\r
-                                       \r
-                                       break;\r
-                               case TCP_Connection_Closing:\r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                                                          TCPHeaderIN->SourcePort);\r
-\r
-                                               TCPHeaderOUT->Flags = (TCP_FLAG_ACK | TCP_FLAG_FIN);\r
-                                               PacketResponse      = true;\r
-                                               \r
-                                               ConnectionInfo->Buffer.InUse = false;\r
-                                               \r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_FINWait1);\r
-\r
-                                       break;\r
-                               case TCP_Connection_FINWait1:\r
-                                       if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK))\r
-                                       {\r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                                                          TCPHeaderIN->SourcePort);\r
-\r
-                                               TCPHeaderOUT->Flags = TCP_FLAG_ACK;\r
-                                               PacketResponse      = true;\r
-\r
-                                               ConnectionInfo->SequenceNumberIn++;\r
-                                               ConnectionInfo->SequenceNumberOut++;\r
-                                               \r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Closed);\r
-                                       }\r
-                                       else if (TCPHeaderIN->Flags == TCP_FLAG_ACK)\r
-                                       {\r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_FINWait2);\r
-                                       }\r
-                                       \r
-                                       break;\r
-                               case TCP_Connection_FINWait2:\r
-                                       if (TCPHeaderIN->Flags == (TCP_FLAG_FIN | TCP_FLAG_ACK))\r
-                                       {\r
-                                               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                                                          TCPHeaderIN->SourcePort);\r
-\r
-                                               TCPHeaderOUT->Flags = TCP_FLAG_ACK;\r
-                                               PacketResponse      = true;\r
-\r
-                                               ConnectionInfo->SequenceNumberIn++;\r
-                                               ConnectionInfo->SequenceNumberOut++;\r
-                                               \r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Closed);\r
-                                       }\r
-                               \r
-                                       break;\r
-                               case TCP_Connection_CloseWait:\r
-                                       if (TCPHeaderIN->Flags == TCP_FLAG_ACK)\r
-                                       {\r
-                                               TCP_SetConnectionState(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                                                          TCPHeaderIN->SourcePort, TCP_Connection_Closed);\r
-                                       }\r
-                                       \r
-                                       break;\r
-                       }\r
-               }\r
-       }\r
-       else\r
-       {\r
-               /* Port is not open, indicate via a RST/ACK response to the sender */\r
-               TCPHeaderOUT->Flags = (TCP_FLAG_RST | TCP_FLAG_ACK);                            \r
-               PacketResponse      = true;\r
-       }\r
-       \r
-       /* Check if we need to respond to the sent packet */\r
-       if (PacketResponse)\r
-       {\r
-               ConnectionInfo = TCP_GetConnectionInfo(TCPHeaderIN->DestinationPort, IPHeaderIN->SourceAddress,\r
-                                                      TCPHeaderIN->SourcePort);\r
-\r
-               TCPHeaderOUT->SourcePort           = TCPHeaderIN->DestinationPort;\r
-               TCPHeaderOUT->DestinationPort      = TCPHeaderIN->SourcePort;\r
-               TCPHeaderOUT->SequenceNumber       = SwapEndian_32(ConnectionInfo->SequenceNumberOut);\r
-               TCPHeaderOUT->AcknowledgmentNumber = SwapEndian_32(ConnectionInfo->SequenceNumberIn);\r
-               TCPHeaderOUT->DataOffset           = (sizeof(TCP_Header_t) / sizeof(uint32_t));\r
-               \r
-               if (!(ConnectionInfo->Buffer.InUse))\r
-                 TCPHeaderOUT->WindowSize         = SwapEndian_16(TCP_WINDOW_SIZE);\r
-               else\r
-                 TCPHeaderOUT->WindowSize         = SwapEndian_16(TCP_WINDOW_SIZE - ConnectionInfo->Buffer.Length);\r
-\r
-               TCPHeaderOUT->UrgentPointer        = 0;\r
-               TCPHeaderOUT->Checksum             = 0;\r
-               TCPHeaderOUT->Reserved             = 0;\r
-               \r
-               TCPHeaderOUT->Checksum             = TCP_Checksum16(TCPHeaderOUT, IPHeaderIN->DestinationAddress,\r
-                                                                   IPHeaderIN->SourceAddress, sizeof(TCP_Header_t));                                   \r
-\r
-               return sizeof(TCP_Header_t);    \r
-       }\r
-\r
-       return NO_RESPONSE;\r
-}\r
-\r
-/** Calculates the appropriate TCP checksum, consisting of the addition of the one's compliment of each word,\r
- *  complimented.\r
- *\r
- *  \param TCPHeaderOutStart  Pointer to the start of the packet's outgoing TCP header\r
- *  \param SourceAddress      Source protocol IP address of the outgoing IP header\r
- *  \param SourceAddress      DestinationAddress protocol IP address of the outgoing IP header\r
- *  \param TCPOutSize         Size in bytes of the TCP data header and payload\r
- *\r
- *  \return A 16-bit TCP checksum value\r
- */\r
-static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddress,\r
-                               IP_Address_t DestinationAddress, uint16_t TCPOutSize)\r
-{\r
-       uint32_t Checksum = 0;\r
-       \r
-       /* TCP/IP checksums are the addition of the one's compliment of each word including the IP pseudo-header,\r
-          complimented */\r
-       \r
-       Checksum += ((uint16_t*)&SourceAddress)[0];\r
-       Checksum += ((uint16_t*)&SourceAddress)[1];\r
-       Checksum += ((uint16_t*)&DestinationAddress)[0];\r
-       Checksum += ((uint16_t*)&DestinationAddress)[1];\r
-       Checksum += SwapEndian_16(PROTOCOL_TCP);\r
-       Checksum += SwapEndian_16(TCPOutSize);\r
-\r
-       for (uint8_t CurrWord = 0; CurrWord < (TCPOutSize >> 1); CurrWord++)\r
-         Checksum += ((uint16_t*)TCPHeaderOutStart)[CurrWord];\r
-       \r
-       if (TCPOutSize & 0x01)\r
-         Checksum += (((uint16_t*)TCPHeaderOutStart)[TCPOutSize >> 1] & 0x00FF);\r
-         \r
-       while (Checksum & 0xFFFF0000)\r
-         Checksum = ((Checksum & 0xFFFF) + (Checksum >> 16));\r
-       \r
-       return ~Checksum;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/TCP.h b/Demos/Device/RNDISEthernet/TCP.h
deleted file mode 100644 (file)
index d4b72a5..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for TCP.c.\r
- */\r
-\r
-#ifndef _TCP_H_\r
-#define _TCP_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               \r
-               #include <LUFA/Scheduler/Scheduler.h>\r
-               \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               #include "ProtocolDecoders.h"\r
-               \r
-       /* Macros: */\r
-               /** Maximum number of TCP ports which can be open at the one time */\r
-               #define MAX_OPEN_TCP_PORTS              1\r
-\r
-               /** Maximum number of TCP connections which can be sustained at the one time */\r
-               #define MAX_TCP_CONNECTIONS             1\r
-\r
-               /** TCP window size, giving the maximum number of bytes which can be buffered at the one time */\r
-               #define TCP_WINDOW_SIZE                 1024\r
-               \r
-               /** Port number for HTTP transmissions */\r
-               #define TCP_PORT_HTTP                   SwapEndian_16(80)\r
-               \r
-               /** Data direction indicator for a TCP application buffer, indicating data from host-to-device */\r
-               #define TCP_PACKETDIR_IN                false\r
-\r
-               /** Data direction indicator for a TCP application buffer, indicating data from device-to-host */\r
-               #define TCP_PACKETDIR_OUT               true\r
-               \r
-               /** Congestion Window Reduced TCP flag mask */\r
-               #define TCP_FLAG_CWR                    (1 << 7)\r
-\r
-               /** Explicit Congestion Notification TCP flag mask */\r
-               #define TCP_FLAG_ECE                    (1 << 6)\r
-\r
-               /** Urgent TCP flag mask */\r
-               #define TCP_FLAG_URG                    (1 << 5)\r
-\r
-               /** Data Acknowledge TCP flag mask */\r
-               #define TCP_FLAG_ACK                    (1 << 4)\r
-\r
-               /** Data Push TCP flag mask */\r
-               #define TCP_FLAG_PSH                    (1 << 3)\r
-\r
-               /** Reset TCP flag mask */\r
-               #define TCP_FLAG_RST                    (1 << 2)\r
-\r
-               /** Synchronize TCP flag mask */\r
-               #define TCP_FLAG_SYN                    (1 << 1)\r
-\r
-               /** Connection Finalize TCP flag mask */\r
-               #define TCP_FLAG_FIN                    (1 << 0)\r
-               \r
-               /** Application macro: Determines if the given application buffer contains a packet received from the host\r
-                *\r
-                *  \param Buffer  Application buffer to check\r
-                *\r
-                *  \return Boolean true if the buffer contains a packet from the host, false otherwise\r
-                */\r
-               #define TCP_APP_HAS_RECEIVED_PACKET(Buffer)  (Buffer->Ready && (Buffer->Direction == TCP_PACKETDIR_IN))\r
-\r
-               /** Application macro: Indicates if the application buffer is currently locked by the application for device-to-host transfers.\r
-                *\r
-                *  \param Buffer  Application buffer to check\r
-                *\r
-                *  \return Boolean true if the buffer has been captured by the application for device-to-host transmissions, false otherwise\r
-                */\r
-               #define TCP_APP_HAVE_CAPTURED_BUFFER(Buffer) (!(Buffer->Ready) && Buffer->InUse && \\r
-                                                             (Buffer->Direction == TCP_PACKETDIR_OUT))\r
-\r
-               /** Application macro: Indicates if the application can lock the buffer for multiple continued device-to-host transmissions.\r
-                *\r
-                *  \param Buffer  Application buffer to check\r
-                *\r
-                *  \return Boolean true if the buffer may be captured by the application for device-to-host transmissions, false otherwise\r
-                */\r
-               #define TCP_APP_CAN_CAPTURE_BUFFER(Buffer)   Buffer->InUse\r
-\r
-               /** Application macro: Captures the application buffer, locking it for device-to-host transmissions only. This should be\r
-                *  performed when the application needs to transmit several packets worth of data in succession with no interruptions from the host.\r
-                *\r
-                *  \note The application must check that the buffer can be locked first using TCP_APP_CAN_CAPTURE_BUFFER().\r
-                *\r
-                *  \param Buffer  Application buffer to lock\r
-                */\r
-               #define TCP_APP_CAPTURE_BUFFER(Buffer)       MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->InUse = true; }MACROE\r
-\r
-               /** Application macro: Releases a captured application buffer, allowing for host-to-device packets to be received.\r
-                *\r
-                *  \param Buffer  Application buffer to release\r
-                */\r
-               #define TCP_APP_RELEASE_BUFFER(Buffer)       MACROS{ Buffer->InUse = false; }MACROE\r
-\r
-               /** Application macro: Sends the contents of the given application buffer to the host.\r
-                *\r
-                *  \param Buffer  Application buffer to send\r
-                *  \param Len     Length of data contained in the buffer\r
-                */\r
-               #define TCP_APP_SEND_BUFFER(Buffer, Len)     MACROS{ Buffer->Direction = TCP_PACKETDIR_OUT; Buffer->Length = Len; Buffer->Ready = true; }MACROE\r
-\r
-               /** Application macro: Clears the application buffer, ready for a packet to be written to it.\r
-                *\r
-                *  \param Buffer  Application buffer to clear\r
-                */\r
-               #define TCP_APP_CLEAR_BUFFER(Buffer)         MACROS{ Buffer->Ready = false; Buffer->Length = 0; }MACROE\r
-               \r
-               /** Application macro: Closes an open connection to a host.\r
-                *\r
-                *  \param Connection  Open TCP connection to close\r
-                */\r
-               #define TCP_APP_CLOSECONNECTION(Connection)  MACROS{ Connection->State = TCP_Connection_Closing;  }MACROE\r
-\r
-       /* Enums: */\r
-               /** Enum for possible TCP port states */\r
-               enum TCP_PortStates_t\r
-               {\r
-                       TCP_Port_Closed            = 0, /**< TCP port closed, no connections to a host may be made on this port. */\r
-                       TCP_Port_Open              = 1, /**< TCP port open, connections to a host may be made on this port. */\r
-               };\r
-       \r
-               /** Enum for possible TCP connection states */\r
-               enum TCP_ConnectionStates_t\r
-               {\r
-                       TCP_Connection_Listen      = 0, /**< Listening for a connection from a host */\r
-                       TCP_Connection_SYNSent     = 1, /**< Unused */\r
-                       TCP_Connection_SYNReceived = 2, /**< SYN received, waiting for ACK */\r
-                       TCP_Connection_Established = 3, /**< Connection established in both directions */\r
-                       TCP_Connection_FINWait1    = 4, /**< Closing, waiting for ACK */\r
-                       TCP_Connection_FINWait2    = 5, /**< Closing, waiting for FIN ACK */\r
-                       TCP_Connection_CloseWait   = 6, /**< Closing, waiting for ACK */\r
-                       TCP_Connection_Closing     = 7, /**< Unused */\r
-                       TCP_Connection_LastACK     = 8, /**< Unused */\r
-                       TCP_Connection_TimeWait    = 9, /**< Unused */\r
-                       TCP_Connection_Closed      = 10, /**< Connection closed in both directions */                   \r
-               };\r
-       \r
-       /* Type Defines: */\r
-               /** Type define for a TCP connection buffer structure, including size, data and direction */\r
-               typedef struct\r
-               {\r
-                       uint16_t               Length; /**< Length of data in the TCP application buffer */\r
-                       uint8_t                Data[TCP_WINDOW_SIZE]; /**< TCP application data buffer */\r
-                       bool                   Direction; /**< Buffer transmission direction, either TCP_PACKETDIR_IN  or TCP_PACKETDIR_OUT */\r
-                       bool                   Ready; /**< If data from host, indicates buffer ready to be read, otherwise indicates\r
-                                                      *   buffer ready to be sent to the host\r
-                                                      */\r
-                       bool                   InUse; /** Indicates if the buffer is locked to to the current direction, and cannot be changed */\r
-               } TCP_ConnectionBuffer_t;\r
-\r
-               /** Type define for a TCP connection information structure */\r
-               typedef struct\r
-               {\r
-                       uint32_t               SequenceNumberIn; /**< Current TCP sequence number for host-to-device */ \r
-                       uint32_t               SequenceNumberOut; /**< Current TCP sequence number for device-to-host */\r
-                       TCP_ConnectionBuffer_t Buffer; /**< Connection application data buffer */\r
-               } TCP_ConnectionInfo_t;\r
-\r
-               /** Type define for a complete TCP connection state */\r
-               typedef struct\r
-               {\r
-                       uint16_t               Port; /**< Connection port number on the device */\r
-                       uint16_t               RemotePort; /**< Connection port number on the host */\r
-                       IP_Address_t           RemoteAddress; /**< Connection protocol IP address of the host */\r
-                       TCP_ConnectionInfo_t   Info; /**< Connection information, including application buffer */\r
-                       uint8_t                State; /**< Current connection state, a value from the TCP_ConnectionStates_t enum */\r
-               } TCP_ConnectionState_t;\r
-\r
-               /** Type define for a TCP port state */\r
-               typedef struct\r
-               {\r
-                       uint16_t               Port; /**< TCP port number on the device */\r
-                       uint8_t                State; /**< Current port state, a value from the TCP_PortStates_t enum */\r
-                       void                   (*ApplicationHandler) (TCP_ConnectionState_t* ConnectionState,\r
-                                                                     TCP_ConnectionBuffer_t* Buffer); /**< Port application handler */\r
-               } TCP_PortState_t;\r
-\r
-               /** Type define for a TCP packet header */\r
-               typedef struct\r
-               {\r
-                       uint16_t               SourcePort; /**< Source port of the TCP packet */\r
-                       uint16_t               DestinationPort; /**< Destination port of the TCP packet */\r
-                       \r
-                       uint32_t               SequenceNumber; /**< Data sequence number of the packet */\r
-                       uint32_t               AcknowledgmentNumber; /**< Data acknowledgment number of the packet */\r
-                       \r
-                       unsigned char          Reserved : 4; /**< Reserved, must be all 0 */\r
-                       unsigned char          DataOffset : 4; /**< Offset of the data from the start of the header, in 4 byte chunks */\r
-                       uint8_t                Flags; /**< TCP packet flags */\r
-                       uint16_t               WindowSize; /**< Current data window size (bytes remaining in reception buffer) */\r
-                       \r
-                       uint16_t               Checksum; /**< TCP checksum */\r
-                       uint16_t               UrgentPointer; /**< Urgent data pointer */\r
-               } TCP_Header_t;\r
-\r
-       /* Tasks: */\r
-               TASK(TCP_Task);\r
-               \r
-       /* External Variables: */\r
-               TCP_PortState_t PortStateTable[MAX_OPEN_TCP_PORTS];\r
-\r
-       /* Function Prototypes: */\r
-               void                  TCP_Init(void);\r
-               bool                  TCP_SetPortState(uint16_t Port, uint8_t State, void (*Handler)(TCP_ConnectionState_t*, TCP_ConnectionBuffer_t*));\r
-               uint8_t               TCP_GetPortState(uint16_t Port);\r
-               bool                  TCP_SetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort, uint8_t State);\r
-               uint8_t               TCP_GetConnectionState(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);\r
-               TCP_ConnectionInfo_t* TCP_GetConnectionInfo(uint16_t Port, IP_Address_t RemoteAddress, uint16_t RemotePort);\r
-               int16_t               TCP_ProcessTCPPacket(void* IPHeaderInStart, void* TCPHeaderInStart, void* TCPHeaderOutStart);\r
-\r
-               #if defined(INCLUDE_FROM_TCP_C)\r
-                       static uint16_t TCP_Checksum16(void* TCPHeaderOutStart, IP_Address_t SourceAddress,\r
-                                                                                  IP_Address_t DestinationAddress, uint16_t TCPOutSize);\r
-               #endif\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/UDP.c b/Demos/Device/RNDISEthernet/UDP.c
deleted file mode 100644 (file)
index 1f571c3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  User Datagram Protocol (UDP) packet handling routines. This protocol handles high throughput, low\r
- *  reliability packets which are typically used to encapsulate streaming data.\r
- */\r
\r
-#define  INCLUDE_FROM_UDP_C\r
-#include "UDP.h"\r
-\r
-/** Processes a UDP packet inside an Ethernet frame, and writes the appropriate response\r
- *  to the output Ethernet frame if a subprotocol handler has created a response packet.\r
- *\r
- *  \param IPHeaderInStart    Pointer to the start of the incoming packet's IP header\r
- *  \param UDPHeaderInStart   Pointer to the start of the incoming packet's UDP header\r
- *  \param UDPHeaderOutStart  Pointer to the start of the outgoing packet's UDP header\r
- *\r
- *  \return The number of bytes written to the out Ethernet frame if any, NO_RESPONSE otherwise\r
- */\r
-int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart)\r
-{\r
-       UDP_Header_t* UDPHeaderIN  = (UDP_Header_t*)UDPHeaderInStart;\r
-       UDP_Header_t* UDPHeaderOUT = (UDP_Header_t*)UDPHeaderOutStart;\r
-       \r
-       int16_t RetSize = NO_RESPONSE;\r
-       \r
-       DecodeUDPHeader(UDPHeaderInStart);\r
-       \r
-       /* Check to see if the UDP packet is a DHCP packet */\r
-       if (SwapEndian_16(UDPHeaderIN->DestinationPort) == UDP_PORT_DHCP_REQUEST)\r
-       {\r
-               RetSize = DHCP_ProcessDHCPPacket(IPHeaderInStart,\r
-                                                &((uint8_t*)UDPHeaderInStart)[sizeof(UDP_Header_t)],\r
-                                            &((uint8_t*)UDPHeaderOutStart)[sizeof(UDP_Header_t)]);\r
-       }\r
-       \r
-       /* Check to see if the protocol processing routine has filled out a response */\r
-       if (RetSize > 0)\r
-       {\r
-               /* Fill out the response UDP packet header */\r
-               UDPHeaderOUT->SourcePort      = UDPHeaderIN->DestinationPort;\r
-               UDPHeaderOUT->DestinationPort = UDPHeaderIN->SourcePort;\r
-               UDPHeaderOUT->Checksum        = 0;\r
-               UDPHeaderOUT->Length          = SwapEndian_16(sizeof(UDP_Header_t) + RetSize);\r
-\r
-               /* Return the size of the response so far */\r
-               return (sizeof(UDP_Header_t) + RetSize);\r
-       }\r
-       \r
-       return NO_RESPONSE;\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/UDP.h b/Demos/Device/RNDISEthernet/UDP.h
deleted file mode 100644 (file)
index 60bbe21..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for IP.c.\r
- */\r
-\r
-#ifndef _UDP_H_\r
-#define _UDP_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-       \r
-               #include "EthernetProtocols.h"\r
-               #include "Ethernet.h"\r
-               #include "ProtocolDecoders.h"\r
-       \r
-       /* Macros: */\r
-               /** Source UDP port for a DHCP request */\r
-               #define UDP_PORT_DHCP_REQUEST 67\r
-\r
-               /** Destination UDP port for a DHCP reply */\r
-               #define UDP_PORT_DHCP_REPLY   68\r
-                       \r
-       /* Type Defines: */\r
-               /** Type define for a UDP packet header */\r
-               typedef struct\r
-               {\r
-                       uint16_t SourcePort; /**< Packet source port */\r
-                       uint16_t DestinationPort; /**< Packet destination port */\r
-                       uint16_t Length; /**< Total packet length, in bytes */\r
-                       uint16_t Checksum; /**< Optional UDP packet checksum */\r
-               } UDP_Header_t;\r
-               \r
-       /* Function Prototypes: */\r
-               int16_t UDP_ProcessUDPPacket(void* IPHeaderInStart, void* UDPHeaderInStart, void* UDPHeaderOutStart);\r
-\r
-#endif\r
diff --git a/Demos/Device/RNDISEthernet/Webserver.c b/Demos/Device/RNDISEthernet/Webserver.c
deleted file mode 100644 (file)
index c07f2c8..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Simple webserver application for demonstrating the RNDIS demo and TCP/IP stack. This\r
- *  application will serve up a static HTTP webpage when requested by the host.\r
- */\r
-\r
-#include "Webserver.h"\r
-\r
-/** HTTP server response header, for transmission before the page contents. This indicates to the host that a page exists at the\r
- *  given location, and gives extra connection information.\r
- */\r
-char PROGMEM HTTPHeader[] = "HTTP/1.1 200 OK\r\n"\r
-                            "Server: LUFA RNDIS\r\n"\r
-                            "Content-type: text/html\r\n"\r
-                            "Connection: close\r\n\r\n";\r
-\r
-/** HTTP page to serve to the host when a HTTP request is made. This page is too long for a single response, thus it is automatically\r
- *  broken up into smaller blocks and sent as a series of packets each time the webserver application callback is run.\r
- */\r
-char PROGMEM HTTPPage[]   = \r
-               "<html>"\r
-               "       <head>"\r
-               "               <title>"\r
-               "                       LUFA Webserver Demo"\r
-               "               </title>"\r
-               "       </head>"\r
-               "       <body>"\r
-               "               <h1>Hello from your USB AVR!</h1>"\r
-               "               <p>"\r
-               "                       Hello! Welcome to the LUFA RNDIS Demo Webserver test page, running on your USB AVR via the LUFA library. This demonstrates the HTTP webserver, TCP/IP stack and RNDIS demo all running atop the LUFA USB stack."\r
-               "                       <br /><br />"\r
-               "                       <small>Project Information: <a href=\"http://www.fourwalledcubicle.com/LUFA.php\">http://www.fourwalledcubicle.com/LUFA.php</a>.</small>"\r
-               "                       <hr />"\r
-               "                       <i>LUFA Version: </i>" LUFA_VERSION_STRING\r
-               "               </p>"\r
-               "       </body>"\r
-               "</html>";\r
-\r
-\r
-/** Initializes the Webserver application, opening the appropriate HTTP port in the TCP handler and registering the application\r
- *  callback routine for packets sent to the HTTP protocol port.\r
- */\r
-void Webserver_Init(void)\r
-{\r
-       /* Open the HTTP port in the TCP protocol so that HTTP connections to the device can be established */\r
-       TCP_SetPortState(TCP_PORT_HTTP, TCP_Port_Open, Webserver_ApplicationCallback);\r
-}\r
-\r
-/** Indicates if a given request equals the given HTTP command.\r
- *\r
- *  \param RequestHeader  HTTP request made by the host\r
- *  \param Command        HTTP command to compare the request to\r
- *\r
- *  \return Boolean true if the command matches the request, false otherwise\r
- */\r
-static bool IsHTTPCommand(uint8_t* RequestHeader, char* Command)\r
-{\r
-       /* Returns true if the non null terminated string in RequestHeader matches the null terminated string Command */\r
-       return (strncmp((char*)RequestHeader, Command, strlen(Command)) == 0);\r
-}\r
-\r
-/** Application callback routine, executed each time the TCP processing task runs. This callback determines what request\r
- *  has been made (if any), and serves up appropriate responses.\r
- *\r
- *  \param ConnectionState  Pointer to a TCP Connection State structure giving connection information\r
- *  \param Buffer           Pointer to the application's send/receive packet buffer\r
- */\r
-void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer)\r
-{\r
-       char*          BufferDataStr = (char*)Buffer->Data;\r
-       static uint8_t PageBlock     = 0;\r
-       \r
-       /* Check to see if a packet has been received on the HTTP port from a remote host */\r
-       if (TCP_APP_HAS_RECEIVED_PACKET(Buffer))\r
-       {\r
-               if (IsHTTPCommand(Buffer->Data, "GET"))\r
-               {\r
-                       PageBlock = 0;\r
-\r
-                       /* Copy the HTTP response header into the packet buffer */\r
-                       strcpy_P(BufferDataStr, HTTPHeader);\r
-                       \r
-                       /* Send the buffer contents to the host */\r
-                       TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));\r
-\r
-                       /* Lock the buffer to Device->Host transmissions only while we send the page contents */\r
-                       TCP_APP_CAPTURE_BUFFER(Buffer);\r
-               }\r
-               else if (IsHTTPCommand(Buffer->Data, "HEAD"))\r
-               {\r
-                       /* Copy the HTTP response header into the packet buffer */\r
-                       strcpy_P(BufferDataStr, HTTPHeader);\r
-\r
-                       /* Send the buffer contents to the host */\r
-                       TCP_APP_SEND_BUFFER(Buffer, strlen(BufferDataStr));\r
-               }\r
-               else if (IsHTTPCommand(Buffer->Data, "TRACE"))\r
-               {\r
-                       /* Echo the host's query back to the host */\r
-                       TCP_APP_SEND_BUFFER(Buffer, Buffer->Length);\r
-               }\r
-               else\r
-               {\r
-                       /* Unknown request, just clear the buffer (drop the packet) */\r
-                       TCP_APP_CLEAR_BUFFER(Buffer);\r
-               }\r
-       }\r
-       else if (TCP_APP_HAVE_CAPTURED_BUFFER(Buffer))\r
-       {\r
-               uint16_t RemLength = strlen_P(&HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE]);\r
-               uint16_t Length;\r
-       \r
-               /* Determine the length of the loaded block */\r
-               Length = ((RemLength > HTTP_REPLY_BLOCK_SIZE) ? HTTP_REPLY_BLOCK_SIZE : RemLength);\r
-\r
-               /* Copy the next buffer sized block of the page to the packet buffer */\r
-               strncpy_P(BufferDataStr, &HTTPPage[PageBlock * HTTP_REPLY_BLOCK_SIZE], Length);\r
-               \r
-               /* Send the buffer contents to the host */\r
-               TCP_APP_SEND_BUFFER(Buffer, Length);\r
-\r
-               /* Check to see if the entire page has been sent */\r
-               if (PageBlock++ == (sizeof(HTTPPage) / HTTP_REPLY_BLOCK_SIZE))\r
-               {\r
-                       /* Unlock the buffer so that the host can fill it with future packets */\r
-                       TCP_APP_RELEASE_BUFFER(Buffer);\r
-                       \r
-                       /* Close the connection to the host */\r
-                       TCP_APP_CLOSECONNECTION(ConnectionState);\r
-               }\r
-       }\r
-}\r
diff --git a/Demos/Device/RNDISEthernet/Webserver.h b/Demos/Device/RNDISEthernet/Webserver.h
deleted file mode 100644 (file)
index b2193ad..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for Webserver.c.\r
- */\r
\r
-#ifndef _WEBSERVER_H_\r
-#define _WEBSERVER_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <avr/pgmspace.h>\r
-               \r
-               #include <LUFA/Version.h>\r
-               \r
-               #include "TCP.h"\r
-       \r
-       /* Macros: */\r
-               /** Maximum size of a HTTP response per transmission */\r
-               #define  HTTP_REPLY_BLOCK_SIZE     128\r
-       \r
-       /* Function Prototypes: */\r
-               void Webserver_Init(void);\r
-               void Webserver_ApplicationCallback(TCP_ConnectionState_t* ConnectionState, TCP_ConnectionBuffer_t* Buffer);\r
-\r
-#endif\r
index 15c33ef..f40c37b 100644 (file)
@@ -125,16 +125,16 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
       Descriptors.c                                               \\r
-      RNDIS.c                                                     \\r
-         Ethernet.c                                                  \\r
-         ProtocolDecoders.c                                          \\r
-         ICMP.c                                                      \\r
-         TCP.c                                                       \\r
-         UDP.c                                                       \\r
-         DHCP.c                                                      \\r
-         ARP.c                                                       \\r
-         IP.c                                                        \\r
-         Webserver.c                                                 \\r
+      Lib/RNDIS.c                                                 \\r
+         Lib/Ethernet.c                                              \\r
+         Lib/ProtocolDecoders.c                                      \\r
+         Lib/ICMP.c                                                  \\r
+         Lib/TCP.c                                                   \\r
+         Lib/UDP.c                                                   \\r
+         Lib/DHCP.c                                                  \\r
+         Lib/ARP.c                                                   \\r
+         Lib/IP.c                                                    \\r
+         Lib/Webserver.c                                             \\r
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \\r
diff --git a/Demos/Device/USBtoSerial/Lib/RingBuff.c b/Demos/Device/USBtoSerial/Lib/RingBuff.c
new file mode 100644 (file)
index 0000000..1f477f1
--- /dev/null
@@ -0,0 +1,120 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+#include "RingBuff.h"\r
+\r
+void Buffer_Initialize(RingBuff_t* Buffer)\r
+{\r
+       BUFF_ATOMIC_BLOCK\r
+       {\r
+               Buffer->InPtr    = (RingBuff_Data_t*)&Buffer->Buffer;\r
+               Buffer->OutPtr   = (RingBuff_Data_t*)&Buffer->Buffer;\r
+               Buffer->Elements = 0;\r
+       }\r
+}\r
+\r
+void Buffer_StoreElement(RingBuff_t* Buffer, RingBuff_Data_t Data)\r
+{\r
+       BUFF_ATOMIC_BLOCK\r
+       {\r
+       #if defined(BUFF_DROPOLD)\r
+               if (Buffer->Elements == BUFF_LENGTH)\r
+               {\r
+                       Buffer->OutPtr++;\r
+       \r
+                       if (Buffer->OutPtr == &Buffer->Buffer[BUFF_LENGTH])\r
+                         Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;\r
+               }\r
+               else\r
+               {\r
+                       Buffer->Elements++;\r
+               }\r
+       #elif defined(BUFF_DROPNEW)\r
+               if (Buffer->Elements == BUFF_LENGTH)\r
+                 return;\r
+       \r
+                 Buffer->Elements++;\r
+       #elif defined(BUFF_NODROPCHECK)\r
+                 Buffer->Elements++;\r
+       #endif\r
+       \r
+               *(Buffer->InPtr) = Data;\r
+               Buffer->InPtr++;\r
+       \r
+               if (Buffer->InPtr == &Buffer->Buffer[BUFF_LENGTH])\r
+                 Buffer->InPtr = (RingBuff_Data_t*)&Buffer->Buffer;\r
+       }\r
+}\r
+\r
+RingBuff_Data_t Buffer_GetElement(RingBuff_t* Buffer)\r
+{\r
+       RingBuff_Data_t BuffData;\r
+       \r
+       BUFF_ATOMIC_BLOCK\r
+       {\r
+#if defined(BUFF_EMPTYRETURNSZERO)\r
+               if (!(Buffer->Elements))\r
+                 return 0;\r
+#elif !defined(BUFF_NOEMPTYCHECK)\r
+       #error No empty buffer check behaviour specified.\r
+#endif\r
+\r
+               BuffData = *(Buffer->OutPtr);\r
+       \r
+               Buffer->OutPtr++;\r
+               Buffer->Elements--;\r
+       \r
+               if (Buffer->OutPtr == &Buffer->Buffer[BUFF_LENGTH])\r
+                 Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;\r
+       }\r
+       \r
+       return BuffData;\r
+}\r
+\r
+#if defined(BUFF_USEPEEK)\r
+RingBuff_Data_t Buffer_PeekElement(const RingBuff_t* Buffer)\r
+{\r
+       RingBuff_Data_t BuffData;\r
+\r
+       BUFF_ATOMIC_BLOCK\r
+       {\r
+#if defined(BUFF_EMPTYRETURNSZERO)\r
+               if (!(Buffer->Elements))\r
+                 return 0;\r
+#elif !defined(BUFF_NOEMPTYCHECK)\r
+       #error No empty buffer check behaviour specified.\r
+#endif\r
+\r
+               BuffData = *(Buffer->OutPtr);\r
+       }\r
+\r
+       return BuffData;\r
+}\r
+#endif\r
diff --git a/Demos/Device/USBtoSerial/Lib/RingBuff.h b/Demos/Device/USBtoSerial/Lib/RingBuff.h
new file mode 100644 (file)
index 0000000..23288d8
--- /dev/null
@@ -0,0 +1,116 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/* Buffer Configuration: */\r
+   /* Buffer length - select static size of created ring buffers: */\r
+        #define BUFF_STATICSIZE 128      // Set to the static ring buffer size for all ring buffers (place size after define)\r
+\r
+   /* Volatile mode - uncomment to make buffers volatile, for use in ISRs, etc: */\r
+        #define BUFF_VOLATILE            // Uncomment to cause all ring buffers to become volatile (and atomic if multi-byte) in access\r
+\r
+   /* Drop mode - select behaviour when Buffer_StoreElement called on a full buffer: */\r
+     #define BUFF_DROPOLD             // Uncomment to cause full ring buffers to drop the oldest character to make space when full\r
+     // #define BUFF_DROPNEW          // Uncomment to cause full ring buffers to drop the new character when full\r
+     // #define BUFF_NODROPCHECK      // Uncomment to ignore full ring buffer checks - checking left to user!\r
+\r
+   /* Underflow behaviour - select behaviour when Buffer_GetElement is called with an empty ring buffer: */\r
+     //#define BUFF_EMPTYRETURNSZERO  // Uncomment to return 0 when an empty ring buffer is read\r
+     #define BUFF_NOEMPTYCHECK        // Uncomment to disable checking of empty ring buffers - checking left to user!\r
+       \r
+   /* Buffer storage type - set the datatype for the stored data */\r
+     #define BUFF_DATATYPE uint8_t    // Change to the data type that is going to be stored into the buffer\r
+       \r
+   /* Peek routine - uncomment to include the peek routine (fetches next byte without removing it from the buffer */\r
+     //#define BUFF_USEPEEK\r
+               \r
+#ifndef _RINGBUFF_H_\r
+#define _RINGBUFF_H_\r
+\r
+       /* Includes: */\r
+       #include <avr/io.h>\r
+       #include <avr/interrupt.h>\r
+       #include <util/atomic.h>\r
+       #include <limits.h>\r
+\r
+       #include <LUFA/Common/Common.h>\r
+\r
+       /* Defines and checks: */\r
+       #if defined(BUFF_STATICSIZE)\r
+               #define BUFF_LENGTH BUFF_STATICSIZE\r
+       #else\r
+               #error No buffer length specified!\r
+       #endif\r
+\r
+       #if !(defined(BUFF_DROPOLD) || defined(BUFF_DROPNEW) || defined(BUFF_NODROPCHECK))\r
+               #error No buffer drop mode specified.\r
+       #endif\r
+\r
+       #if !defined(BUFF_DATATYPE)\r
+               #error Ringbuffer storage data type not specified.\r
+       #endif\r
+\r
+       #if defined(BUFF_VOLATILE)\r
+               #define BUFF_MODE            volatile\r
+               #define BUFF_ATOMIC_BLOCK    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)\r
+       #else\r
+               #define BUFF_MODE\r
+               #define BUFF_ATOMIC_BLOCK\r
+       #endif\r
+\r
+       #if (BUFF_STATICSIZE   > LONG_MAX)\r
+               #define RingBuff_Elements_t uint64_t\r
+       #elif (BUFF_STATICSIZE > INT_MAX)\r
+               #define RingBuff_Elements_t uint32_t\r
+       #elif (BUFF_STATICSIZE > CHAR_MAX)\r
+               #define RingBuff_Elements_t uint16_t\r
+       #else\r
+               #define RingBuff_Elements_t uint8_t\r
+       #endif\r
+       \r
+       /* Type Defines: */\r
+       typedef BUFF_DATATYPE RingBuff_Data_t;\r
+\r
+       typedef BUFF_MODE struct\r
+       {\r
+               RingBuff_Data_t      Buffer[BUFF_LENGTH];\r
+               RingBuff_Data_t*     InPtr;\r
+               RingBuff_Data_t*     OutPtr;\r
+               RingBuff_Elements_t  Elements;\r
+       } RingBuff_t;\r
+               \r
+       /* Function Prototypes: */\r
+       void            Buffer_Initialize(RingBuff_t* Buff);\r
+       void            Buffer_StoreElement(RingBuff_t* Buffer, RingBuff_Data_t Data);\r
+       RingBuff_Data_t Buffer_GetElement(RingBuff_t* Buffer);\r
+       #if defined(BUFF_USEPEEK)\r
+               RingBuff_Data_t Buffer_PeekElement(const RingBuff_t* Buffer);\r
+       #endif\r
+       \r
+#endif\r
diff --git a/Demos/Device/USBtoSerial/RingBuff.c b/Demos/Device/USBtoSerial/RingBuff.c
deleted file mode 100644 (file)
index 1f477f1..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-#include "RingBuff.h"\r
-\r
-void Buffer_Initialize(RingBuff_t* Buffer)\r
-{\r
-       BUFF_ATOMIC_BLOCK\r
-       {\r
-               Buffer->InPtr    = (RingBuff_Data_t*)&Buffer->Buffer;\r
-               Buffer->OutPtr   = (RingBuff_Data_t*)&Buffer->Buffer;\r
-               Buffer->Elements = 0;\r
-       }\r
-}\r
-\r
-void Buffer_StoreElement(RingBuff_t* Buffer, RingBuff_Data_t Data)\r
-{\r
-       BUFF_ATOMIC_BLOCK\r
-       {\r
-       #if defined(BUFF_DROPOLD)\r
-               if (Buffer->Elements == BUFF_LENGTH)\r
-               {\r
-                       Buffer->OutPtr++;\r
-       \r
-                       if (Buffer->OutPtr == &Buffer->Buffer[BUFF_LENGTH])\r
-                         Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;\r
-               }\r
-               else\r
-               {\r
-                       Buffer->Elements++;\r
-               }\r
-       #elif defined(BUFF_DROPNEW)\r
-               if (Buffer->Elements == BUFF_LENGTH)\r
-                 return;\r
-       \r
-                 Buffer->Elements++;\r
-       #elif defined(BUFF_NODROPCHECK)\r
-                 Buffer->Elements++;\r
-       #endif\r
-       \r
-               *(Buffer->InPtr) = Data;\r
-               Buffer->InPtr++;\r
-       \r
-               if (Buffer->InPtr == &Buffer->Buffer[BUFF_LENGTH])\r
-                 Buffer->InPtr = (RingBuff_Data_t*)&Buffer->Buffer;\r
-       }\r
-}\r
-\r
-RingBuff_Data_t Buffer_GetElement(RingBuff_t* Buffer)\r
-{\r
-       RingBuff_Data_t BuffData;\r
-       \r
-       BUFF_ATOMIC_BLOCK\r
-       {\r
-#if defined(BUFF_EMPTYRETURNSZERO)\r
-               if (!(Buffer->Elements))\r
-                 return 0;\r
-#elif !defined(BUFF_NOEMPTYCHECK)\r
-       #error No empty buffer check behaviour specified.\r
-#endif\r
-\r
-               BuffData = *(Buffer->OutPtr);\r
-       \r
-               Buffer->OutPtr++;\r
-               Buffer->Elements--;\r
-       \r
-               if (Buffer->OutPtr == &Buffer->Buffer[BUFF_LENGTH])\r
-                 Buffer->OutPtr = (RingBuff_Data_t*)&Buffer->Buffer;\r
-       }\r
-       \r
-       return BuffData;\r
-}\r
-\r
-#if defined(BUFF_USEPEEK)\r
-RingBuff_Data_t Buffer_PeekElement(const RingBuff_t* Buffer)\r
-{\r
-       RingBuff_Data_t BuffData;\r
-\r
-       BUFF_ATOMIC_BLOCK\r
-       {\r
-#if defined(BUFF_EMPTYRETURNSZERO)\r
-               if (!(Buffer->Elements))\r
-                 return 0;\r
-#elif !defined(BUFF_NOEMPTYCHECK)\r
-       #error No empty buffer check behaviour specified.\r
-#endif\r
-\r
-               BuffData = *(Buffer->OutPtr);\r
-       }\r
-\r
-       return BuffData;\r
-}\r
-#endif\r
diff --git a/Demos/Device/USBtoSerial/RingBuff.h b/Demos/Device/USBtoSerial/RingBuff.h
deleted file mode 100644 (file)
index 23288d8..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/* Buffer Configuration: */\r
-   /* Buffer length - select static size of created ring buffers: */\r
-        #define BUFF_STATICSIZE 128      // Set to the static ring buffer size for all ring buffers (place size after define)\r
-\r
-   /* Volatile mode - uncomment to make buffers volatile, for use in ISRs, etc: */\r
-        #define BUFF_VOLATILE            // Uncomment to cause all ring buffers to become volatile (and atomic if multi-byte) in access\r
-\r
-   /* Drop mode - select behaviour when Buffer_StoreElement called on a full buffer: */\r
-     #define BUFF_DROPOLD             // Uncomment to cause full ring buffers to drop the oldest character to make space when full\r
-     // #define BUFF_DROPNEW          // Uncomment to cause full ring buffers to drop the new character when full\r
-     // #define BUFF_NODROPCHECK      // Uncomment to ignore full ring buffer checks - checking left to user!\r
-\r
-   /* Underflow behaviour - select behaviour when Buffer_GetElement is called with an empty ring buffer: */\r
-     //#define BUFF_EMPTYRETURNSZERO  // Uncomment to return 0 when an empty ring buffer is read\r
-     #define BUFF_NOEMPTYCHECK        // Uncomment to disable checking of empty ring buffers - checking left to user!\r
-       \r
-   /* Buffer storage type - set the datatype for the stored data */\r
-     #define BUFF_DATATYPE uint8_t    // Change to the data type that is going to be stored into the buffer\r
-       \r
-   /* Peek routine - uncomment to include the peek routine (fetches next byte without removing it from the buffer */\r
-     //#define BUFF_USEPEEK\r
-               \r
-#ifndef _RINGBUFF_H_\r
-#define _RINGBUFF_H_\r
-\r
-       /* Includes: */\r
-       #include <avr/io.h>\r
-       #include <avr/interrupt.h>\r
-       #include <util/atomic.h>\r
-       #include <limits.h>\r
-\r
-       #include <LUFA/Common/Common.h>\r
-\r
-       /* Defines and checks: */\r
-       #if defined(BUFF_STATICSIZE)\r
-               #define BUFF_LENGTH BUFF_STATICSIZE\r
-       #else\r
-               #error No buffer length specified!\r
-       #endif\r
-\r
-       #if !(defined(BUFF_DROPOLD) || defined(BUFF_DROPNEW) || defined(BUFF_NODROPCHECK))\r
-               #error No buffer drop mode specified.\r
-       #endif\r
-\r
-       #if !defined(BUFF_DATATYPE)\r
-               #error Ringbuffer storage data type not specified.\r
-       #endif\r
-\r
-       #if defined(BUFF_VOLATILE)\r
-               #define BUFF_MODE            volatile\r
-               #define BUFF_ATOMIC_BLOCK    ATOMIC_BLOCK(ATOMIC_RESTORESTATE)\r
-       #else\r
-               #define BUFF_MODE\r
-               #define BUFF_ATOMIC_BLOCK\r
-       #endif\r
-\r
-       #if (BUFF_STATICSIZE   > LONG_MAX)\r
-               #define RingBuff_Elements_t uint64_t\r
-       #elif (BUFF_STATICSIZE > INT_MAX)\r
-               #define RingBuff_Elements_t uint32_t\r
-       #elif (BUFF_STATICSIZE > CHAR_MAX)\r
-               #define RingBuff_Elements_t uint16_t\r
-       #else\r
-               #define RingBuff_Elements_t uint8_t\r
-       #endif\r
-       \r
-       /* Type Defines: */\r
-       typedef BUFF_DATATYPE RingBuff_Data_t;\r
-\r
-       typedef BUFF_MODE struct\r
-       {\r
-               RingBuff_Data_t      Buffer[BUFF_LENGTH];\r
-               RingBuff_Data_t*     InPtr;\r
-               RingBuff_Data_t*     OutPtr;\r
-               RingBuff_Elements_t  Elements;\r
-       } RingBuff_t;\r
-               \r
-       /* Function Prototypes: */\r
-       void            Buffer_Initialize(RingBuff_t* Buff);\r
-       void            Buffer_StoreElement(RingBuff_t* Buffer, RingBuff_Data_t Data);\r
-       RingBuff_Data_t Buffer_GetElement(RingBuff_t* Buffer);\r
-       #if defined(BUFF_USEPEEK)\r
-               RingBuff_Data_t Buffer_PeekElement(const RingBuff_t* Buffer);\r
-       #endif\r
-       \r
-#endif\r
index cd1f42c..8e7e8ae 100644 (file)
@@ -43,7 +43,8 @@
                #include <avr/power.h>\r
 \r
                #include "Descriptors.h"\r
-               #include "RingBuff.h"\r
+\r
+               #include "Lib/RingBuff.h"\r
 \r
                #include <LUFA/Version.h>                         // Library Version Information\r
                #include <LUFA/Drivers/USB/USB.h>                 // USB Functionality\r
index 7da8b97..708e872 100644 (file)
@@ -125,7 +125,7 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          Descriptors.c                                               \\r
-         RingBuff.c                                                  \\r
+         Lib/RingBuff.c                                              \\r
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \\r
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \\r
diff --git a/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c b/Demos/Host/MassStorageHost/Lib/MassStoreCommands.c
new file mode 100644 (file)
index 0000000..95aafca
--- /dev/null
@@ -0,0 +1,685 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Mass Storage Device commands, to issue MSD commands to the device for\r
+ *  reading device status, capacity, and other characteristics. This file\r
+ *  also contains block read and write functions, so that device blocks\r
+ *  can be read and written. In general, these functions would be chained\r
+ *  to a FAT library to give file-level access to an attached device's contents.\r
+ *\r
+ *  \note Many Mass Storage devices on the market are non-compliant to the\r
+ *        specifications and thus can prove difficult to interface with. It\r
+ *        may be necessary to retry the functions in the module several times\r
+ *        after they have returned and error to successfully send the command\r
+ *        to the device. Some devices may also need to have the stream function\r
+ *        timeout period extended beyond 100ms (some badly designed devices exceeding\r
+ *        1.5 seconds occasionally) by defining USB_STREAM_TIMEOUT_MS to a\r
+ *        larger value in the project makefile and passing it to the compiler\r
+ *        via the -D switch.\r
+ */\r
\r
+#define  INCLUDE_FROM_MASSSTORE_COMMANDS_C\r
+#include "MassStoreCommands.h"\r
+\r
+/* Globals: */\r
+/** Current CBW to send to the device. This is automatically filled by the routines\r
+ *  in this file and is not externally accessible.\r
+ */\r
+static CommandBlockWrapper_t  SCSICommandBlock;\r
+\r
+/** Current CSW received from the device. This is automatically filled by the routines\r
+ *  in this file and is externally accessible so that the return codes may be checked.\r
+ */\r
+CommandStatusWrapper_t        SCSICommandStatus;\r
+\r
+/** Current Tag value used in issued CBWs to the device. This is automatically incremented\r
+ *  by the routines in this file, and is not externally accessible.\r
+ */\r
+static uint32_t               MassStore_Tag = 1;\r
+\r
+\r
+/** Routine to send the current CBW to the device, and increment the Tag value as needed.\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+static uint8_t MassStore_SendCommand(void)\r
+{\r
+       uint8_t ErrorCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* Each transmission should have a unique tag value, excluding values 0 and 0xFFFFFFFF */\r
+       if (++MassStore_Tag == 0xFFFFFFFF)\r
+         MassStore_Tag = 1;\r
+\r
+       /* Select the OUT data pipe for CBW transmission */\r
+       Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
+       Pipe_Unfreeze();\r
+\r
+       /* Write the CBW command to the OUT pipe */\r
+       if ((ErrorCode = Pipe_Write_Stream_LE(&SCSICommandBlock, sizeof(CommandBlockWrapper_t))) != PIPE_RWSTREAM_NoError)\r
+         return ErrorCode;\r
+\r
+       /* Send the data in the OUT pipe to the attached device */\r
+       Pipe_ClearOUT();\r
+       \r
+       while(!(Pipe_IsOUTReady()));\r
+\r
+       /* Freeze pipe after use */\r
+       Pipe_Freeze();\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Waits until the attached device is ready to accept data following a CBW, checking\r
+ *  to ensure that the device has not stalled the transaction.\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+static uint8_t MassStore_WaitForDataReceived(void)\r
+{\r
+       uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;\r
+\r
+       /* Unfreeze the OUT pipe so that it can be checked */\r
+       Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
+       Pipe_Unfreeze();\r
+\r
+       /* Select the IN data pipe for data reception */\r
+       Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
+       Pipe_Unfreeze();\r
+\r
+       /* Wait until data received in the IN pipe */\r
+       while (!(Pipe_IsINReceived()))\r
+       {\r
+               /* Check to see if a new frame has been issued (1ms elapsed) */\r
+               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               {\r
+                       /* Clear the flag and decrement the timeout period counter */\r
+                       USB_INT_Clear(USB_INT_HSOFI);\r
+                       TimeoutMSRem--;\r
+\r
+                       /* Check to see if the timeout period for the command has elapsed */\r
+                       if (!(TimeoutMSRem))\r
+                         return PIPE_RWSTREAM_Timeout;\r
+               }\r
+       \r
+               Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
+\r
+               /* Check if pipe stalled (command failed by device) */\r
+               if (Pipe_IsStalled())\r
+               {\r
+                       /* Clear the stall condition on the OUT pipe */\r
+                       MassStore_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE);\r
+\r
+                       return PIPE_RWSTREAM_PipeStalled;\r
+               }\r
+\r
+               Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
+\r
+               /* Check if pipe stalled (command failed by device) */\r
+               if (Pipe_IsStalled())\r
+               {\r
+                       /* Clear the stall condition on the IN pipe */\r
+                       MassStore_ClearPipeStall(MASS_STORE_DATA_IN_PIPE);\r
+\r
+                       return PIPE_RWSTREAM_PipeStalled;\r
+               }\r
+                 \r
+               /* Check to see if the device was disconnected, if so exit function */\r
+               if (!(USB_IsConnected))\r
+                 return PIPE_RWSTREAM_DeviceDisconnected;\r
+       };\r
+\r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Sends or receives the transaction's data stage to or from the attached device, reading or\r
+ *  writing to the nominated buffer.\r
+ *\r
+ *  \param  BufferPtr  Pointer to the data buffer to read from or write to\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+static uint8_t MassStore_SendReceiveData(void* BufferPtr)\r
+{\r
+       uint8_t  ErrorCode = PIPE_RWSTREAM_NoError;\r
+       uint16_t BytesRem  = SCSICommandBlock.Header.DataTransferLength;\r
+\r
+       /* Check the direction of the SCSI command data stage */\r
+       if (SCSICommandBlock.Header.Flags & COMMAND_DIRECTION_DATA_IN)\r
+       {\r
+               /* Select the IN data pipe for data reception */\r
+               Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
+               Pipe_Unfreeze();\r
+               \r
+               /* Read in the block data from the pipe */\r
+               if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)\r
+                 return ErrorCode;\r
+\r
+               /* Acknowledge the packet */\r
+               Pipe_ClearIN();\r
+       }\r
+       else\r
+       {\r
+               /* Select the OUT data pipe for data transmission */\r
+               Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
+               Pipe_Unfreeze();\r
+\r
+               /* Write the block data to the pipe */\r
+               if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)\r
+                 return ErrorCode;\r
+\r
+               /* Acknowledge the packet */\r
+               Pipe_ClearOUT();\r
+               \r
+               while (!(Pipe_IsOUTReady()));\r
+       }\r
+       \r
+       /* Freeze used pipe after use */\r
+       Pipe_Freeze();\r
+\r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Routine to receive the current CSW from the device.\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+static uint8_t MassStore_GetReturnedStatus(void)\r
+{\r
+       uint8_t ErrorCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* If an error in the command ocurred, abort */\r
+       if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
+         return ErrorCode;\r
+\r
+       /* Select the IN data pipe for data reception */\r
+       Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
+       Pipe_Unfreeze();\r
+       \r
+       /* Load in the CSW from the attached device */\r
+       if ((ErrorCode = Pipe_Read_Stream_LE(&SCSICommandStatus, sizeof(CommandStatusWrapper_t))) != PIPE_RWSTREAM_NoError)\r
+         return ErrorCode;\r
+         \r
+       /* Clear the data ready for next reception */\r
+       Pipe_ClearIN();\r
+       \r
+       /* Freeze the IN pipe after use */\r
+       Pipe_Freeze();\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Clears the stall condition in the attached device on the nominated endpoint number.\r
+ *\r
+ *  \param EndpointNum  Endpoint number in the attached device whose stall condition is to be cleared\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum)\r
+{\r
+       USB_ControlRequest = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
+                       .bRequest      = REQ_ClearFeature,\r
+                       .wValue        = FEATURE_ENDPOINT_HALT,\r
+                       .wIndex        = EndpointNum,\r
+                       .wLength       = 0,\r
+               };\r
+       \r
+       /* Select the control pipe for the request transfer */\r
+       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
+       return USB_Host_SendControlRequest(NULL);\r
+}\r
+\r
+/** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface,\r
+ *  readying the device for the next CBW.\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_MassStorageReset(void)\r
+{\r
+       USB_ControlRequest = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
+                       .bRequest      = REQ_MassStorageReset,\r
+                       .wValue        = 0,\r
+                       .wIndex        = 0,\r
+                       .wLength       = 0,\r
+               };\r
+       \r
+       /* Select the control pipe for the request transfer */\r
+       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
+       return USB_Host_SendControlRequest(NULL);\r
+}\r
+\r
+/** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical\r
+ *  Unit in the attached device.\r
+ *\r
+ *  \param MaxLUNIndex  Pointer to the location that the maximum LUN index value should be stored\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex)\r
+{\r
+       uint8_t ErrorCode;\r
+\r
+       USB_ControlRequest = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
+                       .bRequest      = REQ_GetMaxLUN,\r
+                       .wValue        = 0,\r
+                       .wIndex        = 0,\r
+                       .wLength       = 1,\r
+               };\r
+               \r
+       /* Select the control pipe for the request transfer */\r
+       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
+       if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)\r
+       {\r
+               /* Clear the pipe stall */\r
+               Pipe_ClearStall();\r
+       \r
+               /* Some faulty Mass Storage devices don't implement the GET_MAX_LUN request, so assume a single LUN */\r
+               *MaxLUNIndex = 0;       \r
+       }\r
+       \r
+       return ErrorCode;\r
+}\r
+\r
+/** Issues a SCSI Request Sense command to the attached device, to determine the current SCSI sense information. This\r
+ *  gives error codes for the last issued SCSI command to the device.\r
+ *\r
+ *  \param LUNIndex  Index of the LUN inside the device the command is being addressed to\r
+ *  \param SensePtr  Pointer to the sense data structure where the sense data from the device is to be stored\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)\r
+{\r
+       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* Create a CBW with a SCSI command to issue REQUEST SENSE command */\r
+       SCSICommandBlock = (CommandBlockWrapper_t)\r
+               {\r
+                       .Header =\r
+                               {\r
+                                       .Signature          = CBW_SIGNATURE,\r
+                                       .Tag                = MassStore_Tag,\r
+                                       .DataTransferLength = sizeof(SCSI_Request_Sense_Response_t),\r
+                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
+                                       .LUN                = LUNIndex,\r
+                                       .SCSICommandLength  = 6\r
+                               },\r
+                                       \r
+                       .SCSICommandData =\r
+                               {\r
+                                       SCSI_CMD_REQUEST_SENSE,\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       sizeof(SCSI_Request_Sense_Response_t), // Allocation Length\r
+                                       0x00                    // Unused (control)\r
+                               }\r
+               };\r
+       \r
+       /* Send SCSI command to the attached device */\r
+       MassStore_SendCommand();\r
+\r
+       /* Wait until data received from the device */\r
+       if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+\r
+       /* Read the returned sense data into the buffer */\r
+       if ((ReturnCode = MassStore_SendReceiveData((uint8_t*)SensePtr)) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }       \r
+       \r
+       /* Read in the returned CSW from the device */\r
+       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Issues a SCSI Device Block Read command to the attached device, to read in one or more data blocks from the\r
+ *  storage medium into a buffer.\r
+ *\r
+ *  \param LUNIndex      Index of the LUN inside the device the command is being addressed to\r
+ *  \param BlockAddress  Start block address to read from\r
+ *  \param Blocks        Number of blocks to read from the device\r
+ *  \param BlockSize     Size in bytes of each block to read\r
+ *  \param BufferPtr     Pointer to the buffer where the read data is to be written to\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
+                                  const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr)\r
+{\r
+       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* Create a CBW with a SCSI command to read in the given blocks from the device */\r
+       SCSICommandBlock = (CommandBlockWrapper_t)\r
+               {\r
+                       .Header =\r
+                               {\r
+                                       .Signature          = CBW_SIGNATURE,\r
+                                       .Tag                = MassStore_Tag,\r
+                                       .DataTransferLength = ((uint32_t)Blocks * BlockSize),\r
+                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
+                                       .LUN                = LUNIndex,\r
+                                       .SCSICommandLength  = 10\r
+                               },\r
+                                       \r
+                       .SCSICommandData =\r
+                               {\r
+                                       SCSI_CMD_READ_10,\r
+                                       0x00,                   // Unused (control bits, all off)\r
+                                       (BlockAddress >> 24),   // MSB of Block Address\r
+                                       (BlockAddress >> 16),\r
+                                       (BlockAddress >> 8),\r
+                                       (BlockAddress & 0xFF),  // LSB of Block Address\r
+                                       0x00,                   // Unused (reserved)\r
+                                       0x00,                   // MSB of Total Blocks to Read\r
+                                       Blocks,                 // LSB of Total Blocks to Read\r
+                                       0x00                    // Unused (control)\r
+                               }\r
+               };\r
+       \r
+       /* Send SCSI command to the attached device */\r
+       MassStore_SendCommand();\r
+\r
+       /* Wait until data received from the device */\r
+       if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+\r
+       /* Read the returned block data into the buffer */\r
+       if ((ReturnCode = MassStore_SendReceiveData(BufferPtr)) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }       \r
+       \r
+       /* Read in the returned CSW from the device */\r
+       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Issues a SCSI Device Block Write command to the attached device, to write one or more data blocks to the\r
+ *  storage medium from a buffer.\r
+ *\r
+ *  \param LUNIndex      Index of the LUN inside the device the command is being addressed to\r
+ *  \param BlockAddress  Start block address to write to\r
+ *  \param Blocks        Number of blocks to write to in the device\r
+ *  \param BlockSize     Size in bytes of each block to write\r
+ *  \param BufferPtr     Pointer to the buffer where the write data is to be sourced from\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
+                                   const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr)\r
+{\r
+       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* Create a CBW with a SCSI command to write the given blocks to the device */\r
+       SCSICommandBlock = (CommandBlockWrapper_t)\r
+               {\r
+                       .Header =\r
+                               {\r
+                                       .Signature          = CBW_SIGNATURE,\r
+                                       .Tag                = MassStore_Tag,\r
+                                       .DataTransferLength = ((uint32_t)Blocks * BlockSize),\r
+                                       .Flags              = COMMAND_DIRECTION_DATA_OUT,\r
+                                       .LUN                = LUNIndex,\r
+                                       .SCSICommandLength  = 10\r
+                               },\r
+                                       \r
+                       .SCSICommandData =\r
+                               {\r
+                                       SCSI_CMD_WRITE_10,\r
+                                       0x00,                   // Unused (control bits, all off)\r
+                                       (BlockAddress >> 24),   // MSB of Block Address\r
+                                       (BlockAddress >> 16),\r
+                                       (BlockAddress >> 8),\r
+                                       (BlockAddress & 0xFF),  // LSB of Block Address\r
+                                       0x00,                   // Unused (reserved)\r
+                                       0x00,                   // MSB of Total Blocks to Write\r
+                                       Blocks,                 // LSB of Total Blocks to Write\r
+                                       0x00                    // Unused (control)\r
+                               }\r
+               };\r
+       \r
+       /* Send SCSI command to the attached device */\r
+       MassStore_SendCommand();\r
+\r
+       /* Write the data to the device from the buffer */\r
+       if ((ReturnCode = MassStore_SendReceiveData(BufferPtr)) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }       \r
+       \r
+       /* Read in the returned CSW from the device */\r
+       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Issues a SCSI Device Test Unit Ready command to the attached device, to determine if the device is ready to accept\r
+ *  other commands.\r
+ *\r
+ *  \param LUNIndex      Index of the LUN inside the device the command is being addressed to\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex)\r
+{\r
+       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;     \r
+\r
+       /* Create a CBW with a SCSI command to issue TEST UNIT READY command */\r
+       SCSICommandBlock = (CommandBlockWrapper_t)\r
+               {\r
+                       .Header =\r
+                               {\r
+                                       .Signature          = CBW_SIGNATURE,\r
+                                       .Tag                = MassStore_Tag,\r
+                                       .DataTransferLength = 0,\r
+                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
+                                       .LUN                = LUNIndex,\r
+                                       .SCSICommandLength  = 6\r
+                               },\r
+                                       \r
+                       .SCSICommandData =\r
+                               {\r
+                                       SCSI_CMD_TEST_UNIT_READY,\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       0x00                    // Unused (control)\r
+                               }\r
+               };\r
+       \r
+       /* Send SCSI command to the attached device */\r
+       MassStore_SendCommand();\r
+\r
+       /* Read in the returned CSW from the device */\r
+       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Issues a SCSI Device Read Capacity command to the attached device, to determine the capacity of the\r
+ *  given Logical Unit within the device.\r
+ *\r
+ *  \param LUNIndex     Index of the LUN inside the device the command is being addressed to\r
+ *  \param CapacityPtr  Device capacity structure where the capacity data is to be stored\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const CapacityPtr)\r
+{\r
+       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* Create a CBW with a SCSI command to issue READ CAPACITY command */\r
+       SCSICommandBlock = (CommandBlockWrapper_t)\r
+               {\r
+                       .Header =\r
+                               {\r
+                                       .Signature          = CBW_SIGNATURE,\r
+                                       .Tag                = MassStore_Tag,\r
+                                       .DataTransferLength = sizeof(SCSI_Capacity_t),\r
+                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
+                                       .LUN                = LUNIndex,\r
+                                       .SCSICommandLength  = 10\r
+                               },\r
+                                       \r
+                       .SCSICommandData =\r
+                               {\r
+                                       SCSI_CMD_READ_CAPACITY_10,\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // MSB of Logical block address\r
+                                       0x00,\r
+                                       0x00,\r
+                                       0x00,                   // LSB of Logical block address\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Partial Medium Indicator\r
+                                       0x00                    // Unused (control)\r
+                               }\r
+               };\r
+       \r
+       /* Send SCSI command to the attached device */\r
+       MassStore_SendCommand();\r
+\r
+       /* Wait until data received from the device */\r
+       if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+\r
+       /* Read the returned capacity data into the buffer */\r
+       if ((ReturnCode = MassStore_SendReceiveData(CapacityPtr)) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+         \r
+       /* Endian-correct the read data */\r
+       CapacityPtr->Blocks    = SwapEndian_32(CapacityPtr->Blocks);\r
+       CapacityPtr->BlockSize = SwapEndian_32(CapacityPtr->BlockSize);\r
+       \r
+       /* Read in the returned CSW from the device */\r
+       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Issues a SCSI Device Prevent/Allow Medium Removal command to the attached device, to lock the physical media from\r
+ *  being removed. This is a legacy command for SCSI disks with removable storage (such as ZIP disks), but should still\r
+ *  be issued before the first read or write command is sent.\r
+ *\r
+ *  \param LUNIndex        Index of the LUN inside the device the command is being addressed to\r
+ *  \param PreventRemoval  Whether or not the LUN media should be locked to prevent removal or not\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval)\r
+{\r
+       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
+\r
+       /* Create a CBW with a SCSI command to issue PREVENT ALLOW MEDIUM REMOVAL command */\r
+       SCSICommandBlock = (CommandBlockWrapper_t)\r
+               {\r
+                       .Header =\r
+                               {\r
+                                       .Signature          = CBW_SIGNATURE,\r
+                                       .Tag                = MassStore_Tag,\r
+                                       .DataTransferLength = 0,\r
+                                       .Flags              = COMMAND_DIRECTION_DATA_OUT,\r
+                                       .LUN                = LUNIndex,\r
+                                       .SCSICommandLength  = 6\r
+                               },\r
+                                       \r
+                       .SCSICommandData =\r
+                               {\r
+                                       SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL,\r
+                                       0x00,                   // Reserved\r
+                                       0x00,                   // Reserved\r
+                                       PreventRemoval,         // Prevent flag\r
+                                       0x00,                   // Reserved\r
+                                       0x00                    // Unused (control)\r
+                               }\r
+               };\r
+       \r
+       /* Send SCSI command to the attached device */\r
+       MassStore_SendCommand();\r
+\r
+       /* Read in the returned CSW from the device */\r
+       if ((ReturnCode = MassStore_GetReturnedStatus()))\r
+       {\r
+               Pipe_Freeze();\r
+               return ReturnCode;\r
+       }\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
diff --git a/Demos/Host/MassStorageHost/Lib/MassStoreCommands.h b/Demos/Host/MassStorageHost/Lib/MassStoreCommands.h
new file mode 100644 (file)
index 0000000..28f6a15
--- /dev/null
@@ -0,0 +1,175 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for MassStoreCommands.c.\r
+ */\r
\r
+#ifndef _MASS_STORE_COMMANDS_H_\r
+#define _MASS_STORE_COMMANDS_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+\r
+               #include "MassStorageHost.h"\r
+               #include "SCSI_Codes.h"\r
+\r
+               #include <LUFA/Drivers/USB/USB.h>                    // USB Functionality\r
+\r
+       /* Macros: */\r
+               /** Class specific request to reset the Mass Storage interface of the attached device */\r
+               #define REQ_MassStorageReset             0xFF\r
+\r
+               /** Class specific request to retrieve the maximum Logical Unit Number (LUN) index of the attached device */\r
+               #define REQ_GetMaxLUN                    0xFE\r
+\r
+               /** Command Block Wrapper signature byte, for verification of valid CBW blocks */\r
+               #define CBW_SIGNATURE                    0x43425355UL\r
+\r
+               /** Command Static Wrapper signature byte, for verification of valid CSW blocks */\r
+               #define CSW_SIGNATURE                    0x53425355UL\r
+               \r
+               /** Data direction mask for the Flags field of a CBW, indicating Host-to-Device transfer direction */\r
+               #define COMMAND_DIRECTION_DATA_OUT       (0 << 7)\r
+\r
+               /** Data direction mask for the Flags field of a CBW, indicating Device-to-Host transfer direction */\r
+               #define COMMAND_DIRECTION_DATA_IN        (1 << 7)\r
+               \r
+               /** Timeout period between the issuing of a CBW to a device, and the reception of the first packet */\r
+               #define COMMAND_DATA_TIMEOUT_MS          500\r
+\r
+               /** Pipe number of the Mass Storage data IN pipe */\r
+               #define MASS_STORE_DATA_IN_PIPE          1\r
+\r
+               /** Pipe number of the Mass Storage data OUT pipe */\r
+               #define MASS_STORE_DATA_OUT_PIPE         2\r
+\r
+       /* Type defines: */\r
+               /** Type define for a Mass Storage class Command Block Wrapper, used to wrap SCSI\r
+                *  commands for transport over the USB bulk endpoints to the device.\r
+                */\r
+               typedef struct\r
+               {\r
+                       struct\r
+                       {\r
+                               uint32_t Signature; /**< Command block signature, always equal to CBW_SIGNATURE */\r
+                               uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW */\r
+                               uint32_t DataTransferLength; /**< Length of data to transfer, following the CBW */\r
+                               uint8_t  Flags; /**< Block flags, equal to one of the COMMAND_DIRECTION_DATA_* macros */\r
+                               uint8_t  LUN; /**< Logical Unit Number the CBW is addressed to in the device */\r
+                               uint8_t  SCSICommandLength; /**< Length of the SCSI command in the CBW */\r
+                       } Header;\r
+                       \r
+                       uint8_t SCSICommandData[16]; /**< SCSI command to issue to the device */\r
+               } CommandBlockWrapper_t;\r
+               \r
+               /** Type define for a Mass Storage class Command Status Wrapper, used to wrap SCSI\r
+                *  responses for transport over the USB bulk endpoints from the device.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint32_t Signature; /**< Command status signature, always equal to CSW_SIGNATURE */\r
+                       uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW */\r
+                       uint32_t DataTransferResidue; /**< Length of data not transferred */\r
+                       uint8_t  Status; /**< Command status, a value from the MassStorageHost_CommandStatusCodes_t enum */\r
+               } CommandStatusWrapper_t;\r
+               \r
+               /** Type define for a SCSI Sense structure. Structures of this type are filled out by the\r
+                *  device via the MassStore_RequestSense() function, indicating the current sense data of the\r
+                *  device (giving explicit error codes for the last issued command). For details of the\r
+                *  structure contents, refer to the SCSI specifications.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint8_t       ReponseCode;\r
+\r
+                       uint8_t       SegmentNumber;\r
+                       \r
+                       unsigned char SenseKey            : 4;\r
+                       unsigned char _RESERVED1          : 1;\r
+                       unsigned char ILI                 : 1;\r
+                       unsigned char EOM                 : 1;\r
+                       unsigned char FileMark            : 1;\r
+                       \r
+                       uint8_t      Information[4];\r
+                       uint8_t      AdditionalLength;\r
+                       uint8_t      CmdSpecificInformation[4];\r
+                       uint8_t      AdditionalSenseCode;\r
+                       uint8_t      AdditionalSenseQualifier;\r
+                       uint8_t      FieldReplaceableUnitCode;\r
+                       uint8_t      SenseKeySpecific[3];\r
+               } SCSI_Request_Sense_Response_t;\r
+\r
+               /** SCSI capacity structure, to hold the total capacity of the device in both the number\r
+                *  of blocks in the current LUN, and the size of each block. This structure is filled by\r
+                *  the device when the MassStore_ReadCapacity() function is called.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */\r
+                       uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */\r
+               } SCSI_Capacity_t;\r
+\r
+       /* Enums: */\r
+               /** CSW status return codes, indicating the overall status of the issued CBW */\r
+               enum MassStorageHost_CommandStatusCodes_t\r
+               {\r
+                       Command_Pass = 0, /**< Command completed successfully */\r
+                       Command_Fail = 1, /**< Command failed to complete successfully */\r
+                       Phase_Error  = 2 /**< Phase error while processing the issued command */\r
+               };\r
+               \r
+       /* External Variables: */\r
+               extern CommandStatusWrapper_t SCSICommandStatus;\r
+               \r
+       /* Function Prototypes: */\r
+               #if defined(INCLUDE_FROM_MASSSTORE_COMMANDS_C)\r
+                       static uint8_t MassStore_SendCommand(void);\r
+                       static uint8_t MassStore_WaitForDataReceived(void);\r
+                       static uint8_t MassStore_SendReceiveData(void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1);\r
+                       static uint8_t MassStore_GetReturnedStatus(void);\r
+               #endif\r
+               \r
+               uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum);\r
+               uint8_t MassStore_MassStorageReset(void);\r
+               uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);\r
+               uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)\r
+                                              ATTR_NON_NULL_PTR_ARG(2);\r
+               uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
+                                                 const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);\r
+               uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
+                                           const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);\r
+               uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const CapacityPtr)\r
+                                              ATTR_NON_NULL_PTR_ARG(2);\r
+               uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex);\r
+               uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval);\r
+\r
+#endif\r
diff --git a/Demos/Host/MassStorageHost/Lib/SCSI_Codes.h b/Demos/Host/MassStorageHost/Lib/SCSI_Codes.h
new file mode 100644 (file)
index 0000000..2b2213d
--- /dev/null
@@ -0,0 +1,85 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header containing macros for possible SCSI commands and SENSE data. Refer to\r
+ *  the SCSI standard documentation for more information on each SCSI command and\r
+ *  the SENSE data.\r
+ */\r
\r
+#ifndef _SCSI_CODES_H_\r
+#define _SCSI_CODES_H_\r
+\r
+       /* Macros: */\r
+               #define SCSI_CMD_INQUIRY                               0x12\r
+               #define SCSI_CMD_REQUEST_SENSE                         0x03\r
+               #define SCSI_CMD_TEST_UNIT_READY                       0x00\r
+               #define SCSI_CMD_READ_CAPACITY_10                      0x25\r
+               #define SCSI_CMD_SEND_DIAGNOSTIC                       0x1D\r
+               #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL          0x1E\r
+               #define SCSI_CMD_WRITE_10                              0x2A\r
+               #define SCSI_CMD_READ_10                               0x28\r
+               #define SCSI_CMD_WRITE_6                               0x0A\r
+               #define SCSI_CMD_READ_6                                0x08\r
+               #define SCSI_CMD_VERIFY_10                             0x2F\r
+               #define SCSI_CMD_MODE_SENSE_6                          0x1A\r
+               #define SCSI_CMD_MODE_SENSE_10                         0x5A\r
+\r
+               #define SCSI_SENSE_KEY_GOOD                            0x00\r
+               #define SCSI_SENSE_KEY_RECOVERED_ERROR                 0x01\r
+               #define SCSI_SENSE_KEY_NOT_READY                       0x02\r
+               #define SCSI_SENSE_KEY_MEDIUM_ERROR                    0x03\r
+               #define SCSI_SENSE_KEY_HARDWARE_ERROR                  0x04\r
+               #define SCSI_SENSE_KEY_ILLEGAL_REQUEST                 0x05\r
+               #define SCSI_SENSE_KEY_UNIT_ATTENTION                  0x06\r
+               #define SCSI_SENSE_KEY_DATA_PROTECT                    0x07\r
+               #define SCSI_SENSE_KEY_BLANK_CHECK                     0x08\r
+               #define SCSI_SENSE_KEY_VENDOR_SPECIFIC                 0x09\r
+               #define SCSI_SENSE_KEY_COPY_ABORTED                    0x0A\r
+               #define SCSI_SENSE_KEY_ABORTED_COMMAND                 0x0B\r
+               #define SCSI_SENSE_KEY_VOLUME_OVERFLOW                 0x0D\r
+               #define SCSI_SENSE_KEY_MISCOMPARE                      0x0E\r
+\r
+               #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION          0x00\r
+               #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY             0x04\r
+               #define SCSI_ASENSE_INVALID_FIELD_IN_CDB               0x24\r
+               #define SCSI_ASENSE_WRITE_PROTECTED                    0x27\r
+               #define SCSI_ASENSE_FORMAT_ERROR                       0x31\r
+               #define SCSI_ASENSE_INVALID_COMMAND                    0x20\r
+               #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21\r
+               #define SCSI_ASENSE_MEDIUM_NOT_PRESENT                 0x3A\r
+\r
+               #define SCSI_ASENSEQ_NO_QUALIFIER                      0x00\r
+               #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED             0x01\r
+               #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED     0x02\r
+               #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS             0x07\r
+\r
+#endif\r
index 1646ad7..6e1e5cd 100644 (file)
@@ -45,7 +45,8 @@
                #include <ctype.h>\r
 \r
                #include "ConfigDescriptor.h"\r
-               #include "MassStoreCommands.h"\r
+\r
+               #include "Lib/MassStoreCommands.h"\r
 \r
                #include <LUFA/Version.h>                                // Library Version Information\r
                #include <LUFA/Drivers/Misc/TerminalCodes.h>             // ANSI Terminal Escape Codes\r
diff --git a/Demos/Host/MassStorageHost/MassStoreCommands.c b/Demos/Host/MassStorageHost/MassStoreCommands.c
deleted file mode 100644 (file)
index 95aafca..0000000
+++ /dev/null
@@ -1,685 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Mass Storage Device commands, to issue MSD commands to the device for\r
- *  reading device status, capacity, and other characteristics. This file\r
- *  also contains block read and write functions, so that device blocks\r
- *  can be read and written. In general, these functions would be chained\r
- *  to a FAT library to give file-level access to an attached device's contents.\r
- *\r
- *  \note Many Mass Storage devices on the market are non-compliant to the\r
- *        specifications and thus can prove difficult to interface with. It\r
- *        may be necessary to retry the functions in the module several times\r
- *        after they have returned and error to successfully send the command\r
- *        to the device. Some devices may also need to have the stream function\r
- *        timeout period extended beyond 100ms (some badly designed devices exceeding\r
- *        1.5 seconds occasionally) by defining USB_STREAM_TIMEOUT_MS to a\r
- *        larger value in the project makefile and passing it to the compiler\r
- *        via the -D switch.\r
- */\r
\r
-#define  INCLUDE_FROM_MASSSTORE_COMMANDS_C\r
-#include "MassStoreCommands.h"\r
-\r
-/* Globals: */\r
-/** Current CBW to send to the device. This is automatically filled by the routines\r
- *  in this file and is not externally accessible.\r
- */\r
-static CommandBlockWrapper_t  SCSICommandBlock;\r
-\r
-/** Current CSW received from the device. This is automatically filled by the routines\r
- *  in this file and is externally accessible so that the return codes may be checked.\r
- */\r
-CommandStatusWrapper_t        SCSICommandStatus;\r
-\r
-/** Current Tag value used in issued CBWs to the device. This is automatically incremented\r
- *  by the routines in this file, and is not externally accessible.\r
- */\r
-static uint32_t               MassStore_Tag = 1;\r
-\r
-\r
-/** Routine to send the current CBW to the device, and increment the Tag value as needed.\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-static uint8_t MassStore_SendCommand(void)\r
-{\r
-       uint8_t ErrorCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* Each transmission should have a unique tag value, excluding values 0 and 0xFFFFFFFF */\r
-       if (++MassStore_Tag == 0xFFFFFFFF)\r
-         MassStore_Tag = 1;\r
-\r
-       /* Select the OUT data pipe for CBW transmission */\r
-       Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
-       Pipe_Unfreeze();\r
-\r
-       /* Write the CBW command to the OUT pipe */\r
-       if ((ErrorCode = Pipe_Write_Stream_LE(&SCSICommandBlock, sizeof(CommandBlockWrapper_t))) != PIPE_RWSTREAM_NoError)\r
-         return ErrorCode;\r
-\r
-       /* Send the data in the OUT pipe to the attached device */\r
-       Pipe_ClearOUT();\r
-       \r
-       while(!(Pipe_IsOUTReady()));\r
-\r
-       /* Freeze pipe after use */\r
-       Pipe_Freeze();\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Waits until the attached device is ready to accept data following a CBW, checking\r
- *  to ensure that the device has not stalled the transaction.\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-static uint8_t MassStore_WaitForDataReceived(void)\r
-{\r
-       uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;\r
-\r
-       /* Unfreeze the OUT pipe so that it can be checked */\r
-       Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
-       Pipe_Unfreeze();\r
-\r
-       /* Select the IN data pipe for data reception */\r
-       Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
-       Pipe_Unfreeze();\r
-\r
-       /* Wait until data received in the IN pipe */\r
-       while (!(Pipe_IsINReceived()))\r
-       {\r
-               /* Check to see if a new frame has been issued (1ms elapsed) */\r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
-               {\r
-                       /* Clear the flag and decrement the timeout period counter */\r
-                       USB_INT_Clear(USB_INT_HSOFI);\r
-                       TimeoutMSRem--;\r
-\r
-                       /* Check to see if the timeout period for the command has elapsed */\r
-                       if (!(TimeoutMSRem))\r
-                         return PIPE_RWSTREAM_Timeout;\r
-               }\r
-       \r
-               Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
-\r
-               /* Check if pipe stalled (command failed by device) */\r
-               if (Pipe_IsStalled())\r
-               {\r
-                       /* Clear the stall condition on the OUT pipe */\r
-                       MassStore_ClearPipeStall(MASS_STORE_DATA_OUT_PIPE);\r
-\r
-                       return PIPE_RWSTREAM_PipeStalled;\r
-               }\r
-\r
-               Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
-\r
-               /* Check if pipe stalled (command failed by device) */\r
-               if (Pipe_IsStalled())\r
-               {\r
-                       /* Clear the stall condition on the IN pipe */\r
-                       MassStore_ClearPipeStall(MASS_STORE_DATA_IN_PIPE);\r
-\r
-                       return PIPE_RWSTREAM_PipeStalled;\r
-               }\r
-                 \r
-               /* Check to see if the device was disconnected, if so exit function */\r
-               if (!(USB_IsConnected))\r
-                 return PIPE_RWSTREAM_DeviceDisconnected;\r
-       };\r
-\r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Sends or receives the transaction's data stage to or from the attached device, reading or\r
- *  writing to the nominated buffer.\r
- *\r
- *  \param  BufferPtr  Pointer to the data buffer to read from or write to\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-static uint8_t MassStore_SendReceiveData(void* BufferPtr)\r
-{\r
-       uint8_t  ErrorCode = PIPE_RWSTREAM_NoError;\r
-       uint16_t BytesRem  = SCSICommandBlock.Header.DataTransferLength;\r
-\r
-       /* Check the direction of the SCSI command data stage */\r
-       if (SCSICommandBlock.Header.Flags & COMMAND_DIRECTION_DATA_IN)\r
-       {\r
-               /* Select the IN data pipe for data reception */\r
-               Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
-               Pipe_Unfreeze();\r
-               \r
-               /* Read in the block data from the pipe */\r
-               if ((ErrorCode = Pipe_Read_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)\r
-                 return ErrorCode;\r
-\r
-               /* Acknowledge the packet */\r
-               Pipe_ClearIN();\r
-       }\r
-       else\r
-       {\r
-               /* Select the OUT data pipe for data transmission */\r
-               Pipe_SelectPipe(MASS_STORE_DATA_OUT_PIPE);\r
-               Pipe_Unfreeze();\r
-\r
-               /* Write the block data to the pipe */\r
-               if ((ErrorCode = Pipe_Write_Stream_LE(BufferPtr, BytesRem)) != PIPE_RWSTREAM_NoError)\r
-                 return ErrorCode;\r
-\r
-               /* Acknowledge the packet */\r
-               Pipe_ClearOUT();\r
-               \r
-               while (!(Pipe_IsOUTReady()));\r
-       }\r
-       \r
-       /* Freeze used pipe after use */\r
-       Pipe_Freeze();\r
-\r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Routine to receive the current CSW from the device.\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-static uint8_t MassStore_GetReturnedStatus(void)\r
-{\r
-       uint8_t ErrorCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* If an error in the command ocurred, abort */\r
-       if ((ErrorCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
-         return ErrorCode;\r
-\r
-       /* Select the IN data pipe for data reception */\r
-       Pipe_SelectPipe(MASS_STORE_DATA_IN_PIPE);\r
-       Pipe_Unfreeze();\r
-       \r
-       /* Load in the CSW from the attached device */\r
-       if ((ErrorCode = Pipe_Read_Stream_LE(&SCSICommandStatus, sizeof(CommandStatusWrapper_t))) != PIPE_RWSTREAM_NoError)\r
-         return ErrorCode;\r
-         \r
-       /* Clear the data ready for next reception */\r
-       Pipe_ClearIN();\r
-       \r
-       /* Freeze the IN pipe after use */\r
-       Pipe_Freeze();\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Clears the stall condition in the attached device on the nominated endpoint number.\r
- *\r
- *  \param EndpointNum  Endpoint number in the attached device whose stall condition is to be cleared\r
- *\r
- *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
- */\r
-uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum)\r
-{\r
-       USB_ControlRequest = (USB_Request_Header_t)\r
-               {\r
-                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
-                       .bRequest      = REQ_ClearFeature,\r
-                       .wValue        = FEATURE_ENDPOINT_HALT,\r
-                       .wIndex        = EndpointNum,\r
-                       .wLength       = 0,\r
-               };\r
-       \r
-       /* Select the control pipe for the request transfer */\r
-       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
-\r
-       return USB_Host_SendControlRequest(NULL);\r
-}\r
-\r
-/** Issues a Mass Storage class specific request to reset the attached device's Mass Storage interface,\r
- *  readying the device for the next CBW.\r
- *\r
- *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
- */\r
-uint8_t MassStore_MassStorageReset(void)\r
-{\r
-       USB_ControlRequest = (USB_Request_Header_t)\r
-               {\r
-                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_CLASS | REQREC_INTERFACE),\r
-                       .bRequest      = REQ_MassStorageReset,\r
-                       .wValue        = 0,\r
-                       .wIndex        = 0,\r
-                       .wLength       = 0,\r
-               };\r
-       \r
-       /* Select the control pipe for the request transfer */\r
-       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
-\r
-       return USB_Host_SendControlRequest(NULL);\r
-}\r
-\r
-/** Issues a Mass Storage class specific request to determine the index of the highest numbered Logical\r
- *  Unit in the attached device.\r
- *\r
- *  \param MaxLUNIndex  Pointer to the location that the maximum LUN index value should be stored\r
- *\r
- *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
- */\r
-uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex)\r
-{\r
-       uint8_t ErrorCode;\r
-\r
-       USB_ControlRequest = (USB_Request_Header_t)\r
-               {\r
-                       .bmRequestType = (REQDIR_DEVICETOHOST | REQTYPE_CLASS | REQREC_INTERFACE),\r
-                       .bRequest      = REQ_GetMaxLUN,\r
-                       .wValue        = 0,\r
-                       .wIndex        = 0,\r
-                       .wLength       = 1,\r
-               };\r
-               \r
-       /* Select the control pipe for the request transfer */\r
-       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
-\r
-       if ((ErrorCode = USB_Host_SendControlRequest(MaxLUNIndex)) == HOST_SENDCONTROL_SetupStalled)\r
-       {\r
-               /* Clear the pipe stall */\r
-               Pipe_ClearStall();\r
-       \r
-               /* Some faulty Mass Storage devices don't implement the GET_MAX_LUN request, so assume a single LUN */\r
-               *MaxLUNIndex = 0;       \r
-       }\r
-       \r
-       return ErrorCode;\r
-}\r
-\r
-/** Issues a SCSI Request Sense command to the attached device, to determine the current SCSI sense information. This\r
- *  gives error codes for the last issued SCSI command to the device.\r
- *\r
- *  \param LUNIndex  Index of the LUN inside the device the command is being addressed to\r
- *  \param SensePtr  Pointer to the sense data structure where the sense data from the device is to be stored\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)\r
-{\r
-       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* Create a CBW with a SCSI command to issue REQUEST SENSE command */\r
-       SCSICommandBlock = (CommandBlockWrapper_t)\r
-               {\r
-                       .Header =\r
-                               {\r
-                                       .Signature          = CBW_SIGNATURE,\r
-                                       .Tag                = MassStore_Tag,\r
-                                       .DataTransferLength = sizeof(SCSI_Request_Sense_Response_t),\r
-                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
-                                       .LUN                = LUNIndex,\r
-                                       .SCSICommandLength  = 6\r
-                               },\r
-                                       \r
-                       .SCSICommandData =\r
-                               {\r
-                                       SCSI_CMD_REQUEST_SENSE,\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       sizeof(SCSI_Request_Sense_Response_t), // Allocation Length\r
-                                       0x00                    // Unused (control)\r
-                               }\r
-               };\r
-       \r
-       /* Send SCSI command to the attached device */\r
-       MassStore_SendCommand();\r
-\r
-       /* Wait until data received from the device */\r
-       if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-\r
-       /* Read the returned sense data into the buffer */\r
-       if ((ReturnCode = MassStore_SendReceiveData((uint8_t*)SensePtr)) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }       \r
-       \r
-       /* Read in the returned CSW from the device */\r
-       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Issues a SCSI Device Block Read command to the attached device, to read in one or more data blocks from the\r
- *  storage medium into a buffer.\r
- *\r
- *  \param LUNIndex      Index of the LUN inside the device the command is being addressed to\r
- *  \param BlockAddress  Start block address to read from\r
- *  \param Blocks        Number of blocks to read from the device\r
- *  \param BlockSize     Size in bytes of each block to read\r
- *  \param BufferPtr     Pointer to the buffer where the read data is to be written to\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
-                                  const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr)\r
-{\r
-       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* Create a CBW with a SCSI command to read in the given blocks from the device */\r
-       SCSICommandBlock = (CommandBlockWrapper_t)\r
-               {\r
-                       .Header =\r
-                               {\r
-                                       .Signature          = CBW_SIGNATURE,\r
-                                       .Tag                = MassStore_Tag,\r
-                                       .DataTransferLength = ((uint32_t)Blocks * BlockSize),\r
-                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
-                                       .LUN                = LUNIndex,\r
-                                       .SCSICommandLength  = 10\r
-                               },\r
-                                       \r
-                       .SCSICommandData =\r
-                               {\r
-                                       SCSI_CMD_READ_10,\r
-                                       0x00,                   // Unused (control bits, all off)\r
-                                       (BlockAddress >> 24),   // MSB of Block Address\r
-                                       (BlockAddress >> 16),\r
-                                       (BlockAddress >> 8),\r
-                                       (BlockAddress & 0xFF),  // LSB of Block Address\r
-                                       0x00,                   // Unused (reserved)\r
-                                       0x00,                   // MSB of Total Blocks to Read\r
-                                       Blocks,                 // LSB of Total Blocks to Read\r
-                                       0x00                    // Unused (control)\r
-                               }\r
-               };\r
-       \r
-       /* Send SCSI command to the attached device */\r
-       MassStore_SendCommand();\r
-\r
-       /* Wait until data received from the device */\r
-       if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-\r
-       /* Read the returned block data into the buffer */\r
-       if ((ReturnCode = MassStore_SendReceiveData(BufferPtr)) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }       \r
-       \r
-       /* Read in the returned CSW from the device */\r
-       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Issues a SCSI Device Block Write command to the attached device, to write one or more data blocks to the\r
- *  storage medium from a buffer.\r
- *\r
- *  \param LUNIndex      Index of the LUN inside the device the command is being addressed to\r
- *  \param BlockAddress  Start block address to write to\r
- *  \param Blocks        Number of blocks to write to in the device\r
- *  \param BlockSize     Size in bytes of each block to write\r
- *  \param BufferPtr     Pointer to the buffer where the write data is to be sourced from\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
-                                   const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr)\r
-{\r
-       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* Create a CBW with a SCSI command to write the given blocks to the device */\r
-       SCSICommandBlock = (CommandBlockWrapper_t)\r
-               {\r
-                       .Header =\r
-                               {\r
-                                       .Signature          = CBW_SIGNATURE,\r
-                                       .Tag                = MassStore_Tag,\r
-                                       .DataTransferLength = ((uint32_t)Blocks * BlockSize),\r
-                                       .Flags              = COMMAND_DIRECTION_DATA_OUT,\r
-                                       .LUN                = LUNIndex,\r
-                                       .SCSICommandLength  = 10\r
-                               },\r
-                                       \r
-                       .SCSICommandData =\r
-                               {\r
-                                       SCSI_CMD_WRITE_10,\r
-                                       0x00,                   // Unused (control bits, all off)\r
-                                       (BlockAddress >> 24),   // MSB of Block Address\r
-                                       (BlockAddress >> 16),\r
-                                       (BlockAddress >> 8),\r
-                                       (BlockAddress & 0xFF),  // LSB of Block Address\r
-                                       0x00,                   // Unused (reserved)\r
-                                       0x00,                   // MSB of Total Blocks to Write\r
-                                       Blocks,                 // LSB of Total Blocks to Write\r
-                                       0x00                    // Unused (control)\r
-                               }\r
-               };\r
-       \r
-       /* Send SCSI command to the attached device */\r
-       MassStore_SendCommand();\r
-\r
-       /* Write the data to the device from the buffer */\r
-       if ((ReturnCode = MassStore_SendReceiveData(BufferPtr)) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }       \r
-       \r
-       /* Read in the returned CSW from the device */\r
-       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Issues a SCSI Device Test Unit Ready command to the attached device, to determine if the device is ready to accept\r
- *  other commands.\r
- *\r
- *  \param LUNIndex      Index of the LUN inside the device the command is being addressed to\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex)\r
-{\r
-       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;     \r
-\r
-       /* Create a CBW with a SCSI command to issue TEST UNIT READY command */\r
-       SCSICommandBlock = (CommandBlockWrapper_t)\r
-               {\r
-                       .Header =\r
-                               {\r
-                                       .Signature          = CBW_SIGNATURE,\r
-                                       .Tag                = MassStore_Tag,\r
-                                       .DataTransferLength = 0,\r
-                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
-                                       .LUN                = LUNIndex,\r
-                                       .SCSICommandLength  = 6\r
-                               },\r
-                                       \r
-                       .SCSICommandData =\r
-                               {\r
-                                       SCSI_CMD_TEST_UNIT_READY,\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       0x00                    // Unused (control)\r
-                               }\r
-               };\r
-       \r
-       /* Send SCSI command to the attached device */\r
-       MassStore_SendCommand();\r
-\r
-       /* Read in the returned CSW from the device */\r
-       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Issues a SCSI Device Read Capacity command to the attached device, to determine the capacity of the\r
- *  given Logical Unit within the device.\r
- *\r
- *  \param LUNIndex     Index of the LUN inside the device the command is being addressed to\r
- *  \param CapacityPtr  Device capacity structure where the capacity data is to be stored\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const CapacityPtr)\r
-{\r
-       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* Create a CBW with a SCSI command to issue READ CAPACITY command */\r
-       SCSICommandBlock = (CommandBlockWrapper_t)\r
-               {\r
-                       .Header =\r
-                               {\r
-                                       .Signature          = CBW_SIGNATURE,\r
-                                       .Tag                = MassStore_Tag,\r
-                                       .DataTransferLength = sizeof(SCSI_Capacity_t),\r
-                                       .Flags              = COMMAND_DIRECTION_DATA_IN,\r
-                                       .LUN                = LUNIndex,\r
-                                       .SCSICommandLength  = 10\r
-                               },\r
-                                       \r
-                       .SCSICommandData =\r
-                               {\r
-                                       SCSI_CMD_READ_CAPACITY_10,\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // MSB of Logical block address\r
-                                       0x00,\r
-                                       0x00,\r
-                                       0x00,                   // LSB of Logical block address\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Partial Medium Indicator\r
-                                       0x00                    // Unused (control)\r
-                               }\r
-               };\r
-       \r
-       /* Send SCSI command to the attached device */\r
-       MassStore_SendCommand();\r
-\r
-       /* Wait until data received from the device */\r
-       if ((ReturnCode = MassStore_WaitForDataReceived()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-\r
-       /* Read the returned capacity data into the buffer */\r
-       if ((ReturnCode = MassStore_SendReceiveData(CapacityPtr)) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-         \r
-       /* Endian-correct the read data */\r
-       CapacityPtr->Blocks    = SwapEndian_32(CapacityPtr->Blocks);\r
-       CapacityPtr->BlockSize = SwapEndian_32(CapacityPtr->BlockSize);\r
-       \r
-       /* Read in the returned CSW from the device */\r
-       if ((ReturnCode = MassStore_GetReturnedStatus()) != PIPE_RWSTREAM_NoError)\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Issues a SCSI Device Prevent/Allow Medium Removal command to the attached device, to lock the physical media from\r
- *  being removed. This is a legacy command for SCSI disks with removable storage (such as ZIP disks), but should still\r
- *  be issued before the first read or write command is sent.\r
- *\r
- *  \param LUNIndex        Index of the LUN inside the device the command is being addressed to\r
- *  \param PreventRemoval  Whether or not the LUN media should be locked to prevent removal or not\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval)\r
-{\r
-       uint8_t ReturnCode = PIPE_RWSTREAM_NoError;\r
-\r
-       /* Create a CBW with a SCSI command to issue PREVENT ALLOW MEDIUM REMOVAL command */\r
-       SCSICommandBlock = (CommandBlockWrapper_t)\r
-               {\r
-                       .Header =\r
-                               {\r
-                                       .Signature          = CBW_SIGNATURE,\r
-                                       .Tag                = MassStore_Tag,\r
-                                       .DataTransferLength = 0,\r
-                                       .Flags              = COMMAND_DIRECTION_DATA_OUT,\r
-                                       .LUN                = LUNIndex,\r
-                                       .SCSICommandLength  = 6\r
-                               },\r
-                                       \r
-                       .SCSICommandData =\r
-                               {\r
-                                       SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL,\r
-                                       0x00,                   // Reserved\r
-                                       0x00,                   // Reserved\r
-                                       PreventRemoval,         // Prevent flag\r
-                                       0x00,                   // Reserved\r
-                                       0x00                    // Unused (control)\r
-                               }\r
-               };\r
-       \r
-       /* Send SCSI command to the attached device */\r
-       MassStore_SendCommand();\r
-\r
-       /* Read in the returned CSW from the device */\r
-       if ((ReturnCode = MassStore_GetReturnedStatus()))\r
-       {\r
-               Pipe_Freeze();\r
-               return ReturnCode;\r
-       }\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
diff --git a/Demos/Host/MassStorageHost/MassStoreCommands.h b/Demos/Host/MassStorageHost/MassStoreCommands.h
deleted file mode 100644 (file)
index 28f6a15..0000000
+++ /dev/null
@@ -1,175 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for MassStoreCommands.c.\r
- */\r
\r
-#ifndef _MASS_STORE_COMMANDS_H_\r
-#define _MASS_STORE_COMMANDS_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-\r
-               #include "MassStorageHost.h"\r
-               #include "SCSI_Codes.h"\r
-\r
-               #include <LUFA/Drivers/USB/USB.h>                    // USB Functionality\r
-\r
-       /* Macros: */\r
-               /** Class specific request to reset the Mass Storage interface of the attached device */\r
-               #define REQ_MassStorageReset             0xFF\r
-\r
-               /** Class specific request to retrieve the maximum Logical Unit Number (LUN) index of the attached device */\r
-               #define REQ_GetMaxLUN                    0xFE\r
-\r
-               /** Command Block Wrapper signature byte, for verification of valid CBW blocks */\r
-               #define CBW_SIGNATURE                    0x43425355UL\r
-\r
-               /** Command Static Wrapper signature byte, for verification of valid CSW blocks */\r
-               #define CSW_SIGNATURE                    0x53425355UL\r
-               \r
-               /** Data direction mask for the Flags field of a CBW, indicating Host-to-Device transfer direction */\r
-               #define COMMAND_DIRECTION_DATA_OUT       (0 << 7)\r
-\r
-               /** Data direction mask for the Flags field of a CBW, indicating Device-to-Host transfer direction */\r
-               #define COMMAND_DIRECTION_DATA_IN        (1 << 7)\r
-               \r
-               /** Timeout period between the issuing of a CBW to a device, and the reception of the first packet */\r
-               #define COMMAND_DATA_TIMEOUT_MS          500\r
-\r
-               /** Pipe number of the Mass Storage data IN pipe */\r
-               #define MASS_STORE_DATA_IN_PIPE          1\r
-\r
-               /** Pipe number of the Mass Storage data OUT pipe */\r
-               #define MASS_STORE_DATA_OUT_PIPE         2\r
-\r
-       /* Type defines: */\r
-               /** Type define for a Mass Storage class Command Block Wrapper, used to wrap SCSI\r
-                *  commands for transport over the USB bulk endpoints to the device.\r
-                */\r
-               typedef struct\r
-               {\r
-                       struct\r
-                       {\r
-                               uint32_t Signature; /**< Command block signature, always equal to CBW_SIGNATURE */\r
-                               uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW */\r
-                               uint32_t DataTransferLength; /**< Length of data to transfer, following the CBW */\r
-                               uint8_t  Flags; /**< Block flags, equal to one of the COMMAND_DIRECTION_DATA_* macros */\r
-                               uint8_t  LUN; /**< Logical Unit Number the CBW is addressed to in the device */\r
-                               uint8_t  SCSICommandLength; /**< Length of the SCSI command in the CBW */\r
-                       } Header;\r
-                       \r
-                       uint8_t SCSICommandData[16]; /**< SCSI command to issue to the device */\r
-               } CommandBlockWrapper_t;\r
-               \r
-               /** Type define for a Mass Storage class Command Status Wrapper, used to wrap SCSI\r
-                *  responses for transport over the USB bulk endpoints from the device.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint32_t Signature; /**< Command status signature, always equal to CSW_SIGNATURE */\r
-                       uint32_t Tag; /**< Current CBW tag, to positively associate a CBW with a CSW */\r
-                       uint32_t DataTransferResidue; /**< Length of data not transferred */\r
-                       uint8_t  Status; /**< Command status, a value from the MassStorageHost_CommandStatusCodes_t enum */\r
-               } CommandStatusWrapper_t;\r
-               \r
-               /** Type define for a SCSI Sense structure. Structures of this type are filled out by the\r
-                *  device via the MassStore_RequestSense() function, indicating the current sense data of the\r
-                *  device (giving explicit error codes for the last issued command). For details of the\r
-                *  structure contents, refer to the SCSI specifications.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint8_t       ReponseCode;\r
-\r
-                       uint8_t       SegmentNumber;\r
-                       \r
-                       unsigned char SenseKey            : 4;\r
-                       unsigned char _RESERVED1          : 1;\r
-                       unsigned char ILI                 : 1;\r
-                       unsigned char EOM                 : 1;\r
-                       unsigned char FileMark            : 1;\r
-                       \r
-                       uint8_t      Information[4];\r
-                       uint8_t      AdditionalLength;\r
-                       uint8_t      CmdSpecificInformation[4];\r
-                       uint8_t      AdditionalSenseCode;\r
-                       uint8_t      AdditionalSenseQualifier;\r
-                       uint8_t      FieldReplaceableUnitCode;\r
-                       uint8_t      SenseKeySpecific[3];\r
-               } SCSI_Request_Sense_Response_t;\r
-\r
-               /** SCSI capacity structure, to hold the total capacity of the device in both the number\r
-                *  of blocks in the current LUN, and the size of each block. This structure is filled by\r
-                *  the device when the MassStore_ReadCapacity() function is called.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint32_t Blocks; /**< Number of blocks in the addressed LUN of the device */\r
-                       uint32_t BlockSize; /**< Number of bytes in each block in the addressed LUN */\r
-               } SCSI_Capacity_t;\r
-\r
-       /* Enums: */\r
-               /** CSW status return codes, indicating the overall status of the issued CBW */\r
-               enum MassStorageHost_CommandStatusCodes_t\r
-               {\r
-                       Command_Pass = 0, /**< Command completed successfully */\r
-                       Command_Fail = 1, /**< Command failed to complete successfully */\r
-                       Phase_Error  = 2 /**< Phase error while processing the issued command */\r
-               };\r
-               \r
-       /* External Variables: */\r
-               extern CommandStatusWrapper_t SCSICommandStatus;\r
-               \r
-       /* Function Prototypes: */\r
-               #if defined(INCLUDE_FROM_MASSSTORE_COMMANDS_C)\r
-                       static uint8_t MassStore_SendCommand(void);\r
-                       static uint8_t MassStore_WaitForDataReceived(void);\r
-                       static uint8_t MassStore_SendReceiveData(void* BufferPtr) ATTR_NON_NULL_PTR_ARG(1);\r
-                       static uint8_t MassStore_GetReturnedStatus(void);\r
-               #endif\r
-               \r
-               uint8_t MassStore_ClearPipeStall(const uint8_t EndpointNum);\r
-               uint8_t MassStore_MassStorageReset(void);\r
-               uint8_t MassStore_GetMaxLUN(uint8_t* const MaxLUNIndex);\r
-               uint8_t MassStore_RequestSense(const uint8_t LUNIndex, const SCSI_Request_Sense_Response_t* const SensePtr)\r
-                                              ATTR_NON_NULL_PTR_ARG(2);\r
-               uint8_t MassStore_ReadDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
-                                                 const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);\r
-               uint8_t MassStore_WriteDeviceBlock(const uint8_t LUNIndex, const uint32_t BlockAddress,\r
-                                           const uint8_t Blocks, const uint16_t BlockSize, void* BufferPtr) ATTR_NON_NULL_PTR_ARG(5);\r
-               uint8_t MassStore_ReadCapacity(const uint8_t LUNIndex, SCSI_Capacity_t* const CapacityPtr)\r
-                                              ATTR_NON_NULL_PTR_ARG(2);\r
-               uint8_t MassStore_TestUnitReady(const uint8_t LUNIndex);\r
-               uint8_t MassStore_PreventAllowMediumRemoval(const uint8_t LUNIndex, const bool PreventRemoval);\r
-\r
-#endif\r
diff --git a/Demos/Host/MassStorageHost/SCSI_Codes.h b/Demos/Host/MassStorageHost/SCSI_Codes.h
deleted file mode 100644 (file)
index 2b2213d..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header containing macros for possible SCSI commands and SENSE data. Refer to\r
- *  the SCSI standard documentation for more information on each SCSI command and\r
- *  the SENSE data.\r
- */\r
\r
-#ifndef _SCSI_CODES_H_\r
-#define _SCSI_CODES_H_\r
-\r
-       /* Macros: */\r
-               #define SCSI_CMD_INQUIRY                               0x12\r
-               #define SCSI_CMD_REQUEST_SENSE                         0x03\r
-               #define SCSI_CMD_TEST_UNIT_READY                       0x00\r
-               #define SCSI_CMD_READ_CAPACITY_10                      0x25\r
-               #define SCSI_CMD_SEND_DIAGNOSTIC                       0x1D\r
-               #define SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL          0x1E\r
-               #define SCSI_CMD_WRITE_10                              0x2A\r
-               #define SCSI_CMD_READ_10                               0x28\r
-               #define SCSI_CMD_WRITE_6                               0x0A\r
-               #define SCSI_CMD_READ_6                                0x08\r
-               #define SCSI_CMD_VERIFY_10                             0x2F\r
-               #define SCSI_CMD_MODE_SENSE_6                          0x1A\r
-               #define SCSI_CMD_MODE_SENSE_10                         0x5A\r
-\r
-               #define SCSI_SENSE_KEY_GOOD                            0x00\r
-               #define SCSI_SENSE_KEY_RECOVERED_ERROR                 0x01\r
-               #define SCSI_SENSE_KEY_NOT_READY                       0x02\r
-               #define SCSI_SENSE_KEY_MEDIUM_ERROR                    0x03\r
-               #define SCSI_SENSE_KEY_HARDWARE_ERROR                  0x04\r
-               #define SCSI_SENSE_KEY_ILLEGAL_REQUEST                 0x05\r
-               #define SCSI_SENSE_KEY_UNIT_ATTENTION                  0x06\r
-               #define SCSI_SENSE_KEY_DATA_PROTECT                    0x07\r
-               #define SCSI_SENSE_KEY_BLANK_CHECK                     0x08\r
-               #define SCSI_SENSE_KEY_VENDOR_SPECIFIC                 0x09\r
-               #define SCSI_SENSE_KEY_COPY_ABORTED                    0x0A\r
-               #define SCSI_SENSE_KEY_ABORTED_COMMAND                 0x0B\r
-               #define SCSI_SENSE_KEY_VOLUME_OVERFLOW                 0x0D\r
-               #define SCSI_SENSE_KEY_MISCOMPARE                      0x0E\r
-\r
-               #define SCSI_ASENSE_NO_ADDITIONAL_INFORMATION          0x00\r
-               #define SCSI_ASENSE_LOGICAL_UNIT_NOT_READY             0x04\r
-               #define SCSI_ASENSE_INVALID_FIELD_IN_CDB               0x24\r
-               #define SCSI_ASENSE_WRITE_PROTECTED                    0x27\r
-               #define SCSI_ASENSE_FORMAT_ERROR                       0x31\r
-               #define SCSI_ASENSE_INVALID_COMMAND                    0x20\r
-               #define SCSI_ASENSE_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x21\r
-               #define SCSI_ASENSE_MEDIUM_NOT_PRESENT                 0x3A\r
-\r
-               #define SCSI_ASENSEQ_NO_QUALIFIER                      0x00\r
-               #define SCSI_ASENSEQ_FORMAT_COMMAND_FAILED             0x01\r
-               #define SCSI_ASENSEQ_INITIALIZING_COMMAND_REQUIRED     0x02\r
-               #define SCSI_ASENSEQ_OPERATION_IN_PROGRESS             0x07\r
-\r
-#endif\r
index d4792ae..f50f598 100644 (file)
@@ -125,7 +125,7 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          ConfigDescriptor.c                                          \\r
-         MassStoreCommands.c                                         \\r
+         Lib/MassStoreCommands.c                                     \\r
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \\r
diff --git a/Demos/Host/StillImageHost/Lib/PIMACodes.h b/Demos/Host/StillImageHost/Lib/PIMACodes.h
new file mode 100644 (file)
index 0000000..38755ab
--- /dev/null
@@ -0,0 +1,51 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header containing macros for possible PIMA commands. Refer to the PIMA standard\r
+ *  documentation for more information on each PIMA command.\r
+ */\r
+\r
+#ifndef _PIMA_CODES_H_\r
+\r
+       /* Macros: */\r
+               #define PIMA_OPERATION_GETDEVICEINFO         0x1001\r
+               #define PIMA_OPERATION_OPENSESSION           0x1002\r
+               #define PIMA_OPERATION_CLOSESESSION          0x1003\r
+               \r
+               #define PIMA_RESPONSE_OK                     0x2001\r
+               #define PIMA_RESPONSE_GENERALERROR           0x2002\r
+               #define PIMA_RESPONSE_SESSIONNOTOPEN         0x2003\r
+               #define PIMA_RESPONSE_INVALIDTRANSACTIONID   0x2004\r
+               #define PIMA_RESPONSE_OPERATIONNOTSUPPORTED  0x2005\r
+               #define PIMA_RESPONSE_PARAMETERNOTSUPPORTED  0x2006\r
+\r
+#endif\r
diff --git a/Demos/Host/StillImageHost/Lib/StillImageCommands.c b/Demos/Host/StillImageHost/Lib/StillImageCommands.c
new file mode 100644 (file)
index 0000000..8f05e48
--- /dev/null
@@ -0,0 +1,279 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Still Image Device commands, to issue PIMA commands to the device for\r
+ *  reading device status, capacity, and other characteristics as well as\r
+ *  reading and writing of stored image data.\r
+ */\r
+\r
+#include "StillImageCommands.h"\r
+\r
+/* Globals: */\r
+/** PIMA block container for the block to send to the device */\r
+PIMA_Container_t PIMA_SendBlock;\r
+\r
+/** PIMA block container for the last received block from the device */\r
+PIMA_Container_t PIMA_ReceivedBlock;\r
+\r
+/** PIMA block container for the last event block received from the device */\r
+PIMA_Container_t PIMA_EventBlock;\r
+\r
+\r
+/** Function to send the PIMA command container to the attached still image device. */\r
+void SImage_SendBlockHeader(void)\r
+{\r
+       /* Unfreeze the data OUT pipe ready for data transmission */\r
+       Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
+       Pipe_Unfreeze();\r
+\r
+       /* Write the PIMA block to the data OUT pipe */\r
+       Pipe_Write_Stream_LE(&PIMA_SendBlock, PIMA_COMMAND_SIZE(0));\r
+       \r
+       /* If the block type is a command, send its parameters (if any) */\r
+       if (PIMA_SendBlock.Type == CType_CommandBlock)\r
+       {\r
+               /* Determine the size of the parameters in the block via the data length attribute */\r
+               uint8_t ParamBytes = (PIMA_SendBlock.DataLength - PIMA_COMMAND_SIZE(0));\r
+\r
+               /* Check if any parameters in the command block */\r
+               if (ParamBytes)\r
+               {\r
+                       /* Write the PIMA parameters to the data OUT pipe */\r
+                       Pipe_Write_Stream_LE(&PIMA_SendBlock.Params, ParamBytes);\r
+               }\r
+               \r
+               /* Send the PIMA command block to the attached device */\r
+               Pipe_ClearOUT();\r
+       }\r
+                                       \r
+       /* Freeze pipe after use */\r
+       Pipe_Freeze();\r
+}\r
+\r
+/** Function to receive a PIMA event container from the attached still image device. */\r
+void SImage_RecieveEventHeader(void)\r
+{\r
+       /* Unfreeze the events pipe */\r
+       Pipe_SelectPipe(SIMAGE_EVENTS_PIPE);\r
+       Pipe_Unfreeze();\r
+       \r
+       /* Read in the event data into the global structure */\r
+       Pipe_Read_Stream_LE(&PIMA_EventBlock, sizeof(PIMA_EventBlock));\r
+       \r
+       /* Clear the pipe after read complete to prepare for next event */\r
+       Pipe_ClearIN();\r
+       \r
+       /* Freeze the event pipe again after use */\r
+       Pipe_Freeze();\r
+}\r
+\r
+/** Function to receive a PIMA response container from the attached still image device. */\r
+uint8_t SImage_RecieveBlockHeader(void)\r
+{\r
+       uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;\r
+\r
+       /* Unfreeze the data IN pipe */\r
+       Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
+       Pipe_Unfreeze();\r
+       \r
+       /* Wait until data received on the IN pipe */\r
+       while (!(Pipe_IsReadWriteAllowed()))\r
+       {\r
+               /* Check to see if a new frame has been issued (1ms elapsed) */\r
+               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
+               {\r
+                       /* Clear the flag and decrement the timeout period counter */\r
+                       USB_INT_Clear(USB_INT_HSOFI);\r
+                       TimeoutMSRem--;\r
+\r
+                       /* Check to see if the timeout period for the command has elapsed */\r
+                       if (!(TimeoutMSRem))\r
+                       {\r
+                               /* Return error code */\r
+                               return PIPE_RWSTREAM_Timeout;\r
+                       }\r
+               }\r
+               \r
+               Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
+\r
+               /* Check if pipe stalled (command failed by device) */\r
+               if (Pipe_IsStalled())\r
+               {\r
+                       /* Clear the stall condition on the OUT pipe */\r
+                       SImage_ClearPipeStall(SIMAGE_DATA_OUT_PIPE);\r
+\r
+                       /* Return error code and break out of the loop */\r
+                       return PIPE_RWSTREAM_PipeStalled;\r
+               }\r
+\r
+               Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
+\r
+               /* Check if pipe stalled (command failed by device) */\r
+               if (Pipe_IsStalled())\r
+               {\r
+                       /* Clear the stall condition on the IN pipe */\r
+                       SImage_ClearPipeStall(SIMAGE_DATA_IN_PIPE);\r
+\r
+                       /* Return error code */\r
+                       return PIPE_RWSTREAM_PipeStalled;\r
+               }\r
+                 \r
+               /* Check to see if the device was disconnected, if so exit function */\r
+               if (!(USB_IsConnected))\r
+               {\r
+                       /* Return error code */\r
+                       return PIPE_RWSTREAM_DeviceDisconnected;\r
+               }\r
+       };\r
+       \r
+       /* Freeze OUT pipe after use */\r
+       Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
+       Pipe_Freeze();\r
+\r
+       /* Select the IN data pipe for data reception */\r
+       Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
+       \r
+       /* Load in the response from the attached device */\r
+       Pipe_Read_Stream_LE(&PIMA_ReceivedBlock, PIMA_COMMAND_SIZE(0));\r
+       \r
+       /* Check if the returned block type is a response block */\r
+       if (PIMA_ReceivedBlock.Type == CType_ResponseBlock)\r
+       {\r
+               /* Determine the size of the parameters in the block via the data length attribute */\r
+               uint8_t ParamBytes = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));\r
+\r
+               /* Check if the device has returned any parameters */\r
+               if (ParamBytes)\r
+               {\r
+                       /* Read the PIMA parameters from the data IN pipe */\r
+                       Pipe_Read_Stream_LE(&PIMA_ReceivedBlock.Params, ParamBytes);\r
+               }\r
+               \r
+               /* Clear pipe bank after use */\r
+               Pipe_ClearIN();\r
+       }\r
+       \r
+       /* Freeze the IN pipe after use */\r
+       Pipe_Freeze();\r
+       \r
+       return PIPE_RWSTREAM_NoError;\r
+}\r
+\r
+/** Function to send the given data to the device, after a command block has been issued.\r
+ *\r
+ *  \param Buffer  Source data buffer to send to the device\r
+ *  \param Bytes   Number of bytes to send\r
+ */\r
+void SImage_SendData(void* Buffer, uint16_t Bytes)\r
+{\r
+       /* Unfreeze the data OUT pipe */\r
+       Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
+       Pipe_Unfreeze();\r
+       \r
+       /* Write the data contents to the pipe */\r
+       Pipe_Write_Stream_LE(Buffer, Bytes);\r
+\r
+       /* Send the last packet to the attached device */\r
+       Pipe_ClearOUT();\r
+\r
+       /* Freeze the pipe again after use */\r
+       Pipe_Freeze();\r
+}\r
+\r
+/** Function to receive the given data to the device, after a response block has been received.\r
+ *\r
+ *  \param Buffer  Destination data buffer to put read bytes from the device\r
+ *  \param Bytes   Number of bytes to receive\r
+ *\r
+ *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
+ */\r
+uint8_t SImage_ReadData(void* Buffer, uint16_t Bytes)\r
+{\r
+       uint8_t ErrorCode;\r
+\r
+       /* Unfreeze the data IN pipe */\r
+       Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
+       Pipe_Unfreeze();\r
+\r
+       /* Read in the data into the buffer */\r
+       ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes);\r
+\r
+       /* Freeze the pipe again after use */\r
+       Pipe_Freeze();\r
+       \r
+       return ErrorCode;\r
+}\r
+\r
+/** Function to test if a PIMA event block is waiting to be read in from the attached device.\r
+ *\r
+ *  \return True if an event is waiting to be read in from the device, false otherwise\r
+ */\r
+bool SImage_IsEventReceived(void)\r
+{\r
+       bool IsEventReceived = false;\r
+\r
+       /* Unfreeze the Event pipe */\r
+       Pipe_SelectPipe(SIMAGE_EVENTS_PIPE);\r
+       Pipe_Unfreeze();\r
+       \r
+       /* If the pipe contains data, an event has been received */\r
+       if (Pipe_BytesInPipe())\r
+         IsEventReceived = true;\r
+       \r
+       /* Freeze the pipe after use */\r
+       Pipe_Freeze();\r
+       \r
+       return IsEventReceived;\r
+}\r
+\r
+/** Clears the stall condition in the attached device on the nominated endpoint number.\r
+ *\r
+ *  \param EndpointNum  Endpoint number in the attached device whose stall condition is to be cleared\r
+ *\r
+ *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
+ */\r
+uint8_t SImage_ClearPipeStall(const uint8_t EndpointNum)\r
+{\r
+       USB_ControlRequest = (USB_Request_Header_t)\r
+               {\r
+                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
+                       .bRequest      = REQ_ClearFeature,\r
+                       .wValue        = FEATURE_ENDPOINT_HALT,\r
+                       .wIndex        = EndpointNum,\r
+                       .wLength       = 0,\r
+               };\r
+       \r
+       /* Select the control pipe for the request transfer */\r
+       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
+\r
+       return USB_Host_SendControlRequest(NULL);\r
+}\r
diff --git a/Demos/Host/StillImageHost/Lib/StillImageCommands.h b/Demos/Host/StillImageHost/Lib/StillImageCommands.h
new file mode 100644 (file)
index 0000000..ad0ba55
--- /dev/null
@@ -0,0 +1,110 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for StillImageCommands.c.\r
+ */\r
\r
+#ifndef _STILL_IMAGE_COMMANDS_H_\r
+#define _STILL_IMAGE_COMMANDS_H_\r
+\r
+       /* Includes: */\r
+               #include <LUFA/Drivers/USB/USB.h>                        // USB Functionality\r
+               \r
+               #include "PIMACodes.h"\r
+\r
+       /* Macros: */\r
+               /** Pipe number of the Still Image data IN pipe */\r
+               #define SIMAGE_DATA_IN_PIPE            0x01\r
+\r
+               /** Pipe number of the Still Image data OUT pipe */\r
+               #define SIMAGE_DATA_OUT_PIPE           0x02\r
+\r
+               /** Pipe number of the Still Image events pipe */\r
+               #define SIMAGE_EVENTS_PIPE             0x03\r
+\r
+               /** Timeout period between the issuing of a command to a device, and the reception of the first packet */\r
+               #define COMMAND_DATA_TIMEOUT_MS        5000\r
+               \r
+               /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for\r
+                *  a command container.\r
+                *\r
+                *  \param params  Number of parameters which are to be sent in the Param field of the container\r
+                */\r
+               #define PIMA_COMMAND_SIZE(params)      ((sizeof(PIMA_SendBlock) - sizeof(PIMA_SendBlock.Params)) + \\r
+                                                       (params * sizeof(PIMA_SendBlock.Params[0])))\r
+\r
+               /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for\r
+                *  a data container.\r
+                *\r
+                *  \param datalen  Length in bytes of the data in the container\r
+                */\r
+               #define PIMA_DATA_SIZE(datalen)        ((sizeof(PIMA_SendBlock) - sizeof(PIMA_SendBlock.Params)) + datalen)\r
+\r
+       /* Type Defines: */\r
+               /** Type define for a PIMA container, use to send commands and receive responses to and from an\r
+                *  attached Still Image device.\r
+                */\r
+               typedef struct\r
+               {\r
+                       uint32_t DataLength; /**< Length of the container and data, in bytes */\r
+                       uint16_t Type; /**< Container type, a value from the PIMA_Container_Types_t enum */\r
+                       uint16_t Code; /**< Command, event or response code of the container */\r
+                       uint32_t TransactionID; /**< Unique container ID to link blocks together */\r
+                       uint32_t Params[4]; /**< Block parameters to be issued along with the block code (command blocks only) */\r
+               } PIMA_Container_t;\r
+       \r
+       /* Enums: */\r
+               /** Enum for the possible PIMA contains types. */\r
+               enum PIMA_Container_Types_t\r
+               {\r
+                       CType_Undefined         = 0, /**< Undefined container type */\r
+                       CType_CommandBlock      = 1, /**< Command Block container type */\r
+                       CType_DataBlock         = 2, /**< Data Block container type */\r
+                       CType_ResponseBlock     = 3, /**< Response container type */\r
+                       CType_EventBlock        = 4, /**< Event Block container type */\r
+               };\r
+       \r
+       /* External Variables: */\r
+               extern PIMA_Container_t PIMA_SendBlock;\r
+               extern PIMA_Container_t PIMA_ReceivedBlock;\r
+               extern PIMA_Container_t PIMA_EventBlock;\r
+       \r
+       /* Function Prototypes: */\r
+               void    SImage_SendBlockHeader(void);\r
+               uint8_t SImage_RecieveBlockHeader(void);\r
+               void    SImage_RecieveEventHeader(void);\r
+               void    SImage_SendData(void* Buffer, uint16_t Bytes);\r
+               uint8_t SImage_ReadData(void* Buffer, uint16_t Bytes);\r
+               bool    SImage_IsEventReceived(void);\r
+               uint8_t SImage_ClearPipeStall(const uint8_t EndpointNum);\r
+\r
+#endif\r
diff --git a/Demos/Host/StillImageHost/PIMACodes.h b/Demos/Host/StillImageHost/PIMACodes.h
deleted file mode 100644 (file)
index 38755ab..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header containing macros for possible PIMA commands. Refer to the PIMA standard\r
- *  documentation for more information on each PIMA command.\r
- */\r
-\r
-#ifndef _PIMA_CODES_H_\r
-\r
-       /* Macros: */\r
-               #define PIMA_OPERATION_GETDEVICEINFO         0x1001\r
-               #define PIMA_OPERATION_OPENSESSION           0x1002\r
-               #define PIMA_OPERATION_CLOSESESSION          0x1003\r
-               \r
-               #define PIMA_RESPONSE_OK                     0x2001\r
-               #define PIMA_RESPONSE_GENERALERROR           0x2002\r
-               #define PIMA_RESPONSE_SESSIONNOTOPEN         0x2003\r
-               #define PIMA_RESPONSE_INVALIDTRANSACTIONID   0x2004\r
-               #define PIMA_RESPONSE_OPERATIONNOTSUPPORTED  0x2005\r
-               #define PIMA_RESPONSE_PARAMETERNOTSUPPORTED  0x2006\r
-\r
-#endif\r
diff --git a/Demos/Host/StillImageHost/StillImageCommands.c b/Demos/Host/StillImageHost/StillImageCommands.c
deleted file mode 100644 (file)
index 8f05e48..0000000
+++ /dev/null
@@ -1,279 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Still Image Device commands, to issue PIMA commands to the device for\r
- *  reading device status, capacity, and other characteristics as well as\r
- *  reading and writing of stored image data.\r
- */\r
-\r
-#include "StillImageCommands.h"\r
-\r
-/* Globals: */\r
-/** PIMA block container for the block to send to the device */\r
-PIMA_Container_t PIMA_SendBlock;\r
-\r
-/** PIMA block container for the last received block from the device */\r
-PIMA_Container_t PIMA_ReceivedBlock;\r
-\r
-/** PIMA block container for the last event block received from the device */\r
-PIMA_Container_t PIMA_EventBlock;\r
-\r
-\r
-/** Function to send the PIMA command container to the attached still image device. */\r
-void SImage_SendBlockHeader(void)\r
-{\r
-       /* Unfreeze the data OUT pipe ready for data transmission */\r
-       Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
-       Pipe_Unfreeze();\r
-\r
-       /* Write the PIMA block to the data OUT pipe */\r
-       Pipe_Write_Stream_LE(&PIMA_SendBlock, PIMA_COMMAND_SIZE(0));\r
-       \r
-       /* If the block type is a command, send its parameters (if any) */\r
-       if (PIMA_SendBlock.Type == CType_CommandBlock)\r
-       {\r
-               /* Determine the size of the parameters in the block via the data length attribute */\r
-               uint8_t ParamBytes = (PIMA_SendBlock.DataLength - PIMA_COMMAND_SIZE(0));\r
-\r
-               /* Check if any parameters in the command block */\r
-               if (ParamBytes)\r
-               {\r
-                       /* Write the PIMA parameters to the data OUT pipe */\r
-                       Pipe_Write_Stream_LE(&PIMA_SendBlock.Params, ParamBytes);\r
-               }\r
-               \r
-               /* Send the PIMA command block to the attached device */\r
-               Pipe_ClearOUT();\r
-       }\r
-                                       \r
-       /* Freeze pipe after use */\r
-       Pipe_Freeze();\r
-}\r
-\r
-/** Function to receive a PIMA event container from the attached still image device. */\r
-void SImage_RecieveEventHeader(void)\r
-{\r
-       /* Unfreeze the events pipe */\r
-       Pipe_SelectPipe(SIMAGE_EVENTS_PIPE);\r
-       Pipe_Unfreeze();\r
-       \r
-       /* Read in the event data into the global structure */\r
-       Pipe_Read_Stream_LE(&PIMA_EventBlock, sizeof(PIMA_EventBlock));\r
-       \r
-       /* Clear the pipe after read complete to prepare for next event */\r
-       Pipe_ClearIN();\r
-       \r
-       /* Freeze the event pipe again after use */\r
-       Pipe_Freeze();\r
-}\r
-\r
-/** Function to receive a PIMA response container from the attached still image device. */\r
-uint8_t SImage_RecieveBlockHeader(void)\r
-{\r
-       uint16_t TimeoutMSRem = COMMAND_DATA_TIMEOUT_MS;\r
-\r
-       /* Unfreeze the data IN pipe */\r
-       Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
-       Pipe_Unfreeze();\r
-       \r
-       /* Wait until data received on the IN pipe */\r
-       while (!(Pipe_IsReadWriteAllowed()))\r
-       {\r
-               /* Check to see if a new frame has been issued (1ms elapsed) */\r
-               if (USB_INT_HasOccurred(USB_INT_HSOFI))\r
-               {\r
-                       /* Clear the flag and decrement the timeout period counter */\r
-                       USB_INT_Clear(USB_INT_HSOFI);\r
-                       TimeoutMSRem--;\r
-\r
-                       /* Check to see if the timeout period for the command has elapsed */\r
-                       if (!(TimeoutMSRem))\r
-                       {\r
-                               /* Return error code */\r
-                               return PIPE_RWSTREAM_Timeout;\r
-                       }\r
-               }\r
-               \r
-               Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
-\r
-               /* Check if pipe stalled (command failed by device) */\r
-               if (Pipe_IsStalled())\r
-               {\r
-                       /* Clear the stall condition on the OUT pipe */\r
-                       SImage_ClearPipeStall(SIMAGE_DATA_OUT_PIPE);\r
-\r
-                       /* Return error code and break out of the loop */\r
-                       return PIPE_RWSTREAM_PipeStalled;\r
-               }\r
-\r
-               Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
-\r
-               /* Check if pipe stalled (command failed by device) */\r
-               if (Pipe_IsStalled())\r
-               {\r
-                       /* Clear the stall condition on the IN pipe */\r
-                       SImage_ClearPipeStall(SIMAGE_DATA_IN_PIPE);\r
-\r
-                       /* Return error code */\r
-                       return PIPE_RWSTREAM_PipeStalled;\r
-               }\r
-                 \r
-               /* Check to see if the device was disconnected, if so exit function */\r
-               if (!(USB_IsConnected))\r
-               {\r
-                       /* Return error code */\r
-                       return PIPE_RWSTREAM_DeviceDisconnected;\r
-               }\r
-       };\r
-       \r
-       /* Freeze OUT pipe after use */\r
-       Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
-       Pipe_Freeze();\r
-\r
-       /* Select the IN data pipe for data reception */\r
-       Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
-       \r
-       /* Load in the response from the attached device */\r
-       Pipe_Read_Stream_LE(&PIMA_ReceivedBlock, PIMA_COMMAND_SIZE(0));\r
-       \r
-       /* Check if the returned block type is a response block */\r
-       if (PIMA_ReceivedBlock.Type == CType_ResponseBlock)\r
-       {\r
-               /* Determine the size of the parameters in the block via the data length attribute */\r
-               uint8_t ParamBytes = (PIMA_ReceivedBlock.DataLength - PIMA_COMMAND_SIZE(0));\r
-\r
-               /* Check if the device has returned any parameters */\r
-               if (ParamBytes)\r
-               {\r
-                       /* Read the PIMA parameters from the data IN pipe */\r
-                       Pipe_Read_Stream_LE(&PIMA_ReceivedBlock.Params, ParamBytes);\r
-               }\r
-               \r
-               /* Clear pipe bank after use */\r
-               Pipe_ClearIN();\r
-       }\r
-       \r
-       /* Freeze the IN pipe after use */\r
-       Pipe_Freeze();\r
-       \r
-       return PIPE_RWSTREAM_NoError;\r
-}\r
-\r
-/** Function to send the given data to the device, after a command block has been issued.\r
- *\r
- *  \param Buffer  Source data buffer to send to the device\r
- *  \param Bytes   Number of bytes to send\r
- */\r
-void SImage_SendData(void* Buffer, uint16_t Bytes)\r
-{\r
-       /* Unfreeze the data OUT pipe */\r
-       Pipe_SelectPipe(SIMAGE_DATA_OUT_PIPE);\r
-       Pipe_Unfreeze();\r
-       \r
-       /* Write the data contents to the pipe */\r
-       Pipe_Write_Stream_LE(Buffer, Bytes);\r
-\r
-       /* Send the last packet to the attached device */\r
-       Pipe_ClearOUT();\r
-\r
-       /* Freeze the pipe again after use */\r
-       Pipe_Freeze();\r
-}\r
-\r
-/** Function to receive the given data to the device, after a response block has been received.\r
- *\r
- *  \param Buffer  Destination data buffer to put read bytes from the device\r
- *  \param Bytes   Number of bytes to receive\r
- *\r
- *  \return A value from the Pipe_Stream_RW_ErrorCodes_t enum\r
- */\r
-uint8_t SImage_ReadData(void* Buffer, uint16_t Bytes)\r
-{\r
-       uint8_t ErrorCode;\r
-\r
-       /* Unfreeze the data IN pipe */\r
-       Pipe_SelectPipe(SIMAGE_DATA_IN_PIPE);\r
-       Pipe_Unfreeze();\r
-\r
-       /* Read in the data into the buffer */\r
-       ErrorCode = Pipe_Read_Stream_LE(Buffer, Bytes);\r
-\r
-       /* Freeze the pipe again after use */\r
-       Pipe_Freeze();\r
-       \r
-       return ErrorCode;\r
-}\r
-\r
-/** Function to test if a PIMA event block is waiting to be read in from the attached device.\r
- *\r
- *  \return True if an event is waiting to be read in from the device, false otherwise\r
- */\r
-bool SImage_IsEventReceived(void)\r
-{\r
-       bool IsEventReceived = false;\r
-\r
-       /* Unfreeze the Event pipe */\r
-       Pipe_SelectPipe(SIMAGE_EVENTS_PIPE);\r
-       Pipe_Unfreeze();\r
-       \r
-       /* If the pipe contains data, an event has been received */\r
-       if (Pipe_BytesInPipe())\r
-         IsEventReceived = true;\r
-       \r
-       /* Freeze the pipe after use */\r
-       Pipe_Freeze();\r
-       \r
-       return IsEventReceived;\r
-}\r
-\r
-/** Clears the stall condition in the attached device on the nominated endpoint number.\r
- *\r
- *  \param EndpointNum  Endpoint number in the attached device whose stall condition is to be cleared\r
- *\r
- *  \return A value from the USB_Host_SendControlErrorCodes_t enum\r
- */\r
-uint8_t SImage_ClearPipeStall(const uint8_t EndpointNum)\r
-{\r
-       USB_ControlRequest = (USB_Request_Header_t)\r
-               {\r
-                       .bmRequestType = (REQDIR_HOSTTODEVICE | REQTYPE_STANDARD | REQREC_ENDPOINT),\r
-                       .bRequest      = REQ_ClearFeature,\r
-                       .wValue        = FEATURE_ENDPOINT_HALT,\r
-                       .wIndex        = EndpointNum,\r
-                       .wLength       = 0,\r
-               };\r
-       \r
-       /* Select the control pipe for the request transfer */\r
-       Pipe_SelectPipe(PIPE_CONTROLPIPE);\r
-\r
-       return USB_Host_SendControlRequest(NULL);\r
-}\r
diff --git a/Demos/Host/StillImageHost/StillImageCommands.h b/Demos/Host/StillImageHost/StillImageCommands.h
deleted file mode 100644 (file)
index ad0ba55..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for StillImageCommands.c.\r
- */\r
\r
-#ifndef _STILL_IMAGE_COMMANDS_H_\r
-#define _STILL_IMAGE_COMMANDS_H_\r
-\r
-       /* Includes: */\r
-               #include <LUFA/Drivers/USB/USB.h>                        // USB Functionality\r
-               \r
-               #include "PIMACodes.h"\r
-\r
-       /* Macros: */\r
-               /** Pipe number of the Still Image data IN pipe */\r
-               #define SIMAGE_DATA_IN_PIPE            0x01\r
-\r
-               /** Pipe number of the Still Image data OUT pipe */\r
-               #define SIMAGE_DATA_OUT_PIPE           0x02\r
-\r
-               /** Pipe number of the Still Image events pipe */\r
-               #define SIMAGE_EVENTS_PIPE             0x03\r
-\r
-               /** Timeout period between the issuing of a command to a device, and the reception of the first packet */\r
-               #define COMMAND_DATA_TIMEOUT_MS        5000\r
-               \r
-               /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for\r
-                *  a command container.\r
-                *\r
-                *  \param params  Number of parameters which are to be sent in the Param field of the container\r
-                */\r
-               #define PIMA_COMMAND_SIZE(params)      ((sizeof(PIMA_SendBlock) - sizeof(PIMA_SendBlock.Params)) + \\r
-                                                       (params * sizeof(PIMA_SendBlock.Params[0])))\r
-\r
-               /** Used in the DataLength field of a PIMA container, to give the total container size in bytes for\r
-                *  a data container.\r
-                *\r
-                *  \param datalen  Length in bytes of the data in the container\r
-                */\r
-               #define PIMA_DATA_SIZE(datalen)        ((sizeof(PIMA_SendBlock) - sizeof(PIMA_SendBlock.Params)) + datalen)\r
-\r
-       /* Type Defines: */\r
-               /** Type define for a PIMA container, use to send commands and receive responses to and from an\r
-                *  attached Still Image device.\r
-                */\r
-               typedef struct\r
-               {\r
-                       uint32_t DataLength; /**< Length of the container and data, in bytes */\r
-                       uint16_t Type; /**< Container type, a value from the PIMA_Container_Types_t enum */\r
-                       uint16_t Code; /**< Command, event or response code of the container */\r
-                       uint32_t TransactionID; /**< Unique container ID to link blocks together */\r
-                       uint32_t Params[4]; /**< Block parameters to be issued along with the block code (command blocks only) */\r
-               } PIMA_Container_t;\r
-       \r
-       /* Enums: */\r
-               /** Enum for the possible PIMA contains types. */\r
-               enum PIMA_Container_Types_t\r
-               {\r
-                       CType_Undefined         = 0, /**< Undefined container type */\r
-                       CType_CommandBlock      = 1, /**< Command Block container type */\r
-                       CType_DataBlock         = 2, /**< Data Block container type */\r
-                       CType_ResponseBlock     = 3, /**< Response container type */\r
-                       CType_EventBlock        = 4, /**< Event Block container type */\r
-               };\r
-       \r
-       /* External Variables: */\r
-               extern PIMA_Container_t PIMA_SendBlock;\r
-               extern PIMA_Container_t PIMA_ReceivedBlock;\r
-               extern PIMA_Container_t PIMA_EventBlock;\r
-       \r
-       /* Function Prototypes: */\r
-               void    SImage_SendBlockHeader(void);\r
-               uint8_t SImage_RecieveBlockHeader(void);\r
-               void    SImage_RecieveEventHeader(void);\r
-               void    SImage_SendData(void* Buffer, uint16_t Bytes);\r
-               uint8_t SImage_ReadData(void* Buffer, uint16_t Bytes);\r
-               bool    SImage_IsEventReceived(void);\r
-               uint8_t SImage_ClearPipeStall(const uint8_t EndpointNum);\r
-\r
-#endif\r
index 909ed89..b563767 100644 (file)
@@ -43,8 +43,9 @@
                #include <stdio.h>\r
                \r
                #include "ConfigDescriptor.h"\r
-               #include "PIMACodes.h"\r
-               #include "StillImageCommands.h"\r
+\r
+               #include "Lib/PIMACodes.h"\r
+               #include "Lib/StillImageCommands.h"\r
 \r
                #include <LUFA/Drivers/Misc/TerminalCodes.h>             // ANSI Terminal Escape Codes\r
                #include <LUFA/Drivers/USB/USB.h>                        // USB Functionality\r
index bcb036f..8c1ca0b 100644 (file)
@@ -124,7 +124,7 @@ LUFA_PATH = ../../..
 # List C source files here. (C dependencies are automatically generated.)\r
 SRC = $(TARGET).c                                                 \\r
          ConfigDescriptor.c                                          \\r
-         StillImageCommands.c                                        \\r
+         Lib/StillImageCommands.c                                    \\r
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/SerialStream.c         \\r
          $(LUFA_PATH)/LUFA/Drivers/Peripheral/Serial.c               \\r
index 2409a3e..b5ceb65 100644 (file)
@@ -1 +1 @@
-<Project name="LUFA"><Folder name="Demos"><Folder name="Device"><Folder name="AudioInput"><File path="Demos\Device\AudioInput\AudioInput.c"></File><File path="Demos\Device\AudioInput\AudioInput.h"></File><File path="Demos\Device\AudioInput\AudioInput.txt"></File><File path="Demos\Device\AudioInput\Descriptors.c"></File><File path="Demos\Device\AudioInput\Descriptors.h"></File><File path="Demos\Device\AudioInput\Doxygen.conf"></File><File path="Demos\Device\AudioInput\makefile"></File></Folder><Folder name="AudioOutput"><File path="Demos\Device\AudioOutput\AudioOutput.c"></File><File path="Demos\Device\AudioOutput\AudioOutput.h"></File><File path="Demos\Device\AudioOutput\AudioOutput.txt"></File><File path="Demos\Device\AudioOutput\Descriptors.c"></File><File path="Demos\Device\AudioOutput\Descriptors.h"></File><File path="Demos\Device\AudioOutput\Doxygen.conf"></File><File path="Demos\Device\AudioOutput\makefile"></File></Folder><Folder name="CDC"><File path="Demos\Device\CDC\CDC.c"></File><File path="Demos\Device\CDC\CDC.h"></File><File path="Demos\Device\CDC\CDC.txt"></File><File path="Demos\Device\CDC\Descriptors.c"></File><File path="Demos\Device\CDC\Descriptors.h"></File><File path="Demos\Device\CDC\Doxygen.conf"></File><File path="Demos\Device\CDC\LUFA CDC.inf"></File><File path="Demos\Device\CDC\makefile"></File></Folder><Folder name="DualCDC"><File path="Demos\Device\DualCDC\Descriptors.c"></File><File path="Demos\Device\DualCDC\Descriptors.h"></File><File path="Demos\Device\DualCDC\Doxygen.conf"></File><File path="Demos\Device\DualCDC\DualCDC.c"></File><File path="Demos\Device\DualCDC\DualCDC.h"></File><File path="Demos\Device\DualCDC\DualCDC.txt"></File><File path="Demos\Device\DualCDC\LUFA DualCDC.inf"></File><File path="Demos\Device\DualCDC\makefile"></File></Folder><Folder name="GenericHID"><File path="Demos\Device\GenericHID\Descriptors.c"></File><File path="Demos\Device\GenericHID\Descriptors.h"></File><File path="Demos\Device\GenericHID\GenericHID.c"></File><File path="Demos\Device\GenericHID\GenericHID.h"></File><File path="Demos\Device\GenericHID\makefile"></File><File path="Demos\Device\GenericHID\GenericHID.txt"></File><File path="Demos\Device\GenericHID\Doxygen.conf"></File></Folder><Folder name="Joystick"><File path="Demos\Device\Joystick\Descriptors.c"></File><File path="Demos\Device\Joystick\Descriptors.h"></File><File path="Demos\Device\Joystick\Doxygen.conf"></File><File path="Demos\Device\Joystick\Joystick.c"></File><File path="Demos\Device\Joystick\Joystick.h"></File><File path="Demos\Device\Joystick\Joystick.txt"></File><File path="Demos\Device\Joystick\makefile"></File></Folder><Folder name="Keyboard"><File path="Demos\Device\Keyboard\Descriptors.c"></File><File path="Demos\Device\Keyboard\Descriptors.h"></File><File path="Demos\Device\Keyboard\Doxygen.conf"></File><File path="Demos\Device\Keyboard\Keyboard.c"></File><File path="Demos\Device\Keyboard\Keyboard.h"></File><File path="Demos\Device\Keyboard\Keyboard.txt"></File><File path="Demos\Device\Keyboard\makefile"></File></Folder><Folder name="KeyboardMouse"><File path="Demos\Device\KeyboardMouse\Descriptors.c"></File><File path="Demos\Device\KeyboardMouse\Descriptors.h"></File><File path="Demos\Device\KeyboardMouse\Doxygen.conf"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.c"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.h"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.txt"></File><File path="Demos\Device\KeyboardMouse\makefile"></File></Folder><Folder name="MassStorage"><File path="Demos\Device\MassStorage\DataflashManager.c"></File><File path="Demos\Device\MassStorage\DataflashManager.h"></File><File path="Demos\Device\MassStorage\Descriptors.c"></File><File path="Demos\Device\MassStorage\Descriptors.h"></File><File path="Demos\Device\MassStorage\Doxygen.conf"></File><File path="Demos\Device\MassStorage\makefile"></File><File path="Demos\Device\MassStorage\MassStorage.c"></File><File path="Demos\Device\MassStorage\MassStorage.h"></File><File path="Demos\Device\MassStorage\MassStorage.txt"></File><File path="Demos\Device\MassStorage\SCSI.c"></File><File path="Demos\Device\MassStorage\SCSI.h"></File><File path="Demos\Device\MassStorage\SCSI_Codes.h"></File></Folder><Folder name="MIDI"><File path="Demos\Device\MIDI\Descriptors.c"></File><File path="Demos\Device\MIDI\Descriptors.h"></File><File path="Demos\Device\MIDI\Doxygen.conf"></File><File path="Demos\Device\MIDI\makefile"></File><File path="Demos\Device\MIDI\MIDI.c"></File><File path="Demos\Device\MIDI\MIDI.h"></File><File path="Demos\Device\MIDI\MIDI.txt"></File></Folder><Folder name="Mouse"><File path="Demos\Device\Mouse\Descriptors.c"></File><File path="Demos\Device\Mouse\Descriptors.h"></File><File path="Demos\Device\Mouse\Doxygen.conf"></File><File path="Demos\Device\Mouse\makefile"></File><File path="Demos\Device\Mouse\Mouse.c"></File><File path="Demos\Device\Mouse\Mouse.h"></File><File path="Demos\Device\Mouse\Mouse.txt"></File></Folder><Folder name="RNDISEthernet"><File path="Demos\Device\RNDISEthernet\ARP.c"></File><File path="Demos\Device\RNDISEthernet\ARP.h"></File><File path="Demos\Device\RNDISEthernet\Descriptors.c"></File><File path="Demos\Device\RNDISEthernet\Descriptors.h"></File><File path="Demos\Device\RNDISEthernet\DHCP.c"></File><File path="Demos\Device\RNDISEthernet\DHCP.h"></File><File path="Demos\Device\RNDISEthernet\Doxygen.conf"></File><File path="Demos\Device\RNDISEthernet\Ethernet.c"></File><File path="Demos\Device\RNDISEthernet\Ethernet.h"></File><File path="Demos\Device\RNDISEthernet\EthernetProtocols.h"></File><File path="Demos\Device\RNDISEthernet\ICMP.c"></File><File path="Demos\Device\RNDISEthernet\ICMP.h"></File><File path="Demos\Device\RNDISEthernet\IP.c"></File><File path="Demos\Device\RNDISEthernet\IP.h"></File><File path="Demos\Device\RNDISEthernet\LUFA RNDIS.inf"></File><File path="Demos\Device\RNDISEthernet\makefile"></File><File path="Demos\Device\RNDISEthernet\ProtocolDecoders.c"></File><File path="Demos\Device\RNDISEthernet\ProtocolDecoders.h"></File><File path="Demos\Device\RNDISEthernet\RNDIS.c"></File><File path="Demos\Device\RNDISEthernet\RNDIS.h"></File><File path="Demos\Device\RNDISEthernet\RNDISConstants.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.c"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.txt"></File><File path="Demos\Device\RNDISEthernet\TCP.c"></File><File path="Demos\Device\RNDISEthernet\TCP.h"></File><File path="Demos\Device\RNDISEthernet\UDP.c"></File><File path="Demos\Device\RNDISEthernet\UDP.h"></File><File path="Demos\Device\RNDISEthernet\Webserver.c"></File><File path="Demos\Device\RNDISEthernet\Webserver.h"></File></Folder><Folder name="USBtoSerial"><File path="Demos\Device\USBtoSerial\Descriptors.c"></File><File path="Demos\Device\USBtoSerial\Descriptors.h"></File><File path="Demos\Device\USBtoSerial\Doxygen.conf"></File><File path="Demos\Device\USBtoSerial\LUFA USBtoSerial.inf"></File><File path="Demos\Device\USBtoSerial\makefile"></File><File path="Demos\Device\USBtoSerial\RingBuff.c"></File><File path="Demos\Device\USBtoSerial\RingBuff.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.c"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.txt"></File></Folder><File path="Demos\Device\makefile"></File></Folder><Folder name="Host"><Folder name="CDCHost"><File path="Demos\Host\CDCHost\CDCHost.c"></File><File path="Demos\Host\CDCHost\CDCHost.h"></File><File path="Demos\Host\CDCHost\CDCHost.txt"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.c"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.h"></File><File path="Demos\Host\CDCHost\Doxygen.conf"></File><File path="Demos\Host\CDCHost\makefile"></File></Folder><Folder name="GenericHIDHost"><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.c"></File><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.h"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.c"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.h"></File><File path="Demos\Host\GenericHIDHost\makefile"></File><File path="Demos\Host\GenericHIDHost\Doxygen.conf"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.txt"></File></Folder><Folder name="KeyboardHost"><File path="Demos\Host\KeyboardHost\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHost\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHost\Doxygen.conf"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.c"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.h"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.txt"></File><File path="Demos\Host\KeyboardHost\makefile"></File></Folder><Folder name="KeyboardHostWithParser"><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHostWithParser\Doxygen.conf"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.c"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.c"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.txt"></File><File path="Demos\Host\KeyboardHostWithParser\makefile"></File></Folder><Folder name="MassStorageHost"><File path="Demos\Host\MassStorageHost\ConfigDescriptor.c"></File><File path="Demos\Host\MassStorageHost\ConfigDescriptor.h"></File><File path="Demos\Host\MassStorageHost\Doxygen.conf"></File><File path="Demos\Host\MassStorageHost\makefile"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.c"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.h"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.txt"></File><File path="Demos\Host\MassStorageHost\MassStoreCommands.c"></File><File path="Demos\Host\MassStorageHost\MassStoreCommands.h"></File><File path="Demos\Host\MassStorageHost\SCSI_Codes.h"></File></Folder><Folder name="MouseHost"><File path="Demos\Host\MouseHost\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHost\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHost\Doxygen.conf"></File><File path="Demos\Host\MouseHost\makefile"></File><File path="Demos\Host\MouseHost\MouseHost.c"></File><File path="Demos\Host\MouseHost\MouseHost.h"></File><File path="Demos\Host\MouseHost\MouseHost.txt"></File></Folder><Folder name="MouseHostWithParser"><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHostWithParser\Doxygen.conf"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.c"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.h"></File><File path="Demos\Host\MouseHostWithParser\makefile"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.c"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.h"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.txt"></File></Folder><Folder name="StillImageHost"><File path="Demos\Host\StillImageHost\ConfigDescriptor.c"></File><File path="Demos\Host\StillImageHost\ConfigDescriptor.h"></File><File path="Demos\Host\StillImageHost\Doxygen.conf"></File><File path="Demos\Host\StillImageHost\makefile"></File><File path="Demos\Host\StillImageHost\PIMACodes.h"></File><File path="Demos\Host\StillImageHost\StillImageCommands.c"></File><File path="Demos\Host\StillImageHost\StillImageCommands.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.c"></File><File path="Demos\Host\StillImageHost\StillImageHost.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.txt"></File></Folder><File path="Demos\Host\makefile"></File></Folder><Folder name="OTG"><Folder name="TestApp"><File path="Demos\OTG\TestApp\Descriptors.c"></File><File path="Demos\OTG\TestApp\Descriptors.h"></File><File path="Demos\OTG\TestApp\Doxygen.conf"></File><File path="Demos\OTG\TestApp\makefile"></File><File path="Demos\OTG\TestApp\TestApp.c"></File><File path="Demos\OTG\TestApp\TestApp.h"></File><File path="Demos\OTG\TestApp\TestApp.txt"></File><File path="Demos\OTG\TestApp\TestEvents.c"></File><File path="Demos\OTG\TestApp\TestEvents.h"></File></Folder><File path="Demos\OTG\makefile"></File></Folder><File path="Demos\makefile"></File></Folder><Folder name="LUFA"><Folder name="Common"><File path="LUFA\Common\Common.h"></File><File path="LUFA\Common\FunctionAttributes.h"></File><File path="LUFA\Common\BoardTypes.h"></File></Folder><Folder name="Drivers"><Folder name="USB"><Folder name="LowLevel"><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.c"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.h"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.c"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.h"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\Device.h"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.c"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.h"></File><File path="LUFA\Drivers\USB\LowLevel\Host.c"></File><File path="LUFA\Drivers\USB\LowLevel\Host.h"></File><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\OTG.h"></File></Folder><Folder name="HighLevel"><File path="LUFA\Drivers\USB\HighLevel\USBTask.h"></File><File path="LUFA\Drivers\USB\HighLevel\Events.c"></File><File path="LUFA\Drivers\USB\HighLevel\Events.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.c"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBTask.c"></File><File path="LUFA\Drivers\USB\HighLevel\StdDescriptors.h"></File><File path="LUFA\Drivers\USB\HighLevel\StdRequestType.h"></File><File path="LUFA\Drivers\USB\HighLevel\StreamCallbacks.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBMode.h"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.c"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.h"></File></Folder><Folder name="Class"><File path="LUFA\Drivers\USB\Class\HIDParser.c"></File><File path="LUFA\Drivers\USB\Class\HIDParser.h"></File><File path="LUFA\Drivers\USB\Class\HIDReportData.h"></File></Folder><File path="LUFA\Drivers\USB\USB.h"></File></Folder><Folder name="Misc"><File path="LUFA\Drivers\Misc\TerminalCodes.h"></File></Folder><Folder name="Board"><Folder name="USBKEY"><File path="LUFA\Drivers\Board\USBKEY\Dataflash.h"></File><File path="LUFA\Drivers\Board\USBKEY\Joystick.h"></File><File path="LUFA\Drivers\Board\USBKEY\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\USBKEY\LEDs.h"></File><File path="LUFA\Drivers\Board\USBKEY\Buttons.h"></File></Folder><Folder name="STK526"><File path="LUFA\Drivers\Board\STK526\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK526\Joystick.h"></File><File path="LUFA\Drivers\Board\STK526\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\STK526\LEDs.h"></File><File path="LUFA\Drivers\Board\STK526\Buttons.h"></File></Folder><Folder name="STK525"><File path="LUFA\Drivers\Board\STK525\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK525\Joystick.h"></File><File path="LUFA\Drivers\Board\STK525\AT45DB321C.h"></File><File path="LUFA\Drivers\Board\STK525\LEDs.h"></File><File path="LUFA\Drivers\Board\STK525\Buttons.h"></File></Folder><Folder name="RZUSBSTICK"><File path="LUFA\Drivers\Board\RZUSBSTICK\LEDs.h"></File></Folder><Folder name="ATAVRUSBRF01"><File path="LUFA\Drivers\Board\ATAVRUSBRF01\LEDs.h"></File><File path="LUFA\Drivers\Board\ATAVRUSBRF01\Buttons.h"></File></Folder><File path="LUFA\Drivers\Board\Temperature.h"></File><File path="LUFA\Drivers\Board\Dataflash.h"></File><File path="LUFA\Drivers\Board\Joystick.h"></File><File path="LUFA\Drivers\Board\Temperature.c"></File><File path="LUFA\Drivers\Board\LEDs.h"></File><File path="LUFA\Drivers\Board\Buttons.h"></File></Folder><Folder name="Peripheral"><Folder name="AT90USBXXX67"><File path="LUFA\Drivers\Peripheral\AT90USBXXX67\ADC.h"></File></Folder><File path="LUFA\Drivers\Peripheral\ADC.h"></File><File path="LUFA\Drivers\Peripheral\Serial.c"></File><File path="LUFA\Drivers\Peripheral\Serial.h"></File><File path="LUFA\Drivers\Peripheral\SPI.h"></File><File path="LUFA\Drivers\Peripheral\SerialStream.c"></File><File path="LUFA\Drivers\Peripheral\SerialStream.h"></File></Folder></Folder><Folder name="Scheduler"><File path="LUFA\Scheduler\Scheduler.h"></File><File path="LUFA\Scheduler\Scheduler.c"></File></Folder><Folder name="MemoryAllocator"><File path="LUFA\MemoryAllocator\DynAlloc.h"></File><File path="LUFA\MemoryAllocator\DynAlloc.c"></File></Folder><Folder name="DriverStubs"><File path="LUFA\DriverStubs\Dataflash.h"></File><File path="LUFA\DriverStubs\Joystick.h"></File><File path="LUFA\DriverStubs\LEDs.h"></File><File path="LUFA\DriverStubs\Buttons.h"></File></Folder><File path="LUFA\makefile"></File><File path="LUFA\Version.h"></File><File path="LUFA\BuildingLinkableLibraries.txt"></File><File path="LUFA\GettingStarted.txt"></File><File path="LUFA\MainPage.txt"></File><File path="LUFA\SchedulerOverview.txt"></File><File path="LUFA\VIDAndPIDValues.txt"></File><File path="LUFA\ChangeLog.txt"></File><File path="LUFA\CompileTimeTokens.txt"></File><File path="LUFA\MigrationInformation.txt"></File><File path="LUFA\DirectorySummaries.txt"></File><File path="LUFA\Doxygen.conf"></File><File path="LUFA\WritingBoardDrivers.txt"></File><File path="LUFA\LUFAPoweredProjects.txt"></File><File path="LUFA\Groups.txt"></File></Folder><Folder name="Projects"><Folder name="MagStripe"><File path="Projects\Magstripe\Descriptors.c"></File><File path="Projects\Magstripe\Descriptors.h"></File><File path="Projects\Magstripe\Magstripe.c"></File><File path="Projects\Magstripe\Magstripe.h"></File><File path="Projects\Magstripe\MagstripeHW.h"></File><File path="Projects\Magstripe\makefile"></File><File path="Projects\Magstripe\Magstripe.txt"></File><File path="Projects\Magstripe\Doxygen.conf"></File><File path="Projects\Magstripe\CircularBitBuffer.c"></File><File path="Projects\Magstripe\CircularBitBuffer.h"></File></Folder><File path="Projects\makefile"></File></Folder><Folder name="Bootloaders"><Folder name="DFU"><File path="Bootloaders\DFU\BootloaderDFU.c"></File><File path="Bootloaders\DFU\BootloaderDFU.h"></File><File path="Bootloaders\DFU\Descriptors.c"></File><File path="Bootloaders\DFU\Descriptors.h"></File><File path="Bootloaders\DFU\makefile"></File><File path="Bootloaders\DFU\BootloaderDFU.txt"></File><File path="Bootloaders\DFU\Doxygen.conf"></File></Folder><Folder name="CDC"><File path="Bootloaders\CDC\BootloaderCDC.c"></File><File path="Bootloaders\CDC\BootloaderCDC.h"></File><File path="Bootloaders\CDC\Descriptors.c"></File><File path="Bootloaders\CDC\Descriptors.h"></File><File path="Bootloaders\CDC\makefile"></File><File path="Bootloaders\CDC\LUFA CDC Bootloader.inf"></File><File path="Bootloaders\CDC\Doxygen.conf"></File><File path="Bootloaders\CDC\BootloaderCDC.txt"></File></Folder><Folder name="TeensyHID"><File path="Bootloaders\TeensyHID\Descriptors.c"></File><File path="Bootloaders\TeensyHID\Descriptors.h"></File><File path="Bootloaders\TeensyHID\makefile"></File><File path="Bootloaders\TeensyHID\TeensyHID.c"></File><File path="Bootloaders\TeensyHID\TeensyHID.h"></File><File path="Bootloaders\TeensyHID\TeensyHID.txt"></File></Folder><File path="Bootloaders\makefile"></File></Folder><File path="makefile"></File></Project>
\ No newline at end of file
+<Project name="LUFA"><Folder name="Demos"><Folder name="Device"><Folder name="AudioInput"><File path="Demos\Device\AudioInput\AudioInput.c"></File><File path="Demos\Device\AudioInput\AudioInput.h"></File><File path="Demos\Device\AudioInput\AudioInput.txt"></File><File path="Demos\Device\AudioInput\Descriptors.c"></File><File path="Demos\Device\AudioInput\Descriptors.h"></File><File path="Demos\Device\AudioInput\Doxygen.conf"></File><File path="Demos\Device\AudioInput\makefile"></File></Folder><Folder name="AudioOutput"><File path="Demos\Device\AudioOutput\AudioOutput.c"></File><File path="Demos\Device\AudioOutput\AudioOutput.h"></File><File path="Demos\Device\AudioOutput\AudioOutput.txt"></File><File path="Demos\Device\AudioOutput\Descriptors.c"></File><File path="Demos\Device\AudioOutput\Descriptors.h"></File><File path="Demos\Device\AudioOutput\Doxygen.conf"></File><File path="Demos\Device\AudioOutput\makefile"></File></Folder><Folder name="CDC"><File path="Demos\Device\CDC\CDC.c"></File><File path="Demos\Device\CDC\CDC.h"></File><File path="Demos\Device\CDC\CDC.txt"></File><File path="Demos\Device\CDC\Descriptors.c"></File><File path="Demos\Device\CDC\Descriptors.h"></File><File path="Demos\Device\CDC\Doxygen.conf"></File><File path="Demos\Device\CDC\LUFA CDC.inf"></File><File path="Demos\Device\CDC\makefile"></File></Folder><Folder name="DualCDC"><File path="Demos\Device\DualCDC\Descriptors.c"></File><File path="Demos\Device\DualCDC\Descriptors.h"></File><File path="Demos\Device\DualCDC\Doxygen.conf"></File><File path="Demos\Device\DualCDC\DualCDC.c"></File><File path="Demos\Device\DualCDC\DualCDC.h"></File><File path="Demos\Device\DualCDC\DualCDC.txt"></File><File path="Demos\Device\DualCDC\LUFA DualCDC.inf"></File><File path="Demos\Device\DualCDC\makefile"></File></Folder><Folder name="GenericHID"><File path="Demos\Device\GenericHID\Descriptors.c"></File><File path="Demos\Device\GenericHID\Descriptors.h"></File><File path="Demos\Device\GenericHID\GenericHID.c"></File><File path="Demos\Device\GenericHID\GenericHID.h"></File><File path="Demos\Device\GenericHID\makefile"></File><File path="Demos\Device\GenericHID\GenericHID.txt"></File><File path="Demos\Device\GenericHID\Doxygen.conf"></File></Folder><Folder name="Joystick"><File path="Demos\Device\Joystick\Descriptors.c"></File><File path="Demos\Device\Joystick\Descriptors.h"></File><File path="Demos\Device\Joystick\Doxygen.conf"></File><File path="Demos\Device\Joystick\Joystick.c"></File><File path="Demos\Device\Joystick\Joystick.h"></File><File path="Demos\Device\Joystick\Joystick.txt"></File><File path="Demos\Device\Joystick\makefile"></File></Folder><Folder name="Keyboard"><File path="Demos\Device\Keyboard\Descriptors.c"></File><File path="Demos\Device\Keyboard\Descriptors.h"></File><File path="Demos\Device\Keyboard\Doxygen.conf"></File><File path="Demos\Device\Keyboard\Keyboard.c"></File><File path="Demos\Device\Keyboard\Keyboard.h"></File><File path="Demos\Device\Keyboard\Keyboard.txt"></File><File path="Demos\Device\Keyboard\makefile"></File></Folder><Folder name="KeyboardMouse"><File path="Demos\Device\KeyboardMouse\Descriptors.c"></File><File path="Demos\Device\KeyboardMouse\Descriptors.h"></File><File path="Demos\Device\KeyboardMouse\Doxygen.conf"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.c"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.h"></File><File path="Demos\Device\KeyboardMouse\KeyboardMouse.txt"></File><File path="Demos\Device\KeyboardMouse\makefile"></File></Folder><Folder name="MassStorage"><Folder name="Lib"><File path="Demos\Device\MassStorage\Lib\DataflashManager.c"></File><File path="Demos\Device\MassStorage\Lib\DataflashManager.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI.c"></File><File path="Demos\Device\MassStorage\Lib\SCSI.h"></File><File path="Demos\Device\MassStorage\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Device\MassStorage\Descriptors.c"></File><File path="Demos\Device\MassStorage\Descriptors.h"></File><File path="Demos\Device\MassStorage\Doxygen.conf"></File><File path="Demos\Device\MassStorage\makefile"></File><File path="Demos\Device\MassStorage\MassStorage.c"></File><File path="Demos\Device\MassStorage\MassStorage.h"></File><File path="Demos\Device\MassStorage\MassStorage.txt"></File></Folder><Folder name="MIDI"><File path="Demos\Device\MIDI\Descriptors.c"></File><File path="Demos\Device\MIDI\Descriptors.h"></File><File path="Demos\Device\MIDI\Doxygen.conf"></File><File path="Demos\Device\MIDI\makefile"></File><File path="Demos\Device\MIDI\MIDI.c"></File><File path="Demos\Device\MIDI\MIDI.h"></File><File path="Demos\Device\MIDI\MIDI.txt"></File></Folder><Folder name="Mouse"><File path="Demos\Device\Mouse\Descriptors.c"></File><File path="Demos\Device\Mouse\Descriptors.h"></File><File path="Demos\Device\Mouse\Doxygen.conf"></File><File path="Demos\Device\Mouse\makefile"></File><File path="Demos\Device\Mouse\Mouse.c"></File><File path="Demos\Device\Mouse\Mouse.h"></File><File path="Demos\Device\Mouse\Mouse.txt"></File></Folder><Folder name="RNDISEthernet"><Folder name="Lib"><File path="Demos\Device\RNDISEthernet\Lib\Webserver.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ARP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\DHCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.c"></File><File path="Demos\Device\RNDISEthernet\Lib\Ethernet.h"></File><File path="Demos\Device\RNDISEthernet\Lib\EthernetProtocols.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ICMP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\IP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.c"></File><File path="Demos\Device\RNDISEthernet\Lib\ProtocolDecoders.h"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDIS.c"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDIS.h"></File><File path="Demos\Device\RNDISEthernet\Lib\RNDISConstants.h"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\TCP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.c"></File><File path="Demos\Device\RNDISEthernet\Lib\UDP.h"></File><File path="Demos\Device\RNDISEthernet\Lib\Webserver.c"></File></Folder><File path="Demos\Device\RNDISEthernet\Descriptors.c"></File><File path="Demos\Device\RNDISEthernet\Descriptors.h"></File><File path="Demos\Device\RNDISEthernet\Doxygen.conf"></File><File path="Demos\Device\RNDISEthernet\LUFA RNDIS.inf"></File><File path="Demos\Device\RNDISEthernet\makefile"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.c"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.h"></File><File path="Demos\Device\RNDISEthernet\RNDISEthernet.txt"></File></Folder><Folder name="USBtoSerial"><Folder name="Lib"><File path="Demos\Device\USBtoSerial\Lib\RingBuff.c"></File><File path="Demos\Device\USBtoSerial\Lib\RingBuff.h"></File></Folder><File path="Demos\Device\USBtoSerial\Descriptors.c"></File><File path="Demos\Device\USBtoSerial\Descriptors.h"></File><File path="Demos\Device\USBtoSerial\Doxygen.conf"></File><File path="Demos\Device\USBtoSerial\LUFA USBtoSerial.inf"></File><File path="Demos\Device\USBtoSerial\makefile"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.c"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.h"></File><File path="Demos\Device\USBtoSerial\USBtoSerial.txt"></File></Folder><File path="Demos\Device\makefile"></File></Folder><Folder name="Host"><Folder name="CDCHost"><File path="Demos\Host\CDCHost\CDCHost.c"></File><File path="Demos\Host\CDCHost\CDCHost.h"></File><File path="Demos\Host\CDCHost\CDCHost.txt"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.c"></File><File path="Demos\Host\CDCHost\ConfigDescriptor.h"></File><File path="Demos\Host\CDCHost\Doxygen.conf"></File><File path="Demos\Host\CDCHost\makefile"></File></Folder><Folder name="GenericHIDHost"><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.c"></File><File path="Demos\Host\GenericHIDHost\ConfigDescriptor.h"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.c"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.h"></File><File path="Demos\Host\GenericHIDHost\makefile"></File><File path="Demos\Host\GenericHIDHost\Doxygen.conf"></File><File path="Demos\Host\GenericHIDHost\GenericHIDHost.txt"></File></Folder><Folder name="KeyboardHost"><File path="Demos\Host\KeyboardHost\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHost\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHost\Doxygen.conf"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.c"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.h"></File><File path="Demos\Host\KeyboardHost\KeyboardHost.txt"></File><File path="Demos\Host\KeyboardHost\makefile"></File></Folder><Folder name="KeyboardHostWithParser"><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\KeyboardHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\KeyboardHostWithParser\Doxygen.conf"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.c"></File><File path="Demos\Host\KeyboardHostWithParser\HIDReport.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.c"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.h"></File><File path="Demos\Host\KeyboardHostWithParser\KeyboardHostWithParser.txt"></File><File path="Demos\Host\KeyboardHostWithParser\makefile"></File></Folder><Folder name="MassStorageHost"><Folder name="Lib"><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.c"></File><File path="Demos\Host\MassStorageHost\Lib\MassStoreCommands.h"></File><File path="Demos\Host\MassStorageHost\Lib\SCSI_Codes.h"></File></Folder><File path="Demos\Host\MassStorageHost\ConfigDescriptor.c"></File><File path="Demos\Host\MassStorageHost\ConfigDescriptor.h"></File><File path="Demos\Host\MassStorageHost\Doxygen.conf"></File><File path="Demos\Host\MassStorageHost\makefile"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.c"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.h"></File><File path="Demos\Host\MassStorageHost\MassStorageHost.txt"></File></Folder><Folder name="MouseHost"><File path="Demos\Host\MouseHost\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHost\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHost\Doxygen.conf"></File><File path="Demos\Host\MouseHost\makefile"></File><File path="Demos\Host\MouseHost\MouseHost.c"></File><File path="Demos\Host\MouseHost\MouseHost.h"></File><File path="Demos\Host\MouseHost\MouseHost.txt"></File></Folder><Folder name="MouseHostWithParser"><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.c"></File><File path="Demos\Host\MouseHostWithParser\ConfigDescriptor.h"></File><File path="Demos\Host\MouseHostWithParser\Doxygen.conf"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.c"></File><File path="Demos\Host\MouseHostWithParser\HIDReport.h"></File><File path="Demos\Host\MouseHostWithParser\makefile"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.c"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.h"></File><File path="Demos\Host\MouseHostWithParser\MouseHostWithParser.txt"></File></Folder><Folder name="StillImageHost"><Folder name="Lib"><File path="Demos\Host\StillImageHost\Lib\PIMACodes.h"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.c"></File><File path="Demos\Host\StillImageHost\Lib\StillImageCommands.h"></File></Folder><File path="Demos\Host\StillImageHost\ConfigDescriptor.c"></File><File path="Demos\Host\StillImageHost\ConfigDescriptor.h"></File><File path="Demos\Host\StillImageHost\Doxygen.conf"></File><File path="Demos\Host\StillImageHost\makefile"></File><File path="Demos\Host\StillImageHost\StillImageHost.c"></File><File path="Demos\Host\StillImageHost\StillImageHost.h"></File><File path="Demos\Host\StillImageHost\StillImageHost.txt"></File></Folder><File path="Demos\Host\makefile"></File></Folder><Folder name="OTG"><Folder name="TestApp"><File path="Demos\OTG\TestApp\Descriptors.c"></File><File path="Demos\OTG\TestApp\Descriptors.h"></File><File path="Demos\OTG\TestApp\Doxygen.conf"></File><File path="Demos\OTG\TestApp\makefile"></File><File path="Demos\OTG\TestApp\TestApp.c"></File><File path="Demos\OTG\TestApp\TestApp.h"></File><File path="Demos\OTG\TestApp\TestApp.txt"></File><File path="Demos\OTG\TestApp\TestEvents.c"></File><File path="Demos\OTG\TestApp\TestEvents.h"></File></Folder><File path="Demos\OTG\makefile"></File></Folder><File path="Demos\makefile"></File></Folder><Folder name="LUFA"><Folder name="Common"><File path="LUFA\Common\Common.h"></File><File path="LUFA\Common\FunctionAttributes.h"></File><File path="LUFA\Common\BoardTypes.h"></File></Folder><Folder name="Drivers"><Folder name="USB"><Folder name="LowLevel"><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.c"></File><File path="LUFA\Drivers\USB\LowLevel\LowLevel.h"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.c"></File><File path="LUFA\Drivers\USB\LowLevel\Pipe.h"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\DevChapter9.h"></File><File path="LUFA\Drivers\USB\LowLevel\Device.h"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.c"></File><File path="LUFA\Drivers\USB\LowLevel\Endpoint.h"></File><File path="LUFA\Drivers\USB\LowLevel\Host.c"></File><File path="LUFA\Drivers\USB\LowLevel\Host.h"></File><File path="LUFA\Drivers\USB\LowLevel\HostChapter9.c"></File><File path="LUFA\Drivers\USB\LowLevel\OTG.h"></File></Folder><Folder name="HighLevel"><File path="LUFA\Drivers\USB\HighLevel\USBTask.h"></File><File path="LUFA\Drivers\USB\HighLevel\Events.c"></File><File path="LUFA\Drivers\USB\HighLevel\Events.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.c"></File><File path="LUFA\Drivers\USB\HighLevel\USBInterrupt.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBTask.c"></File><File path="LUFA\Drivers\USB\HighLevel\StdDescriptors.h"></File><File path="LUFA\Drivers\USB\HighLevel\StdRequestType.h"></File><File path="LUFA\Drivers\USB\HighLevel\StreamCallbacks.h"></File><File path="LUFA\Drivers\USB\HighLevel\USBMode.h"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.c"></File><File path="LUFA\Drivers\USB\HighLevel\ConfigDescriptor.h"></File></Folder><Folder name="Class"><File path="LUFA\Drivers\USB\Class\HIDParser.c"></File><File path="LUFA\Drivers\USB\Class\HIDParser.h"></File><File path="LUFA\Drivers\USB\Class\HIDReportData.h"></File></Folder><File path="LUFA\Drivers\USB\USB.h"></File></Folder><Folder name="Misc"><File path="LUFA\Drivers\Misc\TerminalCodes.h"></File></Folder><Folder name="Board"><Folder name="USBKEY"><File path="LUFA\Drivers\Board\USBKEY\Dataflash.h"></File><File path="LUFA\Drivers\Board\USBKEY\Joystick.h"></File><File path="LUFA\Drivers\Board\USBKEY\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\USBKEY\LEDs.h"></File><File path="LUFA\Drivers\Board\USBKEY\Buttons.h"></File></Folder><Folder name="STK526"><File path="LUFA\Drivers\Board\STK526\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK526\Joystick.h"></File><File path="LUFA\Drivers\Board\STK526\AT45DB642D.h"></File><File path="LUFA\Drivers\Board\STK526\LEDs.h"></File><File path="LUFA\Drivers\Board\STK526\Buttons.h"></File></Folder><Folder name="STK525"><File path="LUFA\Drivers\Board\STK525\Dataflash.h"></File><File path="LUFA\Drivers\Board\STK525\Joystick.h"></File><File path="LUFA\Drivers\Board\STK525\AT45DB321C.h"></File><File path="LUFA\Drivers\Board\STK525\LEDs.h"></File><File path="LUFA\Drivers\Board\STK525\Buttons.h"></File></Folder><Folder name="RZUSBSTICK"><File path="LUFA\Drivers\Board\RZUSBSTICK\LEDs.h"></File></Folder><Folder name="ATAVRUSBRF01"><File path="LUFA\Drivers\Board\ATAVRUSBRF01\LEDs.h"></File><File path="LUFA\Drivers\Board\ATAVRUSBRF01\Buttons.h"></File></Folder><File path="LUFA\Drivers\Board\Temperature.h"></File><File path="LUFA\Drivers\Board\Dataflash.h"></File><File path="LUFA\Drivers\Board\Joystick.h"></File><File path="LUFA\Drivers\Board\Temperature.c"></File><File path="LUFA\Drivers\Board\LEDs.h"></File><File path="LUFA\Drivers\Board\Buttons.h"></File></Folder><Folder name="Peripheral"><Folder name="AT90USBXXX67"><File path="LUFA\Drivers\Peripheral\AT90USBXXX67\ADC.h"></File></Folder><File path="LUFA\Drivers\Peripheral\ADC.h"></File><File path="LUFA\Drivers\Peripheral\Serial.c"></File><File path="LUFA\Drivers\Peripheral\Serial.h"></File><File path="LUFA\Drivers\Peripheral\SPI.h"></File><File path="LUFA\Drivers\Peripheral\SerialStream.c"></File><File path="LUFA\Drivers\Peripheral\SerialStream.h"></File></Folder></Folder><Folder name="Scheduler"><File path="LUFA\Scheduler\Scheduler.h"></File><File path="LUFA\Scheduler\Scheduler.c"></File></Folder><Folder name="MemoryAllocator"><File path="LUFA\MemoryAllocator\DynAlloc.h"></File><File path="LUFA\MemoryAllocator\DynAlloc.c"></File></Folder><Folder name="DriverStubs"><File path="LUFA\DriverStubs\Dataflash.h"></File><File path="LUFA\DriverStubs\Joystick.h"></File><File path="LUFA\DriverStubs\LEDs.h"></File><File path="LUFA\DriverStubs\Buttons.h"></File></Folder><File path="LUFA\makefile"></File><File path="LUFA\Version.h"></File><File path="LUFA\BuildingLinkableLibraries.txt"></File><File path="LUFA\GettingStarted.txt"></File><File path="LUFA\MainPage.txt"></File><File path="LUFA\SchedulerOverview.txt"></File><File path="LUFA\VIDAndPIDValues.txt"></File><File path="LUFA\ChangeLog.txt"></File><File path="LUFA\CompileTimeTokens.txt"></File><File path="LUFA\MigrationInformation.txt"></File><File path="LUFA\DirectorySummaries.txt"></File><File path="LUFA\Doxygen.conf"></File><File path="LUFA\WritingBoardDrivers.txt"></File><File path="LUFA\LUFAPoweredProjects.txt"></File><File path="LUFA\Groups.txt"></File></Folder><Folder name="Projects"><Folder name="MagStripe"><Folder name="Lib"><File path="Projects\Magstripe\Lib\CircularBitBuffer.c"></File><File path="Projects\Magstripe\Lib\CircularBitBuffer.h"></File><File path="Projects\Magstripe\Lib\MagstripeHW.h"></File></Folder><File path="Projects\Magstripe\Descriptors.c"></File><File path="Projects\Magstripe\Descriptors.h"></File><File path="Projects\Magstripe\Magstripe.c"></File><File path="Projects\Magstripe\Magstripe.h"></File><File path="Projects\Magstripe\makefile"></File><File path="Projects\Magstripe\Magstripe.txt"></File><File path="Projects\Magstripe\Doxygen.conf"></File></Folder><File path="Projects\makefile"></File></Folder><Folder name="Bootloaders"><Folder name="DFU"><File path="Bootloaders\DFU\BootloaderDFU.c"></File><File path="Bootloaders\DFU\BootloaderDFU.h"></File><File path="Bootloaders\DFU\Descriptors.c"></File><File path="Bootloaders\DFU\Descriptors.h"></File><File path="Bootloaders\DFU\makefile"></File><File path="Bootloaders\DFU\BootloaderDFU.txt"></File><File path="Bootloaders\DFU\Doxygen.conf"></File></Folder><Folder name="CDC"><File path="Bootloaders\CDC\BootloaderCDC.c"></File><File path="Bootloaders\CDC\BootloaderCDC.h"></File><File path="Bootloaders\CDC\Descriptors.c"></File><File path="Bootloaders\CDC\Descriptors.h"></File><File path="Bootloaders\CDC\makefile"></File><File path="Bootloaders\CDC\LUFA CDC Bootloader.inf"></File><File path="Bootloaders\CDC\Doxygen.conf"></File><File path="Bootloaders\CDC\BootloaderCDC.txt"></File></Folder><Folder name="TeensyHID"><File path="Bootloaders\TeensyHID\Descriptors.c"></File><File path="Bootloaders\TeensyHID\Descriptors.h"></File><File path="Bootloaders\TeensyHID\makefile"></File><File path="Bootloaders\TeensyHID\TeensyHID.c"></File><File path="Bootloaders\TeensyHID\TeensyHID.h"></File><File path="Bootloaders\TeensyHID\TeensyHID.txt"></File></Folder><File path="Bootloaders\makefile"></File></Folder><File path="makefile"></File></Project>
\ No newline at end of file
index 4a7f34e..68aa6c7 100644 (file)
@@ -28,6 +28,7 @@
   *  - Fixed incorrect PID value being used in the USBtoSerial project (thanks to Phill)\r
   *  - Deleted StdDescriptors.c, renamed USB_GetDescriptor() to CALLBACK_USB_GetDescriptor, moved ConfigDescriptor.c/.h from the\r
   *    LUFA/Drivers/USB/Class/ directory to LUFA/Drivers/USB/HighLevel/ in preperation for the new USB class APIs\r
+  *  - Moved out each demos' functionality library files (e.g. Ring Buffer library) to /Lib directories for a better directory structure\r
   *\r
   *\r
   *  \section Sec_ChangeLog090510 Version 090510\r
diff --git a/Projects/Magstripe/CircularBitBuffer.c b/Projects/Magstripe/CircularBitBuffer.c
deleted file mode 100644 (file)
index 5d23762..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Denver Gingerich (denver [at] ossguy [dot] com)\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** Circular bit buffer library. This will allow for individual bits\r
- *  to be stored in packed form inside circular buffers, to reduce\r
- *  overall RAM usage.\r
- */\r
-\r
-#include "CircularBitBuffer.h"\r
-\r
-/** Function to initialize or reset a bit buffer, ready for data to be stored into it. */\r
-void BitBuffer_Init(BitBuffer_t* Buffer)\r
-{\r
-       /* Reset the number of stored bits in the buffer */\r
-       Buffer->Elements        = 0;\r
-       \r
-       /* Reset the data in and out pointer structures in the buffer to the first buffer bit */\r
-       Buffer->In.CurrentByte  = Buffer->Data;\r
-       Buffer->In.ByteMask     = (1 << 0);\r
-       Buffer->Out.CurrentByte = Buffer->Data;\r
-       Buffer->Out.ByteMask    = (1 << 0);\r
-}\r
-\r
-/** Function to store the given bit into the given bit buffer. */\r
-void BitBuffer_StoreNextBit(BitBuffer_t* Buffer, bool Bit)\r
-{\r
-       /* If the bit to store is true, set the next bit in the buffer */\r
-       if (Bit)\r
-         *Buffer->In.CurrentByte |= Buffer->In.ByteMask;\r
-       \r
-       /* Increment the number of stored bits in the buffer counter */\r
-       Buffer->Elements++;\r
-       \r
-       /* Check if the current buffer byte is full of stored bits */\r
-       if (Buffer->In.ByteMask == (1 << 7))\r
-       {\r
-               /* Check if the end of the buffer has been reached, if so reset to start of buffer, otherwise advance to next bit */\r
-               if (Buffer->In.CurrentByte != &Buffer->Data[sizeof(Buffer->Data) - 1])\r
-                 Buffer->In.CurrentByte++;\r
-               else\r
-                 Buffer->In.CurrentByte = Buffer->Data;\r
-                 \r
-               /* Reset the storage bit mask in the current buffer byte to the first bit */            \r
-               Buffer->In.ByteMask = (1 << 0);\r
-       }\r
-       else\r
-       {\r
-               /* Shift the current storage bit mask to the next bit in the current byte */\r
-               Buffer->In.ByteMask <<= 1;\r
-       }\r
-}\r
-\r
-/** Function to retrieve the next bit stored in the given bit buffer. */\r
-bool BitBuffer_GetNextBit(BitBuffer_t* Buffer)\r
-{      \r
-       /* Retrieve the value of the next bit stored in the buffer */\r
-       bool Bit = ((*Buffer->Out.CurrentByte & Buffer->Out.ByteMask) != 0);\r
-\r
-       /* Clear the buffer bit */\r
-       *Buffer->Out.CurrentByte &= ~Buffer->Out.ByteMask;\r
-\r
-       /* Decrement the number of stored bits in the buffer counter */\r
-       Buffer->Elements--;\r
-       \r
-       /* Check if the current buffer byte is empty of stored bits */  \r
-       if (Buffer->Out.ByteMask == (1 << 7))\r
-       {\r
-               /* Check if the end of the buffer has been reached, if so reset to start of buffer, otherwise advance to next bit */\r
-               if (Buffer->Out.CurrentByte != &Buffer->Data[sizeof(Buffer->Data) - 1])\r
-                 Buffer->Out.CurrentByte++;\r
-               else\r
-                 Buffer->Out.CurrentByte = Buffer->Data;               \r
-               \r
-               /* Reset the retrieval bit mask in the current buffer byte to the first bit */          \r
-               Buffer->Out.ByteMask = (1 << 0);\r
-       }\r
-       else\r
-       {\r
-               /* Shift the current retrieval bit mask to the next bit in the current byte */\r
-               Buffer->Out.ByteMask <<= 1;\r
-       }\r
-\r
-       /* Return the retrieved bit from the buffer */\r
-       return Bit;\r
-}\r
diff --git a/Projects/Magstripe/CircularBitBuffer.h b/Projects/Magstripe/CircularBitBuffer.h
deleted file mode 100644 (file)
index 6f1fa15..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*\r
-             LUFA Library\r
-     Copyright (C) Dean Camera, 2009.\r
-              \r
-  dean [at] fourwalledcubicle [dot] com\r
-      www.fourwalledcubicle.com\r
-*/\r
-\r
-/*\r
-  Copyright 2009  Denver Gingerich (denver [at] ossguy [dot] com)\r
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
-\r
-  Permission to use, copy, modify, and distribute this software\r
-  and its documentation for any purpose and without fee is hereby\r
-  granted, provided that the above copyright notice appear in all\r
-  copies and that both that the copyright notice and this\r
-  permission notice and warranty disclaimer appear in supporting\r
-  documentation, and that the name of the author not be used in\r
-  advertising or publicity pertaining to distribution of the\r
-  software without specific, written prior permission.\r
-\r
-  The author disclaim all warranties with regard to this\r
-  software, including all implied warranties of merchantability\r
-  and fitness.  In no event shall the author be liable for any\r
-  special, indirect or consequential damages or any damages\r
-  whatsoever resulting from loss of use, data or profits, whether\r
-  in an action of contract, negligence or other tortious action,\r
-  arising out of or in connection with the use or performance of\r
-  this software.\r
-*/\r
-\r
-/** \file\r
- *\r
- *  Header file for CircularBitBuffer.c.\r
- */\r
-\r
-#ifndef _CIRCULARBITBUFFER_H_\r
-#define _CIRCULARBITBUFFER_H_\r
-\r
-       /* Includes: */\r
-               #include <avr/io.h>\r
-               #include <stdbool.h>\r
-               \r
-               #include <LUFA/Common/Common.h>\r
-\r
-       /* Macros: */\r
-               #if (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \\r
-                    defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__)) || defined(__DOXYGEN__)\r
-                       /** Maximum number of bits which can be stored into a bit buffer. The memory usage is one eighth of this value per buffer. */\r
-                       #define MAX_BITS 8192\r
-               #else\r
-                       #define MAX_BITS 1024\r
-               #endif\r
-               \r
-       /* Type Defines: */\r
-               /* Type define for a pointer to a bit in a bit buffer. */\r
-               typedef struct\r
-               {\r
-                       uint8_t* CurrentByte; /**< Pointer to the current byte in the buffer */\r
-                       uint8_t  ByteMask; /**< Mask of the current bit in the buffer */\r
-               } BitBufferPointer_t;\r
-\r
-               /** Type define for a circular packet bit buffer. */\r
-               typedef struct\r
-               {\r
-                       uint8_t            Data[MAX_BITS / 8]; /**< Buffer to hold the stored bits in packed form */\r
-                       uint16_t           Elements; /**< Number of stored bits in the bit buffer */\r
-                       \r
-                       BitBufferPointer_t In; /**< Bit pointer to the next storage location in the buffer */\r
-                       BitBufferPointer_t Out; /**< Bit pointer to the next retrieval location in the buffer */\r
-               } BitBuffer_t;\r
-               \r
-       /* Function Prototypes: */      \r
-               /** Initializes or resets a given bit buffer, ready to store new bits.\r
-                *  \r
-                *  \param Buffer  Bit buffer to initialize\r
-                */\r
-               void BitBuffer_Init(BitBuffer_t* Buffer) ATTR_NON_NULL_PTR_ARG(1);\r
-               \r
-               /** Stores a bit into the next location inside a given bit buffer.\r
-                *\r
-                *  \param Buffer  Bit buffer to store a bit into\r
-                *  \param Bit  Bit to store into the buffer\r
-                */\r
-               void BitBuffer_StoreNextBit(BitBuffer_t* Buffer, bool Bit) ATTR_NON_NULL_PTR_ARG(1);\r
-               \r
-               /** Retrieves a bit from the next location inside a given bit buffer.\r
-                *\r
-                *  \param Buffer  Bit buffer to store a bit into\r
-                *\r
-                *  \return Next bit from the buffer\r
-                */\r
-               bool BitBuffer_GetNextBit(BitBuffer_t* Buffer) ATTR_NON_NULL_PTR_ARG(1);\r
-               \r
-#endif\r
diff --git a/Projects/Magstripe/Lib/CircularBitBuffer.c b/Projects/Magstripe/Lib/CircularBitBuffer.c
new file mode 100644 (file)
index 0000000..5d23762
--- /dev/null
@@ -0,0 +1,113 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Denver Gingerich (denver [at] ossguy [dot] com)\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** Circular bit buffer library. This will allow for individual bits\r
+ *  to be stored in packed form inside circular buffers, to reduce\r
+ *  overall RAM usage.\r
+ */\r
+\r
+#include "CircularBitBuffer.h"\r
+\r
+/** Function to initialize or reset a bit buffer, ready for data to be stored into it. */\r
+void BitBuffer_Init(BitBuffer_t* Buffer)\r
+{\r
+       /* Reset the number of stored bits in the buffer */\r
+       Buffer->Elements        = 0;\r
+       \r
+       /* Reset the data in and out pointer structures in the buffer to the first buffer bit */\r
+       Buffer->In.CurrentByte  = Buffer->Data;\r
+       Buffer->In.ByteMask     = (1 << 0);\r
+       Buffer->Out.CurrentByte = Buffer->Data;\r
+       Buffer->Out.ByteMask    = (1 << 0);\r
+}\r
+\r
+/** Function to store the given bit into the given bit buffer. */\r
+void BitBuffer_StoreNextBit(BitBuffer_t* Buffer, bool Bit)\r
+{\r
+       /* If the bit to store is true, set the next bit in the buffer */\r
+       if (Bit)\r
+         *Buffer->In.CurrentByte |= Buffer->In.ByteMask;\r
+       \r
+       /* Increment the number of stored bits in the buffer counter */\r
+       Buffer->Elements++;\r
+       \r
+       /* Check if the current buffer byte is full of stored bits */\r
+       if (Buffer->In.ByteMask == (1 << 7))\r
+       {\r
+               /* Check if the end of the buffer has been reached, if so reset to start of buffer, otherwise advance to next bit */\r
+               if (Buffer->In.CurrentByte != &Buffer->Data[sizeof(Buffer->Data) - 1])\r
+                 Buffer->In.CurrentByte++;\r
+               else\r
+                 Buffer->In.CurrentByte = Buffer->Data;\r
+                 \r
+               /* Reset the storage bit mask in the current buffer byte to the first bit */            \r
+               Buffer->In.ByteMask = (1 << 0);\r
+       }\r
+       else\r
+       {\r
+               /* Shift the current storage bit mask to the next bit in the current byte */\r
+               Buffer->In.ByteMask <<= 1;\r
+       }\r
+}\r
+\r
+/** Function to retrieve the next bit stored in the given bit buffer. */\r
+bool BitBuffer_GetNextBit(BitBuffer_t* Buffer)\r
+{      \r
+       /* Retrieve the value of the next bit stored in the buffer */\r
+       bool Bit = ((*Buffer->Out.CurrentByte & Buffer->Out.ByteMask) != 0);\r
+\r
+       /* Clear the buffer bit */\r
+       *Buffer->Out.CurrentByte &= ~Buffer->Out.ByteMask;\r
+\r
+       /* Decrement the number of stored bits in the buffer counter */\r
+       Buffer->Elements--;\r
+       \r
+       /* Check if the current buffer byte is empty of stored bits */  \r
+       if (Buffer->Out.ByteMask == (1 << 7))\r
+       {\r
+               /* Check if the end of the buffer has been reached, if so reset to start of buffer, otherwise advance to next bit */\r
+               if (Buffer->Out.CurrentByte != &Buffer->Data[sizeof(Buffer->Data) - 1])\r
+                 Buffer->Out.CurrentByte++;\r
+               else\r
+                 Buffer->Out.CurrentByte = Buffer->Data;               \r
+               \r
+               /* Reset the retrieval bit mask in the current buffer byte to the first bit */          \r
+               Buffer->Out.ByteMask = (1 << 0);\r
+       }\r
+       else\r
+       {\r
+               /* Shift the current retrieval bit mask to the next bit in the current byte */\r
+               Buffer->Out.ByteMask <<= 1;\r
+       }\r
+\r
+       /* Return the retrieved bit from the buffer */\r
+       return Bit;\r
+}\r
diff --git a/Projects/Magstripe/Lib/CircularBitBuffer.h b/Projects/Magstripe/Lib/CircularBitBuffer.h
new file mode 100644 (file)
index 0000000..6f1fa15
--- /dev/null
@@ -0,0 +1,95 @@
+/*\r
+             LUFA Library\r
+     Copyright (C) Dean Camera, 2009.\r
+              \r
+  dean [at] fourwalledcubicle [dot] com\r
+      www.fourwalledcubicle.com\r
+*/\r
+\r
+/*\r
+  Copyright 2009  Denver Gingerich (denver [at] ossguy [dot] com)\r
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)\r
+\r
+  Permission to use, copy, modify, and distribute this software\r
+  and its documentation for any purpose and without fee is hereby\r
+  granted, provided that the above copyright notice appear in all\r
+  copies and that both that the copyright notice and this\r
+  permission notice and warranty disclaimer appear in supporting\r
+  documentation, and that the name of the author not be used in\r
+  advertising or publicity pertaining to distribution of the\r
+  software without specific, written prior permission.\r
+\r
+  The author disclaim all warranties with regard to this\r
+  software, including all implied warranties of merchantability\r
+  and fitness.  In no event shall the author be liable for any\r
+  special, indirect or consequential damages or any damages\r
+  whatsoever resulting from loss of use, data or profits, whether\r
+  in an action of contract, negligence or other tortious action,\r
+  arising out of or in connection with the use or performance of\r
+  this software.\r
+*/\r
+\r
+/** \file\r
+ *\r
+ *  Header file for CircularBitBuffer.c.\r
+ */\r
+\r
+#ifndef _CIRCULARBITBUFFER_H_\r
+#define _CIRCULARBITBUFFER_H_\r
+\r
+       /* Includes: */\r
+               #include <avr/io.h>\r
+               #include <stdbool.h>\r
+               \r
+               #include <LUFA/Common/Common.h>\r
+\r
+       /* Macros: */\r
+               #if (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB647__) || \\r
+                    defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__)) || defined(__DOXYGEN__)\r
+                       /** Maximum number of bits which can be stored into a bit buffer. The memory usage is one eighth of this value per buffer. */\r
+                       #define MAX_BITS 8192\r
+               #else\r
+                       #define MAX_BITS 1024\r
+               #endif\r
+               \r
+       /* Type Defines: */\r
+               /* Type define for a pointer to a bit in a bit buffer. */\r
+               typedef struct\r
+               {\r
+                       uint8_t* CurrentByte; /**< Pointer to the current byte in the buffer */\r
+                       uint8_t  ByteMask; /**< Mask of the current bit in the buffer */\r
+               } BitBufferPointer_t;\r
+\r
+               /** Type define for a circular packet bit buffer. */\r
+               typedef struct\r
+               {\r
+                       uint8_t            Data[MAX_BITS / 8]; /**< Buffer to hold the stored bits in packed form */\r
+                       uint16_t           Elements; /**< Number of stored bits in the bit buffer */\r
+                       \r
+                       BitBufferPointer_t In; /**< Bit pointer to the next storage location in the buffer */\r
+                       BitBufferPointer_t Out; /**< Bit pointer to the next retrieval location in the buffer */\r
+               } BitBuffer_t;\r
+               \r
+       /* Function Prototypes: */      \r
+               /** Initializes or resets a given bit buffer, ready to store new bits.\r
+                *  \r
+                *  \param Buffer  Bit buffer to initialize\r
+                */\r
+               void BitBuffer_Init(BitBuffer_t* Buffer) ATTR_NON_NULL_PTR_ARG(1);\r
+               \r
+               /** Stores a bit into the next location inside a given bit buffer.\r
+                *\r
+                *  \param Buffer  Bit buffer to store a bit into\r
+                *  \param Bit  Bit to store into the buffer\r
+                */\r
+               void BitBuffer_StoreNextBit(BitBuffer_t* Buffer, bool Bit) ATTR_NON_NULL_PTR_ARG(1);\r
+               \r
+               /** Retrieves a bit from the next location inside a given bit buffer.\r
+                *\r
+                *  \param Buffer  Bit buffer to store a bit into\r
+                *\r
+                *  \return Next bit from the buffer\r
+                */\r
+               bool BitBuffer_GetNextBit(BitBuffer_t* Buffer) ATTR_NON_NULL_PTR_ARG(1);\r
+               \r
+#endif\r
diff --git a/Projects/Magstripe/Lib/MagstripeHW.h b/Projects/Magstripe/Lib/MagstripeHW.h
new file mode 100644 (file)
index 0000000..c468118
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+  Copyright 2009  Denver Gingerich (denver [at] ossguy [dot] com)
+  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+  Permission to use, copy, modify, and distribute this software
+  and its documentation for any purpose and without fee is hereby
+  granted, 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
+  software without specific, written prior permission.
+
+  The author disclaim all warranties with regard to this
+  software, including all implied warranties of merchantability
+  and fitness.  In no event shall the author be liable for any
+  special, indirect or consequential damages or any damages
+  whatsoever resulting from loss of use, data or profits, whether
+  in an action of contract, negligence or other tortious action,
+  arising out of or in connection with the use or performance of
+  this software.
+*/
+
+/*
+       NOTE: The user of this include file MUST define the following macros
+       prior to including the file:
+
+       MAG_T1_CLOCK_PIN   Pin connected to Track 1 clock wire (ie. PORTC1)
+       MAG_T1_DATA_PIN    Pin connected to Track 1 data wire (ie. PORTC2)
+       MAG_T2_CLOCK_PIN   Pin connected to Track 2 clock wire (ie. PORTC3)
+       MAG_T2_DATA_PIN    Pin connected to Track 2 data wire (ie. PORTC0)
+       MAG_T3_CLOCK_PIN   Pin connected to Track 3 clock wire (ie. PORTC5)
+       MAG_T3_DATA_PIN    Pin connected to Track 3 data wire (ie. PORTC6)
+       MAG_CLS_PIN        Pin connected to card loaded wire (ie. PORTC4)
+       MAG_PIN            PIN macro for the reader's port (ie. PINC)
+       MAG_DDR            DDR macro for the reader's port (ie. DDRC)
+       MAG_PORT           PORT macro for the reader's port (ie. PORTC)
+
+       The example macros listed above assume that the Track 2 data wire is
+       connected to pin 0 on port C, the Track 2 clock wire is connected to
+       pin 3 on port C (similarly for Tracks 1 and 3), and the card loaded
+       wire is connected to pin 4 on port C.
+
+       If the magstripe reader you are using only reads one or two tracks,
+       then set the clock and data pins for the tracks it doesn't read to a
+       pin that is unused.  For example, on the AT90USBKey, any of the pins on
+       port C that do not have wires attached will be unused since they are
+       not connected to any onboard devices (such as the joystick or
+       temperature sensor).
+
+       Connecting wires to pins on different ports (ie. a data wire to pin 0
+       on port C and a clock wire to pin 0 on port D) is currently
+       unsupported.  All pins specified above must be on the same port.
+*/
+
+/** \file
+ *
+ *  Driver header for a TTL Magnetic Card reader device (such as the Omron V3B-4K).
+ */
+
+#ifndef _MAGSTRIPEHW_H_
+#define _MAGSTRIPEHW_H_
+
+       /* Includes: */
+               #include <avr/io.h>
+
+               #include <LUFA/Common/Common.h>
+
+       /* Private Interface - For use in library only: */
+               /* Macros: */
+                       /** Mask of the track data, clock and card detection pins. */
+                       #define MAG_MASK    (MAG_T1_DATA | MAG_T1_CLOCK | \
+                                            MAG_T2_DATA | MAG_T2_CLOCK | \
+                                            MAG_T3_DATA | MAG_T3_CLOCK | \
+                                            MAG_CARDPRESENT)
+
+       /* Public Interface - May be used in end-application: */
+               /* Inline Functions: */
+                       /** Initializes the magnetic stripe card reader ports and pins so that the card reader
+                        *  device can be controlled and read by the card reader driver. This must be called before
+                        *  trying to read any of the card reader's status lines.
+                        */
+                       static inline void Magstripe_Init(void)
+                       {
+                               MAG_DDR  &= ~MAG_MASK;
+                               MAG_PORT |=  MAG_MASK;
+                       };
+
+                       /** Returns the status of all the magnetic card reader's outputs.
+                        *
+                        *  \return A mask indicating which card lines are high or low
+                        */
+                       static inline uint8_t Magstripe_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
+                       static inline uint8_t Magstripe_GetStatus(void)
+                       {
+                               /* Magstripe IOs are active low and must be inverted when read */
+                               return ((uint8_t)~MAG_PIN & MAG_MASK);
+                       }
+
+#endif
index a83496b..c700bca 100644 (file)
@@ -46,8 +46,9 @@
                #include <string.h>\r
 \r
                #include "Descriptors.h"\r
-               #include "MagstripeHW.h"\r
-               #include "CircularBitBuffer.h"\r
+\r
+               #include "Lib/MagstripeHW.h"\r
+               #include "Lib/CircularBitBuffer.h"\r
 \r
                #include <LUFA/Version.h>                    // Library Version Information\r
                #include <LUFA/Drivers/USB/USB.h>            // USB Functionality\r
diff --git a/Projects/Magstripe/MagstripeHW.h b/Projects/Magstripe/MagstripeHW.h
deleted file mode 100644 (file)
index c468118..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
-  Copyright 2009  Denver Gingerich (denver [at] ossguy [dot] com)
-  Copyright 2009  Dean Camera (dean [at] fourwalledcubicle [dot] com)
-
-  Permission to use, copy, modify, and distribute this software
-  and its documentation for any purpose and without fee is hereby
-  granted, 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
-  software without specific, written prior permission.
-
-  The author disclaim all warranties with regard to this
-  software, including all implied warranties of merchantability
-  and fitness.  In no event shall the author be liable for any
-  special, indirect or consequential damages or any damages
-  whatsoever resulting from loss of use, data or profits, whether
-  in an action of contract, negligence or other tortious action,
-  arising out of or in connection with the use or performance of
-  this software.
-*/
-
-/*
-       NOTE: The user of this include file MUST define the following macros
-       prior to including the file:
-
-       MAG_T1_CLOCK_PIN   Pin connected to Track 1 clock wire (ie. PORTC1)
-       MAG_T1_DATA_PIN    Pin connected to Track 1 data wire (ie. PORTC2)
-       MAG_T2_CLOCK_PIN   Pin connected to Track 2 clock wire (ie. PORTC3)
-       MAG_T2_DATA_PIN    Pin connected to Track 2 data wire (ie. PORTC0)
-       MAG_T3_CLOCK_PIN   Pin connected to Track 3 clock wire (ie. PORTC5)
-       MAG_T3_DATA_PIN    Pin connected to Track 3 data wire (ie. PORTC6)
-       MAG_CLS_PIN        Pin connected to card loaded wire (ie. PORTC4)
-       MAG_PIN            PIN macro for the reader's port (ie. PINC)
-       MAG_DDR            DDR macro for the reader's port (ie. DDRC)
-       MAG_PORT           PORT macro for the reader's port (ie. PORTC)
-
-       The example macros listed above assume that the Track 2 data wire is
-       connected to pin 0 on port C, the Track 2 clock wire is connected to
-       pin 3 on port C (similarly for Tracks 1 and 3), and the card loaded
-       wire is connected to pin 4 on port C.
-
-       If the magstripe reader you are using only reads one or two tracks,
-       then set the clock and data pins for the tracks it doesn't read to a
-       pin that is unused.  For example, on the AT90USBKey, any of the pins on
-       port C that do not have wires attached will be unused since they are
-       not connected to any onboard devices (such as the joystick or
-       temperature sensor).
-
-       Connecting wires to pins on different ports (ie. a data wire to pin 0
-       on port C and a clock wire to pin 0 on port D) is currently
-       unsupported.  All pins specified above must be on the same port.
-*/
-
-/** \file
- *
- *  Driver header for a TTL Magnetic Card reader device (such as the Omron V3B-4K).
- */
-
-#ifndef _MAGSTRIPEHW_H_
-#define _MAGSTRIPEHW_H_
-
-       /* Includes: */
-               #include <avr/io.h>
-
-               #include <LUFA/Common/Common.h>
-
-       /* Private Interface - For use in library only: */
-               /* Macros: */
-                       /** Mask of the track data, clock and card detection pins. */
-                       #define MAG_MASK    (MAG_T1_DATA | MAG_T1_CLOCK | \
-                                            MAG_T2_DATA | MAG_T2_CLOCK | \
-                                            MAG_T3_DATA | MAG_T3_CLOCK | \
-                                            MAG_CARDPRESENT)
-
-       /* Public Interface - May be used in end-application: */
-               /* Inline Functions: */
-                       /** Initializes the magnetic stripe card reader ports and pins so that the card reader
-                        *  device can be controlled and read by the card reader driver. This must be called before
-                        *  trying to read any of the card reader's status lines.
-                        */
-                       static inline void Magstripe_Init(void)
-                       {
-                               MAG_DDR  &= ~MAG_MASK;
-                               MAG_PORT |=  MAG_MASK;
-                       };
-
-                       /** Returns the status of all the magnetic card reader's outputs.
-                        *
-                        *  \return A mask indicating which card lines are high or low
-                        */
-                       static inline uint8_t Magstripe_GetStatus(void) ATTR_WARN_UNUSED_RESULT;
-                       static inline uint8_t Magstripe_GetStatus(void)
-                       {
-                               /* Magstripe IOs are active low and must be inverted when read */
-                               return ((uint8_t)~MAG_PIN & MAG_MASK);
-                       }
-
-#endif
index 6a77cf0..962c999 100644 (file)
@@ -125,7 +125,7 @@ LUFA_PATH = ../..
 # List C source files here. (C dependencies are automatically generated.)
 SRC = $(TARGET).c                                                 \
          Descriptors.c                                               \
-         CircularBitBuffer.c                                         \
+         Lib/CircularBitBuffer.c                                     \
          $(LUFA_PATH)/LUFA/Scheduler/Scheduler.c                     \
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/DevChapter9.c        \
          $(LUFA_PATH)/LUFA/Drivers/USB/LowLevel/Endpoint.c           \