Contiki 2.6
|
00001 /* 00002 * Copyright (c) 2006, Swedish Institute of Computer Science 00003 * All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 3. Neither the name of the Institute nor the names of its contributors 00014 * may be used to endorse or promote products derived from this software 00015 * without specific prior written permission. 00016 * 00017 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 00018 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00019 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00020 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 00021 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00022 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 00023 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 00024 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00025 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 00027 * SUCH DAMAGE. 00028 * 00029 * @(#)$Id: rom.c,v 1.2 2006/12/01 15:06:42 bg- Exp $ 00030 */ 00031 00032 #include "contiki.h" 00033 00034 #include "dev/rom.h" 00035 00036 struct ictx { 00037 int s; 00038 unsigned short ie1, ie2, wdtctl; 00039 }; 00040 00041 static void 00042 mask_intr(struct ictx *c) 00043 { 00044 /* Disable all interrupts. */ 00045 c->s = splhigh(); 00046 00047 #define WDTRPW 0x6900 /* Watchdog key returned by read */ 00048 00049 /* Disable all NMI-Interrupt sources */ 00050 c->wdtctl = WDTCTL; 00051 c->wdtctl ^= (WDTRPW ^ WDTPW); 00052 WDTCTL = WDTPW | WDTHOLD; 00053 c->ie1 = IE1; 00054 IE1 = 0x00; 00055 c->ie2 = IE2; 00056 IE2 = 0x00; 00057 00058 /* MSP430F1611 257 < f < 476 kHz, 2.4576MHz/(5+1) = 409.6 kHz. */ 00059 FCTL2 = FWKEY | FSSEL_SMCLK | (FN2 | FN1); 00060 FCTL3 = FWKEY; /* Unlock flash. */ 00061 } 00062 00063 static void 00064 rest_intr(struct ictx *c) 00065 { 00066 FCTL1 = FWKEY; /* Disable erase or write. */ 00067 FCTL3 = FWKEY | LOCK; /* Lock flash. */ 00068 /* Restore interrupts. */ 00069 IE2 = c->ie2; 00070 IE1 = c->ie1; 00071 WDTCTL = c->wdtctl; 00072 splx(c->s); 00073 } 00074 00075 /* 00076 * This helper routine must reside in RAM! 00077 */ 00078 static void 00079 blkwrt(void *to, const void *from, const void *from_end) 00080 // __attribute__ ((section(".data"))) 00081 ; 00082 00083 int 00084 rom_erase(long nbytes, off_t offset) 00085 { 00086 int nb = nbytes; 00087 char *to = (char *)(uintptr_t)offset; 00088 struct ictx c; 00089 00090 if(nbytes % ROM_ERASE_UNIT_SIZE != 0) { 00091 return -1; 00092 } 00093 00094 if(offset % ROM_ERASE_UNIT_SIZE != 0) { 00095 return -1; 00096 } 00097 00098 while (nbytes > 0) { 00099 mask_intr(&c); 00100 00101 FCTL1 = FWKEY | ERASE; /* Segment erase. */ 00102 *to = 0; /* Erase segment containing to. */ 00103 nbytes -= ROM_ERASE_UNIT_SIZE; 00104 to += ROM_ERASE_UNIT_SIZE; 00105 00106 rest_intr(&c); 00107 } 00108 00109 return nb; 00110 } 00111 00112 int 00113 rom_pwrite(const void *buf, int nbytes, off_t offset) 00114 { 00115 const char *from = buf; 00116 int nb = nbytes; 00117 char *to = (char *)(uintptr_t)offset; 00118 struct ictx c; 00119 00120 mask_intr(&c); 00121 00122 while(nbytes > 0) { 00123 int n = (nbytes > 64) ? 64 : nbytes; 00124 FCTL1 = FWKEY | BLKWRT | WRT; /* Enable block write. */ 00125 blkwrt(to, from, from + n); 00126 while(FCTL3 & BUSY); 00127 to += 64; 00128 from += 64; 00129 nbytes -= n; 00130 } 00131 00132 rest_intr(&c); 00133 00134 return nb; 00135 } 00136 00137 /* 00138 * This helper routine must reside in RAM! 00139 */ 00140 asm(".data"); 00141 asm(".p2align 1,0"); 00142 asm(".type blkwrt,@function"); 00143 asm(".section .data"); 00144 00145 static void 00146 blkwrt(void *_to, const void *_from, const void *_from_end) 00147 { 00148 unsigned short *to = _to; 00149 const unsigned short *from = _from; 00150 const unsigned short *from_end = _from_end; 00151 do { 00152 *to++ = *from++; 00153 while(!(FCTL3 & WAIT)); 00154 } while(from < from_end); 00155 FCTL1 = FWKEY; /* Disable block write. */ 00156 /* Now ROM is available again! */ 00157 }