PipeStream.c 8.36 KB
Newer Older
1 2
/*
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4 5
              
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7 8 9
*/

/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

  Permission to use, copy, modify, distribute, and sell this 
  software and its documentation for any purpose is hereby granted
  without fee, provided that the above copyright notice appear in 
  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.
*/

#define  __INCLUDE_FROM_USB_DRIVER
#include "USBMode.h"

#if defined(USB_CAN_BE_HOST)

#include "PipeStream.h"

38 39
uint8_t Pipe_Discard_Stream(uint16_t Length,
                            uint16_t* const BytesProcessed)
40 41
{
	uint8_t  ErrorCode;
42
	uint16_t BytesInTransfer = 0;
43 44 45 46 47 48
	
	Pipe_SetPipeToken(PIPE_TOKEN_IN);

	if ((ErrorCode = Pipe_WaitUntilReady()))
	  return ErrorCode;

49 50 51
	if (BytesProcessed != NULL)
	  Length -= *BytesProcessed;

52 53 54 55 56 57
	while (Length)
	{
		if (!(Pipe_IsReadWriteAllowed()))
		{
			Pipe_ClearIN();
				
58 59 60 61 62
			if (BytesProcessed != NULL)
			{
				*BytesProcessed += BytesInTransfer;
				return PIPE_RWSTREAM_IncompleteTransfer;
			}
63 64 65 66 67 68

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
69
			Pipe_Discard_8();
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
			
			Length--;
			BytesInTransfer++;
		}
	}

	return PIPE_RWSTREAM_NoError;
}

uint8_t Pipe_Null_Stream(uint16_t Length,
                         uint16_t* const BytesProcessed)
{
	uint8_t  ErrorCode;
	uint16_t BytesInTransfer = 0;
	
	Pipe_SetPipeToken(PIPE_TOKEN_OUT);

	if ((ErrorCode = Pipe_WaitUntilReady()))
	  return ErrorCode;

	if (BytesProcessed != NULL)
	  Length -= *BytesProcessed;

	while (Length)
	{
		if (!(Pipe_IsReadWriteAllowed()))
		{
			Pipe_ClearOUT();
				
			if (BytesProcessed != NULL)
			{
				*BytesProcessed += BytesInTransfer;
				return PIPE_RWSTREAM_IncompleteTransfer;
			}
104 105
			
			USB_USBTask();
106 107 108 109 110 111

			if ((ErrorCode = Pipe_WaitUntilReady()))
			  return ErrorCode;
		}
		else
		{
112
			Pipe_Write_8(0);
113
			
114
			Length--;
115
			BytesInTransfer++;
116 117 118 119 120 121 122 123 124 125 126 127 128 129
		}
	}

	return PIPE_RWSTREAM_NoError;
}

/* The following abuses the C preprocessor in order to copy-past common code with slight alterations,
 * so that the code needs to be written once. It is a crude form of templating to reduce code maintenance. */

#define  TEMPLATE_FUNC_NAME                        Pipe_Write_Stream_LE
#define  TEMPLATE_BUFFER_TYPE                      const void*
#define  TEMPLATE_TOKEN                            PIPE_TOKEN_OUT
#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearOUT()
#define  TEMPLATE_BUFFER_OFFSET(Length)            0
130
#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream += Amount
131
#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         Pipe_Write_8(*BufferPtr)
132 133 134 135 136 137 138
#include "Template/Template_Pipe_RW.c"

#define  TEMPLATE_FUNC_NAME                        Pipe_Write_Stream_BE
#define  TEMPLATE_BUFFER_TYPE                      const void*
#define  TEMPLATE_TOKEN                            PIPE_TOKEN_OUT
#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearOUT()
#define  TEMPLATE_BUFFER_OFFSET(Length)            (Length - 1)
139
#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream -= Amount
140
#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         Pipe_Write_8(*BufferPtr)
141 142 143 144 145 146 147
#include "Template/Template_Pipe_RW.c"

#define  TEMPLATE_FUNC_NAME                        Pipe_Read_Stream_LE
#define  TEMPLATE_BUFFER_TYPE                      void*
#define  TEMPLATE_TOKEN                            PIPE_TOKEN_IN
#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearIN()
#define  TEMPLATE_BUFFER_OFFSET(Length)            0
148
#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream += Amount
149
#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         *BufferPtr = Pipe_Read_8()
150 151 152 153 154 155 156
#include "Template/Template_Pipe_RW.c"

