updated example name”

This commit is contained in:
2017-06-10 17:57:47 +08:00
parent 5de4ac202c
commit c5327f8717
827 changed files with 1 additions and 1 deletions

View File

@@ -0,0 +1,948 @@
/*******************************************************************************
Filename: osal_snv.c
Revised: $Date: 2015-07-22 10:45:09 -0700 (Wed, 22 Jul 2015) $
Revision: $Revision: 44392 $
Description: This module contains the OSAL simple non-volatile memory
functions.
Copyright 2009 - 2015 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
*******************************************************************************/
/*********************************************************************
* INCLUDES
*/
#include "hal_adc.h"
#include "hal_flash.h"
#include "hal_types.h"
#include "pwrmon.h"
#include "comdef.h"
#include "OSAL.h"
#include "osal_snv.h"
#include "hal_assert.h"
#include "saddr.h"
#include <driverlib/vims.h>
#include <driverlib/aon_batmon.h>
#ifdef OSAL_SNV_UINT16_ID
# error "This OSAL SNV implementation does not support the extended ID space"
#endif
#if !defined( NO_OSAL_SNV )
/*********************************************************************
* CONSTANTS
*/
// NV page configuration
#define OSAL_NV_PAGE_BEGIN ((uint32)HAL_NV_PAGE_BEG)
#define OSAL_NV_PAGE_SIZE HAL_FLASH_PAGE_SIZE
#define OSAL_NV_PAGES_USED HAL_NV_PAGE_CNT
// Default byte value when flash is erased
#define OSAL_NV_ERASED 0xFF
// NV page header size in bytes
#define OSAL_NV_PAGE_HDR_SIZE 4
// In case pages 0-1 are ever used, define a null page value.
#define OSAL_NV_PAGE_NULL 0
// In case item Id 0 is ever used, define a null item value.
#define OSAL_NV_ITEM_NULL 0
// Length in bytes of a flash word
#define OSAL_NV_WORD_SIZE HAL_FLASH_WORD_SIZE
// NV page header offset within a page
#define OSAL_NV_PAGE_HDR_OFFSET 0
// Flag in a length field of an item header to indicate validity
// of the length field
#define OSAL_NV_INVALID_LEN_MARK 0x8000
// Flag in an ID field of an item header to indicate validity of
// the identifier field
#define OSAL_NV_INVALID_ID_MARK 0x8000
// Bit difference between active page state indicator value and
// transfer page state indicator value
#define OSAL_NV_ACTIVE_XFER_DIFF 0x00100000
// active page state indicator value
#define OSAL_NV_ACTIVE_PAGE_STATE OSAL_NV_ACTIVE_XFER_DIFF
// transfer page state indicator value
#define OSAL_NV_XFER_PAGE_STATE (OSAL_NV_ACTIVE_PAGE_STATE ^ \
OSAL_NV_ACTIVE_XFER_DIFF)
#define OSAL_NV_MIN_COMPACT_THRESHOLD 70 // Minimum compaction threshold
#define OSAL_NV_MAX_COMPACT_THRESHOLD 95 // Maximum compaction threshold
/*********************************************************************
* MACROS
*/
// Checks whether CC26xx voltage high enough to erase/write NV
#ifdef NV_VOLTAGE_CHECK
#define SNV_CHECK_VOLTAGE() (PWRMON_check(MIN_VDD_FLASH))
#else
#define SNV_CHECK_VOLTAGE() (TRUE)
#endif //NV_VOLTAGE_CHECK
/*********************************************************************
* TYPEDEFS
*/
// NV item header structure
typedef struct
{
uint16 id;
uint16 len;
} osalNvItemHdr_t;
// Note that osalSnvId_t and osalSnvLen_t cannot be bigger than uint16
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
extern uint8* HalFlashGetAddress( uint8 pg, uint16 offset );
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* LOCAL VARIABLES
*/
// Allocate SNV area in flash.
#if defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment=4096
#pragma location = ".snvSectors"
const uint8 SNV_FLASH[OSAL_NV_PAGE_SIZE * OSAL_NV_PAGES_USED];
#elif defined(__TI_COMPILER_VERSION) || defined(__TI_COMPILER_VERSION__)
#pragma location = (OSAL_NV_PAGE_BEGIN << 12);
const uint8 SNV_FLASH[OSAL_NV_PAGE_SIZE * OSAL_NV_PAGES_USED] = {0x00};
#else
#error "Unknown Compiler! Support for SNV not provided!"
#endif
// Flash Pages
static uint8 nvPageBeg;
static uint8 nvPageEnd;
// active page
static uint8 activePg;
// active page offset
static uint16 pgOff;
// flag to indicate that an error has occurred while writing to or erasing the
// flash device. Once this flag indicates failure, it is unsafe to attempt
// another write or erase.
static uint8 failF;
// Flag to indicate that a non-fatal error occurred while writing to or erasing
// Flash memory. If flag is set, it's safe to attempt another write or erase.
// This flag is reset by any API calls that cause an erase/write to Flash.
static uint8 failW;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static uint8 initNV( void );
static void setActivePage( uint8 pg );
static void setXferPage(void);
static void erasePage( uint8 pg );
static void findOffset( void );
static void compactPage( uint8 pg );
static void writeWord( uint8 pg, uint16 offset, uint8 *pBuf, osalSnvLen_t cnt );
/*********************************************************************
* @fn enableCache
*
* @brief enable cache.
*
* @param state - the VIMS state returned from disableCache.
*
* @return none.
*/
static void enableCache ( uint8 state )
{
if ( state != VIMS_MODE_DISABLED )
{
// Enable the Cache.
VIMSModeSet( VIMS_BASE, VIMS_MODE_ENABLED );
}
}
/*********************************************************************
* @fn disableCache
*
* @brief invalidate and disable cache.
*
* @param none
*
* @return VIMS state
*/
static uint8 disableCache ( void )
{
uint8 state = VIMSModeGet( VIMS_BASE );
// Check VIMS state
if ( state != VIMS_MODE_DISABLED )
{
// Invalidate cache
VIMSModeSet( VIMS_BASE, VIMS_MODE_DISABLED );
// Wait for disabling to be complete
while ( VIMSModeGet( VIMS_BASE ) != VIMS_MODE_DISABLED );
}
return state;
}
/*********************************************************************
* @fn initNV
*
* @brief Initialize the NV flash pages.
*
* @param none
*
* @return TRUE if initialization succeeds. FALSE, otherwise.
*/
static uint8 initNV( void )
{
uint8 pg;
uint32 pgHdr;
uint8 xferPg = OSAL_NV_PAGE_NULL;
failF = failW = FALSE;
activePg = OSAL_NV_PAGE_NULL;
// Pick active page and clean up erased page if necessary
for ( pg = nvPageBeg; pg <= nvPageEnd; pg++ )
{
HalFlashRead(pg, OSAL_NV_PAGE_HDR_OFFSET, (uint8 *)(&pgHdr), OSAL_NV_PAGE_HDR_SIZE);
if (pgHdr == OSAL_NV_ACTIVE_PAGE_STATE)
{
if (activePg != OSAL_NV_PAGE_NULL)
{
// Both pages are active only when power failed during flash erase and
// with very low probability.
// As it is hard (code size intensive) to figure out which page is the real active page,
// and theoretically impossible as well in lowest probability, erase both pages
// in this case
erasePage(activePg);
erasePage(pg);
activePg = OSAL_NV_PAGE_NULL;
}
else
{
activePg = pg;
}
}
else if (pgHdr == OSAL_NV_XFER_PAGE_STATE)
{
// workaround for new NV system, both pages are 0x00'd.
if (xferPg != NULL)
{
// erase everything!
erasePage(xferPg);
}
xferPg = pg;
}
else
{
// Erase this page if it is not erased.
// This is to ensure that any page that we're in the middle of
// compacting gets erased.
erasePage(pg);
}
}
if (activePg == OSAL_NV_PAGE_NULL)
{
if (xferPg == OSAL_NV_PAGE_NULL)
{
// Both pages are erased. This must be initial state.
// Pick one page as active page.
setActivePage(nvPageBeg);
pgOff = OSAL_NV_PAGE_HDR_SIZE;
// If setting active page from a completely erased page failed,
// it is not recommended to operate any further.
// Other cases, even if non-active page is corrupt, NV module can still read
// the active page content and hence this function could return TRUE.
return (!failW);
}
else
{
// Compacting a page hasn't completed in previous power cycle.
// Complete the compacting.
activePg = xferPg;
findOffset();
compactPage(xferPg);
}
}
else
{
if (xferPg != OSAL_NV_PAGE_NULL)
{
// Compacting has completed except for the final step of erasing
// the xferPage.
erasePage(xferPg);
}
// find the active page offset to write a new variable location item
findOffset();
}
return !failW;
}
/*********************************************************************
* @fn setActivePage
*
* @brief Set page header active state to be active.
*
* @param pg - Valid NV page to activate.
*
* @return none
*/
static void setActivePage( uint8 pg )
{
uint32 pgHdr;
pgHdr = OSAL_NV_ACTIVE_PAGE_STATE;
// Write word to flash.
writeWord( pg, OSAL_NV_PAGE_HDR_OFFSET, (uint8*) &pgHdr, 1 );
if (!failF)
{
activePg = pg;
}
}
/*********************************************************************
* @fn setXferPage
*
* @brief Set active page header state to be transfer state.
*
* @param none
*
* @return none
*/
static void setXferPage(void)
{
uint32 pgHdr;
// erase difference bit between active state and xfer state
pgHdr = OSAL_NV_XFER_PAGE_STATE;
// Write word to flash.
writeWord( activePg, OSAL_NV_PAGE_HDR_OFFSET, (uint8*)&pgHdr, 1);
}
/*********************************************************************
* @fn erasePage
*
* @brief Erases a page in Flash.
*
* @param pg - Valid NV page to erase.
*
* @return none
*/
static void erasePage( uint8 pg )
{
if (SNV_CHECK_VOLTAGE() == FALSE)
{
// Power monitor indicates low voltage
failW = TRUE;
return;
}
else
{
halIntState_t cs;
uint8 state;
uint32_t err;
HAL_ENTER_CRITICAL_SECTION(cs);
// Disable the cache.
state = disableCache();
// Erase the page.
err = FlashSectorErase( (uint32)HalFlashGetAddress(pg, 0));
// Enable the cache.
enableCache(state);
// Page erase failed, further usage is unsafe.
if (err != FAPI_STATUS_SUCCESS)
{
failF = failW = TRUE;
}
HAL_EXIT_CRITICAL_SECTION(cs);
}
}
/*********************************************************************
* @fn findOffset
*
* @brief find an offset of an empty space in active page
* where to write a new item to.
*
* @param None
*
* @return none
*/
static void findOffset(void)
{
uint16 offset;
for (offset = OSAL_NV_PAGE_SIZE - OSAL_NV_WORD_SIZE;
offset >= OSAL_NV_PAGE_HDR_SIZE;
offset -= OSAL_NV_WORD_SIZE)
{
uint32 tmp;
HalFlashRead(activePg, offset, (uint8 *)&tmp, OSAL_NV_WORD_SIZE);
if (tmp != 0xFFFFFFFF)
{
break;
}
}
pgOff = offset + OSAL_NV_WORD_SIZE;
}
/*********************************************************************
* @fn findItem
*
* @brief find a valid item from a designated page and offset
*
* @param pg - NV page
* @param offset - offset in the NV page from where to start
* search up.
* Usually this parameter is set to the empty space
* offset.
* @param id - NV item ID to search for
*
* @return offset of the item, 0 when not found
*/
static uint16 findItem(uint8 pg, uint16 offset, osalSnvId_t id)
{
offset -= OSAL_NV_WORD_SIZE;
while (offset >= OSAL_NV_PAGE_HDR_SIZE)
{
osalNvItemHdr_t hdr;
HalFlashRead(pg, offset, (uint8 *) &hdr, OSAL_NV_WORD_SIZE);
if (hdr.id == id)
{
// item found
// length field could be corrupt. Mask invalid length mark.
uint8 len = hdr.len & ~OSAL_NV_INVALID_LEN_MARK;
return offset - len;
}
else if (hdr.len & OSAL_NV_INVALID_LEN_MARK)
{
offset -= OSAL_NV_WORD_SIZE;
}
else
{
// valid length field
if (hdr.len + OSAL_NV_WORD_SIZE <= offset)
{
// valid length
offset -= hdr.len + OSAL_NV_WORD_SIZE;
}
else
{
// active page is corrupt
// This could happen if NV initialization failed upon failure to erase
// page and active page is set to uncleanly erased page.
HAL_ASSERT_FORCED();
return 0;
}
}
}
return 0;
}
/*********************************************************************
* @fn writeItem
*
* @brief Write a data item to NV. Function can write an entire item to NV
*
* @param pg - Page number
* @param offset - offset within the NV page where to write the new item
* @param id - NV item ID
* @param alignedLen - Length of data to write in bytes, aligned in flash word
* boundary
* @param *pBuf - Data to write.
*
* @return none
*/
static void writeItem( uint8 pg, uint16 offset, osalSnvId_t id, uint16 alignedLen, uint8 *pBuf )
{
osalNvItemHdr_t hdr;
hdr.id = 0xFFFF;
hdr.len = alignedLen | OSAL_NV_INVALID_LEN_MARK;
// Write the len portion of the header first
writeWord(pg, offset + alignedLen, (uint8 *) &hdr, 1);
// remove invalid len mark
hdr.len &= ~OSAL_NV_INVALID_LEN_MARK;
writeWord(pg, offset + alignedLen, (uint8 *) &hdr, 1);
// Copy over the data, converting length to words.
writeWord(pg, offset, pBuf, alignedLen / OSAL_NV_WORD_SIZE);
// value is valid. Write header except for the most significant bit.
hdr.id = id | OSAL_NV_INVALID_ID_MARK;
writeWord(pg, offset + alignedLen, (uint8 *) &hdr, 1);
// write the most significant bit
hdr.id &= ~OSAL_NV_INVALID_ID_MARK;
writeWord(pg, offset + alignedLen, (uint8 *) &hdr, 1);
}
/*********************************************************************
* @fn xferItem
*
* @brief Copy an NV item from the active page to a designated page.
*
* @param pg - NV page where to copy the item to.
* @param offset - NV page offset where to copy the item to.
* @param alignedLen - Length of data to write, aligned in flash word
* boundary.
* @param srcOff - NV page offset of the original data in active page
*
* @return none.
*/
static void xferItem( uint8 pg, uint16 offset, uint16 alignedLen, uint16 srcOff )
{
uint8 tmp[OSAL_NV_WORD_SIZE];
uint16 i = 0;
// Copy over the data
while (i <= alignedLen)
{
HalFlashRead(activePg, srcOff + i, tmp, OSAL_NV_WORD_SIZE);
writeWord(pg, offset + i, tmp, 1);
i += OSAL_NV_WORD_SIZE;
}
}
/*********************************************************************
* @fn compactPage
*
* @brief Compacts the page specified.
*
* @param srcPg - Valid NV page to compact from.
* The page must have changed its state (header) to xfer state
* prior to this function call. This function will not
* modify the state of its header to xfer state before starting
* to compact.
*
* @return none.
*/
static void compactPage( uint8 srcPg )
{
uint16 srcOff, dstOff;
uint8 dstPg;
osalSnvId_t lastId = (osalSnvId_t) 0xFFFF;
dstPg = (srcPg == nvPageBeg)? nvPageEnd : nvPageBeg;
dstOff = OSAL_NV_PAGE_HDR_SIZE;
// Read from the latest value
srcOff = pgOff - sizeof(osalNvItemHdr_t);
while (srcOff >= OSAL_NV_PAGE_HDR_SIZE)
{
osalNvItemHdr_t hdr;
if (failW)
{
// Failure during transfer item will make next findItem error prone.
return;
}
HalFlashRead(srcPg, srcOff, (uint8 *) &hdr, OSAL_NV_WORD_SIZE);
if (hdr.id == 0xFFFF)
{
// Invalid entry. Skip this one.
if (hdr.len & OSAL_NV_INVALID_LEN_MARK)
{
srcOff -= OSAL_NV_WORD_SIZE;
}
else
{
if (hdr.len + OSAL_NV_WORD_SIZE <= srcOff)
{
srcOff -= hdr.len + OSAL_NV_WORD_SIZE;
}
else
{
// invalid length. Source page must be a corrupt page.
// This is possible only if the NV initialization failed upon erasing
// what is selected as active page.
// This is supposed to be a very rare case, as power should be
// shutdown exactly during erase and then the page header is
// still retained as either the Xfer or the Active state.
// For production code, it might be useful to attempt to erase the page
// so that at next power cycle at least the device is runnable
// (with all entries removed).
// However, it might be still better not to attempt erasing the page
// just to see if this very rare case actually happened.
//erasePage(srcPg);
HAL_ASSERT_FORCED();
return;
}
}
continue;
}
// Consider only valid item
if (!(hdr.id & OSAL_NV_INVALID_ID_MARK) && hdr.id != lastId)
{
// lastId is used to speed up compacting in case the same item ID
// items were neighboring each other contiguously.
lastId = (osalSnvId_t) hdr.id;
// Check if the latest value of the item was already written
if (findItem(dstPg, dstOff, lastId) == 0)
{
// This item was not copied over yet.
// This must be the latest value.
// Write the latest value to the destination page
xferItem(dstPg, dstOff, hdr.len, srcOff - hdr.len);
dstOff += hdr.len + OSAL_NV_WORD_SIZE;
}
}
srcOff -= hdr.len + OSAL_NV_WORD_SIZE;
}
// All items copied.
// Activate the new page
setActivePage(dstPg);
if (failW)
{
// Something bad happened when trying to compact the page
return;
}
pgOff = dstOff; // update active page offset
// Erase the currently active page
erasePage(srcPg);
}
/*********************************************************************
* @fn verifyWordM
*
* @brief verify the data written can be read back and is consistent.
*
* @param pg - A valid NV Flash page.
* @param offset - A valid offset into the page.
* @param pBuf - Pointer to source buffer.
* @param cnt - Number of 4-byte blocks to verify.
*
* @return none
*/
static void verifyWordM( uint8 pg, uint16 offset, uint8 *pBuf, osalSnvLen_t cnt )
{
uint8 tmp[OSAL_NV_WORD_SIZE];
while (cnt--)
{
// Reading byte per byte will reduce code size but will slow down
// and not sure it will meet the timing requirements.
HalFlashRead(pg, offset, tmp, OSAL_NV_WORD_SIZE);
if (FALSE == osal_memcmp(tmp, pBuf, OSAL_NV_WORD_SIZE))
{
// Read-back failed, NV is not safe to use.
failF = failW = TRUE;
return;
}
offset += OSAL_NV_WORD_SIZE;
pBuf += OSAL_NV_WORD_SIZE;
}
}
/*********************************************************************
* @fn writeWord
*
* @brief Writes data to NV.
*
* @param pg - A valid NV Flash page.
* @param offset - A valid offset into the page.
* @param buf - Pointer to source buffer.
* @param cnt - Number of 4-byte blocks to write.
*
* @return none
*/
static void writeWord( uint8 pg, uint16 offset, uint8 *buf, osalSnvLen_t cnt )
{
if ( !failF && SNV_CHECK_VOLTAGE() == TRUE )
{
uint32 addr;
halIntState_t cs;
uint8 state;
// Enter Critical Section
HAL_ENTER_CRITICAL_SECTION(cs);
// Disable Cache
state = disableCache();
// Write data.
addr = (uint32) HalFlashGetAddress(pg, offset);
HalFlashWrite(addr, buf, cnt * (OSAL_NV_WORD_SIZE) );
// Enable cache.
enableCache(state);
verifyWordM(pg, offset, buf, cnt);
HAL_EXIT_CRITICAL_SECTION(cs);
}
}
#endif // !NO_OSAL_SNV
/*********************************************************************
* @fn osal_snv_init
*
* @brief Initialize NV service.
*
* @return SUCCESS if initialization succeeds. FAILURE, otherwise.
*/
uint8 osal_snv_init( void )
{
#if !defined( NO_OSAL_SNV )
uint8 stat = SUCCESS;
// get the first and last page of SNV
// Note: Can also get this information from the FCFG; done this way to stay
// consistent with the flash addresses obtained from the Linker.
// nvPages = *((uint8 *)(FCFG1_BASE + FCFG_FLASH_SIZE_OFFSET));
// nvPageBeg = nvPages - (OSAL_NV_PAGES_USED + CCFG_PAGES_USED);
// nvPageEnd = nvPageBeg + OSAL_NV_PAGES_USED - 1;
// Where FCFG_FLASH_SIZE_OFFSET = 0x2B1, and CCFG_PAGES_USED = 1.
nvPageBeg = (uint32)SNV_FLASH >> 12; //(uint32)OSAL_NV_PAGE_BEGIN;
nvPageEnd = nvPageBeg + OSAL_NV_PAGES_USED - 1;
if (!initNV())
{
// NV initialization failed
HAL_ASSERT_FORCED();
stat = FAILURE;
}
return stat;
#else // NO_OSAL_SNV
// NV initialization failed
HAL_ASSERT_FORCED();
return( FAILURE );
#endif // !NO_OSAL_SNV
}
/*********************************************************************
* @fn osal_snv_write
*
* @brief Write a data item to NV.
*
* @param id - Valid NV item Id.
* @param len - Length of data to write.
* @param *pBuf - Data to write.
*
* @return SUCCESS if successful, NV_OPER_FAILED if failed.
*/
uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void *pBuf )
{
#if !defined( NO_OSAL_SNV )
uint16 alignedLen;
// Reset failW
failW = FALSE;
{
uint16 offset = findItem(activePg, pgOff, id);
if (offset > 0)
{
uint8 tmp;
osalSnvLen_t i;
for (i = 0; i < len; i++)
{
HalFlashRead(activePg, offset, &tmp, 1);
if (tmp != ((uint8 *)pBuf)[i])
{
break;
}
offset++;
}
if (i == len)
{
// Changed value is the same value as before.
// Return here instead of re-writing the same value to NV.
return SUCCESS;
}
}
}
alignedLen = ((len + OSAL_NV_WORD_SIZE - 1) / OSAL_NV_WORD_SIZE) * OSAL_NV_WORD_SIZE;
if ( pgOff + alignedLen + OSAL_NV_WORD_SIZE > OSAL_NV_PAGE_SIZE )
{
setXferPage();
compactPage(activePg);
}
// pBuf shall be referenced beyond its valid length to save code size.
writeItem(activePg, pgOff, id, alignedLen, pBuf);
if (failW)
{
return NV_OPER_FAILED;
}
pgOff += alignedLen + OSAL_NV_WORD_SIZE;
return SUCCESS;
#else
return NV_OPER_FAILED;
#endif // !NO_OSAL_SNV
}
/*********************************************************************
* @fn osal_snv_read
*
* @brief Read data from NV.
*
* @param id - Valid NV item Id.
* @param len - Length of data to read.
* @param *pBuf - Data is read into this buffer.
*
* @return SUCCESS if successful.
* Otherwise, NV_OPER_FAILED for failure.
*/
uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void *pBuf )
{
#if !defined( NO_OSAL_SNV )
uint16 offset = findItem(activePg, pgOff, id);
if (offset != 0)
{
HalFlashRead(activePg, offset, pBuf, len);
return SUCCESS;
}
#endif // !NO_OSAL_SNV
return NV_OPER_FAILED;
}
/*********************************************************************
* @fn osal_snv_compact
*
* @brief Compacts NV if its usage has reached a specific threshold.
*
* @param threshold - compaction threshold
*
* @return SUCCESS if successful,
* NV_OPER_FAILED if failed, or
* INVALIDPARAMETER if threshold invalid.
*/
uint8 osal_snv_compact( uint8 threshold )
{
#if !defined( NO_OSAL_SNV )
if ( ( threshold < OSAL_NV_MIN_COMPACT_THRESHOLD ) ||
( threshold > OSAL_NV_MAX_COMPACT_THRESHOLD ) )
{
return INVALIDPARAMETER;
}
// See if NV active page usage has reached compaction threshold
if ( !failF &&
( (uint32)pgOff * 100 ) >= ( OSAL_NV_PAGE_SIZE * (uint32)threshold ) )
{
// Reset failW
failW = FALSE;
setXferPage();
compactPage(activePg);
return SUCCESS;
}
#endif // !NO_OSAL_SNV
return NV_OPER_FAILED;
}
/*********************************************************************
*********************************************************************/

