OpenCores
URL https://opencores.org/ocsvn/usb_fpga_2_13/usb_fpga_2_13/trunk

Subversion Repositories usb_fpga_2_13

[/] [usb_fpga_2_13/] [trunk/] [include/] [ztex-xmega.h] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 ZTEX
/*!
2
   ZTEX Firmware Kit for EZ-USB FX2 Microcontrollers
3
   Copyright (C) 2009-2014 ZTEX GmbH.
4
   http://www.ztex.de
5
 
6
   This program is free software; you can redistribute it and/or modify
7
   it under the terms of the GNU General Public License version 3 as
8
   published by the Free Software Foundation.
9
 
10
   This program is distributed in the hope that it will be useful, but
11
   WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
   General Public License for more details.
14
 
15
   You should have received a copy of the GNU General Public License
16
   along with this program; if not, see http://www.gnu.org/licenses/.
17
!*/
18
 
19
/*
20
    AVR XMEGA support
21
*/
22
 
23
#ifndef[ZTEX_XMEGA_H]
24
#define[ZTEX_XMEGA_H]
25
 
26
#define[@CAPABILITY_XMEGA;]
27
#define[XMEGA_ENABLED][1]
28
 
29
#ifeq[PDI_PORT][E]
30
#define[PDI_bmMODE]
31
#elifeq[PDI_PORT][A]
32
#elifeq[PDI_PORT][B]
33
#elifeq[PDI_PORT][C]
34
#elifneq[PDI_PORT][D]
35
#error[Macro `PDI_PORT' is not defined correctly. Valid values are: `A', `B', `C', `D' and `E'.]
36
#endif
37
 
38
__xdata BYTE xmega_ec;
39
__xdata WORD xmega_flash_pages;   // in pages
40
__xdata WORD xmega_eeprom_pages;  // in pages
41
__xdata BYTE xmega_flash_page_size;   // as power of 2
42
__xdata BYTE xmega_eeprom_page_size;  // as power of 2
43
 
44
__xdata BYTE nvm_page_type;             // current page type (0: none; 1:FLASH; 2:EEPROM)
45
__xdata WORD nvm_current_page;
46
__xdata DWORD nvm_addr;
47
__xdata BYTE nvm_boot_base;     // BOOT_BASE >> 16
48
 
49
#define[XMEGA_FLASH_START][0x800000]
50
#define[XMEGA_EEPROM_START][0x8C0000]
51
#define[XMEGA_FUSE_START][0x8F0020]
52
 
53
#define[XMEGA_EC_NO_ERROR][0]
54
#define[XMEGA_EC_PDI_READ_ERROR][1]
55
#define[XMEGA_EC_NVM_TIMEOUT][2]
56
#define[XMEGA_EC_INVALID_DEVICE][3]
57
#define[XMEGA_EC_ADDRESS_ERROR][4]
58
#define[XMEGA_EC_NVM_BUSY][5]
59
 
60
#define[PDI_IO][IOPDI_PORT]
61
#define[PDI_CLK][IOPDI_PORTPDI_BIT_CLK]
62
#define[PDI_DATA][IOPDI_PORTPDI_BIT_DATA]
63
#define[PDI_bmCLK][(1<<PDI_BIT_CLK)]
64
#define[PDI_bmDATA][(1<<PDI_BIT_DATA)]
65
 
66
#define[NVM_CMD][0xca]
67
#define[NVM_CTRLA][0xcb]
68
#define[NVM_STATUS][0xcf]
69
 
70
/* *********************************************************************
71
   ***** pdi_send ******************************************************
72
   ********************************************************************* */
