dfa27ad9e83d3b6f3710f7a8c4b36bd29eb86c37
[pub/USBasp.git] / Projects / Unfinished / AVRISP / Lib / V2Protocol.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 /** \file
32 *
33 * V2Protocol handler, to process V2 Protocol commands used in Atmel programmer devices.
34 */
35
36 #define INCLUDE_FROM_V2PROTOCOL_C
37 #include "V2Protocol.h"
38
39 /* Table of masks for SPI_Init() from a given PARAM_SCK_DURATION value */
40 static const uint8_t SPIMaskFromSCKDuration[MAX_SPI_SETTINGS] =
41 {
42 #if (F_CPU == 8000000)
43 SPI_SPEED_FCPU_DIV_2,
44 #endif
45 SPI_SPEED_FCPU_DIV_2, SPI_SPEED_FCPU_DIV_4, SPI_SPEED_FCPU_DIV_8,
46 SPI_SPEED_FCPU_DIV_16, SPI_SPEED_FCPU_DIV_32, SPI_SPEED_FCPU_DIV_64
47 #if (F_CPU == 16000000)
48 , SPI_SPEED_FCPU_DIV_128
49 #endif
50 };
51
52 static void V2Protocol_ReconfigureSPI(void)
53 {
54 uint8_t SCKDuration = V2Params_GetParameterValue(PARAM_SCK_DURATION);
55
56 if (SCKDuration >= MAX_SPI_SETTINGS)
57 SCKDuration = (MAX_SPI_SETTINGS - 1);
58
59 SPI_Init(SPIMaskFromSCKDuration[SCKDuration], true);
60 }
61
62 static void V2Protocol_ChangeTargetResetLine(bool ResetTarget)
63 {
64 if (ResetTarget)
65 {
66 RESET_LINE_DDR |= RESET_LINE_MASK;
67
68 if (!(V2Params_GetParameterValue(PARAM_RESET_POLARITY)))
69 RESET_LINE_PORT |= RESET_LINE_MASK;
70 }
71 else
72 {
73 RESET_LINE_PORT &= ~RESET_LINE_MASK;
74 RESET_LINE_DDR &= ~RESET_LINE_MASK;
75 }
76 }
77
78 void V2Protocol_ProcessCommand(void)
79 {
80 uint8_t V2Command = Endpoint_Read_Byte();
81
82 switch (V2Command)
83 {
84 case CMD_SIGN_ON:
85 V2Protocol_Command_SignOn();
86 break;
87 case CMD_SET_PARAMETER:
88 case CMD_GET_PARAMETER:
89 V2Protocol_Command_GetSetParam(V2Command);
90 break;
91 case CMD_SPI_MULTI:
92 V2Protocol_Command_SPIMulti();
93 break;
94 default:
95 V2Protocol_Command_Unknown(V2Command);
96 break;
97 }
98
99 printf("COMMAND 0x%02x\r\n", V2Command);
100
101 Endpoint_WaitUntilReady();
102 Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
103 }
104
105 static void V2Protocol_Command_Unknown(uint8_t V2Command)
106 {
107 /* Discard all incomming data */
108 while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)
109 {
110 Endpoint_ClearOUT();
111 Endpoint_WaitUntilReady();
112 }
113
114 Endpoint_ClearOUT();
115 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
116 Endpoint_WaitUntilReady();
117
118 Endpoint_Write_Byte(V2Command);
119 Endpoint_Write_Byte(STATUS_CMD_UNKNOWN);
120 Endpoint_ClearIN();
121 }
122
123 static void V2Protocol_Command_SignOn(void)
124 {
125 Endpoint_ClearOUT();
126 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
127 Endpoint_WaitUntilReady();
128
129 V2Protocol_ReconfigureSPI();
130
131 Endpoint_Write_Byte(CMD_SIGN_ON);
132 Endpoint_Write_Byte(STATUS_CMD_OK);
133 Endpoint_Write_Byte(PROGRAMMER_ID_LEN);
134 Endpoint_Write_Stream_LE(PROGRAMMER_ID, PROGRAMMER_ID_LEN);
135 Endpoint_ClearIN();
136 }
137
138 static void V2Protocol_Command_GetSetParam(uint8_t V2Command)
139 {
140 uint8_t ParamID = Endpoint_Read_Byte();
141 uint8_t ParamValue = Endpoint_Read_Byte();
142
143 Endpoint_ClearOUT();
144 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
145 Endpoint_WaitUntilReady();
146
147 uint8_t ParamPrivs = V2Params_GetParameterPrivellages(ParamID);
148
149 Endpoint_Write_Byte(V2Command);
150
151 if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE))
152 {
153 Endpoint_Write_Byte(STATUS_CMD_OK);
154 V2Params_SetParameterValue(ParamID, ParamValue);
155 }
156 else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ))
157 {
158 Endpoint_Write_Byte(STATUS_CMD_OK);
159 Endpoint_Write_Byte(V2Params_GetParameterValue(ParamID));
160 }
161 else
162 {
163 Endpoint_Write_Byte(STATUS_CMD_FAILED);
164 }
165
166 Endpoint_ClearIN();
167 }
168
169 static void V2Protocol_Command_SPIMulti(void)
170 {
171 uint8_t TxBytes = Endpoint_Read_Byte();
172 uint8_t RxBytes = Endpoint_Read_Byte();
173 uint8_t RxStartAddr = Endpoint_Read_Byte();
174 uint8_t TxData[255];
175
176 Endpoint_Read_Stream_LE(TxData, TxBytes);
177
178 Endpoint_ClearOUT();
179 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
180 Endpoint_WaitUntilReady();
181
182 Endpoint_Write_Byte(CMD_SPI_MULTI);
183 Endpoint_Write_Byte(STATUS_CMD_OK);
184
185 uint8_t CurrTxPos = 0;
186 uint8_t CurrRxPos = 0;
187
188 /* Write out bytes to transmit until the start of the bytes to receive is met */
189 while (CurrTxPos < RxStartAddr)
190 {
191 if (CurrTxPos < TxBytes)
192 SPI_SendByte(TxData[CurrTxPos]);
193 else
194 SPI_SendByte(0);
195
196 CurrTxPos++;
197 }
198
199 /* Transmit remaining bytes with padding as needed, read in response bytes */
200 while (CurrRxPos < RxBytes)
201 {
202 if (CurrTxPos < TxBytes)
203 Endpoint_Write_Byte(SPI_TransferByte(TxData[CurrTxPos++]));
204 else
205 Endpoint_Write_Byte(SPI_ReceiveByte());
206
207 CurrRxPos++;
208 }
209
210 Endpoint_Write_Byte(STATUS_CMD_OK);
211 Endpoint_ClearIN();
212 }