View File

@@ -0,0 +1,146 @@
/*******************************************************************************
Filename: osal_snv_wrapper.c
Revised: $Date: 2015-02-10 14:18:04 -0800 (Tue, 10 Feb 2015) $
Revision: $Revision: 42483 $
Description: This module defines the OSAL simple non-volatile memory
functions as a wrapper to On Chip One Page SNV implementation.
Copyright 2009-2014 Texas Instruments Incorporated. All rights reserved.
IMPORTANT: Your use of this Software is limited to those specific rights
granted under the terms of a software license agreement between the user
who downloaded the software, his/her employer (which must be your employer)
and Texas Instruments Incorporated (the "License"). You may not use this
Software unless you agree to abide by the terms of the License. The License
limits your use, and you acknowledge, that the Software may not be modified,
copied or distributed unless embedded on a Texas Instruments microcontroller
or used solely and exclusively in conjunction with a Texas Instruments radio
frequency transceiver, which is integrated into your product. Other than for
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
works of, modify, distribute, perform, display or sell this Software and/or
its documentation for any purpose.
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
Should you have any questions regarding your right to use this Software,
contact Texas Instruments Incorporated at www.TI.com.
*******************************************************************************/
#if !defined( OSAL_SNV )
// Use 2 page SNV by default
#define OSAL_SNV 2
#endif
// Map 2 and 0 to 2 page SNV. 0 was arbitrarily chosen to go here.
#if OSAL_SNV == 2 || OSAL_SNV == 0
#if OSAL_SNV == 0 && !defined(NO_OSAL_SNV)
#define NO_OSAL_SNV
#endif //OSAL_SNV == 0 && !defined(NO_OSAL_SNV)
#include "osal_snv.c"
#elif OSAL_SNV == 1 // This is the 1 page SNV
#include "osal_snv.h"
#include "./../../../services/nv/cc26xx/nvocop.c"
#ifndef SYSTEM_ID
#define SYSTEM_ID NVINTF_SYSID_NVDRVR
#endif
// Convert a threshold percentage to bytes.
#define THRESHOLD2BYTES(x) ((FLASH_PAGE_SIZE) - (((FLASH_PAGE_SIZE) * (x)) / 100))
/*********************************************************************
* @fn osal_snv_init
*
* @brief Initialize NV service.
*
* @param none
*
* @return SUCCESS if initialization succeeds. FAILURE, otherwise.
*/
uint8 osal_snv_init( void )
{
return NVOCOP_initNV(NULL);
}
/*********************************************************************
* @fn osal_snv_read
*
* @brief Read data from NV.
*
* @param id - Valid NV item Id.
* @param len - Length of data to read.
* @param *pBuf - Data is read into this buffer.
*
* @return SUCCESS if successful.
* Otherwise, NV_OPER_FAILED for failure.
*/
uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void *pBuf)
{
NVINTF_itemID_t nv_id;
nv_id.itemID = id;
nv_id.subID = 0;
nv_id.systemID = SYSTEM_ID;
return NVOCOP_readItem(nv_id, 0, len, pBuf);
}
/*********************************************************************
* @fn osal_snv_write
*
* @brief Write a data item to NV.
*
* @param id - Valid NV item Id.
* @param len - Length of data to write.
* @param *pBuf - Data to write.
*
* @return SUCCESS if successful, NV_OPER_FAILED if failed.
*/
uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void *pBuf)
{
NVINTF_itemID_t nv_id;
nv_id.itemID = id;
nv_id.subID = 0;
nv_id.systemID = SYSTEM_ID;
return NVOCOP_writeItem(nv_id, len, pBuf);
}
/*********************************************************************
* @fn osal_snv_compact
*
* @brief Compacts NV if its usage has reached a specific threshold.
*
* @param threshold - compaction threshold.
*
* @return NV_INTF_SUCCESS if successful,
* NV_INTF_FAILURE if failed, or
* NV_INTF_BADPARAM if threshold invalid.
*/
uint8 osal_snv_compact( uint8 threshold )
{
// convert percentage to approximate byte threshold.
if (threshold <= 100)
{
return NVOCOP_compactNV(THRESHOLD2BYTES(threshold));
}
return NVINTF_BADPARAM;
}
#else // bad OSAL_SNV value
#error "Valid OSAL_SNV values are 0, 1, or 2!"
#endif //OSAL_SNV