73
// send one byte to pdi
74
void pdi_send(BYTE b) {
75
    b;                  // this avoids stupid warnings
76
    OEPDI_PORT |= bmBITPDI_BIT_DATA;
77
 
78
__asm
79
#ifdef[PDI_bmMODE]
80
    mov a,dpl
81
 
82
    anl _PDI_IO, #(~PDI_bmDATA)         // start bit
83
    anl _PDI_IO, #(~PDI_bmCLK)  
84
    rrc a
85
    orl _PDI_IO, #(PDI_bmCLK)   
86
 
87
    anl _PDI_IO, #(~PDI_bmDATA)         // 0
88
    jnc 0100200$
89
    orl _PDI_IO, #(PDI_bmDATA)
90
0100200$:
91
    anl _PDI_IO, #(~PDI_bmCLK)  
92
    rrc a
93
    orl _PDI_IO, #(PDI_bmCLK)   
94
 
95
    anl _PDI_IO, #(~PDI_bmDATA)         // 1
96
    jnc 0100201$
97
    orl _PDI_IO, #(PDI_bmDATA)
98
0100201$:
99
    anl _PDI_IO, #(~PDI_bmCLK)  
100
    rrc a
101
    orl _PDI_IO, #(PDI_bmCLK)   
102
 
103
    anl _PDI_IO, #(~PDI_bmDATA)         // 2
104
    jnc 0100202$
105
    orl _PDI_IO, #(PDI_bmDATA)
106
0100202$:
107
    anl _PDI_IO, #(~PDI_bmCLK)  
108
    rrc a
109
    orl _PDI_IO, #(PDI_bmCLK)   
110
 
111
    anl _PDI_IO, #(~PDI_bmDATA)         // 3
112
    jnc 0100203$
113
    orl _PDI_IO, #(PDI_bmDATA)
114
0100203$:
115
    anl _PDI_IO, #(~PDI_bmCLK)  
116
    rrc a
117
    orl _PDI_IO, #(PDI_bmCLK)   
118
 
119
    anl _PDI_IO, #(~PDI_bmDATA)         // 4
120
    jnc 0100204$
121
    orl _PDI_IO, #(PDI_bmDATA)
122
0100204$:
123
    anl _PDI_IO, #(~PDI_bmCLK)  
124
    rrc a
125
    orl _PDI_IO, #(PDI_bmCLK)   
126
 
127
    anl _PDI_IO, #(~PDI_bmDATA)         // 5
128
    jnc 0100205$
129
    orl _PDI_IO, #(PDI_bmDATA)
130
0100205$:
131
    anl _PDI_IO, #(~PDI_bmCLK)  
132
    rrc a
133
    orl _PDI_IO, #(PDI_bmCLK)   
134
 
135
    anl _PDI_IO, #(~PDI_bmDATA)         // 6
136
    jnc 0100206$
137
    orl _PDI_IO, #(PDI_bmDATA)
138
0100206$:
139
    anl _PDI_IO, #(~PDI_bmCLK)  
140
    rrc a
141
    orl _PDI_IO, #(PDI_bmCLK)   
142
 
143
    anl _PDI_IO, #(~PDI_bmDATA)         // 7
144
    jnc 0100207$
145
    orl _PDI_IO, #(PDI_bmDATA)
146
0100207$:
147
    anl _PDI_IO, #(~PDI_bmCLK)  
148
    rrc a
149
    orl _PDI_IO, #(PDI_bmCLK)   
150
 
151
    anl _PDI_IO, #(~PDI_bmDATA)         // parity bit
152
    jnb _PF,0100208$
153
    orl _PDI_IO, #(PDI_bmDATA)
154
0100208$:
155
    anl _PDI_IO, #(~PDI_bmCLK)  
156
    orl _PDI_IO, #(PDI_bmCLK)   
157
 
158
    orl _PDI_IO, #(PDI_bmDATA)          // stop bit 1
159
    anl _PDI_IO, #(~PDI_bmCLK)  
160
    orl _PDI_IO, #(PDI_bmCLK)   
161
 
162
    anl _PDI_IO, #(~PDI_bmCLK)          // stop bit 1
163
    orl _PDI_IO, #(PDI_bmCLK)   
164
#else
165
    mov a,dpl
166
 
167
    clr _PDI_DATA      // start bit
168
    clr _PDI_CLK
169
    rrc a
170
    setb _PDI_CLK
171
 
172
    mov _PDI_DATA,c    // 0
173
    clr _PDI_CLK
174
    rrc a
175
    setb _PDI_CLK
176
 
177
    mov _PDI_DATA,c    // 1
178
    clr _PDI_CLK
179
    rrc a
180
    setb _PDI_CLK
181
 
182
    mov _PDI_DATA,c    // 2
183
    clr _PDI_CLK
184
    rrc a
185
    setb _PDI_CLK
186
 
187
    mov _PDI_DATA,c    // 3
188
    clr _PDI_CLK
189
    rrc a
190
    setb _PDI_CLK
191
 
192
    mov _PDI_DATA,c    // 4
193
    clr _PDI_CLK
194
    rrc a
195
    setb _PDI_CLK
196
 
197
    mov _PDI_DATA,c    // 5
198
    clr _PDI_CLK
199
    rrc a
200
    setb _PDI_CLK
201
 
202
    mov _PDI_DATA,c    // 6
203
    clr _PDI_CLK
204
    rrc a
205
    setb _PDI_CLK
206
 
207
    mov _PDI_DATA,c    // 7
208
    clr _PDI_CLK
209
    rrc a
210
    setb _PDI_CLK
211
 
212
    mov c,_PF
213
    mov _PDI_DATA,c    // parity bit
214
    clr _PDI_CLK
215
    setb _PDI_CLK
216
 
217
    setb _PDI_DATA      // stop bit 1
218
    clr _PDI_CLK
219
    setb _PDI_CLK
220
 
221
    clr _PDI_CLK        // stop bit 2
222
    setb _PDI_CLK
223
#endif[PDI_PORT][A]
224
__endasm;
225
}
226
 
