1 | #include <mega16.h>
|
2 | // Standard Input/Output functions
|
3 | #define RXC = 7;
|
4 | #define SPMEM = 0;
|
5 | #define PGERS = 1:
|
6 | #define RWWSRE = 4;
|
7 | flash unsigned char PAGESIZE = 64; //Pagegröße in word -> 128Byte
|
8 | flash unsigned char SITESIZE = 128; //Anzahl der Seiten -> 128Seiten * 128 Byte
|
9 | flash unsigned char DeviceID = 16;
|
10 | flash unsigned char PAGE_OK = 1;
|
11 | flash unsigned char PAGE_FALSE = 0;
|
12 | flash unsigned int PageAdress = 0x0200;
|
13 |
|
14 |
|
15 | #pragma regalloc- /* Deaktivierung der automatischen Vergabe von Adressen an Variablen*/
|
16 | register unsigned int daten @0x0002;
|
17 | register unsigned int SiteAdress @0x0004;
|
18 | register unsigned int CurrentAdress @0x0006;
|
19 | unsigned char recbyte @0x0062;
|
20 | unsigned int SendSite @0x0064;
|
21 | unsigned int i @0x0066;
|
22 | unsigned int j @0x0068;
|
23 | unsigned char PAGE_BUFFER[128] @0x008A;
|
24 | #pragma regalloc+ /* Aktivierung der automatischen Vergabe von Adressen an Variablen*/
|
25 |
|
26 |
|
27 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
28 | void BOOTLOAD(void);
|
29 | void READ_COM_2_PUFFER(void);
|
30 | void RAM_2_TEMP_PAGE(void);
|
31 | void PAGE_ERASE(void);
|
32 | void REENABLE_RWW(void);
|
33 | void PAGE_WRITE(void);
|
34 | void DO_SPM(void);
|
35 | void RESTORE_ZPOINTER(void);
|
36 |
|
37 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++
|
38 | // Get a character from the USART1 Receiver
|
39 | char getchar(void)
|
40 | {
|
41 | unsigned char data;
|
42 | while ( (UCSRA & 0x80)==0x00 );//0->keine Daten zum Lesen vorhanden 1->Daten bereit zum Lesen
|
43 | data=UDR;
|
44 | return data;
|
45 | }
|
46 |
|
47 | // Write a character to the USART1 Transmitter
|
48 | void putchar(char c)
|
49 | {
|
50 | while ( (UCSRA & 0x20)==0x00 );//0->Daten vorhanden zum senden 1->Frei zum Senden
|
51 | UDR=c;
|
52 | }
|
53 |
|
54 | //M A I N ++++++++++++++++++++++++++++++++++++++++++++++
|
55 | void main(void)
|
56 | {
|
57 | //INIT USART
|
58 | UCSRB=0x18;
|
59 | UCSRC=0x86;
|
60 | UBRRL=0x17;
|
61 | //##########
|
62 | i=0;
|
63 | //Sende Startzeichen
|
64 | putchar(0x01);
|
65 | //Warte um Daten zu empfangen - i>65000->Timeout führe Programm aus
|
66 | while ( ((UCSRA & 0x80)==0) & (i<65000) )i++;
|
67 | if (i<65000)
|
68 | {
|
69 | recbyte=getchar();
|
70 | if(recbyte==0x02)BOOTLOAD();
|
71 | }
|
72 | #asm("jmp 0x00"); //Springe zur an Adresse0x00
|
73 | }
|
74 |
|
75 | void BOOTLOAD(void)
|
76 | {
|
77 | putchar(DeviceID);
|
78 | i = 0;
|
79 | //Warte um Daten zu empfangen - i->Timeout führe Programm aus
|
80 | while ( ((UCSRA&0x80)==0) & (i<65000) ) i++;
|
81 | if (i<65000)
|
82 | {
|
83 | SendSite=getchar();
|
84 | for(SiteAdress=0; SiteAdress<=SendSite; SiteAdress++)
|
85 | {
|
86 | //Z-Pointer auf Adresse abstimmen
|
87 | CurrentAdress = SiteAdress * (1<<6) + PageAdress;
|
88 | //Page löschen
|
89 | PAGE_ERASE();
|
90 | //Reaktivierung des RWW-Bereichs
|
91 | REENABLE_RWW();
|
92 | //Daten aus serielle Schnittstelle lesen und in Array speichern
|
93 | READ_COM_2_PUFFER();
|
94 | //Von Array in temporären Pagespeicher speichern
|
95 | RAM_2_TEMP_PAGE();
|
96 | //Page schreiben
|
97 | PAGE_WRITE();
|
98 | //Reaktivierung des RWW-Bereichs
|
99 | REENABLE_RWW();
|
100 | //von temp Page nach Flash seitenweise kopieren
|
101 | //Rückmelung an HOST, dass PAGE erfolgreich kopiert wurde und soll wenn i<SEND
|
102 | /* if(SiteAdress<SendSite)
|
103 | {
|
104 | putchar(0xFE);
|
105 | while(!(UCSRA&0x80));
|
106 | recbyte=getchar();
|
107 | if(recbyte==1)SendSite++;
|
108 | }
|
109 | */ }
|
110 | }
|
111 | putchar(0xFF);
|
112 | }
|
113 | void READ_COM_2_PUFFER(void)
|
114 | {
|
115 | //Bereit zum Empfangen
|
116 | putchar(0x03);
|
117 | for(j=0;j<(PAGESIZE*2);j++)PAGE_BUFFER[j]=getchar();
|
118 | }
|
119 |
|
120 |
|
121 | void PAGE_ERASE(void)
|
122 | {
|
123 | //Löscht Page die in PAGE-Adresse des Z-Pointer(Z6...Z12) steht
|
124 | #asm
|
125 | movw r30,r6;
|
126 | ldi r17,0x03;
|
127 | #endasm
|
128 | DO_SPM();
|
129 | }
|
130 |
|
131 | void REENABLE_RWW(void)
|
132 | {
|
133 | #asm("ldi r17,0x11");
|
134 | DO_SPM();
|
135 |
|
136 | }
|
137 |
|
138 |
|
139 | void RAM_2_TEMP_PAGE(void)
|
140 | {
|
141 | unsigned char n;
|
142 | for(n=0;n<128;n+=2)
|
143 | {
|
144 | daten=PAGE_BUFFER[j]+256*PAGE_BUFFER[j+1]; //schreibt wort in registerpar r3+r2
|
145 | #asm("movw r0,r2"); //kopiert wert r3+r2 in r1+r0
|
146 | DO_SPM();
|
147 | #asm("adiw r31:r30,2"); //kopiert wert r3+r2 in r1+r0
|
148 | }
|
149 |
|
150 |
|
151 | }
|
152 |
|
153 | void PAGE_WRITE(void)
|
154 | {
|
155 | #asm
|
156 | movw r30,r6;
|
157 | ldi r17,0x05;
|
158 | #endasm
|
159 | DO_SPM();
|
160 | }
|
161 |
|
162 |
|
163 | void DO_SPM(void)
|
164 | {
|
165 | #asm
|
166 | WAIT_SPM:
|
167 | in r16,0x37; //SPMCR in Register r16 einlesen
|
168 | sbrc r16,0x01; //Skip if Bit in Register is Cleared
|
169 | rjmp WAIT_SPM;
|
170 | out 0x37,r17; //schreibe in SPMCR-Register und führe aus
|
171 | spm;
|
172 | #endasm
|
173 | }
|