3 Copyright (C) Dean Camera, 2009.
5 dean [at] fourwalledcubicle [dot] com
6 www.fourwalledcubicle.com
10 Copyright 2009 Dean Camera (dean [at] fourwalledcubicle [dot] com)
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.
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
33 * V2Protocol handler, to process V2 Protocol commands used in Atmel programmer devices.
36 #define INCLUDE_FROM_V2PROTOCOL_C
37 #include "V2Protocol.h"
39 /* Table of masks for SPI_Init() from a given PARAM_SCK_DURATION value */
40 static const uint8_t SPIMaskFromSCKDuration
[] =
42 #if (F_CPU == 8000000)
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
52 /* Non-Volatile Parameter Values for EEPROM storage */
53 uint8_t EEMEM EEPROM_Rest_Polarity
;
55 /* Volatile Parameter Values for RAM storage */
56 static ParameterItem_t ParameterTable
[] =
58 { .ParameterID
= PARAM_BUILD_NUMBER_LOW
,
59 .ParameterValue
= (LUFA_VERSION_INTEGER
>> 8) },
60 { .ParameterID
= PARAM_BUILD_NUMBER_HIGH
,
61 .ParameterValue
= (LUFA_VERSION_INTEGER
& 0xFF) },
62 { .ParameterID
= PARAM_HW_VER
,
63 .ParameterValue
= 0x01 },
64 { .ParameterID
= PARAM_SW_MAJOR
,
65 .ParameterValue
= 0x01 },
66 { .ParameterID
= PARAM_SW_MINOR
,
67 .ParameterValue
= 0x00 },
68 { .ParameterID
= PARAM_VTARGET
,
69 .ParameterValue
= 0x00 },
70 { .ParameterID
= PARAM_SCK_DURATION
,
71 .ParameterValue
= sizeof(SPIMaskFromSCKDuration
) },
72 { .ParameterID
= PARAM_RESET_POLARITY
,
73 .ParameterValue
= 0x01 },
74 { .ParameterID
= PARAM_STATUS_TGT_CONN
,
75 .ParameterValue
= 0x00 },
76 { .ParameterID
= PARAM_DISCHARGEDELAY
,
77 .ParameterValue
= 0x00 },
81 static void V2Protocol_ReconfigureSPI(void)
83 uint8_t SCKDuration
= V2Protocol_GetParameter(PARAM_SCK_DURATION
);
85 if (SCKDuration
>= sizeof(SPIMaskFromSCKDuration
))
86 SCKDuration
= (sizeof(SPIMaskFromSCKDuration
) - 1);
88 SPI_Init(SPIMaskFromSCKDuration
[SCKDuration
], true);
91 static void V2Protocol_ChangeTargetResetLine(bool ResetTarget
)
95 RESET_LINE_DDR
|= RESET_LINE_MASK
;
97 if (!(V2Protocol_GetParameter(PARAM_RESET_POLARITY
)))
98 RESET_LINE_PORT
|= RESET_LINE_MASK
;
102 RESET_LINE_PORT
&= ~RESET_LINE_MASK
;
103 RESET_LINE_DDR
&= ~RESET_LINE_MASK
;
107 static uint8_t V2Protocol_GetParameter(uint8_t ParamID
)
109 /* Find the parameter in the parameter table and retrieve the value */
110 for (uint8_t TableIndex
= 0; TableIndex
< (sizeof(ParameterTable
) / sizeof(ParameterTable
[0])); TableIndex
++)
112 if (ParamID
== ParameterTable
[TableIndex
].ParameterID
)
113 return ParameterTable
[TableIndex
].ParameterValue
;
119 static void V2Protocol_SetParameter(uint8_t ParamID
, uint8_t Value
)
121 /* The target RESET line polarity is a non-volatile parameter, save to EEPROM when changed */
122 if (ParamID
== PARAM_RESET_POLARITY
)
123 eeprom_write_byte(&EEPROM_Rest_Polarity
, Value
);
125 /* Find the parameter in the parameter table and store the new value */
126 for (uint8_t TableIndex
= 0; TableIndex
< (sizeof(ParameterTable
) / sizeof(ParameterTable
[0])); TableIndex
++)
128 if (ParamID
== ParameterTable
[TableIndex
].ParameterID
)
130 ParameterTable
[TableIndex
].ParameterValue
= Value
;
136 void V2Protocol_Init(void)
138 /* Target RESET line polarity is a non-volatile value, retrieve current parameter value from EEPROM */
139 V2Protocol_SetParameter(PARAM_RESET_POLARITY
, eeprom_read_byte(&EEPROM_Rest_Polarity
));
142 void V2Protocol_ProcessCommand(void)
144 uint8_t V2Command
= Endpoint_Read_Byte();
149 V2Protocol_Command_SignOn();
151 case CMD_SET_PARAMETER
:
152 case CMD_GET_PARAMETER
:
153 V2Protocol_Command_GetSetParam(V2Command
);
156 V2Protocol_Command_SPIMulti();
159 V2Protocol_Command_Unknown(V2Command
);
163 printf("COMMAND 0x%02x\r\n", V2Command
);
165 Endpoint_WaitUntilReady();
166 Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT
);
169 static void V2Protocol_Command_Unknown(uint8_t V2Command
)
171 while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE
)
174 while (!(Endpoint_IsOUTReceived()));
178 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN
);
180 Endpoint_Write_Byte(V2Command
);
181 Endpoint_Write_Byte(STATUS_CMD_UNKNOWN
);
185 static void V2Protocol_Command_SignOn(void)
188 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN
);
189 Endpoint_WaitUntilReady();
191 V2Protocol_ReconfigureSPI();
193 Endpoint_Write_Byte(CMD_SIGN_ON
);
194 Endpoint_Write_Byte(STATUS_CMD_OK
);
195 Endpoint_Write_Byte(PROGRAMMER_ID_LEN
);
196 Endpoint_Write_Stream_LE(PROGRAMMER_ID
, PROGRAMMER_ID_LEN
);
200 static void V2Protocol_Command_GetSetParam(uint8_t V2Command
)
202 uint8_t ParamID
= Endpoint_Read_Byte();
203 uint8_t ParamValue
= Endpoint_Read_Byte();
206 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN
);
207 Endpoint_WaitUntilReady();
209 Endpoint_Write_Byte(V2Command
);
210 Endpoint_Write_Byte(STATUS_CMD_OK
);
212 if (V2Command
== CMD_SET_PARAMETER
)
213 V2Protocol_SetParameter(ParamID
, ParamValue
);
215 Endpoint_Write_Byte(V2Protocol_GetParameter(ParamID
));
220 static void V2Protocol_Command_SPIMulti(void)
222 uint8_t TxBytes
= Endpoint_Read_Byte();
223 uint8_t RxBytes
= Endpoint_Read_Byte();
224 uint8_t RxStartAddr
= Endpoint_Read_Byte();
227 Endpoint_Read_Stream_LE(TxData
, TxBytes
);
230 Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN
);
231 Endpoint_WaitUntilReady();
233 Endpoint_Write_Byte(CMD_SPI_MULTI
);
234 Endpoint_Write_Byte(STATUS_CMD_OK
);
236 uint8_t CurrTxPos
= 0;
237 uint8_t CurrRxPos
= 0;
239 while (CurrTxPos
< RxStartAddr
)
241 if (CurrTxPos
< TxBytes
)
242 SPI_SendByte(TxData
[CurrTxPos
]);
249 while (CurrRxPos
< RxBytes
)
251 if (CurrTxPos
< TxBytes
)
252 Endpoint_Write_Byte(SPI_TransferByte(TxData
[CurrTxPos
++]));
254 Endpoint_Write_Byte(SPI_ReceiveByte());
259 Endpoint_Write_Byte(STATUS_CMD_OK
);