227
 
228
/* *********************************************************************
229
   ***** pdi_read ******************************************************
230
   ********************************************************************* */
231
// read byte from PDI
232
BYTE pdi_read() {
233
    xmega_ec = XMEGA_EC_NO_ERROR;
234
    OEPDI_PORT &= ~bmBITPDI_BIT_DATA;
235
 
236
__asm
237
#ifdef[PDI_bmMODE]
238
    anl _PDI_IO, #(~PDI_bmCLK)
239
    orl _PDI_IO, #(PDI_bmCLK)   
240
    mov r1,0
241
010020$:                // wait for the start bit
242
    mov a, _PDI_IO      // start bit
243
    anl a, #(PDI_bmDATA)
244
    jz 010021$
245
    anl _PDI_IO, #(~PDI_bmCLK)
246
    orl _PDI_IO, #(PDI_bmCLK)   
247
    djnz r1,010020$
248
010021$:
249
 
250
    anl _PDI_IO, #(~PDI_bmCLK)
251
    orl _PDI_IO, #(PDI_bmCLK)   
252
    mov a, _PDI_IO              // 0
253
    anl a, #(PDI_bmDATA)
254
    subb a,#1
255
    mov a,r1
256
    rrc a
257
    mov r1,a
258
 
259
    anl _PDI_IO, #(~PDI_bmCLK)
260
    orl _PDI_IO, #(PDI_bmCLK)   
261
    mov a, _PDI_IO              // 1
262
    anl a, #(PDI_bmDATA)
263
    subb a,#1
264
    mov a,r1
265
    rrc a
266
    mov r1,a
267
 
268
    anl _PDI_IO, #(~PDI_bmCLK)
269
    orl _PDI_IO, #(PDI_bmCLK)   
270
    mov a, _PDI_IO              // 2
271
    anl a, #(PDI_bmDATA)
272
    subb a,#1
273
    mov a,r1
274
    rrc a
275
    mov r1,a
276
 
277
    anl _PDI_IO, #(~PDI_bmCLK)
278
    orl _PDI_IO, #(PDI_bmCLK)   
279
    mov a, _PDI_IO              // 3
280
    anl a, #(PDI_bmDATA)
281
    subb a,#1
282
    mov a,r1
283
    rrc a
284
    mov r1,a
285
 
286
    anl _PDI_IO, #(~PDI_bmCLK)
287
    orl _PDI_IO, #(PDI_bmCLK)   
288
    mov a, _PDI_IO              // 4
289
    anl a, #(PDI_bmDATA)
290
    subb a,#1
291
    mov a,r1
292
    rrc a
293
    mov r1,a
294
 
295
    anl _PDI_IO, #(~PDI_bmCLK)
296
    orl _PDI_IO, #(PDI_bmCLK)   
297
    mov a, _PDI_IO              // 5
298
    anl a, #(PDI_bmDATA)
299
    subb a,#1
300
    mov a,r1
301
    rrc a
302
    mov r1,a
303
 
304
    anl _PDI_IO, #(~PDI_bmCLK)
305
    orl _PDI_IO, #(PDI_bmCLK)   
306
    mov a, _PDI_IO              // 6
307
    anl a, #(PDI_bmDATA)
308
    subb a,#1
309
    mov a,r1
310
    rrc a
311
    mov r1,a
312
 
313
    anl _PDI_IO, #(~PDI_bmCLK)
314
    orl _PDI_IO, #(PDI_bmCLK)   
315
    mov a, _PDI_IO              // 7
316
    anl a, #(PDI_bmDATA)
317
    subb a,#1
318
    mov a,r1
319
    rrc a
320
    xrl a,#255
321
    mov r1,a
322
 
323
    anl _PDI_IO, #(~PDI_bmCLK)
324
    orl _PDI_IO, #(PDI_bmCLK)   
325
    mov a, _PDI_IO              // parity bit
326
    anl a, #(PDI_bmDATA)
327
    subb a,#1
328
    mov a,r1
329
    jnc 010022$
330
    jb _PF, 010023$             // parity error
331
    sjmp 010026$
332
010022$:
333
    jnb _PF, 010023$            // parity error
334
010026$:
335
 
336
    anl _PDI_IO, #(~PDI_bmCLK)
337
    orl _PDI_IO, #(PDI_bmCLK)   
338
    mov a, _PDI_IO              // stop bit 1
339
    anl a, #(PDI_bmDATA)
340
    jz 010024$
341
 
342
    anl _PDI_IO, #(~PDI_bmCLK)
343
    orl _PDI_IO, #(PDI_bmCLK)   
344
    mov a, _PDI_IO              // stop bit 2
345
    anl a, #(PDI_bmDATA)
346
    jz 010024$
347
 
348
    mov dpl,r1
349
    ret
350
010023$:
351
    anl _PDI_IO, #(~PDI_bmCLK)
352
    orl _PDI_IO, #(PDI_bmCLK)   
353
010024$:
354
    anl _PDI_IO, #(~PDI_bmCLK)
355
    orl _PDI_IO, #(PDI_bmCLK)   
356
010025$:
357
#else
358
    clr _PDI_CLK
359
    setb _PDI_CLK
360
    mov r1,0
361
010020$:                // wait for the start bit
362
    mov c,_PDI_DATA
363
    jnc 010021$ // start bit
364
    clr _PDI_CLK
365
    setb _PDI_CLK
366
    djnz r1,010020$
367
010021$:
368
 
369
    clr _PDI_CLK
370
    setb _PDI_CLK
371
    mov c,_PDI_DATA     // 0
372
    rrc a
373
 
374
    clr _PDI_CLK
375
    setb _PDI_CLK
376
    mov c,_PDI_DATA     // 1
377
    rrc a
378
 
379
    clr _PDI_CLK
380
    setb _PDI_CLK
381
    mov c,_PDI_DATA     // 2
382
    rrc a
383
 
384
    clr _PDI_CLK
385
    setb _PDI_CLK
386
    mov c,_PDI_DATA     // 3
387
    rrc a
388
 
389
    clr _PDI_CLK
390
    setb _PDI_CLK
391
    mov c,_PDI_DATA     // 4
392
    rrc a
393
 
394
    clr _PDI_CLK
395
    setb _PDI_CLK
396
    mov c,_PDI_DATA     // 5
397
    rrc a
398
 
399
    clr _PDI_CLK
400
    setb _PDI_CLK
401
    mov c,_PDI_DATA     // 6
402
    rrc a
403
 
404
    clr _PDI_CLK
405
    setb _PDI_CLK
406
    mov c,_PDI_DATA     // 7
407
    rrc a
408
 
409
    clr _PDI_CLK
410
    setb _PDI_CLK
411
    mov c,_PDI_DATA     // parity bit
412
    jc 010022$
413
    jb _PF, 010023$     // parity error
414
    sjmp 010026$
415
010022$:
416
    jnb _PF, 010023$    // parity error
417
010026$:
418
 
419
    clr _PDI_CLK
420
    setb _PDI_CLK
421
    mov c,_PDI_DATA     // stop bit 1
422
    jnc 010024$
423
 
424
    clr _PDI_CLK
425
    setb _PDI_CLK
426
    mov c,_PDI_DATA     // stop bit 2
427
    jnc 010025$
428
 
429
    mov dpl,a
430
    ret
431
010023$:
432
    clr _PDI_CLK
433
    setb _PDI_CLK
434
010024$:
435
    clr _PDI_CLK
436
    setb _PDI_CLK
437
010025$:
438
#endif
439
__endasm;
440
    xmega_ec = XMEGA_EC_PDI_READ_ERROR;
441
 
442
    return 0;            // never called (just to avoid warnings)
443
}
444
 
