Contiki 3.x
flash.c
1 /*
2  * Copyright (c) 2014, Lars Schmertmann <SmallLars@t-online.de>.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
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  *
14  * 3. Neither the name of the copyright holder nor the names of its
15  * contributors may be used to endorse or promote products derived
16  * from this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
29  * OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * This file is part of the Contiki operating system.
32  *
33  */
34 
35 #include "flash.h"
36 
37 #define FLASH_BLOCK_SIZE 0x01000
38 
39 #define FLASH_BLOCK_11 0x18000
40 #define FLASH_BLOCK_21 0x1A000
41 
42 #ifndef FLASH_CONF_B1
43 #define FLASH_CONF_B1 FLASH_BLOCK_SIZE
44 #endif
45 
46 #ifndef FLASH_CONF_B2
47 #define FLASH_CONF_B2 FLASH_BLOCK_SIZE
48 #endif
49 
50 #define DEBUG 0
51 
52 #if DEBUG
53 #include <stdio.h>
54 #include "mc1322x.h"
55 #define PRINTF(...) printf(__VA_ARGS__)
56 #else
57 #define PRINTF(...)
58 #endif
59 
60 uint16_t stackPointer;
61 
62 /* private prototypes ----------------------------------------------------- */
63 
64 flash_addr_t getAddr(flash_addr_t address);
65 
66 /* public functions -------------------------------------------------------- */
67 
68 void
70 {
71  PRINTF("Initializing flash ... ");
72 
73  nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 0x0F000000);
74 
75  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\001", FLASH_BLOCK_11, 1);
76  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\001", FLASH_BLOCK_21, 1);
77 
78  uint32_t i;
79  for(i = 1; i < 0x2000; i++) {
80 #if DEBUG
81  if(i % 0x400 == 0) {
82  PRINTF(" .");
83  }
84 #endif
85  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\0", FLASH_BLOCK_11 + i, 1);
86  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, "\0", FLASH_BLOCK_21 + i, 1);
87  }
88 
89  PRINTF("DONE\n");
90 }
91 nvmErr_t
92 flash_getVar(void *dest, flash_addr_t address, uint32_t numBytes)
93 {
94  address = getAddr(address);
95 
96  if(address >= 0x18000 && address <= 0x1EFFF) {
97  PRINTF("Read from Adress: %p\n", address);
98  nvmErr_t err = nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, dest, address, numBytes);
99  if(err) {
100  PRINTF("Read error, nmv_error: %u\n", err);
101  return err;
102  }
103  return gNvmErrNoError_c;
104  }
105 
106  PRINTF("Read error - Invalid pointer.\n");
107  return gNvmErrInvalidPointer_c;
108 }
109 nvmErr_t
110 flash_setVar(void *src, flash_addr_t address, uint32_t numBytes)
111 {
112 #if DEBUG
113  printf("SetVar - START . ");
114  uint32_t time = *MACA_CLK;
115 #endif
116 
117  if(address >= 8192) {
118  PRINTF("Write error - Invalid pointer.\n");
119  return gNvmErrInvalidPointer_c;
120  }
121  uint32_t block_len = (address < 4096 ? FLASH_CONF_B1 : FLASH_CONF_B2);
122 
123  address = getAddr(address);
124 
125  flash_addr_t src_block = address & 0xFF000;
126  flash_addr_t dst_block = src_block ^ 0x01000;
127  address = address & 0x00FFF;
128 
129  if(address < 1 || address >= block_len) {
130  PRINTF("Write error - Invalid pointer.\n");
131  return gNvmErrInvalidPointer_c;
132  }
133  if(address + numBytes > block_len) {
134  PRINTF("Write error - Var is to long.\n");
135  return gNvmErrAddressSpaceOverflow_c;
136  }
137 
138  nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (dst_block / FLASH_BLOCK_SIZE));
139 
140  uint32_t i;
141  uint8_t buf;
142  for(i = 0; i < address; i++) {
143  nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, &buf, src_block + i, 1);
144  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, &buf, dst_block + i, 1);
145  }
146  PRINTF("Write to adress: %p\n", dst_block + i);
147  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, src, dst_block + i, numBytes);
148  for(i += numBytes; i < block_len; i++) {
149  nvm_read(gNvmInternalInterface_c, gNvmType_SST_c, &buf, src_block + i, 1);
150  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, &buf, dst_block + i, 1);
151  }
152 
153  nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (src_block / FLASH_BLOCK_SIZE));
154 
155 #if DEBUG
156  time = *MACA_CLK - time;
157  printf("FINISHED AFTER %u MS\n", time / 250);
158 #endif
159 
160  return gNvmErrNoError_c;
161 }
162 nvmErr_t
163 flash_cmp(void *src, flash_addr_t address, uint32_t numBytes)
164 {
165  address = getAddr(address);
166 
167  if(address >= 0x18000 && address <= 0x1EFFF) {
168  return nvm_verify(gNvmInternalInterface_c, gNvmType_SST_c, src, address, numBytes);
169  }
170  PRINTF("Read error - Invalid pointer.\n");
171  return gNvmErrInvalidPointer_c;
172 }
173 void
175 {
176  stackPointer = 0;
177  nvm_erase(gNvmInternalInterface_c, gNvmType_SST_c, 1 << (FLASH_STACK / FLASH_BLOCK_SIZE));
178 }
179 nvmErr_t
180 flash_stack_push(uint8_t *src, uint32_t numBytes)
181 {
182  if(stackPointer + numBytes > FLASH_BLOCK_SIZE) {
183  return gNvmErrAddressSpaceOverflow_c;
184  }
185 
186  nvm_write(gNvmInternalInterface_c, gNvmType_SST_c, src, FLASH_STACK + stackPointer, numBytes);
187  stackPointer += numBytes;
188  return gNvmErrNoError_c;
189 }
190 uint32_t
192 {
193  return stackPointer;
194 }
195 /* private functions ------------------------------------------------------- */
196 
197 flash_addr_t
198 getAddr(flash_addr_t address)
199 {
200  if(address >= 0x02000) {
201  return address;
202  }
203 
204  flash_addr_t block = (address & 0x01000 ? FLASH_BLOCK_21 : FLASH_BLOCK_11);
205  uint8_t blockcheck = (flash_cmp("\001", block, 1) == 0 ? 0 : 1);
206  return block + (blockcheck << 12) + (address & 0x00FFF);
207 }
uint32_t flash_stack_size()
Stacksize.
Definition: flash.c:191
nvmErr_t flash_cmp(void *src, flash_addr_t address, uint32_t numBytes)
Compares data from RAM with flash memory.
Definition: flash.c:163
void flash_stack_init()
Stack initialisation.
Definition: flash.c:174
nvmErr_t flash_stack_push(uint8_t *src, uint32_t numBytes)
Push data to stack.
Definition: flash.c:180
void flash_init()
Initialize or clear random access blocks.
Definition: flash.c:69
nvmErr_t flash_setVar(void *src, flash_addr_t address, uint32_t numBytes)
Write data to flash memory.
Definition: flash.c:110
nvmErr_t flash_getVar(void *dest, flash_addr_t address, uint32_t numBytes)
Read data from flash memory.
Definition: flash.c:92
App for easy usage of additional flash memory