2 * Copyright (c) 2005, Swedish Institute of Computer Science
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * This file is part of the Contiki operating system.
31 * @(#)$Id: loader-arch.c,v 1.1 2006/06/17 22:41:21 adamdunkels Exp $
35 #include "sys/clock.h"
40 #include "dev/eeprom.h"
41 #include "dev/flash.h"
43 #include "loader/loader-arch.h"
45 void *loader_arch_codeaddr
, *loader_arch_dataaddr
;
48 #define FLASHADDR ((char *)0x8000)
49 #define DATAADDR ((char *)0x900)
52 #define beep(n) do { } while (0)
53 #define beep_beep(n) do { } while (0)
55 /*----------------------------------------------------------------------------------*/
57 loader_arch_load(unsigned short startaddr
)
60 unsigned short codelen
, datalen
, sumlen
;
63 unsigned short *flashptr
;
64 void (* init
)(void *);
65 unsigned char tmpdata
[READSIZE
];
68 /* Read the magic word and version number from the first four bytes
70 eeprom_read(startaddr
, (char *)&tmp
, 2);
71 if(tmp
!= HTONS(LOADER_ARCH_MAGIC
)) {
76 eeprom_read(startaddr
+ 2, (char *)&tmp
, 2);
77 if(tmp
!= HTONS(LOADER_ARCH_VERSION
)) {
83 /* Read the total lenghth that the checksum covers. */
84 eeprom_read(startaddr
, (char *)&sumlen
, 2);
86 sumlen
= htons(sumlen
);
90 for(i
= 0; sumlen
- i
> READSIZE
; i
+= READSIZE
) {
91 eeprom_read(startaddr
+ 2 + i
, tmpdata
, READSIZE
);
93 for(j
= 0; j
< READSIZE
; ++j
) {
95 if(sum
< tmpdata
[j
]) {
101 eeprom_read(startaddr
+ 2 + i
, tmpdata
, READSIZE
);
103 for(j
= 0; j
< sumlen
- i
; ++j
) {
105 if(sum
< tmpdata
[j
]) {
111 /* If the checksum was wrong, we beep. The number of beeps indicate
112 the numerival value of the calculated checksum. */
116 for(i
= 0; i
< (sum
>> 4); ++i
) {
118 for(j
= 0; j
< 2; ++j
) {
123 for(j
= 0; j
< 8; ++j
) {
127 for(i
= 0; i
< (sum
& 0x0f); ++i
) {
129 for(j
= 0; j
< 2; ++j
) {
140 for(i
= 0; i
< 4; ++i
) {
142 for(j
= 0; j
< 2; ++j
) {
146 leds_green(LEDS_OFF
);
150 leds_yellow(LEDS_ON
);
153 /* Read the size of the code segment from the next two bytes in EEPROM. */
154 eeprom_read(startaddr
, (char *)&codelen
, 2);
155 /* Convert from network byte order to host byte order. */
156 codelen
= htons(codelen
);
159 /* Flash program code into ROM. We use the available space in the
160 program's data memory to temporarily store the code before
161 flashing it into ROM. */
164 flashptr
= (unsigned short *)FLASHADDR
;
165 for(ptr
= startaddr
+ 2; ptr
< startaddr
+ 2 + codelen
; ptr
+= READSIZE
) {
167 /* Read data from EEPROM into RAM. */
168 eeprom_read(ptr
, DATAADDR
, READSIZE
);
170 /* Clear flash page on 512 byte boundary. */
171 if((((unsigned short)flashptr
) & 0x01ff) == 0) {
172 flash_clear(flashptr
);
175 /* Burn data from RAM into flash ROM. Flash is burned one 16-bit
176 word at a time, so we need to be careful when incrementing
177 pointers. The flashptr is already a short pointer, so
178 incrementing it by one will actually increment the address by
180 for(i
= 0; i
< READSIZE
/ 2; ++i
) {
181 flash_write(flashptr
, ((unsigned short *)DATAADDR
)[i
]);
188 leds_yellow(LEDS_OFF
);
192 /* Read the size of the code segment from the first two bytes in EEPROM. */
193 eeprom_read(startaddr
+ 2 + codelen
, (char *)&datalen
, 2);
195 /* Convert from network byte order to host byte order. */
196 datalen
= htons(datalen
);
199 /* Read the contents of the data memory into RAM. */
200 eeprom_read(startaddr
+ 2 + codelen
+ 2, DATAADDR
, datalen
);
203 for(i
= 0; i
< 4; ++i
) {
208 leds_green(LEDS_OFF
);
210 /* Execute the loaded program. */
211 init
= ((void (*)(void *))FLASHADDR
);
214 /*----------------------------------------------------------------------------------*/
216 loader_arch_free(void *code
, void *data
)
219 /*----------------------------------------------------------------------------------*/