445
/* *********************************************************************
446
   ***** pdi_enable ****************************************************
447
   ********************************************************************* */
448
// enable the pdi
449
void pdi_enable() {     // enter PDI mode
450
    BYTE i;
451
    PDI_IO &= ~PDI_bmDATA;
452
    PDI_IO |= PDI_bmCLK;
453
    OEPDI_PORT |= bmBITPDI_BIT_DATA | bmBITPDI_BIT_CLK;
454
 
455
    PDI_IO |= PDI_bmDATA;
456
    NOP;
457
    NOP;
458
    NOP;
459
    NOP;
460
    NOP;
461
    NOP;
462
 
463
    for (i=0; i<16; i++) {
464
        PDI_IO &= ~PDI_bmCLK;
465
        PDI_IO |= PDI_bmCLK;
466
    }
467
 
468
    pdi_send(0xc2);
469
    pdi_send(2);
470
}
471
 
472
/* *********************************************************************
473
   ***** nvm_status ****************************************************
474
   ********************************************************************* */
475
// read the NVM_STATUS register
476
BYTE nvm_status () {
477
    pdi_send(0x0c);
478
    pdi_send(NVM_STATUS);
479
    pdi_send(0x01);
480
    pdi_send(0x00);
481
    pdi_send(0x01);
482
    return pdi_read();
483
}
484
 
