Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2010, Mariano Alvira <mar@devl.org> and other contributors 00003 * to the MC1322x project (http://mc1322x.devl.org) 00004 * All rights reserved. 00005 * 00006 * Redistribution and use in source and binary forms, with or without 00007 * modification, are permitted provided that the following conditions 00008 * are met: 00009 * 1. Redistributions of source code must retain the above copyright 00010 * notice, this list of conditions and the following disclaimer. 00011 * 2. Redistributions in binary form must reproduce the above copyright 00012 * notice, this list of conditions and the following disclaimer in the 00013 * documentation and/or other materials provided with the distribution. 00014 * 3. Neither the name of the Institute nor the names of its contributors 00015 * may be used to endorse or promote products derived from this software 00016 * without specific prior written permission. 00017 * 00018 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00019 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00020 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00021 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00022 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00023 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00024 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00025 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00026 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00027 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00028 * SUCH DAMAGE. 00029 * 00030 * This file is part of libmc1322x: see http://mc1322x.devl.org 00031 * for details. 00032 * 00033 * 00034 */ 00035 00036 #include <mc1322x.h> 00037 #include <board.h> 00038 00039 #include "tests.h" 00040 #include "config.h" 00041 00042 #define DEBUG 1 00043 #if DEBUG 00044 #define dbg_putchr(...) putchr(__VA_ARGS__) 00045 #define dbg_putstr(...) putstr(__VA_ARGS__) 00046 #define dbg_put_hex(...) put_hex(__VA_ARGS__) 00047 #define dbg_put_hex16(...) put_hex16(__VA_ARGS__) 00048 #define dbg_put_hex32(...) put_hex32(__VA_ARGS__) 00049 #else 00050 #define dbg_putchr(...) 00051 #define dbg_putstr(...) 00052 #define dbg_put_hex(...) 00053 #define dbg_put_hex16(...) 00054 #define dbg_put_hex32(...) 00055 #endif 00056 00057 uint8_t getc(void) 00058 { 00059 volatile uint8_t c; 00060 while(*UART1_URXCON == 0); 00061 00062 c = *UART1_UDATA; 00063 return c; 00064 } 00065 00066 00067 void flushrx(void); 00068 uint32_t to_u32(volatile uint32_t *c); 00069 00070 enum parse_states { 00071 SCAN_X, 00072 READ_CHARS, 00073 PROCESS, 00074 MAX_STATE, 00075 }; 00076 00077 void main(void) { 00078 nvmType_t type=0; 00079 nvmErr_t err; 00080 volatile uint8_t c; 00081 volatile uint32_t i; 00082 volatile uint32_t buf[4]; 00083 volatile uint32_t len=0; 00084 volatile uint32_t state = SCAN_X; 00085 volatile uint32_t addr,data; 00086 00087 00088 uart_init(INC, MOD, SAMP); 00089 disable_irq(UART1); 00090 00091 vreg_init(); 00092 00093 dbg_putstr("Detecting internal nvm\n\r"); 00094 00095 err = nvm_detect(gNvmInternalInterface_c, &type); 00096 00097 dbg_putstr("nvm_detect returned: 0x"); 00098 dbg_put_hex(err); 00099 dbg_putstr(" type is: 0x"); 00100 dbg_put_hex32(type); 00101 dbg_putstr("\n\r"); 00102 00103 /* erase the flash */ 00104 err = nvm_erase(gNvmInternalInterface_c, type, 0x7fffffff); 00105 00106 dbg_putstr("nvm_erase returned: 0x"); 00107 dbg_put_hex(err); 00108 dbg_putstr("\n\r"); 00109 00110 dbg_putstr(" type is: 0x"); 00111 dbg_put_hex32(type); 00112 dbg_putstr("\n\r"); 00113 00114 /* say we are ready */ 00115 len = 0; 00116 putstr("ready"); 00117 flushrx(); 00118 00119 /* read the length */ 00120 for(i=0; i<4; i++) { 00121 c = uart1_getc(); 00122 /* bail if the first byte of the length is zero */ 00123 len += (c<<(i*8)); 00124 } 00125 00126 dbg_putstr("len: "); 00127 dbg_put_hex32(len); 00128 dbg_putstr("\n\r"); 00129 00130 /* write the OKOK magic */ 00131 00132 #if BOOT_OK 00133 ((uint8_t *)buf)[0] = 'O'; ((uint8_t *)buf)[1] = 'K'; ((uint8_t *)buf)[2] = 'O'; ((uint8_t *)buf)[3] = 'K'; 00134 #elif BOOT_SECURE 00135 ((uint8_t *)buf)[0] = 'S'; ((uint8_t *)buf)[1] = 'E'; ((uint8_t *)buf)[2] = 'C'; ((uint8_t *)buf)[3] = 'U'; 00136 #else 00137 ((uint8_t *)buf)[0] = 'N'; ((uint8_t *)buf)[1] = 'O'; ((uint8_t *)buf)[2] = 'N'; ((uint8_t *)buf)[3] = 'O'; 00138 #endif 00139 00140 dbg_putstr(" type is: 0x"); 00141 dbg_put_hex32(type); 00142 dbg_putstr("\n\r"); 00143 00144 /* don't make a valid boot image if the received length is zero */ 00145 if(len == 0) { 00146 ((uint8_t *)buf)[0] = 'N'; 00147 ((uint8_t *)buf)[1] = 'O'; 00148 ((uint8_t *)buf)[2] = 'N'; 00149 ((uint8_t *)buf)[3] = 'O'; 00150 } 00151 00152 err = nvm_write(gNvmInternalInterface_c, type, (uint8_t *)buf, 0, 4); 00153 00154 dbg_putstr("nvm_write returned: 0x"); 00155 dbg_put_hex(err); 00156 dbg_putstr("\n\r"); 00157 00158 /* write the length */ 00159 err = nvm_write(gNvmInternalInterface_c, type, (uint8_t *)&len, 4, 4); 00160 00161 /* read a byte, write a byte */ 00162 for(i=0; i<len; i++) { 00163 c = getc(); 00164 err = nvm_write(gNvmInternalInterface_c, type, (uint8_t *)&c, 8+i, 1); 00165 } 00166 00167 putstr("flasher done\n\r"); 00168 00169 state = SCAN_X; addr=0; 00170 while((c=getc())) { 00171 if(state == SCAN_X) { 00172 /* read until we see an 'x' */ 00173 if(c==0) { break; } 00174 if(c!='x'){ continue; } 00175 /* go to read_chars once we have an 'x' */ 00176 state = READ_CHARS; 00177 i = 0; 00178 } 00179 if(state == READ_CHARS) { 00180 /* read all the chars up to a ',' */ 00181 ((uint8_t *)buf)[i++] = c; 00182 /* after reading a ',' */ 00183 /* goto PROCESS state */ 00184 if((c == ',') || (c == 0)) { state = PROCESS; } 00185 } 00186 if(state == PROCESS) { 00187 if(addr==0) { 00188 /*interpret the string as the starting address */ 00189 addr = to_u32(buf); 00190 } else { 00191 /* string is data to write */ 00192 data = to_u32(buf); 00193 putstr("writing addr "); 00194 put_hex32(addr); 00195 putstr(" data "); 00196 put_hex32(data); 00197 putstr("\n\r"); 00198 err = nvm_write(gNvmInternalInterface_c, 1, (uint8_t *)&data, addr, 4); 00199 addr += 4; 00200 } 00201 /* look for the next 'x' */ 00202 state=SCAN_X; 00203 } 00204 } 00205 00206 while(1) {continue;}; 00207 } 00208 00209 void flushrx(void) 00210 { 00211 volatile uint8_t c; 00212 while(*UART1_URXCON !=0) { 00213 c = *UART1_UDATA; 00214 } 00215 } 00216 00217 /* Convert from ASCII hex. Returns 00218 the value, or 16 if it was space/newline, or 00219 32 if some other character. */ 00220 uint8_t from_hex(uint8_t ch) 00221 { 00222 if(ch==' ' || ch=='\r' || ch=='\n') 00223 return 16; 00224 00225 if(ch < '0') 00226 goto bad; 00227 if(ch <= '9') 00228 return ch - '0'; 00229 ch |= 0x20; 00230 if(ch < 'a') 00231 goto bad; 00232 if(ch <= 'f') 00233 return ch - 'a' + 10; 00234 bad: 00235 return 32; 00236 } 00237 00238 uint32_t to_u32(volatile uint32_t *c) 00239 { 00240 volatile uint32_t ret=0; 00241 volatile uint32_t i,val; 00242 00243 /* c should be /x\d+,/ */ 00244 i=1; /* skip x */ 00245 while(((uint8_t *)c)[i] != ',') { 00246 ret = ret<<4; 00247 val = from_hex(((uint8_t *)c)[i++]); 00248 ret += val; 00249 } 00250 return ret; 00251 } 00252 00253 00254