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