485
 
486
/* *********************************************************************
487
   ***** nvm_wait_busy *************************************************
488
   ********************************************************************* */
489
// wait up to 40ms if NVM is busy
490
void nvm_wait_busy() {
491
    WORD w;
492
    // wait if nvm controller is busy
493
    for ( w=0; w<40000; w++ ) {
494
        if ( ( (nvm_status() & bmBIT7) == 0) || xmega_ec!=0 )
495
            return;
496
    }
497
    xmega_ec = XMEGA_EC_NVM_BUSY;
498
}
499
 
500
/* *********************************************************************
501
   ***** nvm_init ******************************************************
502
   ********************************************************************* */
503
// enable the NVM access via PDI
504
void nvm_init() {       // activate the NVM controller
505
    BYTE b,c,d;
506
    pdi_enable();
507
 
508
    pdi_send(0xc1);     // reset
509
    pdi_send(0x59);
510
 
511
    pdi_send(0xe0);     // send key
512
    pdi_send(0xff);
513
    pdi_send(0x88);
514
    pdi_send(0xd8);
515
    pdi_send(0xcd);
516
    pdi_send(0x45);
517
    pdi_send(0xab);
518
    pdi_send(0x89);
519
    pdi_send(0x12);
520
 
521
    // wait until NVM is available
522
    b = 0; c = 0;
523
    do {
524
        pdi_send(0x80);
525
        c = pdi_read();
526
        d = ((c & bmBIT1) == 0) && (xmega_ec==0);
527
        b+=1;
528
    } while ( (b!=0) && d );
529
    if ( d )
530
        xmega_ec = XMEGA_EC_NVM_TIMEOUT;
531
}
532
 
533
/* *********************************************************************
534
   ***** nvm_register_write*********************************************
535
   ********************************************************************* */
536
// write to NVM register
537
void nvm_register_write(BYTE offs, BYTE b) {
538
    pdi_send(0x4c);     // direct write
539
    pdi_send(offs);
540
    pdi_send(0x01);
541
    pdi_send(0x00);
542
    pdi_send(0x01);
543
    pdi_send(b);
544
}
545
 
546
/* *********************************************************************
547
   ***** nvm_register_write ********************************************
548
   ********************************************************************* */
549
// enable the NVM access via PDI
550
void nvm_done() {       // deactivate the NVM controller
551
    pdi_send(0xc1);     // disable reset
552
    pdi_send(0);
553
 
554
    nvm_register_write(NVM_CMD,0);       // VNM NOP
555
 
556
    PDI_IO &= ~PDI_bmDATA;
557
    PDI_IO |= PDI_bmCLK;
558
}
559
 
