V2Protocol.c 6.37 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
42
43
44
45
/** Current memory address for FLASH/EEPROM memory read/write commands */
uint32_t CurrentAddress;

/** Flag to indicate that the next read/write operation must update the device's current address */
bool MustSetAddress;


46
/** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.
47
48
49
 *  This routine decodes the issued command and passes off the handling of the command to the
 *  appropriate function.
 */
50
51
void V2Protocol_ProcessCommand(void)
{
52
	uint8_t V2Command = Endpoint_Read_Byte();
53
		  
54
55
56
	switch (V2Command)
	{
		case CMD_SIGN_ON:
57
			V2Protocol_SignOn();
58
59
60
			break;
		case CMD_SET_PARAMETER:
		case CMD_GET_PARAMETER:
61
			V2Protocol_GetSetParam(V2Command);
62
			break;
63
		case CMD_LOAD_ADDRESS:
64
			V2Protocol_LoadAddress();
65
			break;
66
		case CMD_RESET_PROTECTION:
67
			V2Protocol_ResetProtection();
68
			break;
69
#if defined(ENABLE_ISP_PROTOCOL)
70
		case CMD_ENTER_PROGMODE_ISP:
71
			ISPProtocol_EnterISPMode();
72
73
			break;
		case CMD_LEAVE_PROGMODE_ISP:
74
			ISPProtocol_LeaveISPMode();
75
			break;
76
77
		case CMD_PROGRAM_FLASH_ISP:
		case CMD_PROGRAM_EEPROM_ISP:
78
			ISPProtocol_ProgramMemory(V2Command);			
79
80
81
			break;
		case CMD_READ_FLASH_ISP:
		case CMD_READ_EEPROM_ISP:
82
			ISPProtocol_ReadMemory(V2Command);
83
			break;
84
		case CMD_CHIP_ERASE_ISP:
85
			ISPProtocol_ChipErase();
86
87
88
89
90
			break;
		case CMD_READ_FUSE_ISP:
		case CMD_READ_LOCK_ISP:
		case CMD_READ_SIGNATURE_ISP:
		case CMD_READ_OSCCAL_ISP:
91
			ISPProtocol_ReadFuseLockSigOSCCAL(V2Command);
92
93
94
			break;
		case CMD_PROGRAM_FUSE_ISP:
		case CMD_PROGRAM_LOCK_ISP:
95
			ISPProtocol_WriteFuseLock(V2Command);
96
			break;
97
		case CMD_SPI_MULTI:
98
			ISPProtocol_SPIMulti();
99
			break;
100
#endif
101
#if defined(ENABLE_PDI_PROTOCOL)
102
103
104
105
106
107
108
		case CMD_XPROG_SETMODE:
			PDIProtocol_XPROG_SetMode();
			break;
		case CMD_XPROG:
			PDIProtocol_XPROG_Command();
			break;
#endif
109
		default:
110
			V2Protocol_UnknownCommand(V2Command);
111
			break;
112
113
	}
	
114
	Endpoint_WaitUntilReady();
115
116
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
}
117

118
119
120
/** Handler for unknown V2 protocol commands. This discards all sent data and returns a
 *  STATUS_CMD_UNKNOWN status back to the host.
 *
121
 *  \param[in] V2Command  Issued V2 Protocol command byte from the host
122
 */
123
static void V2Protocol_UnknownCommand(const uint8_t V2Command)
124
{
125
	/* Discard all incoming data */
126
	while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)
127
	{
128
		Endpoint_ClearOUT();
129
		Endpoint_WaitUntilReady();
130
	}
131
132
133
134
135
136
137
138

	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);

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

140
/** Handler for the CMD_SIGN_ON command, returning the programmer ID string to the host. */
141
static void V2Protocol_SignOn(void)
142
143
144
{
	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
145

146
147
	Endpoint_Write_Byte(CMD_SIGN_ON);
	Endpoint_Write_Byte(STATUS_CMD_OK);
148
149
	Endpoint_Write_Byte(sizeof(PROGRAMMER_ID) - 1);
	Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1));
150
151
152
	Endpoint_ClearIN();
}

153
154
155
156
157
158
159
160
161
162
163
164
165
166
/** Handler for the CMD_RESET_PROTECTION command, currently implemented as a dummy ACK function
 *  as no ISP short-circuit protection is currently implemented.
 */
static void V2Protocol_ResetProtection(void)
{
	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
	
	Endpoint_Write_Byte(CMD_RESET_PROTECTION);
	Endpoint_Write_Byte(STATUS_CMD_OK);
	Endpoint_ClearIN();	
}


167
168
169
/** Handler for the CMD_SET_PARAMETER and CMD_GET_PARAMETER commands from the host, setting or
 *  getting a device parameter's value from the parameter table.
 *
170
 *  \param[in] V2Command  Issued V2 Protocol command byte from the host
171
 */
172
static void V2Protocol_GetSetParam(const uint8_t V2Command)
173
{
174
175
	uint8_t ParamID = Endpoint_Read_Byte();
	uint8_t ParamValue;
176
	
177
178
	if (V2Command == CMD_SET_PARAMETER)
	  ParamValue = Endpoint_Read_Byte();
179
180
181

	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
182
	
183
	Endpoint_Write_Byte(V2Command);
184
	
185
	uint8_t ParamPrivs = V2Params_GetParameterPrivileges(ParamID);
186
	
187
188
189
	if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE))
	{
		Endpoint_Write_Byte(STATUS_CMD_OK);
190
		V2Params_SetParameterValue(ParamID, ParamValue);
191
192
193
194
	}
	else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ))
	{
		Endpoint_Write_Byte(STATUS_CMD_OK);
195
		Endpoint_Write_Byte(V2Params_GetParameterValue(ParamID));
196
	}
197
	else
198
199
200
	{	
		Endpoint_Write_Byte(STATUS_CMD_FAILED);
	}
201

202
	Endpoint_ClearIN();
203
}
204

205
206
207
208
/** Handler for the CMD_LOAD_ADDRESS command, loading the given device address into a
 *  global storage variable for later use, and issuing LOAD EXTENDED ADDRESS commands
 *  to the attached device as required.
 */
209
static void V2Protocol_LoadAddress(void)
210
{
211
	Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress));
212
213
214

	Endpoint_ClearOUT();
	Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
215
	
216
	MustSetAddress = true;
217
218
219
220
221

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