V2Protocol.c 6.02 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
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
/*
             LUFA Library
     Copyright (C) Dean Camera, 2009.
              
  dean [at] fourwalledcubicle [dot] com
      www.fourwalledcubicle.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.
*/

/** \file
 *
 *  V2Protocol handler, to process V2 Protocol commands used in Atmel programmer devices.
 */

36
#define  INCLUDE_FROM_V2PROTOCOL_C
37
#include "V2Protocol.h"
38

39
40
41
uint32_t CurrentAddress;


42
/* Table of masks for SPI_Init() from a given PARAM_SCK_DURATION value */
43
static const uint8_t SPIMaskFromSCKDuration[MAX_SPI_SETTINGS] =
44
45
46
47
48
49
50
51
52
53
54
55
	{
		#if (F_CPU == 8000000)
		SPI_SPEED_FCPU_DIV_2,
		#endif
		SPI_SPEED_FCPU_DIV_2, SPI_SPEED_FCPU_DIV_4, SPI_SPEED_FCPU_DIV_8,
		SPI_SPEED_FCPU_DIV_16, SPI_SPEED_FCPU_DIV_32, SPI_SPEED_FCPU_DIV_64
		#if (F_CPU == 16000000)										
		, SPI_SPEED_FCPU_DIV_128
		#endif
	};

static void V2Protocol_ReconfigureSPI(void)
56
{
57
	uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION);
58

59
60
	if (SCKDuration >= MAX_SPI_SETTINGS)
	  SCKDuration = (MAX_SPI_SETTINGS - 1);
61
62
63
	  
	SPI_Init(SPIMaskFromSCKDuration[SCKDuration], true);	
}
64
65
66
67
68
69
70

static void V2Protocol_ChangeTargetResetLine(bool ResetTarget)
{
	if (ResetTarget)
	{
		RESET_LINE_DDR  |= RESET_LINE_MASK;
		
71
		if (!(V2Params_GetParameterValue(PARAM_RESET_POLARITY)))
72
73
74
75
76
77
78
79
		  RESET_LINE_PORT |= RESET_LINE_MASK;
	}
	else
	{
		RESET_LINE_PORT &= ~RESET_LINE_MASK;	
		RESET_LINE_DDR  &= ~RESET_LINE_MASK;
	}
}
80
81
82
83

void V2Protocol_ProcessCommand(void)
{
	uint8_t V2Command = Endpoint_Read_Byte();
84
		  
85
86
87
	switch (V2Command)
	{
		case CMD_SIGN_ON:
88
			V2Protocol_Command_SignOn();
89
90
91
			break;
		case CMD_SET_PARAMETER:
		case CMD_GET_PARAMETER:
92
			V2Protocol_Command_GetSetParam(V2Command);
93
			break;
94
95
96
		case CMD_LOAD_ADDRESS:
			V2Protocol_Command_LoadAddress();
			break;
97
		case CMD_SPI_MULTI:
98
			V2Protocol_Command_SPIMulti();
99
			break;		
100
		default:
101
			V2Protocol_Command_Unknown(V2Command);
102
			break;
103
104
	}
	
105
106
	printf("COMMAND 0x%02x\r\n", V2Command);

107
	Endpoint_WaitUntilReady();	
108
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);	
109
}
110

111
static void V2Protocol_Command_Unknown(uint8_t V2Command)
112
113
{
	/* Discard all incomming data */
114
	while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)
115
	{
116
		Endpoint_ClearOUT();
117
		Endpoint_WaitUntilReady();
118
	}
119
120
121

	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
122
	Endpoint_WaitUntilReady();
123
124
125
126
127

	Endpoint_Write_Byte(V2Command);
	Endpoint_Write_Byte(STATUS_CMD_UNKNOWN);
	Endpoint_ClearIN();
}
128

129
static void V2Protocol_Command_SignOn(void)
130
131
132
{
	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
133
134
	Endpoint_WaitUntilReady();

135
	V2Protocol_ReconfigureSPI();
136
	CurrentAddress = 0;
137

138
139
140
141
142
143
144
	Endpoint_Write_Byte(CMD_SIGN_ON);
	Endpoint_Write_Byte(STATUS_CMD_OK);
	Endpoint_Write_Byte(PROGRAMMER_ID_LEN);
	Endpoint_Write_Stream_LE(PROGRAMMER_ID, PROGRAMMER_ID_LEN);
	Endpoint_ClearIN();
}

145
static void V2Protocol_Command_GetSetParam(uint8_t V2Command)
146
147
148
149
150
151
{
	uint8_t ParamID    = Endpoint_Read_Byte();
	uint8_t ParamValue = Endpoint_Read_Byte();

	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
152
153
	Endpoint_WaitUntilReady();
	
154
155
	uint8_t ParamPrivs = V2Params_GetParameterPrivellages(ParamID);
	
156
	Endpoint_Write_Byte(V2Command);
157
158
159
160
161
162
163
164
165
166
167
	
	if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE))
	{
		Endpoint_Write_Byte(STATUS_CMD_OK);
		V2Params_SetParameterValue(ParamID, ParamValue);
	}
	else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ))
	{
		Endpoint_Write_Byte(STATUS_CMD_OK);
		Endpoint_Write_Byte(V2Params_GetParameterValue(ParamID));
	}
168
	else
169
170
171
	{	
		Endpoint_Write_Byte(STATUS_CMD_FAILED);
	}
172

173
	Endpoint_ClearIN();
174
}
175

176
177
178
179
180
181
182
183
184
185
186
187
188
static void V2Protocol_Command_LoadAddress(void)
{
	CurrentAddress = Endpoint_Read_DWord_LE();

	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
	Endpoint_WaitUntilReady();

	Endpoint_Write_Byte(CMD_LOAD_ADDRESS);
	Endpoint_Write_Byte(STATUS_CMD_OK);
	Endpoint_ClearIN();
}

189
static void V2Protocol_Command_SPIMulti(void)
190
{
191
192
	uint8_t TxBytes     = Endpoint_Read_Byte();
	uint8_t RxBytes     = Endpoint_Read_Byte();
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
	uint8_t RxStartAddr = Endpoint_Read_Byte();
	uint8_t TxData[255];
	
	Endpoint_Read_Stream_LE(TxData, TxBytes);
	
	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
	Endpoint_WaitUntilReady();
	
	Endpoint_Write_Byte(CMD_SPI_MULTI);
	Endpoint_Write_Byte(STATUS_CMD_OK);

	uint8_t CurrTxPos = 0;
	uint8_t CurrRxPos = 0;

208
	/* Write out bytes to transmit until the start of the bytes to receive is met */
209
210
211
212
213
214
215
216
217
218
	while (CurrTxPos < RxStartAddr)
	{
		if (CurrTxPos < TxBytes)
		  SPI_SendByte(TxData[CurrTxPos]);
		else
		  SPI_SendByte(0);
		
		CurrTxPos++;
	}

219
	/* Transmit remaining bytes with padding as needed, read in response bytes */
220
221
222
	while (CurrRxPos < RxBytes)
	{
		if (CurrTxPos < TxBytes)
223
		  Endpoint_Write_Byte(SPI_TransferByte(TxData[CurrTxPos++]));
224
		else
225
		  Endpoint_Write_Byte(SPI_ReceiveByte());
226
227
228
229
230
231
232
		
		CurrRxPos++;
	}	
	
	Endpoint_Write_Byte(STATUS_CMD_OK);
	Endpoint_ClearIN();	
}