560
void nvm_done2() {      // deactivate the NVM controller
561
    nvm_register_write(NVM_CMD,0);       // VNM NOP
562
 
563
    PDI_IO &= ~PDI_bmDATA;
564
    PDI_IO |= PDI_bmCLK;
565
}
566
 
567
 
568
/* *********************************************************************
569
   ***** nvm_read ******************************************************
570
   ********************************************************************* */
571
// read NVM
572
BYTE nvm_read ( __xdata BYTE *buf, DWORD addr, BYTE length ) {
573
    BYTE ol = length;
574
 
575
    if ( length == 0 )
576
        return 0;
577
 
578
    nvm_register_write(NVM_CMD,0x43);    // load NVM read command into NVM CMD register
579
 
580
    pdi_send( 0x6b );            // set ptr
581
    pdi_send( addr & 255 );
582
    pdi_send( (addr>>8) & 255 );
583
    pdi_send( (addr>>16) & 255 );
584
    pdi_send( (addr>>24) & 255 );
585
 
586
    pdi_send( 0xa0 );           // repeat cmd
587
    pdi_send( length-1 );
588
    pdi_send( 0x24 );           // read one byte cmd
589
    while ( (length!=0) && (xmega_ec==0) ) {
590
        *buf = pdi_read(); buf++;
591
        length-= 1;
592
    }
593
 
594
    return ol-length;
595
}
596
 
597
/* *********************************************************************
598
   ***** nvm_page_load *************************************************
599
   ********************************************************************* */
600
// write data into NVM page buffer. Flash: cmd=0x23 , EEPROM: cmd=0x33
601
#define[nvm_flash_page_load(][);][nvm_page_load(0x23, $0);]
602
#define[nvm_eeprom_page_load(][);][nvm_page_load(0x33, $0);]
603
 
604
void nvm_page_load ( BYTE cmd, __xdata BYTE *buf, DWORD addr, BYTE length ) {
605
    BYTE ol = length;
606
 
607
    if ( length == 0 )
608
        return;
609
 
610
    nvm_register_write(NVM_CMD,cmd);    // load "Load Page Buffer" command into CMD register NVM CMD register
611
 
612
    pdi_send( 0x6b );            // set ptr
613
    pdi_send( addr & 255 );
614
    pdi_send( (addr>>8) & 255 );
615
    pdi_send( (addr>>16) & 255 );
616
    pdi_send( (addr>>24) & 255 );
617
 
618
    pdi_send( 0xa0 );           // repeat cmd
619
    pdi_send( length-1 );
620
    pdi_send( 0x64 );           // write one byte cmd
621
    while ( length!=0 ) {
622
        pdi_send(*buf); buf++;
623
        length-= 1;
624
    }
625
}
626
 
627
 
628
/* *********************************************************************
629
   ***** nvm_page_write ************************************************
630
   ********************************************************************* */
631
// erase and write nvm page 
632
#define[nvm_flash_page_write(][);][nvm_page_write(((BYTE)((($0)>>16) & 255)) < nvm_boot_base ? 0x25 : 0x2d, $0);]
633
#define[nvm_eeprom_page_write(][);][nvm_page_write(0x35, $0);]
634
void nvm_page_write (BYTE cmd, DWORD addr ) {
635
    nvm_register_write(NVM_CMD, cmd);   // load "erase and write page" command into NVM CMD register
636
 
637
    pdi_send( 0x4c   );                 // direct write
638
    pdi_send( addr & 255 );
639
    pdi_send( (addr>>8) & 255 );
640
    pdi_send( (addr>>16) & 255 );
641
    pdi_send( (addr>>24) & 255 );
642
    pdi_send( 0 );
643
 
644
    nvm_wait_busy();
645
}
646
 
647
/* *********************************************************************
648
   ***** nvm_fuse_write ************************************************
649
   ********************************************************************* */
650
// write fuse
651
void nvm_fuse_write (BYTE idx, BYTE val) {
652
    nvm_register_write(NVM_CMD, 0x4c);   // load "write fuse" command into NVM CMD register
653
 
654
    pdi_send( 0x4c   );                 // direct write
655
    pdi_send( 0x20 | idx );
656
    pdi_send( 0 );
657
    pdi_send( 0x8f );
658
    pdi_send( 0 );
659
    pdi_send( val );
660
 
661
  nvm_wait_busy();
662
}
663
 
