1 /*
2  * Copyright (c) 2015-2019, Texas Instruments Incorporated
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  *
9  * *  Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  *
12  * *  Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * *  Neither the name of Texas Instruments Incorporated nor the names of
17  *    its contributors may be used to endorse or promote products derived
18  *    from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 /*!****************************************************************************
33  *  @file       NVS.h
34  *  @brief      Non-Volatile Storage driver interface
35  *
36  *  @anchor ti_drivers_NVS_Overview
37  *  # Overview #
38  *
39  *  The NVS module allows you to manage non-volatile memory.  Using the
40  *  NVS APIs, you can read and write data from and to persistent storage.
41  *
42  *  Each NVS object is used to manage a region of non-volatile memory.
43  *  The size of the region is specified in the device specific driver's
44  *  hardware attributes.
45  *  A sector is the smallest unit of non-volatile storage that can be erased
46  *  at one time. The size of the sector, or sector size, is hardware specific
47  *  and may be meaningless for some non-volatile storage hardware. For flash
48  *  memory devices, the region must be aligned with the sector size. That is,
49  *  the region must start on a sector boundary. Additionally, the overall size
50  *  of the region must be an integer multiple of the sector size.
51  *
52  *  <hr>
53  *  @anchor ti_drivers_NVS_Usage
54  *  # Usage
55  *
56  *  This section provides a basic @ref ti_drivers_NVS_Synopsis
57  *  "usage summary" and a set of @ref ti_drivers_NVS_Examples "examples"
58  *  in the form of commented code fragments. Detailed descriptions of the
59  *  APIs are provided in subsequent sections.
60 
61  *  The NVS driver interface provides device independent APIs, data types,
62  *  and macros.  The following code example opens an NVS region instance,
63  *  writes a string into it, then prints the string after reading it back
64  *  into a local buffer, and also prints the string from its directly
65  *  addressable location in flash memory.
66  *
67  *  @anchor ti_drivers_NVS_Synopsis
68  *  ## Synopsis
69  *  @anchor ti_drivers_NVS_Synopsis_Code
70  *  @code
71  *  // Import NVS Driver definitions
72  *  #include <ti/drivers/NVS.h>
73  *
74  *  // One time init of NVS driver
75  *  NVS_init();
76  *
77  *  // Initialize optional NVS parameters
78  *  NVS_Params_init(&nvsParams);
79  *
80  *  // Open NVS driver instance
81  *  nvsRegion = NVS_open(config_NVS0, &nvsParams);
82  *
83  *  // write "Hello" to the base address of region 0, verify after write
84  *  status = NVS_write(nvsRegion, 0, "Hello", strlen("Hello")+1, NVS_POST_VERIFY);
85  *
86  *  // Close NVS region
87  *  NVS_close(nvsRegion);
88  *
89  *  @endcode
90  *
91  *  <hr>
92  *  @anchor ti_drivers_NVS_Examples
93  *  # Examples
94  *
95  *  @li @ref ti_drivers_NVS_Examples_open "Opening an NVS region instance"
96  *  @li @ref ti_drivers_NVS_Examples_typical "Typical NVS region operations"
97  *
98  *  @anchor ti_drivers_NVS_Examples_open
99  *  ## Opening an NVS region instance
100  *
101  *  @code
102  *      NVS_Handle nvsRegion;
103  *      NVS_Params nvsParams;
104  *
105  *      NVS_Params_init(&nvsParams);
106  *      nvsRegion = NVS_open(CONFIG_NVS0, &nvsParams);
107  *  @endcode
108  *
109  *  @anchor ti_drivers_NVS_Examples_typical
110  *  ## Erasing, writing, reading an NVS region
111  *
112  *  The following code example opens an NVS region instance, erases the first
113  *  sector of that region, writes a string into it, then prints the string
114  *  after reading it back into a local buffer. If the string is directly CPU
115  *  addressable (i.e. not in SPI flash), the string is printed from
116  *  its location in flash memory.
117  *
118  *  @code
119  *
120  *      // Import NVS Driver definitions
121  *      #include <ti/drivers/NVS.h>
122  *
123  *      NVS_Handle nvsRegion;
124  *      NVS_Attrs regionAttrs;
125  *
126  *      uint_fast16_t status;
127  *      char buf[32];
128  *
129  *      // initialize the NVS driver
130  *      NVS_init();
131  *
132  *      //
133  *      // Open the NVS region specified by the 0th element in the NVS_config[]
134  *      // array defined in ti_drivers_config.c.
135  *      //
136  *      // Use default NVS_Params to open this memory region, hence 'NULL'
137  *      //
138  *      nvsRegion = NVS_open(CONFIG_NVS0, NULL);
139  *
140  *      // Confirm that the NVS region opened properly
141  *      if (nvsRegion == NULL) {
142  *          // Error handling code
143  *      }
144  *
145  *      // Fetch the generic NVS region attributes for nvsRegion
146  *      NVS_getAttrs(nvsRegion, &regionAttrs);
147  *
148  *      // Erase the first sector of nvsRegion
149  *      status = NVS_erase(nvsRegion, 0, regionAttrs.sectorSize);
150  *      if (status != NVS_STATUS_SUCCESS) {
151  *          // Error handling code
152  *      }
153  *
154  *      // Write "Hello" to the base address of nvsRegion, verify after write
155  *      status = NVS_write(nvsRegion, 0, "Hello", strlen("Hello")+1, NVS_POST_VERIFY);
156  *      if (status != NVS_STATUS_SUCCESS) {
157  *          // Error handling code
158  *      }
159  *
160  *      // Copy "Hello" from nvsRegion into local 'buf'
161  *      status = NVS_read(nvsRegion, 0, buf, strlen("Hello")+1);
162  *      if (status != NVS_STATUS_SUCCESS) {
163  *          // Error handling code
164  *      }
165  *
166  *      // Print the string from fetched NVS storage
167  *      System_printf("%s\n", buf);
168  *
169  *      //
170  *      // Print the string using direct flash address reference if valid
171  *      //
172  *      // When the NVS driver is managing SPI flash non volatile
173  *      // storage, the regionBase attribute will be `NVS_REGION_NOT_ADDRESSABLE`
174  *      //
175  *      if (regionAttrs.regionBase != NVS_REGION_NOT_ADDRESSABLE) {
176  *         System_printf("%s\n", regionAttrs.regionBase);
177  *      }
178  *
179  *      // close the region
180  *      NVS_close(nvsRegion);
181  *
182  *  @endcode
183  *
184  *  <hr>
185  *  @anchor ti_drivers_NVS_Configuration
186  *  # Configuration
187  *
188  *  Refer to the @ref driver_configuration "Driver's Configuration" section
189  *  for driver configuration information.
190  *  <hr>
191  *
192  *  # Example discussion
193  *
194  *  Details for the @ref ti_drivers_NVS_Examples_typical "Typical NVS region operations"
195  *  example code above are described in the following subsections.
196  *
197  *  ### NVS Driver Configuration #
198  *
199  *  In order to use the NVS APIs, the application is required to provide
200  *  device-specific NVS configuration in the ti_drivers_config.c file.
201  *  The NVS driver interface defines a configuration data structure,
202  *  #NVS_Config.
203  *
204  *  The application must declare an array of #NVS_Config elements, named
205  *  \p NVS_config[].  Each element of \p NVS_config[] is populated with
206  *  pointers to a device specific NVS driver implementation's function
207  *  table, driver object, and hardware attributes.  The hardware attributes
208  *  define properties such as the NVS region's base address and size,
209  *  Each element in \p NVS_config[] corresponds to a NVS instance, and none
210  *  of the elements should have NULL pointers.
211  *
212  *  You will need to check the device-specific NVS driver implementation's
213  *  header file for example configuration.  Please also refer to the
214  *  ti_drivers_config.c file of any of the examples to see the NVS configuration.
215  *
216  *  ### Initializing the NVS Driver #
217  *
218  *  NVS_init() must be called before any other NVS APIs.  This function
219  *  calls the device implementation's NVS initialization function, for each
220  *  element of \p NVS_config[].
221  *
222  *  ### Opening the NVS Driver #
223  *
224  *  Opening a NVS requires four steps:
225  *  1.  Optionally create and initialize a #NVS_Params structure.
226  *  2.  Fill in the desired parameters.
227  *  3.  Call NVS_open(), passing the index of the NVS region in the #NVS_Config
228  *      structure, and the address of the #NVS_Params structure.
229  *  4.  Check that the #NVS_Handle returned by NVS_open() is non-NULL,
230  *      and save it.  The handle will be used to read and write to the
231  *      NVS you just opened.
232  *
233  *  \note Each NVS index can only be opened exclusively. Calling NVS_open()
234  *  multiple times with the same index will result in an error. The index can
235  *  be re-used if NVS_close() is called first.
236  *
237  *  <hr>
238  *  # Thread Safety #
239  *
240  *  All NVS APIs are globally thread safe. Consequently, only one write,
241  *  erase (or read in the case of SPI flash) operation is allowed to be
242  *  performed at a time, even for distinct NVS regions. Threads initiating
243  *  new NVS writes or erases will block until any current operation completes.
244  *
245  *  # Interrupt Latency During Flash Operations #
246  *
247  *  When writing to or erasing internal flash, interrupts must be disabled
248  *  to avoid executing code in flash while the flash is being reprogrammed.
249  *  This constraint is met internally by the driver. User code does not need
250  *  to safeguard against this.
251  *
252  *  Care must be taken by the user to not perform flash write or erase
253  *  operations during latency critical phases of an application. See the
254  *  NVS_lock() and NVS_unlock() API descriptions for more information.
255  *
256  *****************************************************************************
257  */
258 
259 #ifndef ti_drivers_NVS__include
260 #define ti_drivers_NVS__include
261 
262 #include <stdbool.h>
263 #include <stddef.h>
264 #include <stdint.h>
265 
266 #if defined (__cplusplus)
267 extern "C" {
268 #endif
269 
270 /**
271  *  @defgroup NVS_CONTROL NVS_control command and status codes
272  *  These NVS macros are reservations for NVS.h
273  *  @{
274  */
275 
276 /*!
277  *  Common NVS_control command code reservation offset.
278  *  NVS driver implementations should offset command codes with NVS_CMD_RESERVED
279  *  growing positively
280  *
281  *  Example implementation specific command codes:
282  *  @code
283  *  #define NVSXYZ_CMD_COMMAND0     NVS_CMD_RESERVED + 0
284  *  #define NVSXYZ_CMD_COMMAND1     NVS_CMD_RESERVED + 1
285  *  @endcode
286  */
287 #define NVS_CMD_RESERVED            (32)
288 
289 /*!
290  *  Common NVS_control status code reservation offset.
291  *  NVS driver implementations should offset status codes with
292  *  NVS_STATUS_RESERVED growing negatively.
293  *
294  *  Example implementation specific status codes:
295  *  @code
296  *  #define NVSXYZ_STATUS_ERROR0    NVS_STATUS_RESERVED - 0
297  *  #define NVSXYZ_STATUS_ERROR1    NVS_STATUS_RESERVED - 1
298  *  #define NVSXYZ_STATUS_ERROR2    NVS_STATUS_RESERVED - 2
299  *  @endcode
300  */
301 #define NVS_STATUS_RESERVED         (-32)
302 
303 /**
304  *  @defgroup NVS_STATUS Status Codes
305  *  NVS_STATUS_* macros are general status codes returned by NVS_control()
306  *  @{
307  *  @ingroup NVS_CONTROL
308  */
309 
310 /*!
311  *  @brief   Successful status code returned by:
312  *  NVS_control(), NVS_read(), NVS_write(), NVS_erase(), or
313  *  NVS_lock().
314  *
315  *  APIs returns NVS_STATUS_SUCCESS if the API was executed
316  *  successfully.
317  */
318 #define NVS_STATUS_SUCCESS          (0)
319 
320 /*!
321  *  @brief   Generic error status code returned by:
322  *  NVS_control(), NVS_erase(), or NVS_write(),
323  *
324  *  APIs return NVS_STATUS_ERROR if the API was not executed
325  *  successfully.
326  */
327 #define NVS_STATUS_ERROR            (-1)
328 
329 /*!
330  *  @brief   An error status code returned by NVS_control() for undefined
331  *  command codes.
332  *
333  *  NVS_control() returns #NVS_STATUS_UNDEFINEDCMD if the control code is not
334  *  recognized by the driver implementation.
335  */
336 #define NVS_STATUS_UNDEFINEDCMD     (-2)
337 
338 /*!
339  *  @brief An error status code returned by NVS_lock()
340  *
341  *  NVS_lock() will return this value if the @p timeout has expired
342  */
343 #define NVS_STATUS_TIMEOUT          (-3)
344 
345 /*!
346  *  @brief An error status code returned by NVS_read(), NVS_write(), or
347  *  NVS_erase()
348  *
349  *  Error status code returned if the @p offset argument is invalid
350  *  (e.g., when offset + bufferSize exceeds the size of the region).
351  */
352 #define NVS_STATUS_INV_OFFSET       (-4)
353 
354 /*!
355  *  @brief An error status code
356  *
357  *  Error status code returned by NVS_erase() if the @p offset argument is
358  *  not aligned on a flash sector address.
359  */
360 #define NVS_STATUS_INV_ALIGNMENT    (-5)
361 
362 /*!
363  *  @brief An error status code returned by NVS_erase() and NVS_write()
364  *
365  *  Error status code returned by NVS_erase() if the @p size argument is
366  *  not a multiple of the flash sector size, or if @p offset + @p size
367  *  extends past the end of the region.
368  */
369 #define NVS_STATUS_INV_SIZE         (-6)
370 
371 /*!
372  *  @brief An error status code returned by NVS_write()
373  *
374  *  NVS_write() will return this value if #NVS_WRITE_PRE_VERIFY is
375  *  requested and a flash location can not be changed to the value
376  *  desired.
377  */
378 #define NVS_STATUS_INV_WRITE        (-7)
379 
380 /** @}*/
381 
382 /**
383  *  @defgroup NVS_CMD Command Codes
384  *  NVS_CMD_* macros are general command codes for NVS_control(). Not all NVS
385  *  driver implementations support these command codes.
386  *  @{
387  *  @ingroup NVS_CONTROL
388  */
389 
390 /* Add NVS_CMD_<commands> here */
391 
392 /** @} end NVS commands */
393 
394 /** @} end NVS_CONTROL group */
395 
396 
397 /*!
398  *  @brief NVS write flags
399  *
400  *  The following flags can be or'd together and passed as a bit mask
401  *  to NVS_write.
402  *  @{
403  */
404 
405 /*!
406  *  @brief Erase write flag.
407  *
408  *  If #NVS_WRITE_ERASE is set in the flags passed to NVS_write(), the
409  *  affected destination flash sectors will be erased prior to the
410  *  start of the write operation.
411  */
412 #define NVS_WRITE_ERASE             (0x1)
413 
414 /*!
415  *  @brief Validate write flag.
416  *
417  *  If #NVS_WRITE_PRE_VERIFY is set in the flags passed to NVS_write(), the
418  *  destination address range will be pre-tested to guarantee that the source
419  *  data can be successfully written. If #NVS_WRITE_ERASE is also requested in
420  *  the write flags, then the #NVS_WRITE_PRE_VERIFY modifier is ignored.
421  */
422 #define NVS_WRITE_PRE_VERIFY        (0x2)
423 
424 /*!
425  *  @brief Validate write flag.
426  *
427  *  If #NVS_WRITE_POST_VERIFY is set in the flags passed to NVS_write(), the
428  *  destination address range will be tested after the write is finished to
429  *  verify that the write operation was completed successfully.
430  */
431 #define NVS_WRITE_POST_VERIFY       (0x4)
432 
433 /** @} */
434 
435 /*!
436  *  @brief Special NVS_lock() timeout values
437  *  @{
438  */
439 
440  /*!
441  *  @brief    NVS_lock() Wait forever define
442  */
443 #define NVS_LOCK_WAIT_FOREVER       (~(0U))
444 
445 /*!
446  *  @brief    NVS_lock() No wait define
447  */
448 #define NVS_LOCK_NO_WAIT            (0U)
449 
450 /** @} */
451 
452 /*!
453  *  @brief Special NVS_Attrs.regionBase value
454  *  @{
455  */
456 
457  /*!
458  *  @brief    This region is not directly addressable (e.g.,: SPI flash region)
459  *
460  *  The NVS_Attrs.regionBase field returned by NVS_getAttrs() is set to this
461  *  value by the NVSSPI driver to indicate that the region is not directly
462  *  addressable.
463  */
464 #define NVS_REGION_NOT_ADDRESSABLE  ((void *)(~(0U)))
465 
466 /** @} */
467 
468 /*!
469  *  @brief    NVS Parameters
470  *
471  *  NVS parameters are used with the NVS_open() call. Default values for
472  *  these parameters are set using NVS_Params_init().
473  *
474  *  @sa       NVS_Params_init()
475  */
476 typedef struct
477 {
478     void *custom;    /*!< Custom argument used by driver implementation */
479 } NVS_Params;
480 
481 /*!
482  *  @brief      NVS attributes
483  *
484  *  The address of an NVS_Attrs structure is passed to NVS_getAttrs().
485  *
486  *  @sa     NVS_getAttrs()
487  */
488 typedef struct
489 {
490     void   *regionBase;   /*!< Base address of the NVS region. If the NVS
491                                region is not directly accessible by the MCU
492                                (such as SPI flash), this field will be set to
493                                #NVS_REGION_NOT_ADDRESSABLE. */
494     size_t  regionSize;   /*!< NVS region size in bytes. */
495     size_t  sectorSize;   /*!< Erase sector size in bytes. This attribute is
496                                device specific. */
497 } NVS_Attrs;
498 
499 /*!
500  *  @brief      A handle that is returned from the NVS_open() call.
501  */
502 typedef struct NVS_Config_ *NVS_Handle;
503 
504 /*!
505  *  @brief      A function pointer to a driver specific implementation of
506  *              NVS_close().
507  */
508 typedef void (*NVS_CloseFxn) (NVS_Handle handle);
509 
510 /*!
511  *  @brief      A function pointer to a driver specific implementation of
512  *              NVS_control().
513  */
514 typedef int_fast16_t (*NVS_ControlFxn) (NVS_Handle handle, uint_fast16_t cmd,
515                                         uintptr_t arg);
516 
517 /*!
518  *  @brief      A function pointer to a driver specific implementation of
519  *              NVS_erase().
520  */
521 typedef int_fast16_t (*NVS_EraseFxn) (NVS_Handle handle, size_t offset,
522                                       size_t size);
523 
524 /*!
525  *  @brief      A function pointer to a driver specific implementation of
526  *              NVS_getAttrs().
527  */
528 typedef void (*NVS_GetAttrsFxn) (NVS_Handle handle, NVS_Attrs *attrs);
529 
530 /*!
531  *  @brief      A function pointer to a driver specific implementation of
532  *              NVS_init().
533  */
534 typedef void (*NVS_InitFxn) (void);
535 
536 /*!
537  *  @brief      A function pointer to a driver specific implementation of
538  *              NVS_open().
539  */
540 typedef NVS_Handle (*NVS_OpenFxn) (uint_least8_t index, NVS_Params *params);
541 
542 /*!
543  *  @brief      A function pointer to a driver specific implementation of
544  *              NVS_read().
545  */
546 typedef int_fast16_t (*NVS_ReadFxn) (NVS_Handle handle, size_t offset,
547                                      void *buffer, size_t bufferSize);
548 
549 /*!
550  *  @brief      A function pointer to a driver specific implementation of
551  *              NVS_write().
552  */
553 typedef int_fast16_t (*NVS_WriteFxn) (NVS_Handle handle, size_t offset,
554                                       void *buffer, size_t bufferSize,
555                                       uint_fast16_t flags);
556 
557 /*!
558  *  @brief      A function pointer to a driver specific implementation of
559  *              NVS_lock().
560  */
561 typedef int_fast16_t (*NVS_LockFxn) (NVS_Handle handle, uint32_t timeout);
562 
563 /*!
564  *  @brief      A function pointer to a driver specific implementation of
565  *              NVS_unlock().
566  */
567 typedef void (*NVS_UnlockFxn) (NVS_Handle handle);
568 
569 /*!
570  *  @brief      The definition of an NVS function table that contains the
571  *              required set of functions to control a specific NVS driver
572  *              implementation.
573  */
574 typedef struct
575 {
576     /*! Function to close the specified NVS region */
577     NVS_CloseFxn        closeFxn;
578 
579     /*! Function to apply control command to the specified NVS region */
580     NVS_ControlFxn      controlFxn;
581 
582     /*! Function to erase a portion of the specified NVS region */
583     NVS_EraseFxn        eraseFxn;
584 
585     /*! Function to get the NVS device-specific attributes */
586     NVS_GetAttrsFxn     getAttrsFxn;
587 
588     /*! Function to initialize the NVS module */
589     NVS_InitFxn         initFxn;
590 
591     /*! Function to lock the specified NVS flash region */
592     NVS_LockFxn         lockFxn;
593 
594     /*! Function to open an NVS region */
595     NVS_OpenFxn         openFxn;
596 
597     /*! Function to read from the specified NVS region */
598     NVS_ReadFxn         readFxn;
599 
600     /*! Function to unlock the specified NVS flash region */
601     NVS_UnlockFxn       unlockFxn;
602 
603     /*! Function to write to the specified NVS region */
604     NVS_WriteFxn        writeFxn;
605 } NVS_FxnTable;
606 
607 /*!
608  *  @brief  NVS Global configuration
609  *
610  *  The NVS_Config structure contains a set of pointers used to characterize
611  *  the NVS driver implementation.
612  *
613  *  This structure needs to be defined before calling NVS_init() and it must
614  *  not be changed thereafter.
615  *
616  *  @sa     NVS_init()
617  */
618 typedef struct NVS_Config_
619 {
620     /*! Pointer to a table of driver-specific implementations of NVS APIs */
621     NVS_FxnTable  const *fxnTablePtr;
622 
623     /*! Pointer to a driver specific data object */
624     void                *object;
625 
626     /*! Pointer to a driver specific hardware attributes structure */
627     void          const *hwAttrs;
628 } NVS_Config;
629 
630 /*!
631  *  @brief  Function to close an #NVS_Handle.
632  *
633  *  @param  handle      A handle returned from NVS_open()
634  *
635  *  @sa     NVS_open()
636  */
637 extern void NVS_close(NVS_Handle handle);
638 
639 /*!
640  *  @brief  Function performs implementation specific features on a given
641  *          #NVS_Handle.
642  *
643  *  @pre    NVS_open() must be called first.
644  *
645  *  @param  handle      An #NVS_Handle returned from NVS_open()
646  *
647  *  @param  cmd         A command value defined by the driver specific
648  *                      implementation
649  *
650  *  @param  arg         An optional read or write argument that is
651  *                      accompanied with @p cmd
652  *
653  *  @return Implementation specific return codes. Negative values indicate
654  *          unsuccessful operations.
655  *
656  *  @sa     NVS_open()
657  */
658 extern int_fast16_t NVS_control(NVS_Handle handle, uint_fast16_t cmd, uintptr_t arg);
659 
660 /*!
661  *  @brief  Erase @p size bytes of the region beginning at @p offset bytes
662  *  from the base of the region referenced by the #NVS_Handle.
663  *
664  *  @warning Erasing internal flash on most devices can introduce
665  *  significant interrupt latencies while the erase operation is in
666  *  in progress. The user may want to surround certain real-time
667  *  critical code sections with NVS_lock() and NVS_unlock() calls in order
668  *  to prevent uncoordinated flash erase operations from negatively
669  *  impacting performance.
670  *
671  *  @param   handle     A handle returned from NVS_open()
672  *
673  *  @param   offset     The byte offset into the NVS region to start
674  *                      erasing from (must be erase sector aligned)
675  *
676  *  @param   size       The number of bytes to erase (must be integer
677  *                      multiple of sector size)
678  *
679  *  @retval  #NVS_STATUS_SUCCESS         Success.
680  *  @retval  #NVS_STATUS_INV_ALIGNMENT   If @p offset is not aligned on
681  *                                       a sector boundary
682  *  @retval  #NVS_STATUS_INV_OFFSET      If @p offset exceeds region size
683  *  @retval  #NVS_STATUS_INV_SIZE        If @p size or @p offset + @p size
684  *                                       exceeds region size, or if @p size
685  *                                       is not an integer multiple of
686  *                                       the flash sector size.
687  *  @retval  #NVS_STATUS_ERROR           If an internal error occurred
688  *                                       erasing the flash.
689  */
690 extern int_fast16_t NVS_erase(NVS_Handle handle, size_t offset, size_t size);
691 
692 /*!
693  *  @brief  Function to get the NVS attributes
694  *
695  *  This function will populate a #NVS_Attrs structure with attributes
696  *  specific to the memory region associated with the #NVS_Handle.
697  *
698  *  @param  handle      A handle returned from NVS_open()
699  *
700  *  @param  attrs       Location to store attributes.
701  */
702 extern void NVS_getAttrs(NVS_Handle handle, NVS_Attrs *attrs);
703 
704 /*!
705  *  @brief  Function to initialize the NVS module
706  *
707  *  @pre    The NVS_config structure must exist and be persistent before this
708  *          function can be called. This function must also be called before
709  *          any other NVS APIs.
710  */
711 extern void NVS_init(void);
712 
713 /*!
714  *  @brief  Function to lock the NVS driver
715  *
716  *  This function is provided in the event that the user needs to
717  *  perform some flash related operation not provided by the NVS
718  *  driver API set or if the user simply needs to block flash operations
719  *  for a period of time.
720  *
721  *  For example, the interrupt latency introduced
722  *  by an uncoordinated flash write operation could interfere with some
723  *  critical operation being performed by the application.
724  *
725  *  NVS_lock() prevents any other thread from initiating
726  *  read, write, or erase operations while the user is performing an
727  *  operation which is incompatible with those functions.
728  *
729  *  When the application no longer needs to block flash operations by
730  *  other threads, NVS_unlock() must be called to allow NVS write or erase
731  *  APIs to complete.
732  *
733  *  @param  handle      A handle returned from NVS_open()
734  *
735  *  @param  timeout     Timeout (in milliseconds) to wait,
736  *                      or #NVS_LOCK_WAIT_FOREVER, #NVS_LOCK_NO_WAIT
737  *
738  *  @retval  #NVS_STATUS_SUCCESS         Success.
739  *  @retval  #NVS_STATUS_TIMEOUT         If @p timeout has expired.
740  */
741 extern int_fast16_t NVS_lock(NVS_Handle handle, uint32_t timeout);
742 
743 /*!
744  *  @brief  Open an NVS region for reading and writing.
745  *
746  *  @pre    NVS_init() was called.
747  *
748  *  @param  index         Index in the #NVS_Config table of the region
749  *                        to manage.
750  *
751  *  @param  params        Pointer to a parameter region.  If NULL, default
752  *                        parameter values will be used.
753  *
754  *  @return  A non-zero handle on success, else NULL.
755  */
756 extern NVS_Handle NVS_open(uint_least8_t index, NVS_Params *params);
757 
758 /*!
759  *  @brief  Function to initialize the NVS_Params struct to its defaults
760  *
761  *  @param  params      A pointer to NVS_Params structure for
762  *                      initialization.
763  */
764 extern void NVS_Params_init(NVS_Params *params);
765 
766 /*!
767  *  @brief   Read data from the NVS region associated with the #NVS_Handle.
768  *
769  *  @param   handle     A handle returned from NVS_open()
770  *
771  *  @param   offset     The byte offset into the NVS region to start
772  *                      reading from.
773  *
774  *  @param   buffer     A buffer to copy the data to.
775  *
776  *  @param   bufferSize The size of the buffer (number of bytes to read).
777  *
778  *  @retval  #NVS_STATUS_SUCCESS     Success.
779  *  @retval  #NVS_STATUS_INV_OFFSET  If @p offset + @p size exceed the size
780  *                                   of the region.
781  */
782 extern int_fast16_t NVS_read(NVS_Handle handle, size_t offset, void *buffer,
783                     size_t bufferSize);
784 
785 /*!
786  *  @brief  Function to unlock the NVS driver
787  *
788  *  This function allows NVS write and erase operations to proceed after being
789  *  temporarily inhibited by a call to NVS_lock().
790  *
791  *  @param  handle      A handle returned from NVS_open()
792  */
793 extern void NVS_unlock(NVS_Handle handle);
794 
795 /*!
796  *  @brief   Write data to the NVS region associated with the #NVS_Handle.
797  *
798  *  @warning Writing to internal flash on most devices can introduce
799  *  significant interrupt latencies while the write operation is in
800  *  in progress. The user may want to surround certain real-time
801  *  critical code sections with NVS_lock() and NVS_unlock() calls in order
802  *  to prevent uncoordinated flash write operations from negatively
803  *  impacting performance.
804  *
805  *  @param   handle     A handle returned from NVS_open()
806  *
807  *  @param   offset     The byte offset into the NVS region to start
808  *                      writing.
809  *
810  *  @param   buffer     A buffer containing data to write to
811  *                      the NVS region.
812  *
813  *  @param   bufferSize The size of the buffer (number of bytes to write).
814  *
815  *  @param   flags      Write flags (#NVS_WRITE_ERASE, #NVS_WRITE_PRE_VERIFY,
816  *                      #NVS_WRITE_POST_VERIFY).
817  *
818  *  @retval  #NVS_STATUS_SUCCESS        Success.
819  *  @retval  #NVS_STATUS_ERROR          If the internal flash write operation
820  *                                      failed, or if #NVS_WRITE_POST_VERIFY
821  *                                      was requested and the destination flash
822  *                                      range does not match the source
823  *                                      @p buffer data.
824  *  @retval  #NVS_STATUS_INV_OFFSET     If @p offset + @p size exceed the size
825  *                                      of the region.
826  *  @retval  #NVS_STATUS_INV_WRITE      If #NVS_WRITE_PRE_VERIFY is requested
827  *                                      and the destination flash address range
828  *                                      cannot be change to the values desired.
829  *  @retval  #NVS_STATUS_INV_ALIGNMENT  If #NVS_WRITE_ERASE is requested
830  *                                      and @p offset is not aligned on
831  *                                      a sector boundary
832  *
833  *  @remark  This call may lock a region to ensure atomic access to the region.
834  */
835 extern int_fast16_t NVS_write(NVS_Handle handle, size_t offset, void *buffer,
836                      size_t bufferSize, uint_fast16_t flags);
837 
838 #if defined (__cplusplus)
839 }
840 #endif /* defined (__cplusplus) */
841 
842 /*@}*/
843 #endif /* ti_drivers_NVS__include */
844