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    }