664
/* *********************************************************************
665
   ***** xmega_reset ***************************************************
666
   ********************************************************************* */
667
// reset the xmega
668
void xmega_reset () {
669
    OEPDI_PORT |= bmBITPDI_BIT_CLK;
670
    uwait(20);                  // disable
671
    PDI_IO &= ~PDI_bmCLK;       // enable reset
672
 
673
    uwait(5);
674
    PDI_IO |= PDI_bmCLK;
675
}
676
 
677
/* *********************************************************************
678
   ***** xmega_init ****************************************************
679
   ********************************************************************* */
680
void xmega_init() {
681
    __xdata BYTE xmega_id[3];
682
 
683
    nvm_page_type = 0;
684
    xmega_flash_pages = 0;
685
    xmega_eeprom_pages = 64;
686
    xmega_eeprom_page_size = 5;
687
    xmega_flash_page_size = 9;
688
 
689
 
690
    nvm_init();
691
    if ( xmega_ec != 0 )
692
        return;
693
    nvm_read(xmega_id, 0x01000090, 3);
694
    if ( xmega_ec != 0 )
695
        return;
696
    nvm_done();
697
 
698
    if ( xmega_id[0] != 0x1e ) {
699
        xmega_ec = XMEGA_EC_INVALID_DEVICE;
700
        return;
701
    }
702
 
703
/*  if (  xmega_id[1] == 0x96 && xmega_id[2] == 0x4e ) {        // 64A1 currently not supported
704
        mega_flash_pages = 272;
705
        mega_flash_page_size = 8;
706
        nvm_boot_base = 0x81;
707
    } */
708
    if (  xmega_id[1] == 0x97 && xmega_id[2] == 0x4c ) {        // 128A1
709
        xmega_flash_pages = 272;
710
        nvm_boot_base = 0x82;
711
    }
712
    else if (  xmega_id[1] == 0x97 && xmega_id[2] == 0x4e ) {   // 192A1
713
        xmega_flash_pages = 400;
714
        nvm_boot_base = 0x83;
715
    }
716
    else if (  xmega_id[1] == 0x98 && xmega_id[2] == 0x46 ) {   // 256A1
717
        xmega_flash_pages = 528;
718
        xmega_eeprom_pages = 128;
719
        nvm_boot_base = 0x84;
720
    }
721
    else {
722
        xmega_ec = XMEGA_EC_INVALID_DEVICE;
723
    }
724
}
725
 
726
 
727
 
728
/* *********************************************************************
729
   ***** EP0 vendor request 0x48 ***************************************
730
   ********************************************************************* */
731
// send xmega error and status information to the host
732
ADD_EP0_VENDOR_REQUEST((0x48,,
733
    MEM_COPY1(xmega_ec,EP0BUF,7);
734
    EP0BCH = 0;
735
    EP0BCL = 7;
736
,,
737
    NOP;
738
));;
739
 
740
 
741
/* *********************************************************************
742
   ***** EP0 vendor request 0x49 ***************************************
743
   ********************************************************************* */
744
// reset xmega   
745
ADD_EP0_VENDOR_COMMAND((0x49,,
746
    xmega_reset();
747
,,
748
    NOP;
749
));;
750
 
751
 
752
/* *********************************************************************
753
   ***** EP0 vendor requests 0x4A, 0x4B, 0x4C,0x4D *********************
754
   ********************************************************************* */
755
// read from nvm using: pdi address space (0x4a), flash base (0x4b), EEPROM base (0x4c), FUSE base (0x4d) 
756
BYTE nvm_read_ep0 () {
757
    BYTE i, b;
758
    b = ep0_payload_transfer;
759
    if ( b == 0 )
760
        return 0;
761
 
762
    nvm_init();
763
    i = xmega_ec==0 ? nvm_read(EP0BUF, nvm_addr, b) : 0;
764
    nvm_done();
765
 
766
    nvm_addr += b;
767
    return i;
768
}
769
 
