NHS31xx storage - Maximizing storage for equisized samples
storage_dft.h
Go to the documentation of this file.
1 /*
2  * Copyright 2016-2020 NXP
3  * This software is owned or controlled by NXP and may only be used strictly
4  * in accordance with the applicable license terms. By expressly accepting
5  * such terms or by downloading, installing, activating and/or otherwise using
6  * the software, you are agreeing that you have read, and that you agree to
7  * comply with and are bound by, such license terms. If you do not agree to
8  * be bound by the applicable license terms, then you may not retain, install,
9  * activate or otherwise use the software.
10  */
11 
12 /**
13  * @defgroup MODS_NSS_STORAGE_DFT Diversity Settings
14  * @ingroup MODS_NSS_STORAGE
15  *
16  * The application can adapt the storage module to better fit the different application scenarios through the use of
17  * diversity settings in the form of defines below. Sensible defaults are chosen. To override the default settings,
18  * place the defines with their desired values in the application app_sel.h header file. The compiler will pick up your
19  * defines before parsing this file.
20  *
21  * Additional notes regarding some flags:
22  * - By default, the assigned EEPROM region takes up 2KB and is located just below the read-only EEPROM rows. This
23  * storage space can be moved and resized by adapting #STORAGE_EEPROM_FIRST_ROW and #STORAGE_EEPROM_LAST_ROW.
24  * - By default, the remaining FLASH memory after programming is used for data storage: the available free
25  * FLASH space is automatically determined. It can also be manually assigned: move and resize the storage space in
26  * FLASH by adapting #STORAGE_FLASH_FIRST_PAGE and #STORAGE_FLASH_LAST_PAGE.
27  * - Data is stored decompressed in EEPROM; a chance is given to the application to compress the data before it is moved
28  * to FLASH. For this, define both #STORAGE_COMPRESS_CB and #STORAGE_DECOMPRESS_CB.
29  * - Flash operations should be used sparingly. The amount of data transferred as one block from EEPROM to FLASH can be
30  * controlled using #STORAGE_BLOCK_SIZE_IN_SAMPLES. Too little data puts unnecessary strain on the battery and reduces
31  * compression abilities; too much data risks a portion of the FLASH to remain not utilized when a compressed block of
32  * samples no longer fits.
33  * - The storage module requires the use of at least one general purpose register. This cannot be disabled.
34  * .
35  *
36  * These flags may be overridden:
37  * - #STORAGE_FIRST_ALON_REGISTER
38  * - #STORAGE_SAMPLE_ALON_CACHE_COUNT
39  * - #STORAGE_EEPROM_FIRST_ROW
40  * - #STORAGE_EEPROM_LAST_ROW
41  * - #STORAGE_FLASH_FIRST_PAGE
42  * - #STORAGE_FLASH_LAST_PAGE
43  * - #STORAGE_TYPE
44  * - #STORAGE_BITSIZE
45  * - #STORAGE_SIGNED
46  * - #STORAGE_WORKAREA
47  * - #STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES
48  * - #STORAGE_BLOCK_SIZE_IN_SAMPLES
49  * - #STORAGE_REDUCE_RECOVERY_WRITES
50  * - #STORAGE_COMPRESS_CB
51  * - #STORAGE_DECOMPRESS_CB
52  * .
53  *
54  * These defines are fixed or derived from the above flags and may not be defined or redefined in an application:
55  * - #STORAGE_EEPROM_ROW_COUNT
56  * - #STORAGE_EEPROM_SIZE
57  * - #STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT
58  * - #STORAGE_WORKAREA_SELF_DEFINED
59  * - #STORAGE_WORKAREA_SIZE
60  * - #STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES
61  * - #STORAGE_BLOCK_HEADER_SIZE
62  * - #STORAGE_MAX_UNCOMPRESSED_BLOCK_SIZE_IN_BITS
63  * - #STORAGE_MAX_LOSS_AFTER_CORRUPTION
64  * - #STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS
65  * - #STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES
66  *
67  * @par Choosing correct values
68  * The storage module has many diversity settings, and can be tweaked a lot. Storing data reliably and as
69  * efficient as possible is a complex operation, and every use case will need to adjust a few settings, not
70  * relying on the default values.
71  *
72  * To start, determine the correct sizes of the three memory regions the storage module has exclusive access of:
73  * - General purpose registers: determined via #STORAGE_FIRST_ALON_REGISTER
74  * More general purpose registers means more data can be cached before writing to EEPROM. The more are
75  * assigned, the less EPROM flushes are performed, which prolongs life for batteries with a higher battery
76  * impedance (think printed batteries). But when things fail, all these samples will be lost.
77  * - EEPROM: #STORAGE_EEPROM_FIRST_ROW and #STORAGE_EEPROM_LAST_ROW
78  * By default, a conservative choice is made, leaving ~2 kB alone, for other uses of the application.
79  * The larger the assigned region, the more samples can be stored. This means less room left for the
80  * application to store its state, events and validation results.
81  * - FLASH: #STORAGE_FLASH_FIRST_PAGE and #STORAGE_FLASH_LAST_PAGE
82  * By default, all space not used by the program itself, is used for data storage by the storage module.
83  * Unless your application requires to write to flash for other purposes, it is advised to stick with the
84  * default settings.
85  * .
86  *
87  * Next, determine what will be stored. Each sample given to the storage module must have the same type. Both
88  * basic types and structures or unions are possible. Each sample will be placed back to back, without a single
89  * padding bit; if you know that a few MSBits are always 0, you can choose to store fewer bits, resulting in a
90  * larger storage capacity.
91  * - #STORAGE_TYPE
92  * - #STORAGE_BITSIZE
93  * - #STORAGE_SIGNED
94  * .
95  *
96  * Compression greatly increases the number of samples that can be stored, at the cost of the size of the
97  * compression library itself. Normally, the compression ratio is greater when more samples are compressed at
98  * once.
99  * The storage module allows you to insert function calls to compress and decompress a large number of
100  * samples automatically. @n
101  * Keep in mind that enlarging #STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES also enlarges
102  * #STORAGE_WORKAREA_SIZE, and the memory required for compressing and decompressing.
103  * - #STORAGE_BLOCK_SIZE_IN_SAMPLES
104  * - #STORAGE_COMPRESS_CB
105  * - #STORAGE_DECOMPRESS_CB
106  * .
107  * If a compression is to be used which operates on a single sample at a time, the application can wrap the calls
108  * to the storage module and implement this outside the storage module. An example of this is a mapping operation
109  * which reduces the resolution in specific value ranges.
110  * Be sure to adapt the type and bitsize to match the encoded values.
111  *
112  * Data recovery is paramount. Especially when at the end of the use case lifetime, when dealing with batteries
113  * which can't maintain a stable voltage any more, the risk of data corruption increases. The chance for data
114  * corruption to occur is highly dependent on your specific application, your choice of battery, and your
115  * environmental conditions. And apart from data corruption, the IC might also reset during flushing of EEPROM data,
116  * or during a FLASH program operation. When any of this happens, the storage module must be able to return as
117  * many samples as possible.
118  * @n The storage module ensures only a few most recent samples may get lost.
119  * - The samples stored in the general purposes registers were already mentioned. The number can be defined exactly
120  * using #STORAGE_SAMPLE_ALON_CACHE_COUNT
121  * - If data corruption occurs in EEPROM - or when data corruption in EEPROM is suspected - none of the data in
122  * the affected row can be used anymore. The storage module therefore stores a copy the last data row on a
123  * fixed location.
124  * Since the write endurance limit per EEPROM row is only 10.000, the storage module cannot copy this each
125  * time. Via the setting #STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES the application can decide, taking into
126  * account the maximum number of samples that are to be stored.
127  * If in your use case less than 30.000 samples are stored over the full lifetime of the product, this value
128  * would then be set to 3.
129  * - If data corruption occurs in FLASH, the program will avoid all FLASH operations thereafter. No samples are
130  * lost, but the total storage capacity diminishes, as the FLASH page where the corruption occurred and all
131  * higher FLASH sectors will not be used for data storage any more.
132  * - Writing recovery information in itself can also have an averse impact on the battery. The application is
133  * therefore given an additional choice: the number of EEPROM flushes due to writing recovery data can be
134  * halved, at the expense of an additional 8 bytes of samples which may get lost when data corruption occurs.
135  * If #STORAGE_REDUCE_RECOVERY_WRITES is enabled, only one row is reserved for recovery information, and only
136  * 56 bytes are duplicated.
137  * .
138  * The maximum amount of samples that may get lost due to an unexpected reset, a battery failure, or a data
139  * corruption, is captured in #STORAGE_MAX_LOSS_AFTER_CORRUPTION
140  * To recover all samples safe for the very last, at the expense of (a lot) more EEPROM flush operations, use these
141  * settings:
142  * @code
143  * #define STORAGE_SAMPLE_ALON_CACHE_COUNT 0
144  * #define STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES 1
145  * #define STORAGE_REDUCE_RECOVERY_WRITES 0
146  * @endcode
147  * @{
148  */
149 #ifndef __STORAGE_DFT_H_
150 #define __STORAGE_DFT_H_
151 
152 /**
153  * Helper. Performs integer division, rounding up.
154  * @param n Must be a positive number.
155  * @param d Must be a strict positive number
156  * @internal
157  */
158 #define STORAGE_IDIVUP(n, d) (((n)+(d)-1)/(d))
159 
160 #ifdef STORAGE_CONFIG_ALON_REGISTER
161  /** @warning Its use is discouraged. Present only for backward compatibility. Will be removed in a later SDK. */
162  #define STORAGE_FIRST_ALON_REGISTER STORAGE_CONFIG_ALON_REGISTER
163 #endif
164 
165 #ifndef STORAGE_FIRST_ALON_REGISTER
166  /**
167  * The storage module requires the use of at least one general purpose register. This is used for its own
168  * housekeeping and allows it to finish initialization (#Storage_Init) fast.
169  * In addition, @b all other general purposes registers with an index @b higher @b than given are also reserved for
170  * the storage module. These will be used to minimize EEPROM flush operations by caching as many samples as possible
171  * before committing them to EEPROM.
172  * @pre These registers must be guaranteed not to be touched outside the storage module.
173  * @note More information about the ALON registers can be found in the Power Management Unit driver.
174  * @see STORAGE_SAMPLE_ALON_CACHE_COUNT
175  */
176  #define STORAGE_FIRST_ALON_REGISTER 4
177 #endif
178 #if !(STORAGE_FIRST_ALON_REGISTER >= 0) || !(STORAGE_FIRST_ALON_REGISTER <= 4)
179  #error Invalid value for STORAGE_FIRST_ALON_REGISTER
180 #endif
181 
182 /* ------------------------------------------------------------------------- */
183 
184 #ifndef STORAGE_EEPROM_FIRST_ROW
185  /**
186  * The first EEPROM row assigned for sample storage. Starting from the first byte in this row, until the last byte
187  * in #STORAGE_EEPROM_LAST_ROW, the storage module has full control: no other code may touch this EEPROM region.
188  * @note By default, the EEPROM row 2 kB below the locked EEPROM rows will be chosen.
189  */
190  #define STORAGE_EEPROM_FIRST_ROW (EEPROM_NR_OF_RW_ROWS - (2048 / EEPROM_ROW_SIZE))
191 #endif
192 #if !(STORAGE_EEPROM_FIRST_ROW >= 0) || !(STORAGE_EEPROM_FIRST_ROW < EEPROM_NR_OF_RW_ROWS)
193  #error Invalid value for STORAGE_EEPROM_FIRST_ROW
194 #endif
195 
196 #ifndef STORAGE_EEPROM_LAST_ROW
197  /**
198  * The last EEPROM row assigned for sample storage. Starting from the first byte in #STORAGE_EEPROM_FIRST_ROW,
199  * until the last byte in this row, the storage module has full control: no other code may touch this EEPROM region.
200  * @note the size of the EEPROM region is not required to be a multiple of the FLASH sector size.
201  */
202  #define STORAGE_EEPROM_LAST_ROW (EEPROM_NR_OF_RW_ROWS - 1)
203 #endif
204 #if !(STORAGE_EEPROM_LAST_ROW >= STORAGE_EEPROM_FIRST_ROW) || !(STORAGE_EEPROM_LAST_ROW < EEPROM_NR_OF_RW_ROWS)
205  #error Invalid value for STORAGE_EEPROM_LAST_ROW
206 #endif
207 
208 /** The number of EEPROM rows assigned for sample storage. */
209 #define STORAGE_EEPROM_ROW_COUNT (STORAGE_EEPROM_LAST_ROW - STORAGE_EEPROM_FIRST_ROW + 1)
210 #if STORAGE_EEPROM_ROW_COUNT < 3
211  #error STORAGE_EEPROM_LAST_ROW and STORAGE_EEPROM_FIRST_ROW must be farther apart: at least 3 EEPROM pages must be assigned for storage
212 #endif
213 
214 /** The size of the assigned EEPROM storage in bytes */
215 #define STORAGE_EEPROM_SIZE (STORAGE_EEPROM_ROW_COUNT * EEPROM_ROW_SIZE)
216 
217 /* ------------------------------------------------------------------------- */
218 
219 #ifndef STORAGE_FLASH_FIRST_PAGE
220  /**
221  * The first FLASH page assigned for storage. Starting from the first byte in this page, until the last byte
222  * in #STORAGE_FLASH_LAST_PAGE, the Storage module has full control: no other code will touch this FLASH region.
223  * @note Two special values exist:
224  * - When equal to @c 0, the first empty FLASH page @b after the @c .text and @c .data
225  * sections will be used. This page is automatically determined during link time by the Storage module's code.
226  * - When equal to #STORAGE_FLASH_LAST_PAGE, storage to FLASH is disabled. Only the EEPROM will be used to store
227  * the data.
228  * .
229  * @note The page is not required to be sector aligned.
230  * @warning If a non-zero value is specified, it is the responsibility of the application programmer to ensure the
231  * FLASH location points to outside the @c .text and @c .data sections.
232  */
233  #define STORAGE_FLASH_FIRST_PAGE 0
234 #endif
235 #if !(STORAGE_FLASH_FIRST_PAGE >= 0) || (STORAGE_FLASH_FIRST_PAGE >= FLASH_NR_OF_RW_SECTORS * FLASH_PAGES_PER_SECTOR)
236  #error Invalid value for STORAGE_FLASH_FIRST_PAGE
237 #endif
238 
239 #ifndef STORAGE_FLASH_LAST_PAGE
240  /**
241  * The last FLASH page assigned for storage. Starting from the first byte in #STORAGE_FLASH_FIRST_PAGE,
242  * until the last byte in this page, the Storage module has full control: no other code will touch this FLASH
243  * region.
244  * @note the size of the region is not required to be a multiple of the FLASH sector size.
245  */
246  #define STORAGE_FLASH_LAST_PAGE (FLASH_NR_OF_RW_SECTORS * FLASH_PAGES_PER_SECTOR - 1)
247 #endif
248 #if (STORAGE_FLASH_LAST_PAGE < STORAGE_FLASH_FIRST_PAGE) || (STORAGE_FLASH_LAST_PAGE >= FLASH_NR_OF_RW_SECTORS * FLASH_PAGES_PER_SECTOR)
249  #error Invalid value for STORAGE_FLASH_LAST_PAGE
250 #endif
251 #if (STORAGE_FLASH_FIRST_PAGE == 0) && (STORAGE_FLASH_LAST_PAGE != (FLASH_NR_OF_RW_SECTORS * FLASH_PAGES_PER_SECTOR - 1))
252  #error STORAGE_FLASH_FIRST_PAGE is determined at link time; STORAGE_FLASH_LAST_PAGE can thus not be checked at precompilation time.
253  #error STORAGE_FLASH_LAST_PAGE must be set to the highest possible value in this case.
254 #endif
255 
256 /* ------------------------------------------------------------------------- */
257 
258 #ifndef STORAGE_TYPE
259  /**
260  * The type that is used to store one decompressed sample. When writing, samples are to be delivered using this
261  * type - see #Storage_Write; when reading, samples are returned again using this type -
262  * see #Storage_Read.
263  */
264  #define STORAGE_TYPE uint8_t
265 #endif
266 
267 #ifndef STORAGE_BITSIZE
268  /**
269  * The number of bits that are to be stored for each sample. For each sample given using #Storage_Write
270  * this number of LSBits are written;
271  */
272  #define STORAGE_BITSIZE 8
273 #endif
274 #if (STORAGE_BITSIZE <= 0)
275  #error Invalid value for STORAGE_BITSIZE
276 #endif
277 
278 /**
279  * The maximum number of samples that can be cached in the ALON general purposes registers before they are committed to EEPROM.
280  */
281 #define STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT ((141 - STORAGE_FIRST_ALON_REGISTER * 32) / STORAGE_BITSIZE)
282 /* Magic value 141 is checked at compile time in storage.c */
283 
284 #ifndef STORAGE_SAMPLE_ALON_CACHE_COUNT
285  /**
286  * The number of samples that are cached in the ALON general purposes registers before they are committed to EEPROM.
287  */
288  #define STORAGE_SAMPLE_ALON_CACHE_COUNT STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT
289 #endif
290 #if STORAGE_SAMPLE_ALON_CACHE_COUNT > STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT
291  #error STORAGE_SAMPLE_ALON_CACHE_COUNT must be less than or equal to STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT
292 #endif
293 #if (STORAGE_MAX_SAMPLE_ALON_CACHE_COUNT - STORAGE_SAMPLE_ALON_CACHE_COUNT) * STORAGE_BITSIZE >= 32
294  #warning STORAGE_FIRST_ALON_REGISTER can be set higher, as the last general purpose register is reserved by but will not be used by the storage module
295 #endif
296 
297 
298 #ifndef STORAGE_SIGNED
299  /**
300  * Define or set to a non-zero value (e.g. @c 1) to indicate that #STORAGE_TYPE is a signed type.
301  * - If defined, the bit at position @code (#STORAGE_BITSIZE - 1) @endcode will be treated as the sign bit:
302  * when reading out samples from EEPROM or FLASH, this bit will be propagated left up to the MSBit of
303  * #STORAGE_TYPE.
304  * - If not defined, the MSBits at positions #STORAGE_BITSIZE and up will be set to @c 0.
305  * .
306  * @warning Setting this diversity flag to 1 while #STORAGE_TYPE is a structure, while raise compiler errors.
307  * see #Storage_Read.
308  */
309  #define STORAGE_SIGNED 0
310 #endif
311 
312 /* ------------------------------------------------------------------------- */
313 
314 #ifndef STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES
315  /**
316  * Update the recovery information after adding @c X samples to @b non-volatile memory. This recovery information
317  * is written on a fixed location. When an unexpected reset occurs or a corruption of the data while writing new
318  * content, the recovery information is used to recover as much data as possible.
319  * @note The recovery information is only written in the call to #Storage_DeInit. Depending on the number of calls
320  * to #Storage_Write and its arguments, it is possible more samples have been written than this number.
321  * @pre maximum number of expected data samples / @c STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES < 10.000
322  */
323  #define STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES (1 + STORAGE_SAMPLE_ALON_CACHE_COUNT)
324 #endif
325 #if STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES <= 0
326  #error STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES must be a strict positive number
327 #endif
328 #if STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES < STORAGE_SAMPLE_ALON_CACHE_COUNT
329  #warning STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES is smaller than STORAGE_SAMPLE_ALON_CACHE_COUNT, which makes little sense.
330  #warning Recovery information will be written in Storage_DeInit after STORAGE_SAMPLE_ALON_CACHE_COUNT samples.
331 #endif
332 
333 #ifndef STORAGE_REDUCE_RECOVERY_WRITES
334  /**
335  * - If not defined, or defined to zero, two rows of the assigned EEPROM region for data storage are used for data
336  * recovery. When data corruption occurs, no extra loss of bytes will occur, only
337  * #STORAGE_SAMPLE_ALON_CACHE_COUNT and #STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES contribute to this.
338  * - If defined to a non-zero value:
339  * the space used for recovery - where the duplicate data of the last row and the hint information is stored - is
340  * reduced to just one row. When data corruption occurs, an additional loss of up to 8 bytes can occur.
341  * .
342  */
343  #define STORAGE_REDUCE_RECOVERY_WRITES 0
344 #endif
345 #if (STORAGE_REDUCE_RECOVERY_WRITES != 0) && (STORAGE_REDUCE_RECOVERY_WRITES != 1)
346  #error Leave STORAGE_REDUCE_RECOVERY_WRITES undefined in app_sel.h, or define it to 0 (--> 2 recovery rows) or 1 (--> 1 recovery row)
347 #endif
348 
349 /**
350  * The maximum loss of samples that can occur. The storage module may not be able to return the most recently stored
351  * samples after an EEPROM corruption occurs. A scenario where this can happen is when printed batteries are used,
352  * and the battery has an internal impedance of 2 kOhm or higher, resulting in a barely sufficient voltage when
353  * operating normally, and a below-spec voltage when extra load is generated due to an EEPROM flush operation.
354  * @see STORAGE_SAMPLE_ALON_CACHE_COUNT
355  * @see STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES
356  * @see STORAGE_REDUCE_RECOVERY_WRITES
357  */
358 #define STORAGE_MAX_LOSS_AFTER_CORRUPTION 1 \
359  + STORAGE_SAMPLE_ALON_CACHE_COUNT \
360  + STORAGE_WRITE_RECOVERY_EVERY_X_SAMPLES \
361  + STORAGE_REDUCE_RECOVERY_WRITES * STORAGE_IDIVUP(8 * 8, STORAGE_BITSIZE)
362 
363 /**
364  * The maximum allowed value for #STORAGE_BLOCK_SIZE_IN_SAMPLES. After this many samples, the assigned EEPROM region is
365  * completely filled and no new sample can be written to EEPROM before its contents are moved to FLASH first.
366  * @hideinitializer
367  */
368 #if STORAGE_REDUCE_RECOVERY_WRITES
369  #define STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES (((STORAGE_EEPROM_SIZE - 76) * 8) / STORAGE_BITSIZE)
370  /* Magic value 76 is checked at compile time in storage.c */
371 #else
372  #define STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES (((STORAGE_EEPROM_SIZE - 140) * 8) / STORAGE_BITSIZE)
373  /* Magic value 140 is checked at compile time in storage.c */
374 #endif
375 
376 /** Defines the number of bits required to store one block of samples. */
377 #define STORAGE_MAX_UNCOMPRESSED_BLOCK_SIZE_IN_BITS (STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES * STORAGE_BITSIZE)
378 
379 /**
380  * The size in bytes of the meta data stored just in front of the (compressed) data block in FLASH.
381  */
382 #define STORAGE_BLOCK_HEADER_SIZE 2
383 
384 #ifndef STORAGE_BLOCK_SIZE_IN_SAMPLES
385  /**
386  * After writing this number of samples to EEPROM, the module will try to compress them all at once - see
387  * #STORAGE_COMPRESS_CB - and move them to FLASH - defined by #STORAGE_FLASH_FIRST_PAGE and #STORAGE_FLASH_LAST_PAGE.
388  * @note This size determines the value of #STORAGE_WORKAREA_SIZE - the larger this number, the more SRAM is
389  * required, and the larger chunks the compression and decompression algorithms have to work with.
390  * @note By default, the block size will be chosen such that an uncompressed block can fit in one FLASH sector,
391  * including the accompanying meta data.
392  */
393  #define STORAGE_BLOCK_SIZE_IN_SAMPLES (((1024 - STORAGE_BLOCK_HEADER_SIZE) * 8) / STORAGE_BITSIZE)
394  #if STORAGE_BLOCK_SIZE_IN_SAMPLES > STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES
395  #undef STORAGE_BLOCK_SIZE_IN_SAMPLES
396  #define STORAGE_BLOCK_SIZE_IN_SAMPLES STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES
397  #endif
398 #endif
399 #if ((STORAGE_BLOCK_SIZE_IN_SAMPLES <= 1) || (STORAGE_BLOCK_SIZE_IN_SAMPLES > STORAGE_MAX_BLOCK_SIZE_IN_SAMPLES))
400  #error Invalid value for STORAGE_BLOCK_SIZE_IN_SAMPLES
401 #endif
402 
403 /** Defines the number of bits required to store one block of samples. */
404 #define STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS (STORAGE_BLOCK_SIZE_IN_SAMPLES * STORAGE_BITSIZE)
405 
406 /** Defines the number of bytes required to store one block of samples. */
407 #define STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES STORAGE_IDIVUP(STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BITS, 8)
408 
409 /** The size in bytes of the required memory for this module */
410 #define STORAGE_WORKAREA_SIZE ((FLASH_PAGE_SIZE * 2) + STORAGE_UNCOMPRESSED_BLOCK_SIZE_IN_BYTES)
411 
412 #ifdef STORAGE_WORKAREA
413  #undef STORAGE_WORKAREA_SELF_DEFINED
414 #else
415  /**
416  * Used internally to know when to provide (static) memory for this.
417  * @internal
418  */
419  #define STORAGE_WORKAREA_SELF_DEFINED 1
420  /**
421  * An array, or a pointer to an array of at least #STORAGE_WORKAREA_SIZE bytes.
422  * During the lifetime of this module - starting from the start of the call to #Storage_Init until the end of
423  * the call to #Storage_DeInit, this memory is under full control by this module.
424  * @pre Must be word (32 bits) aligned.
425  */
426  #define STORAGE_WORKAREA sStorage_Workarea
427 #endif
428 
429 /* ------------------------------------------------------------------------- */
430 
431 #ifdef STORAGE_COMPRESS_CB
432  #undef STORAGE_COMPRESS_CB_SELF_DEFINED
433 #else
434  /**
435  * The name of the function - @b not a function pointer - of type #pStorage_CompressCb_t that is able to
436  * compress #STORAGE_BLOCK_SIZE_IN_SAMPLES packed samples of type #STORAGE_TYPE where #STORAGE_BITSIZE bits
437  * are retained for each.
438  * @note When not overridden, the default behavior is to store the data uncompressed, i.e. the data is copied from
439  * EEPROM to FLASH unmodified.
440  * @hideinitializer
441  */
442  #define STORAGE_COMPRESS_CB Storage_DummyCompressCb
443 #endif
444 
445 #ifdef STORAGE_DECOMPRESS_CB
446  #undef STORAGE_DECOMPRESS_CB_SELF_DEFINED
447 #else
448  /**
449  * The name of the function - @b not a function pointer - of type #pStorage_DecompressCb_t that is able to
450  * decompress #STORAGE_BLOCK_SIZE_IN_SAMPLES packed samples of type #STORAGE_TYPE where #STORAGE_BITSIZE bits
451  * are retained for each.
452  * @hideinitializer
453  */
454  #define STORAGE_DECOMPRESS_CB Storage_DummyDecompressCb
455 #endif
456 
457 #endif /** @} */