b095a49c5e73eb49c6cb00f346c074d96a2b27d5
[pub/USBasp.git] / Projects / AVRISP / Lib / PDIProtocol.c
1 /*
2 LUFA Library
3 Copyright (C) Dean Camera, 2009.
4
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
7 */
8
9 /*
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12 Permission to use, copy, modify, and distribute this software
13 and its documentation for any purpose and without fee is hereby
14 granted, provided that the above copyright notice appear in all
15 copies and that both that the copyright notice and this
16 permission notice and warranty disclaimer appear in supporting
17 documentation, and that the name of the author not be used in
18 advertising or publicity pertaining to distribution of the
19 software without specific, written prior permission.
20
21 The author disclaim all warranties with regard to this
22 software, including all implied warranties of merchantability
23 and fitness. In no event shall the author be liable for any
24 special, indirect or consequential damages or any damages
25 whatsoever resulting from loss of use, data or profits, whether
26 in an action of contract, negligence or other tortious action,
27 arising out of or in connection with the use or performance of
28 this software.
29 */
30
31 #if defined(ENABLE_XPROG_PROTOCOL)
32
33 /** \file
34 *
35 * PDI Protocol handler, to process V2 Protocol wrapped PDI commands used in Atmel programmer devices.
36 */
37
38 #define INCLUDE_FROM_XPROG_C
39 #include "PDIProtocol.h"
40
41 uint32_t XPROG_Param_NVMBase;
42 uint32_t XPROG_Param_EEPageSize;
43
44 /** Handler for the CMD_XPROG_SETMODE command, which sets the programmer-to-target protocol used for PDI
45 * XMEGA programming (either PDI or JTAG). Only PDI programming is supported.
46 */
47 void PDIProtocol_XPROG_SetMode(void)
48 {
49 struct
50 {
51 uint8_t Protocol;
52 } SetMode_XPROG_Params;
53
54 Endpoint_Read_Stream_LE(&SetMode_XPROG_Params, sizeof(SetMode_XPROG_Params));
55
56 Endpoint_ClearOUT();
57 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
58
59 Endpoint_Write_Byte(CMD_XPROG_SETMODE);
60 Endpoint_Write_Byte(SetMode_XPROG_Params.Protocol ? STATUS_CMD_FAILED : STATUS_CMD_OK);
61 Endpoint_ClearIN();
62 }
63
64 void PDIProtocol_XPROG_Command(void)
65 {
66 uint8_t XPROGCommand = Endpoint_Read_Byte();
67
68 switch (XPROGCommand)
69 {
70 case XPRG_CMD_ENTER_PROGMODE:
71 PDIProtocol_EnterXPROGMode();
72 break;
73 case XPRG_CMD_LEAVE_PROGMODE:
74 PDIProtocol_LeaveXPROGMode();
75 break;
76 case XPRG_CMD_ERASE:
77 PDIProtocol_EraseChip();
78 break;
79 case XPRG_CMD_WRITE_MEM:
80 PDIProtocol_WriteMemory();
81 break;
82 case XPRG_CMD_READ_MEM:
83 PDIProtocol_ReadMemory();
84 break;
85 case XPRG_CMD_CRC:
86 PDIProtocol_ReadCRC();
87 break;
88 case XPRG_CMD_SET_PARAM:
89 PDIProtocol_SetParam();
90 break;
91 }
92 }
93
94 static void PDIProtocol_EraseChip(void)
95 {
96 uint8_t ReturnStatus = XPRG_ERR_OK;
97
98 struct
99 {
100 uint8_t MemoryType;
101 uint32_t Address;
102 } Erase_XPROG_Params;
103
104 Endpoint_Read_Stream_LE(&Erase_XPROG_Params, sizeof(Erase_XPROG_Params));
105
106 Endpoint_ClearOUT();
107 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
108
109 // TODO: Send erase command here via PDI protocol
110
111 Endpoint_Write_Byte(CMD_XPROG);
112 Endpoint_Write_Byte(XPRG_CMD_ERASE);
113 Endpoint_Write_Byte(ReturnStatus);
114 Endpoint_ClearIN();
115 }
116
117 static void PDIProtocol_WriteMemory(void)
118 {
119 uint8_t ReturnStatus = XPRG_ERR_OK;
120
121 struct
122 {
123 uint8_t MemoryType;
124 uint32_t Address;
125 uint16_t Length;
126 uint8_t ProgData[256];
127 } WriteMemory_XPROG_Params;
128
129 Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params, (sizeof(WriteMemory_XPROG_Params) -
130 sizeof(WriteMemory_XPROG_Params).ProgData));
131 WriteMemory_XPROG_Params.Address = SwapEndian_32(WriteMemory_XPROG_Params.Address);
132 WriteMemory_XPROG_Params.Length = SwapEndian_16(WriteMemory_XPROG_Params.Length);
133 Endpoint_Read_Stream_LE(&WriteMemory_XPROG_Params.ProgData, WriteMemory_XPROG_Params.Length);
134
135 Endpoint_ClearOUT();
136 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
137
138 // TODO: Send program command here via PDI protocol
139
140 Endpoint_Write_Byte(CMD_XPROG);
141 Endpoint_Write_Byte(XPRG_CMD_READ_MEM);
142 Endpoint_Write_Byte(ReturnStatus);
143 Endpoint_ClearIN();
144 }
145
146 static void PDIProtocol_ReadMemory(void)
147 {
148 uint8_t ReturnStatus = XPRG_ERR_OK;
149
150 struct
151 {
152 uint8_t MemoryType;
153 uint32_t Address;
154 uint16_t Length;
155 } ReadMemory_XPROG_Params;
156
157 Endpoint_Read_Stream_LE(&ReadMemory_XPROG_Params, sizeof(ReadMemory_XPROG_Params));
158 ReadMemory_XPROG_Params.Address = SwapEndian_32(ReadMemory_XPROG_Params.Address);
159 ReadMemory_XPROG_Params.Length = SwapEndian_16(ReadMemory_XPROG_Params.Length);
160
161 Endpoint_ClearOUT();
162 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
163
164 // TODO: Send read command here via PDI protocol
165
166 Endpoint_Write_Byte(CMD_XPROG);
167 Endpoint_Write_Byte(XPRG_CMD_READ_MEM);
168 Endpoint_Write_Byte(ReturnStatus);
169
170 // START TEMP
171 uint8_t ProgData[256];
172 for (uint16_t i = 0; i < ReadMemory_XPROG_Params.Length; i++)
173 ProgData[i] = i;
174 Endpoint_Write_Stream_LE(ProgData, ReadMemory_XPROG_Params.Length);
175
176 if (!Endpoint_IsReadWriteAllowed())
177 {
178 Endpoint_ClearIN();
179 while(!(Endpoint_IsReadWriteAllowed()));
180 }
181 // END TEMP
182
183 Endpoint_ClearIN();
184 }
185
186 static void PDIProtocol_ReadCRC(void)
187 {
188 uint8_t ReturnStatus = XPRG_ERR_OK;
189
190 uint8_t CRCType = Endpoint_Read_Byte();
191
192 Endpoint_ClearOUT();
193 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
194
195 uint32_t MemoryCRC = 0;
196
197 // TODO: Read device CRC for desired memory via PDI protocol
198
199 Endpoint_Write_Byte(CMD_XPROG);
200 Endpoint_Write_Byte(XPRG_CMD_CRC);
201 Endpoint_Write_Byte(ReturnStatus);
202
203 if (ReturnStatus == XPRG_ERR_OK)
204 {
205 Endpoint_Write_Byte(MemoryCRC >> 16);
206 Endpoint_Write_Word_LE(MemoryCRC & 0xFFFF);
207 }
208
209 Endpoint_ClearIN();
210 }
211
212 static void PDIProtocol_EnterXPROGMode(void)
213 {
214 uint8_t ReturnStatus = XPRG_ERR_OK;
215
216 Endpoint_ClearOUT();
217 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
218
219 // TODO: Enter device programming mode here via PDI protocol
220
221 Endpoint_Write_Byte(CMD_XPROG);
222 Endpoint_Write_Byte(XPRG_CMD_ENTER_PROGMODE);
223 Endpoint_Write_Byte(ReturnStatus);
224 Endpoint_ClearIN();
225 }
226
227 static void PDIProtocol_LeaveXPROGMode(void)
228 {
229 Endpoint_ClearOUT();
230 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
231
232 // TODO: Exit device programming mode here via PDI protocol
233
234 Endpoint_Write_Byte(CMD_XPROG);
235 Endpoint_Write_Byte(XPRG_CMD_LEAVE_PROGMODE);
236 Endpoint_Write_Byte(XPRG_ERR_OK);
237 Endpoint_ClearIN();
238 }
239
240 static void PDIProtocol_SetParam(void)
241 {
242 uint8_t ReturnStatus = XPRG_ERR_OK;
243
244 uint8_t XPROGParam = Endpoint_Read_Byte();
245
246 if (XPROGParam == XPRG_PARAM_NVMBASE)
247 XPROG_Param_NVMBase = Endpoint_Read_DWord_LE();
248 else if (XPROGParam == XPRG_PARAM_EEPPAGESIZE)
249 XPROG_Param_EEPageSize = Endpoint_Read_Word_LE();
250 else
251 ReturnStatus = XPRG_ERR_FAILED;
252
253 Endpoint_ClearOUT();
254 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
255
256 Endpoint_Write_Byte(CMD_XPROG);
257 Endpoint_Write_Byte(XPRG_CMD_SET_PARAM);
258 Endpoint_Write_Byte(ReturnStatus);
259 Endpoint_ClearIN();
260 }
261
262 #endif