770
ADD_EP0_VENDOR_REQUEST((0x4a: case 0x4b: case 0x4c: case 0x4d,,                 // read from NVM
771
    nvm_addr = *(DWORD*)(&SETUPDAT[2]);
772
    if ( bRequest == 0x4b ) {                                                   // read from Flash
773
        nvm_addr += XMEGA_FLASH_START;
774
    }
775
    else if ( bRequest == 0x4c ) {                                              // read from EEPROM
776
        nvm_addr += XMEGA_EEPROM_START;
777
    }
778
    else if ( bRequest == 0x4d ) {                                              // read FUSES
779
        nvm_addr += XMEGA_FUSE_START;
780
    }
781
    EP0BCH = 0;
782
    EP0BCL = nvm_read_ep0();
783
,,
784
    EP0BCH = 0;
785
    EP0BCL = nvm_read_ep0();
786
));;
787
 
788
 
789
/* *********************************************************************
790
   ***** EP0 vendor command 0x4B ***************************************
791
   ********************************************************************* */
792
// write exactly one flash page
793
void nvm_flash_write_ep0 () {
794
    BYTE b;
795
    b = ep0_payload_transfer;
796
 
797
    nvm_init();
798
    if ( xmega_ec != 0 )
799
        return;
800
 
801
    nvm_flash_page_load(EP0BUF, nvm_addr, b);
802
 
803
    if ( ep0_payload_remaining == 0 ) {
804
        nvm_flash_page_write( nvm_addr );
805
        nvm_done();
806
    }
807
    else {
808
        nvm_done2();
809
    }
810
 
811
    nvm_addr += b;
812
}
813
 
814
ADD_EP0_VENDOR_COMMAND((0x4B,,
815
    nvm_addr = *(DWORD*)(&SETUPDAT[2]);
816
    nvm_addr += XMEGA_FLASH_START;
817
    if ( SETUPDAT[2]!=0 || (SETUPDAT[3] & 1)!=0 || SETUPDAT[7]!=2 || SETUPDAT[6]!=0 || (*(WORD*)(&SETUPDAT[3])>>1)>=xmega_flash_pages )  // only 512 byte pages supported
818
    {
819
        xmega_ec = XMEGA_EC_ADDRESS_ERROR;
820
        EP0_STALL;
821
    }
822
,,
823
    if ( ep0_payload_transfer != 0 ) {
824
        xmega_ec = 0;
825
        nvm_flash_write_ep0();
826
        if ( xmega_ec != 0 ) {
827
            EP0_STALL;
828
        }
829
    }
830
));;
831
 
832
/* *********************************************************************
833
   ***** EP0 vendor command 0x4C ***************************************
834
   ********************************************************************* */
835
// write exactly one EEPROM page
836
ADD_EP0_VENDOR_COMMAND((0x4C,,
837
    nvm_addr = *(DWORD*)(&SETUPDAT[2]);
838
    nvm_addr += XMEGA_EEPROM_START;
839
    if ( ( SETUPDAT[2] & 31 ) != 0 || SETUPDAT[7]!=0 || SETUPDAT[6]!=32 || (*(WORD*)(&SETUPDAT[2])>>5)>=xmega_eeprom_pages )  // only 32 byte pages supported
840
    {
841
        xmega_ec = XMEGA_EC_ADDRESS_ERROR;
842
        EP0_STALL;
843
    }
844
 
845
    nvm_init();
846
    if ( xmega_ec != 0 )
847
        return;
848
 
849
    nvm_eeprom_page_load(EP0BUF, nvm_addr, 32);
850
    nvm_eeprom_page_write( nvm_addr );
851
    nvm_done();
852
,,
853
));;
854
 
855
/* *********************************************************************
856
   ***** EP0 vendor command 0x4D ***************************************
857
   ********************************************************************* */
858
// write one fuse
859
ADD_EP0_VENDOR_COMMAND((0x4D,,
860
    if ( SETUPDAT[6]!=0 || SETUPDAT[7]!=0 || SETUPDAT[5]!=0 || SETUPDAT[4]>7 )
861
    {
862
        xmega_ec = XMEGA_EC_ADDRESS_ERROR;
863
        EP0_STALL;
864
    }
865
 
866
    nvm_init();
867
    nvm_fuse_write(SETUPDAT[4], SETUPDAT[2]);
868
    nvm_done();
869
,,
870
    NOP;
871
));;
872
 
873
 
874
#endif  /*ZTEX_XMEGA_H*/

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.