1 /*
2 #asm
3 .cseg
4 .org mainflash
5 #endasm
6 */
7 void ReadPage(UINT pageStart, UINT *instArr, UCHAR instCount)
8 {
9 register int i;
10 for (i = 0; i < instCount; ++i)
11 {
12 instArr[i] = ReadInst(pageStart + (i << 1));
13 }
14 }
15 void WriteSector(UINT sectorStart, UINT *instArr)
16 {
17 WritePage(sectorStart + 0, instArr+0, 64);
18 WritePage(sectorStart + 128, instArr+64, 64);
19 WritePage(sectorStart + 256, instArr+128, 64);
20 WritePage(sectorStart + 384, instArr+192, 64);
21 }
22 /*
23 #asm
24 .org bootloader
25 #endasm
26 */
27
28 // This is the only code that really needs to reside in the bootloader
29 // since it is reading/writing from flash
30 UINT ReadInst(UINT instAddr)
31 {
32 g_instaddr = instAddr;
33 #asm
34 movw r30, r6 ; // move instAddr to Z pointer
35 lpm r2, Z+ ; // read LSB
36 lpm r3, Z ; // read MSB
37 #endasm
38 return g_instdata;
39 }
40 // instCount must be <= 64 (instructions) (128 bytes)
41 void WritePage(UINT pageStart, UINT *instArr, UCHAR instCount)
42 {
43 register UCHAR i;
44 #asm("cli");
45 g_pageaddr = pageStart;
46
47 for (i = 0; i < instCount; ++i)
48 {
49 // do some big-endian / little-endian crap
50 g_instdata = (instArr[i] >> 8) | (instArr[i] << 8);
51 while (SPMCR&1); //wait for spm complete
52 g_instaddr = pageStart + (i << 1);
53
54 g_spmcrval=1;
55 #asm
56 movw r30, r6 ;//move CurrentAddress to Z pointer
57 mov r1, r3 ;//move Pagedata MSB reg 1
58 mov r0, r2 ;//move Pagedata LSB reg 0
59 sts SpmcrAddr, r10 ;//move spmcrval to SPM control register
60 spm ;//store program memory
61 #endasm
62 }
63
64 while (SPMCR&1); //wait for spm complete
65 g_spmcrval=3; //erase page cmd
66 #asm
67 movw r30, r4 ;//move pageStart to Z pointer
68 sts SpmcrAddr, r10 ;//move spmcrval to SPM control register
69 spm ;//erase page
70 #endasm
71
72 while (SPMCR&1); //wait for spm complete
73 g_spmcrval=5; //write page cmd
74 #asm
75 movw r30, r4 ;//move PageAddress to Z pointer
76 sts SpmcrAddr, r10 ;//move spmcrval to SPM control register
77 spm ;//write page
78 #endasm
79
80 while (SPMCR&1); //wait for spm complete
81 g_spmcrval=0x11; //enableRWW
82
83 #asm
84 sts SpmcrAddr, r10 ;//move spmcrval to SPMCR
85 spm
86 #endasm
87
88 #asm("sei");
89 }