#define  TEMPLATE_FUNC_NAME                        Pipe_Read_Stream_BE
#define  TEMPLATE_BUFFER_TYPE                      void*
#define  TEMPLATE_TOKEN                            PIPE_TOKEN_IN
#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearIN()
#define  TEMPLATE_BUFFER_OFFSET(Length)            (Length - 1)
157
#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream -= Amount
158
#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         *BufferPtr = Pipe_Read_8()
159 160
#include "Template/Template_Pipe_RW.c"

161 162 163 164 165 166 167
#if defined(ARCH_HAS_FLASH_ADDRESS_SPACE)
	#define  TEMPLATE_FUNC_NAME                        Pipe_Write_PStream_LE
	#define  TEMPLATE_BUFFER_TYPE                      const void*
	#define  TEMPLATE_TOKEN                            PIPE_TOKEN_OUT
	#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearOUT()
	#define  TEMPLATE_BUFFER_OFFSET(Length)            0
	#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream += Amount
168
	#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         Pipe_Write_8(pgm_read_byte(BufferPtr))
169 170 171 172 173 174 175 176
	#include "Template/Template_Pipe_RW.c"

	#define  TEMPLATE_FUNC_NAME                        Pipe_Write_PStream_BE
	#define  TEMPLATE_BUFFER_TYPE                      const void*
	#define  TEMPLATE_TOKEN                            PIPE_TOKEN_OUT
	#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearOUT()
	#define  TEMPLATE_BUFFER_OFFSET(Length)            (Length - 1)
	#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream -= Amount
177
	#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         Pipe_Write_8(pgm_read_byte(BufferPtr))
178 179 180 181 182 183 184 185 186 187
	#include "Template/Template_Pipe_RW.c"
#endif

#if defined(ARCH_HAS_EEPROM_ADDRESS_SPACE)
	#define  TEMPLATE_FUNC_NAME                        Pipe_Write_EStream_LE
	#define  TEMPLATE_BUFFER_TYPE                      const void*
	#define  TEMPLATE_TOKEN                            PIPE_TOKEN_OUT
	#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearOUT()
	#define  TEMPLATE_BUFFER_OFFSET(Length)            0
	#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream += Amount
188
	#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         Pipe_Write_8(eeprom_read_byte(BufferPtr))
189 190 191 192 193 194 195 196
	#include "Template/Template_Pipe_RW.c"

	#define  TEMPLATE_FUNC_NAME                        Pipe_Write_EStream_BE
	#define  TEMPLATE_BUFFER_TYPE                      const void*
	#define  TEMPLATE_TOKEN                            PIPE_TOKEN_OUT
	#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearOUT()
	#define  TEMPLATE_BUFFER_OFFSET(Length)            (Length - 1)
	#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream -= Amount
197
	#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         Pipe_Write_8(eeprom_read_byte(BufferPtr))
198 199 200 201 202 203 204 205
	#include "Template/Template_Pipe_RW.c"

	#define  TEMPLATE_FUNC_NAME                        Pipe_Read_EStream_LE
	#define  TEMPLATE_BUFFER_TYPE                      void*
	#define  TEMPLATE_TOKEN                            PIPE_TOKEN_IN
	#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearIN()
	#define  TEMPLATE_BUFFER_OFFSET(Length)            0
	#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream += Amount
206
	#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         eeprom_update_byte(BufferPtr, Pipe_Read_8())
207 208 209 210 211 212 213 214
	#include "Template/Template_Pipe_RW.c"

	#define  TEMPLATE_FUNC_NAME                        Pipe_Read_EStream_BE
	#define  TEMPLATE_BUFFER_TYPE                      void*
	#define  TEMPLATE_TOKEN                            PIPE_TOKEN_IN
	#define  TEMPLATE_CLEAR_PIPE()                     Pipe_ClearIN()
	#define  TEMPLATE_BUFFER_OFFSET(Length)            (Length - 1)
	#define  TEMPLATE_BUFFER_MOVE(BufferPtr, Amount)   DataStream -= Amount
215
	#define  TEMPLATE_TRANSFER_BYTE(BufferPtr)         eeprom_update_byte(BufferPtr, Pipe_Read_8())
216 217
	#include "Template/Template_Pipe_RW.c"
#endif
218 219

#endif
220