forked from ElTangas/jtag2updi
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathsys.h
522 lines (412 loc) · 13.5 KB
/
sys.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
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
/*
* sys.h
*
* Created: 02-10-2018 13:07:18
* Author: JMR_2
*/
#ifndef SYS_H_
#define SYS_H_
#include <avr/io.h>
#include <string.h>
#include <stdio.h> // for size_t
#include "parts.h"
// Disable the response signature during burst writes to permit faster writes
#define NO_ACK_WRITE
// If using a device based on the HV programmer designed by dlloyd (@Dlloyddev on github), enable that functionality
//#define USE_HV_PROGRAMMING
// Disable the host timeout - this is required for use with avrdude in terminal mode (-t)
// but with this disabled, can get "stuck" if communication with host is interrupted at 115200 baud
// as avrdude on next start will try to communicate at 19200 baud. Reset is required to fix this.
// Potential enhancement - if this is set, while waiting for message from host, ALSO count transitions on the RX pin
// If we see a bunch of transitions, but no received characters, we know the host is using the wrong baud rate, and
// so, switch back to 19200 baud.
//#define DISABLE_HOST_TIMEOUT
// Disable the timeout waiting for response from target. Probably not necessary to set. With this disabled, if the target is expected to respond
// but does not, jtag2updi will get stuck waiting for it.
//#define DISABLE_TARGET_TIMEOUT
// Deduces the NVM version from reading the SIB string. Otherwise, the NVM version is deduced from the size of flash pages.
//#define DEDUCE_NVM_VERSION_FROM_SIB
// this will include the SIB, deduced NVM version, and silicon revision in early responses to SET_DEVICE_DESCRIPTPOR (for SIB and NVM version) and ENTER_PROGMODE (for silicon rev)
//#define INCLUDE_EXTRA_INFO_JTAG
// Auxiliary Macros
#define CONCAT(A,B) A##B // concatenate
#define XCONCAT(A,B) CONCAT(A,B) // expand and concatenate
//#define CONCAT3(A,B,C) A##B##C
#if (__AVR_ARCH__ == 103) || (__AVR_ARCH__ == 104)
//We'll call these ones XAVR for purposes of defines, instead of XTINY. This encompasses megaAVR 0-series and DA-series parts
#define XAVR
# define PIN(x) CONCAT(VPORT,x).IN
# define PORT(x) CONCAT(VPORT,x).OUT
# define DDR(x) CONCAT(VPORT,x).DIR
// # define PULLUP_ON(x,y) CONCAT(PORT,x).CONCAT3(PIN,y,CTRL)=0x04
// # define PULLUP_OFF(x,y) CONCAT(PORT,x).CONCAT3(PIN,y,CTRL)=0x04
#else
# define PIN(x) CONCAT(PIN,x)
# define PORT(x) CONCAT(PORT,x)
# define DDR(x) CONCAT(DDR,x)
#endif
/* User Configuration goes up here - the rest down below is defaults that you can override
or stuff that is hardware specific */
#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
// Dickson charge pump pins
# define cpp PIN3_bm // charge pump power or HV Enable, PA3
# define cp1 PIN4_bm // charge pump clock 1, PA4
# define cp2 PIN5_bm // charge pump clock 2, PA5
# define cps PIN1_bm // charge pump shutdown, PB1
//USARTDEBUG not practical here because only one UART.
//#define USE_SPIDEBUG
//SPIPRESC sets prescaler of SPI clock - it can go *INSANELY* fast, such that very little could keep up with it.
#define SPIPRESC (SPI_CLK2X_bm|SPI_PRESC1_bm)
#elif defined( __AVR_ATmega_Mighty__ )
// For ATmega16, 32, ... 128 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.
// #define USE_USARTDEBUG
// #define DEBUG_BAUDVAL 0
#elif defined (__AVR_ATmega_Mini__) || defined(ARDUINO_AVR_LARDU_328E)
// For ATmega8/88/168/328 (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.
//#define USE_SPIDEBUG
//#define SPIPRESC (0x05)
#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
// #define USE_USARTDEBUG
// #define DEBUG_USART 2
// Can even change the host USART if you want
#elif defined (__AVR_ATmega_Zero__ ) || defined( __AVR_DA__)
// 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./
// #define USE_USARTDEBUG
// #define DEBUG_USART USART1
// #define DEBUG_BAUDRATE 2000000UL
#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
// Dickson charge pump pins
# define cpp PIN0_bm // charge pump power or HV Enable, PC0
# define cp1 PIN1_bm // charge pump clock 1, PC1
# define cp2 PIN2_bm // charge pump clock 2, PC2
# define cps PIN3_bm // charge pump shutdown, PC3
#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
# ifndef HVLED_PORT
# define HVLED_PORT A
# endif
# ifndef HVLED_PIN
# define HVLED_PIN 6
# endif
# ifndef UPDI_PORT
# define UPDI_PORT B
# endif
# ifndef UPDI_PIN
# define UPDI_PIN 0
# endif
# ifndef LED_PORT
# define LED_PORT A
# endif
# ifndef LED_PIN
# define LED_PIN 7
# endif
# ifndef HOST_USART
# define HOST_USART USART0
# endif
# ifndef HOST_TX_PORT
# define HOST_TX_PORT B
# endif
# ifndef HOST_TX_PIN
# define HOST_TX_PIN 2
# endif
# ifndef HOST_RX_PIN
# define HOST_RX_PIN 3
# endif
#elif defined( __AVR_ATmega_Mighty__ )
// For ATmega16, 32, ... 128 and the later x4 parts (up to the 1284P).
# ifndef HOST_USART
# define HOST_USART 0
# endif
# ifndef UPDI_PORT
# define UPDI_PORT C
# endif
# ifndef UPDI_PIN
# define UPDI_PIN 7
# endif
# ifndef LED_PORT
# define LED_PORT B
# endif
# ifndef LED_PIN
# define LED_PIN 7
# endif
#elif defined (__AVR_ATmega_Mini__) || defined(ARDUINO_AVR_LARDU_328E)
// For ATmega8/88/168/328 (P, PB) parts
# ifndef HVLED_PORT
# define HVLED_PORT B
# endif
# ifndef HVLED_PIN
# define HVLED_PIN 0
# endif
# ifndef HOST_USART
# define HOST_USART 0
# endif
# ifndef UPDI_PORT
# define UPDI_PORT D
# endif
# ifndef UPDI_PIN
# define UPDI_PIN 6
# endif
#ifdef USE_SPIDEBUG
# ifndef LED_PORT
# define LED_PORT C
# endif
# ifndef LED_PIN
# define LED_PIN 5
# endif
#else
# ifndef LED_PORT
# define LED_PORT B
# endif
# ifndef LED_PIN
# define LED_PIN 5
# endif
# ifndef LED2_PORT
# define LED2_PORT D
# endif
# ifndef LED2_PIN
# define LED2_PIN 7
# endif
#endif
#elif defined (__AVR_ATmega_Mega__)
// 2560 and that family, like the ones used on the Arduino Mega
# ifndef HOST_USART
# define HOST_USART 0
# endif
# ifndef UPDI_PORT
# define UPDI_PORT D
# endif
# ifndef UPDI_PIN
# define UPDI_PIN 3
# endif
# ifndef LED_PORT
# define LED_PORT B
# endif
# ifndef LED_PIN
# define LED_PIN 7
# endif
#elif defined (__AVR_ATmega_Zero__ ) || defined( __AVR_DA__)
// 4808, 4809. and the rest of the megaAVR 0-series
# ifndef HVLED_PORT
# define HVLED_PORT A
# endif
# ifndef HVLED_PIN
# define HVLED_PIN 6
# endif
# ifndef UPDI_PORT
# define UPDI_PORT A
# endif
# ifndef UPDI_PIN
# define UPDI_PIN 3
# endif
# ifndef LED_PORT
# define LED_PORT A
# endif
# ifndef LED_PIN
# define LED_PIN 7
# endif
# ifndef HOST_USART
# define HOST_USART USART0
# endif
# ifndef HOST_TX_PORT
# define HOST_TX_PORT A
# endif
# ifndef HOST_TX_PIN
# define HOST_TX_PIN 0
# endif
# ifndef HOST_RX_PIN
# define HOST_RX_PIN 1
# endif
#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!
// Define USART registers and bits based on the selected HOST_USART for non-XAVR parts
#ifndef XAVR
// Define generic USART flags if not defined already
#ifndef UDRE
#define UDRE XCONCAT(UDRE, HOST_USART)
#define U2X XCONCAT(U2X, HOST_USART)
#define TXEN XCONCAT(TXEN, HOST_USART)
#define RXEN XCONCAT(RXEN, HOST_USART)
#define RXC XCONCAT(RXC, HOST_USART)
#define TXC XCONCAT(TXC, HOST_USART)
#endif
// USART registers
#ifdef UCSRA
#define HOST_UCSRA UCSRA
#define HOST_UCSRB UCSRB
#define HOST_UDR UDR
#else
#define HOST_UCSRA XCONCAT(UCSR, XCONCAT(HOST_USART, A))
#define HOST_UCSRB XCONCAT(UCSR, XCONCAT(HOST_USART, B))
#define HOST_UDR XCONCAT(UDR, HOST_USART)
#endif
// UBRR is more complex and needs a special case
#ifndef UBRR0
// For older AVRs use only low 8 bits of UBRR because low and high parts are not adjacent
#ifdef UBRRL
#define HOST_UBRR UBRRL
#else
#define HOST_UBRR XCONCAT(UBRR, XCONCAT(HOST_USART, L))
#endif
#else
// This is a more modern part; we can use 16 bit UBRR
#define HOST_UBRR XCONCAT(UBRR, HOST_USART)
#endif
#endif
// Some classic AVRs have a single flags register for timers 0 and 1 (TIFR0 and TIFR1 are merged in a single register TIFR)
#ifndef XAVR
#ifndef TIFR1
#define TIFR1 TIFR
#endif
#endif
#ifdef XAVR
#define TIMER_ON TCA_SINGLE_CLKSEL_DIV256_gc | TCA_SINGLE_ENABLE_bm
#define TIMER_OFF TCA_SINGLE_CLKSEL_DIV256_gc
#define TIMEOUT_REG TCA0.SINGLE.INTFLAGS
#define TIMER_CONTROL_REG TCA0.SINGLE.CTRLA
#define TIMER_COUNT_REG TCA0.SINGLE.CNT
#define TIMER_HOST_MAX TCA0.SINGLE.CMP0
#define TIMER_TARGET_MAX TCA0.SINGLE.CMP1
#define WAIT_FOR_HOST TCA_SINGLE_CMP0_bm
#define WAIT_FOR_TARGET TCA_SINGLE_CMP1_bm
#define TIMER_RESET_REG TCA0.SINGLE.CTRLESET
#define TIMER_RESET_CMD TCA_SINGLE_CMD_RESTART_gc
#else
#define TIMER_ON 0x04
#define TIMER_OFF 0x00
#define TIMEOUT_REG TIFR1
#define TIMER_CONTROL_REG TCCR1B
#define TIMER_COUNT_REG TCNT1
#define TIMER_HOST_MAX OCR1A
#define TIMER_TARGET_MAX OCR1B
#define WAIT_FOR_HOST (1<<OCF1A)
#define WAIT_FOR_TARGET (1<<OCF1B)
#endif
#ifndef F_CPU
# warning "F_CPU not defined, assuming 16MHz"
# define F_CPU 16000000U
#endif
// TIMEOUTS
// HOST_TIMEOUT =~250ms
// TARGET_TIMEOUT=~100ms
// Timeout timer is initialized to use /256 divisor
#define HOST_TIMEOUT (F_CPU / 256.0 * 0.25)
#define TARGET_TIMEOUT (F_CPU / 256.0 * 0.1)
#ifndef UPDI_BAUD
# define UPDI_BAUD 100000U // (max 225000 min approx. F_CPU/100)
#endif
/*
* Available UPDI I/O types are:
*
* 1 - timer sofware UART: Compatible only with Mega328P and other AVRs with identical 8 bit timer 0.
* Only the OC0A pin can be used for UPDI I/O. Slightly faster upload speed for a given UPDI_BAUD value.
*
* 2 - bitbang software UART: Compatible with many chips and broad choice of UPDI pins are selectable.
* Slightly slower upload speed for a given UPDI_BAUD value. Download speed is the same.
*/
#ifndef UPDI_IO_TYPE
# define UPDI_IO_TYPE 2
#endif
// Flash constants class
#if defined XAVR
template <typename T>
using FLASH = const T;
#else
# include <avr/pgmspace.h>
# define FLASH const PROGMEM flash
template <typename T>
class flash {
private:
const T data;
public:
// normal constructor
constexpr flash (T _data) : data(_data) {}
// default constructor
constexpr flash () : data(0) {}
operator T() const {
switch (sizeof(T)) {
case 1: return pgm_read_byte(&data);
case 2: return pgm_read_word(&data);
case 4: return pgm_read_dword(&data);
}
}
};
#endif
#if defined XAVR
// Note: adapted from MicroChip appnote TB3216 "Getting Started with USART"
constexpr unsigned int baud_reg_val(unsigned long baud) {
return (F_CPU * 64.0) / (16.0 * baud) + 0.5;
}
#else
constexpr unsigned int baud_reg_val(unsigned long baud) {
return F_CPU/(baud * 8.0) - 0.5;
}
#endif
namespace SYS {
/*
Timeout mechanisms, 5/2020, Spence Konde
*/
inline uint8_t checkTimeouts() {
return TIMEOUT_REG;
}
inline void clearTimeouts() {
TIMEOUT_REG=WAIT_FOR_HOST|WAIT_FOR_TARGET;
}
inline void startTimer(void) __attribute__((always_inline));
inline void startTimer(void) {
#ifdef TIMER_RESET_REG //some timers have a reset register.
TIMER_RESET_REG=TIMER_RESET_CMD;
#else
TIMER_COUNT_REG=0;
#endif
TIMER_CONTROL_REG=TIMER_ON;
}
inline void stopTimer(void) __attribute__((always_inline));
inline void stopTimer(void){ TIMER_CONTROL_REG=TIMER_OFF; }
void init(void);
void setLED(void);
void clearLED(void);
void setVerLED(void);
void clearVerLED(void);
void setHVLED(void);
void clearHVLED(void);
void pulseHV(void);
void updiTriState(void);
void updiHigh(void);
void updiIdle(void);
void updiInitiate(void);
void updiEnable(void);
void setPOWER(void);
void clearPOWER(void);
void cyclePOWER(void);
void checkOVERLOAD(void);
uint8_t checkHVMODE();
}
#endif /* SYS_H_ */