1 /**
2  * \file
3  *
4  * \brief Non volatile memories management
5  *
6  * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved.
7  *
8  * \asf_license_start
9  *
10  * \page License
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions are met:
14  *
15  * 1. Redistributions of source code must retain the above copyright notice,
16  *    this list of conditions and the following disclaimer.
17  *
18  * 2. Redistributions in binary form must reproduce the above copyright notice,
19  *    this list of conditions and the following disclaimer in the documentation
20  *    and/or other materials provided with the distribution.
21  *
22  * 3. The name of Atmel may not be used to endorse or promote products derived
23  *    from this software without specific prior written permission.
24  *
25  * 4. This software may only be redistributed and used in connection with an
26  *    Atmel microcontroller product.
27  *
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38  * POSSIBILITY OF SUCH DAMAGE.
39  *
40  * \asf_license_stop
41  *
42  */
43 /*
44  * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
45  */
46 
47 #ifndef COMMON_NVM_H_INCLUDED
48 #define COMMON_NVM_H_INCLUDED
49 
50 #include "compiler.h"
51 #include "conf_board.h"
52 #include "parts.h"
53 #include "status_codes.h"
54 
55 #ifdef __cplusplus
56 extern "C" {
57 #endif
58 
59 #if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
60 #include "at45dbx.h"
61 #endif
62 
63 /* ! \name Non volatile memory types */
64 /* ! @{ */
65 typedef enum {
66 	INT_FLASH     /* !< Internal Flash */
67 
68 #if (XMEGA || UC3 || SAM4S)
69 	, INT_USERPAGE  /* !< Userpage/User signature */
70 #endif
71 
72 #if XMEGA
73 	, INT_EEPROM    /* !< Internal EEPROM */
74 #endif
75 
76 #if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
77 	, AT45DBX        /* !< External AT45DBX dataflash */
78 #endif
79 } mem_type_t;
80 /* ! @} */
81 
82 #if SAM
83 #       ifndef IFLASH_PAGE_SIZE
84 #               define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
85 #       endif
86 
87 #       ifndef IFLASH_ADDR
88 #               define IFLASH_ADDR IFLASH0_ADDR
89 #       endif
90 #endif
91 
92 /**
93  * \defgroup nvm_group NVM service
94  *
95  * See \ref common_nvm_quickstart.
96  *
97  * This is the common API for non volatile memories. Additional features are
98  * available
99  * in the documentation of the specific modules.
100  *
101  */
102 
103 /**
104  * \brief Initialize the non volatile memory specified.
105  *
106  * \param mem Type of non volatile memory to initialize
107  */
108 status_code_t nvm_init(mem_type_t mem);
109 
110 /**
111  * \brief Read single byte of data.
112  *
113  * \param mem Type of non volatile memory to read
114  * \param address Address to read
115  * \param data Pointer to where to store the read data
116  */
117 status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data);
118 
119 /**
120  * \brief Write single byte of data.
121  *
122  * \note For SAM4S internal flash, the page existed in the address must be erased first
123  *  before written, and the minimum write unit is a page,thus when writing a single
124  *  byte, a whole page that contains the data is writen.
125  *
126  * \param mem Type of non volatile memory to write
127  * \param address Address to write
128  * \param data Data to be written
129  */
130 status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data);
131 
132 /**
133  * \brief Read \a len number of bytes from address \a address in non volatile
134  * memory \a mem and store it in the buffer \a buffer
135  *
136  * \param mem Type of non volatile memory to read
137  * \param address Address to read
138  * \param buffer Pointer to destination buffer
139  * \param len Number of bytes to read
140  */
141 status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
142 		uint32_t len);
143 
144 /**
145  * \brief Write \a len number of bytes at address \a address in non volatile
146  * memory \a mem from the buffer \a buffer
147  *
148  * \note For SAM4S internal flash, the page existed in the address must be erased
149  *  first before written.
150  *
151  * \param mem Type of non volatile memory to write
152  * \param address Address to write
153  * \param buffer Pointer to source buffer
154  * \param len Number of bytes to write
155  */
156 status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
157 		uint32_t len);
158 
159 /**
160  * \brief Erase a page in the non volatile memory.
161  *
162  * The function is only available for internal flash and/or userpage signature.
163  *
164  * \note For SAM4S internal flash erase, the minimum erase unit is 8 pages.
165  *
166  * \param mem Type of non volatile memory to erase
167  * \param page_number Page number to erase
168  */
169 status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number);
170 
171 /**
172  * \brief Get the size of whole non volatile memory specified.
173  *
174  * \param mem Type of non volatile memory
175  * \param size Pointer to where to store the size
176  */
177 status_code_t nvm_get_size(mem_type_t mem, uint32_t *size);
178 
179 /**
180  * \brief Get the size of a page in the non volatile memory specified.
181  *
182  * \param mem Type of non volatile memory
183  * \param size Pointer to where to store the size
184  */
185 status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size);
186 
187 /**
188  * \brief Get the page number from the byte address \a address.
189  *
190  * \param mem Type of non volatile memory
191  * \param address Byte address of the non volatile memory
192  * \param num Pointer to where to store the page number
193  */
194 status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
195 		uint32_t *num);
196 
197 /**
198  * \brief Enable security bit which blocks external read and write access
199  * to the device.
200  *
201  */
202 status_code_t nvm_set_security_bit(void);
203 
204 /**
205  * \page common_nvm_quickstart Quick Start quide for common NVM driver
206  *
207  * This is the quick start quide for the \ref nvm_group "Common NVM driver",
208  * with step-by-step instructions on how to configure and use the driver in a
209  * selection of use cases.
210  *
211  * The use cases contain several code fragments. The code fragments in the
212  * steps for setup can be copied into a custom initialization function, while
213  * the steps for usage can be copied into, e.g., the main application function.
214  *
215  * \section nvm_basic_use_case Basic use case
216  * In this basic use case, NVM driver is configured for Internal Flash
217  *
218  * \section nvm_basic_use_case_setup Setup steps
219  *
220  * \subsection nvm_basic_use_case_setup_code Example code
221  * Add to you application C-file:
222  * \code
223 	if(nvm_init(INT_FLASH) == STATUS_OK)
224 	  do_something();
225 \endcode
226  *
227  * \subsection nvm_basic_use_case_setup_flow Workflow
228  * -# Ensure that board_init() has configured selected I/Os for TWI function
229  * when using external AT45DBX dataflash
230  * -# Ensure that \ref conf_nvm.h is present for the driver.
231  *   - \note This file is only for the driver and should not be included by the
232  * user.
233  * -# Call nvm_init \code nvm_init(INT_FLASH); \endcode
234  * and optionally check its return code
235  *
236  * \section nvm_basic_use_case_usage Usage steps
237  * \subsection nvm_basic_use_case_usage_code_writing Example code: Writing to
238  * non volatile memory
239  * Use in the application C-file:
240  * \code
241 	   uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
242 
243 	   if(nvm_write(INT_FLASH, test_address, (void *)buffer, sizeof(buffer)) ==
244 	 STATUS_OK)
245 	     do_something();
246 \endcode
247  *
248  * \subsection nvm_basic_use_case_usage_flow Workflow
249  * -# Prepare the data you want to send to the non volatile memory
250  *   \code uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; \endcode
251  * -# Call nvm_write \code nvm_write(INT_FLASH, test_address, (void *)buffer,
252 	 sizeof(buffer)) \endcode
253  * and optionally check its return value for STATUS_OK.
254  *
255  * \subsection nvm_basic_use_case_usage_code_reading Example code: Reading from
256  * non volatile memory
257  * Use in application C-file:
258  * \code
259 	   uint8_t data_read[8];
260 
261 	   if(nvm_read(INT_FLASH, test_address, (void *)data_read, sizeof(data_read))
262 	 == STATUS_OK) {
263 	     //Check read content
264 	     if(data_read[0] == 0xAA)
265 	       do_something();
266 	   }
267 \endcode
268  *
269  * \subsection nvm_basic_use_case_usage_flow Workflow
270  * -# Prepare a data buffer that will read data from non volatile memory
271  *   \code uint8_t data_read[8]; \endcode
272  * -# Call nvm_read \code nvm_read(INT_FLASH, test_address, (void *)data_read,
273 	 sizeof(data_read)); \endcode
274  * and optionally check its return value for STATUS_OK.
275  * The data read from the non volatile memory are in data_read.
276  *
277  * \subsection nvm_basic_use_case_usage_code_erasing Example code: Erasing a
278  * page of non volatile memory
279  * Use in the application C-file:
280  * \code
281 	if(nvm_page_erase(INT_FLASH, test_page) == STATUS_OK)
282 	  do_something();
283 \endcode
284  *
285  * \subsection nvm_basic_use_case_usage_flow Workflow
286  * -# Call nvm_page_erase \code nvm_page_erase(INT_FLASH, test_page) \endcode
287  * and optionally check its return value for STATUS_OK.
288  *
289  * \subsection nvm_basic_use_case_usage_code_config Example code: Reading
290  *configuration of non volatile memory
291  * Use in application C-file:
292  * \code
293 	   uint8_t mem_size, page_size, page_num;
294 
295 	   nvm_get_size(INT_FLASH, &mem_size);
296 	   nvm_get_page_size(INT_FLASH, &page_size);
297 	   nvm_get_pagenumber(INT_FLASH, test_address, &page_num);
298 \endcode
299  *
300  * \subsection nvm_basic_use_case_usage_flow Workflow
301  * -# Prepare a buffer to store configuration of non volatile memory
302  *   \code uint8_t mem_size, page_size, page_num; \endcode
303  * -# Call nvm_get_size \code nvm_get_size(INT_FLASH, &mem_size); \endcode
304  * and optionally check its return value for STATUS_OK.
305  * The memory size of the non volatile memory is in mem_size.
306  * -# Call nvm_get_page_size \code nvm_get_page_size(INT_FLASH, &page_size);
307 \endcode
308  * and optionally check its return value for STATUS_OK.
309  * The page size of the non volatile memory is in page_size.
310  * -# Call nvm_get_pagenumber \code nvm_get_page_number(INT_FLASH, test_address,
311 	 &page_num); \endcode
312  * and optionally check its return value for STATUS_OK.
313  * The page number of given address in the non volatile memory is in page_num.
314  *
315  * \subsection nvm_basic_use_case_usage_code_locking Example code: Enabling
316  * security bit
317  * Use in the application C-file:
318  * \code
319 	if(nvm_set_security_bit() == STATUS_OK)
320 	  do_something();
321 \endcode
322  *
323  * \subsection nvm_basic_use_case_usage_flow Workflow
324  * -# Call nvm_set_security_bit \code nvm_set_security_bit() \endcode
325  * and optionally check its return value for STATUS_OK.
326  */
327 
328 #ifdef __cplusplus
329 }
330 #endif
331 
332 #endif /* COMMON_NVM_H_INCLUDED */
333