]> git.donarmstrong.com Git - qmk_firmware.git/blob - protocol/lufa/LUFA-git/Projects/AVRISP-MKII/Lib/V2Protocol.c
Squashed 'tmk_core/' changes from caca2c0..dc0e46e
[qmk_firmware.git] / protocol / lufa / LUFA-git / Projects / AVRISP-MKII / Lib / V2Protocol.c
1 /*
2              LUFA Library
3      Copyright (C) Dean Camera, 2014.
4
5   dean [at] fourwalledcubicle [dot] com
6            www.lufa-lib.org
7 */
8
9 /*
10   Copyright 2014  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11
12   Permission to use, copy, modify, distribute, and sell this
13   software and its documentation for any purpose is hereby granted
14   without fee, provided that the above copyright notice appear in
15   all 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 disclaims 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 /** Current memory address for FLASH/EEPROM memory read/write commands */
40 uint32_t CurrentAddress;
41
42 /** Flag to indicate that the next read/write operation must update the device's current extended FLASH address */
43 bool MustLoadExtendedAddress;
44
45
46 /** ISR to manage timeouts whilst processing a V2Protocol command */
47 ISR(TIMER0_COMPA_vect, ISR_NOBLOCK)
48 {
49         if (TimeoutTicksRemaining)
50           TimeoutTicksRemaining--;
51         else
52           TCCR0B = 0;
53 }
54
55 /** Initializes the hardware and software associated with the V2 protocol command handling. */
56 void V2Protocol_Init(void)
57 {
58         #if defined(ADC) && !defined(NO_VTARGET_DETECT)
59         /* Initialize the ADC converter for VTARGET level detection on supported AVR models */
60         ADC_Init(ADC_FREE_RUNNING | ADC_PRESCALE_128);
61         ADC_SetupChannel(VTARGET_ADC_CHANNEL);
62         ADC_StartReading(VTARGET_REF_MASK | ADC_RIGHT_ADJUSTED | VTARGET_ADC_CHANNEL_MASK);
63         #endif
64
65         /* Timeout timer initialization (~10ms period) */
66         OCR0A  = (((F_CPU / 1024) / 100) - 1);
67         TCCR0A = (1 << WGM01);
68         TIMSK0 = (1 << OCIE0A);
69
70         V2Params_LoadNonVolatileParamValues();
71
72         #if defined(ENABLE_ISP_PROTOCOL)
73         ISPTarget_ConfigureRescueClock();
74         #endif
75 }
76
77 /** Master V2 Protocol packet handler, for received V2 Protocol packets from a connected host.
78  *  This routine decodes the issued command and passes off the handling of the command to the
79  *  appropriate function.
80  */
81 void V2Protocol_ProcessCommand(void)
82 {
83         uint8_t V2Command = Endpoint_Read_8();
84
85         /* Reset timeout counter duration and start the timer */
86         TimeoutTicksRemaining = COMMAND_TIMEOUT_TICKS;
87         TCCR0B = ((1 << CS02) | (1 << CS00));
88
89         switch (V2Command)
90         {
91                 case CMD_SIGN_ON:
92                         V2Protocol_SignOn();
93                         break;
94                 case CMD_SET_PARAMETER:
95                 case CMD_GET_PARAMETER:
96                         V2Protocol_GetSetParam(V2Command);
97                         break;
98                 case CMD_LOAD_ADDRESS:
99                         V2Protocol_LoadAddress();
100                         break;
101                 case CMD_RESET_PROTECTION:
102                         V2Protocol_ResetProtection();
103                         break;
104 #if defined(ENABLE_ISP_PROTOCOL)
105                 case CMD_ENTER_PROGMODE_ISP:
106                         ISPProtocol_EnterISPMode();
107                         break;
108                 case CMD_LEAVE_PROGMODE_ISP:
109                         ISPProtocol_LeaveISPMode();
110                         break;
111                 case CMD_PROGRAM_FLASH_ISP:
112                 case CMD_PROGRAM_EEPROM_ISP:
113                         ISPProtocol_ProgramMemory(V2Command);
114                         break;
115                 case CMD_READ_FLASH_ISP:
116                 case CMD_READ_EEPROM_ISP:
117                         ISPProtocol_ReadMemory(V2Command);
118                         break;
119                 case CMD_CHIP_ERASE_ISP:
120                         ISPProtocol_ChipErase();
121                         break;
122                 case CMD_READ_FUSE_ISP:
123                 case CMD_READ_LOCK_ISP:
124                 case CMD_READ_SIGNATURE_ISP:
125                 case CMD_READ_OSCCAL_ISP:
126                         ISPProtocol_ReadFuseLockSigOSCCAL(V2Command);
127                         break;
128                 case CMD_PROGRAM_FUSE_ISP:
129                 case CMD_PROGRAM_LOCK_ISP:
130                         ISPProtocol_WriteFuseLock(V2Command);
131                         break;
132                 case CMD_SPI_MULTI:
133                         ISPProtocol_SPIMulti();
134                         break;
135 #endif
136 #if defined(ENABLE_XPROG_PROTOCOL)
137                 case CMD_XPROG_SETMODE:
138                         XPROGProtocol_SetMode();
139                         break;
140                 case CMD_XPROG:
141                         XPROGProtocol_Command();
142                         break;
143 #endif
144                 default:
145                         V2Protocol_UnknownCommand(V2Command);
146                         break;
147         }
148
149         /* Disable the timeout management timer */
150         TCCR0B = 0;
151
152         Endpoint_WaitUntilReady();
153         Endpoint_SelectEndpoint(AVRISP_DATA_OUT_EPADDR);
154         Endpoint_SetEndpointDirection(ENDPOINT_DIR_OUT);
155 }
156
157 /** Handler for unknown V2 protocol commands. This discards all sent data and returns a
158  *  STATUS_CMD_UNKNOWN status back to the host.
159  *
160  *  \param[in] V2Command  Issued V2 Protocol command byte from the host
161  */
162 static void V2Protocol_UnknownCommand(const uint8_t V2Command)
163 {
164         /* Discard all incoming data */
165         while (Endpoint_BytesInEndpoint() == AVRISP_DATA_EPSIZE)
166         {
167                 Endpoint_ClearOUT();
168                 Endpoint_WaitUntilReady();
169         }
170
171         Endpoint_ClearOUT();
172         Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
173         Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
174
175         Endpoint_Write_8(V2Command);
176         Endpoint_Write_8(STATUS_CMD_UNKNOWN);
177         Endpoint_ClearIN();
178 }
179
180 /** Handler for the CMD_SIGN_ON command, returning the programmer ID string to the host. */
181 static void V2Protocol_SignOn(void)
182 {
183         Endpoint_ClearOUT();
184         Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
185         Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
186
187         Endpoint_Write_8(CMD_SIGN_ON);
188         Endpoint_Write_8(STATUS_CMD_OK);
189         Endpoint_Write_8(sizeof(PROGRAMMER_ID) - 1);
190         Endpoint_Write_Stream_LE(PROGRAMMER_ID, (sizeof(PROGRAMMER_ID) - 1), NULL);
191         Endpoint_ClearIN();
192 }
193
194 /** Handler for the CMD_RESET_PROTECTION command, implemented as a dummy ACK function as
195  *  no target short-circuit protection is currently implemented.
196  */
197 static void V2Protocol_ResetProtection(void)
198 {
199         Endpoint_ClearOUT();
200         Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
201         Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
202
203         Endpoint_Write_8(CMD_RESET_PROTECTION);
204         Endpoint_Write_8(STATUS_CMD_OK);
205         Endpoint_ClearIN();
206 }
207
208
209 /** Handler for the CMD_SET_PARAMETER and CMD_GET_PARAMETER commands from the host, setting or
210  *  getting a device parameter's value from the parameter table.
211  *
212  *  \param[in] V2Command  Issued V2 Protocol command byte from the host
213  */
214 static void V2Protocol_GetSetParam(const uint8_t V2Command)
215 {
216         uint8_t ParamID = Endpoint_Read_8();
217         uint8_t ParamValue;
218
219         if (V2Command == CMD_SET_PARAMETER)
220           ParamValue = Endpoint_Read_8();
221
222         Endpoint_ClearOUT();
223         Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
224         Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
225
226         Endpoint_Write_8(V2Command);
227
228         uint8_t ParamPrivs = V2Params_GetParameterPrivileges(ParamID);
229
230         if ((V2Command == CMD_SET_PARAMETER) && (ParamPrivs & PARAM_PRIV_WRITE))
231         {
232                 Endpoint_Write_8(STATUS_CMD_OK);
233                 V2Params_SetParameterValue(ParamID, ParamValue);
234         }
235         else if ((V2Command == CMD_GET_PARAMETER) && (ParamPrivs & PARAM_PRIV_READ))
236         {
237                 Endpoint_Write_8(STATUS_CMD_OK);
238                 Endpoint_Write_8(V2Params_GetParameterValue(ParamID));
239         }
240         else
241         {
242                 Endpoint_Write_8(STATUS_CMD_FAILED);
243         }
244
245         Endpoint_ClearIN();
246 }
247
248 /** Handler for the CMD_LOAD_ADDRESS command, loading the given device address into a
249  *  global storage variable for later use, and issuing LOAD EXTENDED ADDRESS commands
250  *  to the attached device as required.
251  */
252 static void V2Protocol_LoadAddress(void)
253 {
254         Endpoint_Read_Stream_BE(&CurrentAddress, sizeof(CurrentAddress), NULL);
255
256         Endpoint_ClearOUT();
257         Endpoint_SelectEndpoint(AVRISP_DATA_IN_EPADDR);
258         Endpoint_SetEndpointDirection(ENDPOINT_DIR_IN);
259
260         if (CurrentAddress & (1UL << 31))
261           MustLoadExtendedAddress = true;
262
263         Endpoint_Write_8(CMD_LOAD_ADDRESS);
264         Endpoint_Write_8(STATUS_CMD_OK);
265         Endpoint_ClearIN();
266 }
267