forked from ElTangas/jtag2updi
-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathdbg.h
421 lines (338 loc) · 12.1 KB
/
dbg.h
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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
/*
* dbg.h
*
* Created:5/11/2020
* Author: Spence Konde (tindie.com/stores/drazzy)
* github.com/SpenceKonde
*/
#ifndef DBG_H_
#define DBG_H_
#include <avr/io.h>
#include "sys.h"
/* User Configuration goes up here - the rest down below is defaults that you can override
or stuff that is hardware specific */
// Uncomment these to enable debug output recording every time one of these UPDI commands is sent and (for load commands) the response.
// note that this will have NO EFFECT if you have not defined either USE_SPIDEBUG or USE_USARTDEBUG and any required parameters!
//#define DEBUG_STCS
//#define DEBUG_LDCS
//#define DEBUG_REP
//#define DEBUG_STS
//#define DEBUG_STPTR
//#define DEBUG_LDS
//#define DEBUG_KEY
//#define DEBUG_RESET
#if defined(__AVR_ATtiny_Zero_One__)
// tinyAVR 0-series and 1-series parts
// 3216, 1604, that kind of thing
#define LED_PORT A
#define LED_PIN 7
// Second LED is used to indicate NVM version, or as an additional debugging aid.
#define LED2_PORT A
#define LED2_PIN 6
//USARTDEBUG not practical here because only one UART.
#elif defined( __AVR_ATmega_Mighty__ )
// For ATmega16, ATmega32, and the later x4 parts (up to the 1284P).
// On the ones with two USARTS, you can use USART debugging.
//
// Here USART debug output is an option too
// at least on parts with the second USART
// You should be able to hit 2MBaud with F_CPU=16000000 and DEBUG_BAUDVAL 0 or 1mbaud with 1 if your serial adapter can't handle that.
// At 20, though, on classic AVRs, you're out of luck unless you have an adapter that can do 2.5 mbaud...have to go all the way down to 500kbaud (DEBUG_BAUDVAL 4) to divide it to something common.. Good thing almost everyone runs them at 16.
#elif defined (__AVR_ATmega_Mini__) || defined(ARDUINO_AVR_LARDU_328E)
// For ATmega328 and 168 (P, PB) parts
// Same deal as before/ Remember that the buildin LED is on the same pin as SCK on most boards, so you'll want to cadd LEDs on other pinn, defaults to D2
// On PB parts can also use second USART. Using the second SPI is not supported.
#elif defined (__AVR_ATmega_Mega__)
// 2560 and that family, like the ones used on the Arduino Mega
// Same as the others with extra USARTS, only here you can specify which one if you must
#elif defined (__AVR_ATmega_Zero__)
// 4808, 4809. and the rest of the megaAVR 0-series
// Same as above, pretty much
// big difference here is your specify the name of the peripheral instead of the number, and the target baud rate, because we grab the OSCCAL value per datasheet./
#endif
/* Defaults and hardware-specific stuff */
/* Shouldn't need to change anything here */
/* IF you want to override, copy it to the blocks above */
#if defined(__AVR_ATtiny_Zero_One__)
// tinyAVR 0-series and 1-series parts HOST_RX_PIN 3
#ifdef USE_SPIDEBUG
#define SPIDEBUG SPI0
//SPI0 is on PORTA
#define SPIPORT A
//PA1, PA3, PA4 are MOSI,SCK,SS on XTINY parts with more than 8 pins, and the ones with 8 pins don't have enough ram to fit the device descriptor so we don't care about them.
//On the megasAVR 0-series and AVR DA-series, this would be 0x50 but otherise everything same I think.. not that people are lining up to use those parts as boring programmers!
#define MOSIPIN 1
#define SCKPIN 3
#ifndef SSPIN
//They get option to change this because they may want to use a different pin,m and they an do that on the parts with the new peripherals that have the SSD bit.
#define SSPIN 4
#endif
#endif //emd of SPIDEBUG section for XTINY
#ifdef USE_USARTDEBUG
#error "Only has one USART!"
#endif
#elif defined( __AVR_ATmega_Mighty__ )
// For ATmega16, ATmega32, and the later x4 parts (up to the 1284P).
#ifdef USE_SPIDEBUG
#define SPIPORT B
#define MOSIPIN 1
#define SCKPIN 3
#define SSPIN 4
#endif
#ifdef USE_USARTDEBUG
#ifdef UCSR1A
#if (!defined(DEBUG_USART)
#define DEBUG_USART 1
#elif (!(DEBUG_USART==1)
#undef DEBUG_USART
#define DEBUG_USART 1
#endif
#else
#error "That part doesn't have another USART"
#endif
#endif
#elif defined (__AVR_ATmega_Mini__) || defined(ARDUINO_AVR_LARDU_328E)
// For ATmega328 and 168 (P, PB) parts
#ifdef USE_SPIDEBUG
#define SPIPORT B
#define MOSIPIN 3
#define SCKPIN 5
#define SSPIN 2
#endif
#ifdef USE_USARTDEBUG
#ifdef UCSR1A
#if (!defined(DEBUG_USART)
#define DEBUG_USART 1
#elif (!(DEBUG_USART==1)
#undef DEBUG_USART
#define DEBUG_USART 1
#endif
#else
#error "That part doesn't have another USART"
#endif
#endif
#elif defined (__AVR_ATmega_Mega__)
// 2560 and that family, like the ones used on the Arduino Mega
#ifdef USE_SPIDEBUG
#define SPIPORT D
#define MOSIPIN 2
#define SCKPIN 1
#define SSPIN 0
#endif
#ifdef USE_USARTDEBUG
#if (!defined(DEBUG_USART)
#define DEBUG_USART 1
#endif
#if (!(DEBUG_USART==1||DEBUG_USART==2||DEBUG_USART==3)
#undef DEBUG_USART
#define DEBUG_USART 1
#endif
#endif
#elif defined (__AVR_ATmega_Zero__)
// 4808, 4809. and the rest of the megaAVR 0-series
#ifdef USE_SPIDEBUG
#define SPIDEBUG SPI0
//SPI0 is on PORTA
#define SPIPORT A
//PA4, PA6, PA7 are MOSI,SCK,SS on megaAVR 0-series
#define MOSIPIN 4
#define SCKPIN 6
#ifndef SSPIN
#define SSPIN 7
#endif
#endif //emd of SPIDEBUG
#ifdef USE_USARTDEBUG
#define DEBUG_TX_PIN 0
#define DEBUG_RX_PIN 1
#if (!defined(DEBUG_USART)
#define DEBUG_USART USART1
#endif
#if DEBUG_USART==USART1
#define DEBUG_TX_PORT C
#elif DEBUG_USART==USART2
#define DEBUG_TX_PORT F
#elif DEBUG_USART==USART3
#define DEBUG_TX_PORT B
#elif DEBUG_USART==USART0
#define DEBUG_TX_PORT A
#else
#undef DEBUG_USART
#define DEBUG_USART USART1
#define DEBUG_TX_PORT C
#endif
#endif //end if USARTDEBUG
#else
#warning "Part not supported - if you didn't provide all the needed pin definitions, that's why it's not compiling"
#endif //End of the defaults!
// Noe we do some general stuff relating the the debugging so they share most of the code...
#if (defined(USE_SPIDEBUG) && defined(USE_USARTDEBUG))
#error "Cannot use both SPI and UART for debugging, pick one"
#endif
#ifdef USE_SPIDEBUG
#define DEBUG_ON
#ifdef XAVR
#define DEBUGDATA SPIDEBUG.DATA
#define DEBUGFLAGS SPIDEBUG.INTFLAGS
#define DEBUGSENDNOW SPI_IF_bp
#else
#ifndef SPDR
//means it's one of the ones woth two of them, 0 and 1...
#define SPIF SPIF0
#define MSTR MSTR0
#define WDE WDE0
#if (SPIDEBUG==1)
#define SPDR SPDR1
#define SPSR SPSR1
#define SPCR SPCR1
#else
#define SPDR SPDR0
#define SPSR SPSR0
#define SPCR SPCR0
#endif
#endif //now it has standard names definedm,= so we define them to match the harmonized names...
#define DEBUGDATA SPDR
#define DEBUGFLAGS SPSR
#define DEBUGSENDNOW SPIF
#endif
#endif
#ifdef USE_USARTDEBUG
#define DEBUG_ON
#ifdef XAVR
#if (HOST_USART == DEBUG_USART)
#error "Host and Debug cannot be on same USART"
#endif
#define DEBUGDATA DEBUG_USART.TXDATAL
#define DEBUGBAUDREG DEBUG_USART.BAUD
#define DEBUGFLAGS DEBUG_USART.STATUS
#define DEBUGSENDNOW USART_DREIF_bp
#ifndef DEBUG_BAUDRATE
#define DEBUG_BAUDRATE 2000000UL
#endif
#else
#define DEBUGSENDNOW UDRE0
#if DEBUG_USART==1
#define DEBUGDATA UDR1
#define DEBUGFLAGS UCSR1A
#define DEBUG_UCSRB UCSR1B
#define DEBUGBAUDREG UBRR1
#elif DEBUG_USART==2
#define DEBUGDATA UDR2
#define DEBUGFLAGS UCSR2A
#define DEBUG_UCSRB UCSR2B
#define DEBUGBAUDREG UBRR2
#elif DEBUG_USART==3
#define DEBUGDATA UDR3
#define DEBUGFLAGS UCSR3A
#define DEBUG_UCSRB UCSR3B
#define DEBUGBAUDREG UBRR3
#elif DEBUG_USART==0
#error "Using USART other than USART0 to communicate with host not supported on classic AVR"
#else
#define DEBUG_USART 1
#define DEBUGDATA UDR1
#define DEBUGFLAGS UCSR1A
#define DEBUG_UCSRB UCSR1B
#define DEBUGBAUDREG UBRR1
#endif
#endif
#endif
#if defined(DEBUG_ON)
namespace DBG {
void initDebug(void);
void updi_st_ptr_l(uint32_t address);
void updi_st_ptr_w(uint16_t address);
void updi_lds(uint32_t address);
void updi_lds(uint16_t address);
void updi_sts(uint32_t address, uint16_t data);
void updi_sts(uint32_t address, uint8_t data);
void updi_sts(uint16_t address, uint16_t data);
void updi_sts(uint16_t address, uint8_t data);
void updi_key();
void updi_rep(uint8_t reps);
void updi_stcs(uint8_t command, uint8_t data);
void updi_ldcs(uint8_t command);
void updi_res(uint32_t data, uint8_t isaddr=1);
void updi_res(uint16_t data, uint8_t isaddr=0);
void updi_res(uint8_t data);
void updi_reset();
void updi_reset_off();
void updi_reset_on();
void updi_post_reset(uint8_t mode);
void debug(const char *str, uint8_t newline=1);
void debug(const uint8_t *data, size_t length, uint8_t newline=0, uint8_t ashex=0);
void debugWriteStr(const char *str);
void debugWriteBytes(const uint8_t *data, size_t length, uint8_t ashex=0);
void debugWriteByte(uint8_t databyte);
void debugWriteHex(uint8_t databyte);
void debug(char prefix, uint8_t data0);
void debug(char prefix, uint8_t data0, uint8_t data1);
void debug(char prefix, uint8_t data0, uint8_t data1, uint8_t data2);
}
#else
// if debug is not on, we need to deal with the specific DEBUG_(subsystem) defines. Rather than make a mess of everywhere that checks for them by adding another check for DEBUG_ON
// we'll just undefine them....
#ifdef DEBUG_STCS
#warning "No debug output method is configured, so DEBUG_STCS being undefined"
#undef DEBUG_STCS
#endif
#ifdef DEBUG_LDCS
#warning "No debug output method is configured, so DEBUG_LDCS being undefined"
#undef DEBUG_LDCS
#endif
#ifdef DEBUG_STS
#warning "No debug output method is configured, so DEBUG_STS being undefined"
#undef DEBUG_STS
#endif
#ifdef DEBUG_LDS
#warning "No debug output method is configured, so DEBUG_LDS being undefined"
#undef DEBUG_LDS
#endif
#ifdef DEBUG_STPTR
#warning "No debug output method is configured, so DEBUG_STPTR being undefined"
#undef DEBUG_STPTR
#endif
#ifdef DEBUG_KEY
#warning "No debug output method is configured, so DEBUG_KEY being undefined"
#undef DEBUG_KEY
#endif
#ifdef DEBUG_REP
#warning "No debug output method is configured, so DEBUG_REP being undefined"
#undef DEBUG_REP
#endif
#ifdef DEBUG_RESET
#warning "No debug output method is configured, so DEBUG_RESET being undefined"
#undef DEBUG_RESET
#endif
namespace DBG {
inline void initDebug(){}
inline void updi_st_ptr_l(uint32_t address){}
inline void updi_st_ptr_w(uint16_t address){}
inline void updi_lds(uint32_t address){}
inline void updi_lds(uint16_t address){}
inline void updi_sts(uint32_t address, uint16_t data){}
inline void updi_sts(uint32_t address, uint8_t data){}
inline void updi_sts(uint16_t address, uint16_t data){}
inline void updi_sts(uint16_t address, uint8_t data){}
inline void updi_key(){}
inline void updi_rep(uint8_t reps){}
inline void updi_stcs(uint8_t command, uint8_t data){}
inline void updi_ldcs(uint8_t command){}
inline void updi_res(uint32_t data, uint8_t isaddr=1){}
inline void updi_res(uint16_t data, uint8_t isaddr=0){}
inline void updi_res(uint8_t data){}
inline void updi_reset(){}
inline void updi_reset_off(){}
inline void updi_reset_on(){}
inline void updi_post_reset(uint8_t mode){}
inline void debug(const char *str, uint8_t newline=1){}
inline void debug(const uint8_t *data, size_t length, uint8_t newline=0, uint8_t ashex=0){}
inline void debugWriteStr(const char *str){}
inline void debugWriteBytes(const uint8_t *data, size_t length, uint8_t ashex=0){}
inline void debugWriteByte(uint8_t databyte){}
inline void debugWriteHex(uint8_t databyte){}
inline void debug(char prefix, uint8_t data0){}
inline void debug(char prefix, uint8_t data0, uint8_t data1){}
inline void debug(char prefix, uint8_t data0, uint8_t data1, uint8_t data2){}
}
#endif
#endif /* DBG_H_ */