Imported more library files
Not compiling currently
This commit is contained in:
70
Libs/platform/emdrv/common/inc/ecode.h
Normal file
70
Libs/platform/emdrv/common/inc/ecode.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Energy Aware drivers error code definitions.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef __SILICON_LABS_ECODE_H__
|
||||
#define __SILICON_LABS_ECODE_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup ecode ECODE - Error Codes
|
||||
* @details ECODE is set of error and status codes related to DMA, RTC, SPI,
|
||||
* NVM, USTIMER, UARTDRV, EZRADIO, TEMP, and NVM3 drivers. These error and
|
||||
* status codes are used by the above listed drivers to update the layer
|
||||
* (using the driver) about an error or status.
|
||||
*
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief Typedef for API function error code return values.
|
||||
*
|
||||
* @details
|
||||
* Bit 24-31: Component, for example emdrv @n
|
||||
* Bit 16-23: Module, for example @ref uartdrv or @ref spidrv @n
|
||||
* Bit 0-15: Error code
|
||||
******************************************************************************/
|
||||
typedef uint32_t Ecode_t;
|
||||
|
||||
#define ECODE_EMDRV_BASE (0xF0000000U) ///< Base value for all EMDRV errorcodes.
|
||||
|
||||
#define ECODE_OK (0U) ///< Generic success return value.
|
||||
|
||||
#define ECODE_EMDRV_SPIDRV_BASE (ECODE_EMDRV_BASE | 0x00002000U) ///< Base value for SPIDRV error codes.
|
||||
#define ECODE_EMDRV_NVM_BASE (ECODE_EMDRV_BASE | 0x00003000U) ///< Base value for NVM error codes.
|
||||
#define ECODE_EMDRV_USTIMER_BASE (ECODE_EMDRV_BASE | 0x00004000U) ///< Base value for USTIMER error codes.
|
||||
#define ECODE_EMDRV_UARTDRV_BASE (ECODE_EMDRV_BASE | 0x00007000U) ///< Base value for UARTDRV error codes.
|
||||
#define ECODE_EMDRV_DMADRV_BASE (ECODE_EMDRV_BASE | 0x00008000U) ///< Base value for DMADRV error codes.
|
||||
#define ECODE_EMDRV_EZRADIODRV_BASE (ECODE_EMDRV_BASE | 0x00009000U) ///< Base value for EZRADIODRV error codes.
|
||||
#define ECODE_EMDRV_TEMPDRV_BASE (ECODE_EMDRV_BASE | 0x0000D000U) ///< Base value for TEMPDRV error codes.
|
||||
#define ECODE_EMDRV_NVM3_BASE (ECODE_EMDRV_BASE | 0x0000E000U) ///< Base value for NVM3 error codes.
|
||||
|
||||
/** @} (end addtogroup ecode) */
|
||||
|
||||
#endif // __SILICON_LABS_ECODE_H__
|
||||
185
Libs/platform/emdrv/dmadrv/inc/dmadrv.h
Normal file
185
Libs/platform/emdrv/dmadrv/inc/dmadrv.h
Normal file
@@ -0,0 +1,185 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief DMADRV API definition.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef __SILICON_LABS_DMADRV_H__
|
||||
#define __SILICON_LABS_DMADRV_H__
|
||||
|
||||
#include "em_device.h"
|
||||
|
||||
#include "ecode.h"
|
||||
|
||||
#include "dmadrv_signals.h"
|
||||
|
||||
#if defined(LDMA_PRESENT) && (LDMA_COUNT == 1)
|
||||
#if (_SILICON_LABS_32B_SERIES > 2)
|
||||
#define EMDRV_DMADRV_LDMA_S3
|
||||
#else
|
||||
#define EMDRV_DMADRV_DMA_PRESENT
|
||||
#define EMDRV_DMADRV_LDMA
|
||||
#endif
|
||||
#else
|
||||
#error "No valid DMA engine defined."
|
||||
#endif
|
||||
|
||||
#include "dmadrv_config.h"
|
||||
#include "sl_code_classification.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup dmadrv
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup dmadrv_error_codes Error Codes
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#define ECODE_EMDRV_DMADRV_OK (ECODE_OK) ///< A successful return value.
|
||||
#define ECODE_EMDRV_DMADRV_PARAM_ERROR (ECODE_EMDRV_DMADRV_BASE | 0x00000001) ///< An illegal input parameter.
|
||||
#define ECODE_EMDRV_DMADRV_NOT_INITIALIZED (ECODE_EMDRV_DMADRV_BASE | 0x00000002) ///< DMA is not initialized.
|
||||
#define ECODE_EMDRV_DMADRV_ALREADY_INITIALIZED (ECODE_EMDRV_DMADRV_BASE | 0x00000003) ///< DMA has already been initialized.
|
||||
#define ECODE_EMDRV_DMADRV_CHANNELS_EXHAUSTED (ECODE_EMDRV_DMADRV_BASE | 0x00000004) ///< No DMA channels available.
|
||||
#define ECODE_EMDRV_DMADRV_IN_USE (ECODE_EMDRV_DMADRV_BASE | 0x00000005) ///< DMA is in use.
|
||||
#define ECODE_EMDRV_DMADRV_ALREADY_FREED (ECODE_EMDRV_DMADRV_BASE | 0x00000006) ///< A DMA channel was free.
|
||||
#define ECODE_EMDRV_DMADRV_CH_NOT_ALLOCATED (ECODE_EMDRV_DMADRV_BASE | 0x00000007) ///< A channel is not reserved.
|
||||
|
||||
/** @} (end addtogroup error codes) */
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* DMADRV transfer completion callback function.
|
||||
*
|
||||
* @details
|
||||
* The callback function is called when a transfer is complete.
|
||||
*
|
||||
* @param[in] channel
|
||||
* The DMA channel number.
|
||||
*
|
||||
* @param[in] sequenceNo
|
||||
* The number of times the callback was called. Useful on long chains of
|
||||
* linked transfers or on endless ping-pong type transfers.
|
||||
*
|
||||
* @param[in] userParam
|
||||
* Optional user parameter supplied on DMA invocation.
|
||||
*
|
||||
* @return
|
||||
* When doing ping-pong transfers, return true to continue or false to
|
||||
* stop transfers.
|
||||
******************************************************************************/
|
||||
typedef bool (*DMADRV_Callback_t)(unsigned int channel,
|
||||
unsigned int sequenceNo,
|
||||
void *userParam);
|
||||
|
||||
Ecode_t DMADRV_AllocateChannel(unsigned int *channelId,
|
||||
void *capabilities);
|
||||
Ecode_t DMADRV_DeInit(void);
|
||||
Ecode_t DMADRV_FreeChannel(unsigned int channelId);
|
||||
Ecode_t DMADRV_Init(void);
|
||||
|
||||
Ecode_t DMADRV_MemoryPeripheral(unsigned int channelId,
|
||||
DMADRV_PeripheralSignal_t peripheralSignal,
|
||||
void *dst,
|
||||
void *src,
|
||||
bool srcInc,
|
||||
int len,
|
||||
DMADRV_DataSize_t size,
|
||||
DMADRV_Callback_t callback,
|
||||
void *cbUserParam);
|
||||
Ecode_t DMADRV_PeripheralMemory(unsigned int channelId,
|
||||
DMADRV_PeripheralSignal_t peripheralSignal,
|
||||
void *dst,
|
||||
void *src,
|
||||
bool dstInc,
|
||||
int len,
|
||||
DMADRV_DataSize_t size,
|
||||
DMADRV_Callback_t callback,
|
||||
void *cbUserParam);
|
||||
Ecode_t DMADRV_MemoryPeripheralPingPong(unsigned int channelId,
|
||||
DMADRV_PeripheralSignal_t peripheralSignal,
|
||||
void *dst,
|
||||
void *src0,
|
||||
void *src1,
|
||||
bool srcInc,
|
||||
int len,
|
||||
DMADRV_DataSize_t size,
|
||||
DMADRV_Callback_t callback,
|
||||
void *cbUserParam);
|
||||
Ecode_t DMADRV_PeripheralMemoryPingPong(unsigned int channelId,
|
||||
DMADRV_PeripheralSignal_t peripheralSignal,
|
||||
void *dst0,
|
||||
void *dst1,
|
||||
void *src,
|
||||
bool dstInc,
|
||||
int len,
|
||||
DMADRV_DataSize_t size,
|
||||
DMADRV_Callback_t callback,
|
||||
void *cbUserParam);
|
||||
|
||||
#if defined(EMDRV_DMADRV_LDMA)
|
||||
Ecode_t DMADRV_LdmaStartTransfer(int channelId,
|
||||
LDMA_TransferCfg_t *transfer,
|
||||
LDMA_Descriptor_t *descriptor,
|
||||
DMADRV_Callback_t callback,
|
||||
void *cbUserParam);
|
||||
#elif defined(EMDRV_DMADRV_LDMA_S3)
|
||||
Ecode_t DMADRV_LdmaStartTransfer(int channelId,
|
||||
sl_hal_ldma_transfer_config_t *transfer,
|
||||
sl_hal_ldma_descriptor_t *descriptor,
|
||||
DMADRV_Callback_t callback,
|
||||
void *cbUserParam);
|
||||
#endif
|
||||
|
||||
Ecode_t DMADRV_PauseTransfer(unsigned int channelId);
|
||||
Ecode_t DMADRV_ResumeTransfer(unsigned int channelId);
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_DMADRV, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
Ecode_t DMADRV_StopTransfer(unsigned int channelId);
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_DMADRV, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
Ecode_t DMADRV_TransferActive(unsigned int channelId,
|
||||
bool *active);
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_DMADRV, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
Ecode_t DMADRV_TransferCompletePending(unsigned int channelId,
|
||||
bool *pending);
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_DMADRV, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
Ecode_t DMADRV_TransferDone(unsigned int channelId,
|
||||
bool *done);
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_DMADRV, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
Ecode_t DMADRV_TransferRemainingCount(unsigned int channelId,
|
||||
int *remaining);
|
||||
|
||||
/** @} (end addtogroup dmadrv) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SILICON_LABS_DMADRV_H__ */
|
||||
223
Libs/platform/emdrv/dmadrv/inc/s2_signals/dmadrv_signals.h
Normal file
223
Libs/platform/emdrv/dmadrv/inc/s2_signals/dmadrv_signals.h
Normal file
@@ -0,0 +1,223 @@
|
||||
#ifndef __SILICON_LABS_DMADRV_SIGNALS_S2_H__
|
||||
#define __SILICON_LABS_DMADRV_SIGNALS_S2_H__
|
||||
|
||||
#include "em_device.h"
|
||||
#include "ecode.h"
|
||||
#include "sl_enum.h"
|
||||
#include "em_ldma.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup dmadrv
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#if defined(LDMAXBAR_COUNT) && (LDMAXBAR_COUNT > 0)
|
||||
|
||||
/// Maximum length of one DMA transfer.
|
||||
#define DMADRV_MAX_XFER_COUNT ((int)((_LDMA_CH_CTRL_XFERCNT_MASK >> _LDMA_CH_CTRL_XFERCNT_SHIFT) + 1))
|
||||
|
||||
/// Peripherals that can trigger LDMA transfers.
|
||||
SL_ENUM_GENERIC(DMADRV_PeripheralSignal_t, uint32_t) {
|
||||
dmadrvPeripheralSignal_NONE = LDMAXBAR_CH_REQSEL_SOURCESEL_NONE, ///< No peripheral selected for DMA triggering.
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0CC0
|
||||
dmadrvPeripheralSignal_TIMER0_CC0 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0CC0 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0CC1
|
||||
dmadrvPeripheralSignal_TIMER0_CC1 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0CC1 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0CC2
|
||||
dmadrvPeripheralSignal_TIMER0_CC2 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0CC2 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0UFOF
|
||||
dmadrvPeripheralSignal_TIMER0_UFOF = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER0UFOF | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1CC0
|
||||
dmadrvPeripheralSignal_TIMER1_CC0 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1CC0 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1CC1
|
||||
dmadrvPeripheralSignal_TIMER1_CC1 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1CC1 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1CC2
|
||||
dmadrvPeripheralSignal_TIMER1_CC2 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1CC2 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1UFOF
|
||||
dmadrvPeripheralSignal_TIMER1_UFOF = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER1UFOF | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART0RXDATAV
|
||||
dmadrvPeripheralSignal_USART0_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_USART0RXDATAV | LDMAXBAR_CH_REQSEL_SOURCESEL_USART0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART0RXDATAVRIGHT
|
||||
dmadrvPeripheralSignal_USART0_RXDATAVRIGHT = LDMAXBAR_CH_REQSEL_SIGSEL_USART0RXDATAVRIGHT | LDMAXBAR_CH_REQSEL_SOURCESEL_USART0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART0TXBL
|
||||
dmadrvPeripheralSignal_USART0_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_USART0TXBL | LDMAXBAR_CH_REQSEL_SOURCESEL_USART0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART0TXBLRIGHT
|
||||
dmadrvPeripheralSignal_USART0_TXBLRIGHT = LDMAXBAR_CH_REQSEL_SIGSEL_USART0TXBLRIGHT | LDMAXBAR_CH_REQSEL_SOURCESEL_USART0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART0TXEMPTY
|
||||
dmadrvPeripheralSignal_USART0_TXEMPTY = LDMAXBAR_CH_REQSEL_SIGSEL_USART0TXEMPTY | LDMAXBAR_CH_REQSEL_SOURCESEL_USART0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART1RXDATAV
|
||||
dmadrvPeripheralSignal_USART1_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_USART1RXDATAV | LDMAXBAR_CH_REQSEL_SOURCESEL_USART1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART1RXDATAVRIGHT
|
||||
dmadrvPeripheralSignal_USART1_RXDATAVRIGHT = LDMAXBAR_CH_REQSEL_SIGSEL_USART1RXDATAVRIGHT | LDMAXBAR_CH_REQSEL_SOURCESEL_USART1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART1TXBL
|
||||
dmadrvPeripheralSignal_USART1_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_USART1TXBL | LDMAXBAR_CH_REQSEL_SOURCESEL_USART1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART1TXBLRIGHT
|
||||
dmadrvPeripheralSignal_USART1_TXBLRIGHT = LDMAXBAR_CH_REQSEL_SIGSEL_USART1TXBLRIGHT | LDMAXBAR_CH_REQSEL_SOURCESEL_USART1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART1TXEMPTY
|
||||
dmadrvPeripheralSignal_USART1_TXEMPTY = LDMAXBAR_CH_REQSEL_SIGSEL_USART1TXEMPTY | LDMAXBAR_CH_REQSEL_SOURCESEL_USART1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART2RXDATAV
|
||||
dmadrvPeripheralSignal_USART2_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_USART2RXDATAV | LDMAXBAR_CH_REQSEL_SOURCESEL_USART2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART2RXDATAVRIGHT
|
||||
dmadrvPeripheralSignal_USART2_RXDATAVRIGHT = LDMAXBAR_CH_REQSEL_SIGSEL_USART2RXDATAVRIGHT | LDMAXBAR_CH_REQSEL_SOURCESEL_USART2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART2TXBL
|
||||
dmadrvPeripheralSignal_USART2_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_USART2TXBL | LDMAXBAR_CH_REQSEL_SOURCESEL_USART2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART2TXBLRIGHT
|
||||
dmadrvPeripheralSignal_USART2_TXBLRIGHT = LDMAXBAR_CH_REQSEL_SIGSEL_USART2TXBLRIGHT | LDMAXBAR_CH_REQSEL_SOURCESEL_USART2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_USART2TXEMPTY
|
||||
dmadrvPeripheralSignal_USART2_TXEMPTY = LDMAXBAR_CH_REQSEL_SIGSEL_USART2TXEMPTY | LDMAXBAR_CH_REQSEL_SOURCESEL_USART2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_I2C0RXDATAV
|
||||
dmadrvPeripheralSignal_I2C0_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_I2C0RXDATAV | LDMAXBAR_CH_REQSEL_SOURCESEL_I2C0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_I2C0TXBL
|
||||
dmadrvPeripheralSignal_I2C0_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_I2C0TXBL | LDMAXBAR_CH_REQSEL_SOURCESEL_I2C0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_I2C1RXDATAV
|
||||
dmadrvPeripheralSignal_I2C1_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_I2C1RXDATAV | LDMAXBAR_CH_REQSEL_SOURCESEL_I2C1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_I2C1TXBL
|
||||
dmadrvPeripheralSignal_I2C1_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_I2C1TXBL | LDMAXBAR_CH_REQSEL_SOURCESEL_I2C1,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_AGCRSSI
|
||||
dmadrvPeripheralSignal_AGC_RSSI = LDMAXBAR_CH_REQSEL_SIGSEL_AGCRSSI | LDMAXBAR_CH_REQSEL_SOURCESEL_AGC,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERBOF
|
||||
dmadrvPeripheralSignal_PROTIMER_BOF = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERBOF | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC0
|
||||
dmadrvPeripheralSignal_PROTIMER_CC0 = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC0 | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC1
|
||||
dmadrvPeripheralSignal_PROTIMER_CC1 = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC1 | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC2
|
||||
dmadrvPeripheralSignal_PROTIMER_CC2 = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC2 | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC3
|
||||
dmadrvPeripheralSignal_PROTIMER_CC3 = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC3 | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC4
|
||||
dmadrvPeripheralSignal_PROTIMER_CC4 = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERCC4 | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERPOF
|
||||
dmadrvPeripheralSignal_PROTIMER_POF = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERPOF | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERWOF
|
||||
dmadrvPeripheralSignal_PROTIMER_WOF = LDMAXBAR_CH_REQSEL_SIGSEL_PROTIMERWOF | LDMAXBAR_CH_REQSEL_SOURCESEL_PROTIMER,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_MODEMDEBUG
|
||||
dmadrvPeripheralSignal_MODEM_DEBUG = LDMAXBAR_CH_REQSEL_SIGSEL_MODEMDEBUG | LDMAXBAR_CH_REQSEL_SOURCESEL_MODEM,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_IADC0IADC_SCAN
|
||||
dmadrvPeripheralSignal_IADC0_IADC_SCAN = LDMAXBAR_CH_REQSEL_SIGSEL_IADC0IADC_SCAN | LDMAXBAR_CH_REQSEL_SOURCESEL_IADC0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_IADC0IADC_SINGLE
|
||||
dmadrvPeripheralSignal_IADC0_IADC_SINGLE = LDMAXBAR_CH_REQSEL_SIGSEL_IADC0IADC_SINGLE | LDMAXBAR_CH_REQSEL_SOURCESEL_IADC0,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_IMEMWDATA
|
||||
dmadrvPeripheralSignal_IMEM_WDATA = LDMAXBAR_CH_REQSEL_SIGSEL_IMEMWDATA | LDMAXBAR_CH_REQSEL_SOURCESEL_IMEM,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2CC0
|
||||
dmadrvPeripheralSignal_TIMER2_CC0 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2CC0 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2CC1
|
||||
dmadrvPeripheralSignal_TIMER2_CC1 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2CC1 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2CC2
|
||||
dmadrvPeripheralSignal_TIMER2_CC2 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2CC2 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2UFOF
|
||||
dmadrvPeripheralSignal_TIMER2_UFOF = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER2UFOF | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER2,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3CC0
|
||||
dmadrvPeripheralSignal_TIMER3_CC0 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3CC0 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER3,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3CC1
|
||||
dmadrvPeripheralSignal_TIMER3_CC1 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3CC1 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER3,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3CC2
|
||||
dmadrvPeripheralSignal_TIMER3_CC2 = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3CC2 | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER3,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3UFOF
|
||||
dmadrvPeripheralSignal_TIMER3_UFOF = LDMAXBAR_CH_REQSEL_SIGSEL_TIMER3UFOF | LDMAXBAR_CH_REQSEL_SOURCESEL_TIMER3,
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUART0TXFL
|
||||
dmadrvPeripheralSignal_EUART0_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_EUART0TXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUART0, ///< Trig on EUART0_TXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUART0RXFL
|
||||
dmadrvPeripheralSignal_EUART0_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_EUART0RXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUART0, ///< Trig on EUART0_RXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART0TXFL
|
||||
dmadrvPeripheralSignal_EUSART0_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART0TXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART0, ///< Trig on EUART0_TXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART0RXFL
|
||||
dmadrvPeripheralSignal_EUSART0_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART0RXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART0, ///< Trig on EUART0_RXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART1TXFL
|
||||
dmadrvPeripheralSignal_EUSART1_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART1TXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART1, ///< Trig on EUART1_TXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART1RXFL
|
||||
dmadrvPeripheralSignal_EUSART1_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART1RXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART1, ///< Trig on EUART1_RXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART2TXFL
|
||||
dmadrvPeripheralSignal_EUSART2_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART2TXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART2, ///< Trig on EUART2_TXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART2RXFL
|
||||
dmadrvPeripheralSignal_EUSART2_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART2RXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART2, ///< Trig on EUART2_RXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART3TXFL
|
||||
dmadrvPeripheralSignal_EUSART3_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART3TXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART3, ///< Trig on EUART2_TXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART3RXFL
|
||||
dmadrvPeripheralSignal_EUSART3_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART3RXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART3, ///< Trig on EUART3_RXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART4TXFL
|
||||
dmadrvPeripheralSignal_EUSART4_TXBL = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART4TXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART4, ///< Trig on EUART4_TXBL.
|
||||
#endif
|
||||
#if defined LDMAXBAR_CH_REQSEL_SIGSEL_EUSART4RXFL
|
||||
dmadrvPeripheralSignal_EUSART4_RXDATAV = LDMAXBAR_CH_REQSEL_SIGSEL_EUSART4RXFL | LDMAXBAR_CH_REQSEL_SOURCESEL_EUSART4, ///< Trig on EUART4_RXBL.
|
||||
#endif
|
||||
};
|
||||
|
||||
/// Data size of one LDMA transfer item.
|
||||
SL_ENUM(DMADRV_DataSize_t) {
|
||||
dmadrvDataSize1 = ldmaCtrlSizeByte, ///< Byte
|
||||
dmadrvDataSize2 = ldmaCtrlSizeHalf, ///< Halfword
|
||||
dmadrvDataSize4 = ldmaCtrlSizeWord ///< Word
|
||||
};
|
||||
|
||||
#endif /* defined( LDMAXBAR_COUNT ) && ( LDMAXBAR_COUNT == 1 ) */
|
||||
|
||||
/** @} (end addtogroup dmadrv) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SILICON_LABS_DMADRV_SIGNALS_S2_H__ */
|
||||
1707
Libs/platform/emdrv/dmadrv/src/dmadrv.c
Normal file
1707
Libs/platform/emdrv/dmadrv/src/dmadrv.c
Normal file
File diff suppressed because it is too large
Load Diff
132
Libs/platform/emdrv/gpiointerrupt/inc/gpiointerrupt.h
Normal file
132
Libs/platform/emdrv/gpiointerrupt/inc/gpiointerrupt.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief GPIOINT API definition
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef GPIOINTERRUPT_H
|
||||
#define GPIOINTERRUPT_H
|
||||
|
||||
#include "em_device.h"
|
||||
#include "em_gpio.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup gpioint
|
||||
* @{
|
||||
******************************************************************************/
|
||||
/*******************************************************************************
|
||||
***************************** DEFINITIONS *********************************
|
||||
******************************************************************************/
|
||||
|
||||
#define INTERRUPT_UNAVAILABLE (0xFF) ///< A MACRO for Interrupt Un-available.
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* TYPEDEFS **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* GPIO interrupt callback function pointer.
|
||||
* @details
|
||||
* Parameters:
|
||||
* @li intNo - The pin interrupt number the callback function is invoked for.
|
||||
*/
|
||||
typedef void (*GPIOINT_IrqCallbackPtr_t)(uint8_t intNo);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
* Extended GPIO interrupt callback function pointer.
|
||||
* @details
|
||||
* Parameters:
|
||||
* @li intNo - The pin interrupt number the callback function is invoked for.
|
||||
* @li ctx - Pointer to callback context.
|
||||
*/
|
||||
typedef void (*GPIOINT_IrqCallbackPtrExt_t)(uint8_t intNo, void *ctx);
|
||||
|
||||
/*******************************************************************************
|
||||
****************************** PROTOTYPES *********************************
|
||||
******************************************************************************/
|
||||
void GPIOINT_Init(void);
|
||||
void GPIOINT_CallbackRegister(uint8_t intNo, GPIOINT_IrqCallbackPtr_t callbackPtr);
|
||||
unsigned int GPIOINT_CallbackRegisterExt(uint8_t pin, GPIOINT_IrqCallbackPtrExt_t callbackPtr, void *callbackCtx);
|
||||
__STATIC_INLINE void GPIOINT_CallbackUnRegister(uint8_t intNo);
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
unsigned int GPIOINT_EM4WUCallbackRegisterExt(GPIO_Port_TypeDef port,
|
||||
uint8_t pin,
|
||||
GPIOINT_IrqCallbackPtrExt_t callbackPtr,
|
||||
void *callbackCtx);
|
||||
__STATIC_INLINE void GPIOINT_EM4WUCallbackUnRegister(uint8_t intNo);
|
||||
#endif
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unregister user callback for a given pin interrupt number.
|
||||
*
|
||||
* @details
|
||||
* Use this function to unregister a callback.
|
||||
*
|
||||
* @param[in] intNo
|
||||
* Pin interrupt number for the callback.
|
||||
*
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void GPIOINT_CallbackUnRegister(uint8_t intNo)
|
||||
{
|
||||
GPIOINT_CallbackRegister(intNo, 0);
|
||||
}
|
||||
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Unregister user EM4WU callback for a given pin interrupt number.
|
||||
*
|
||||
* @details
|
||||
* Use this function to unregister a EM4WU callback.
|
||||
*
|
||||
* @param[in] intNo
|
||||
* Pin interrupt number for the EM4WU callback.
|
||||
*
|
||||
******************************************************************************/
|
||||
__STATIC_INLINE void GPIOINT_EM4WUCallbackUnRegister(uint8_t intNo)
|
||||
{
|
||||
#if defined(_GPIO_IEN_EM4WUIEN_SHIFT)
|
||||
GPIOINT_CallbackRegister(_GPIO_IEN_EM4WUIEN_SHIFT + intNo, 0);
|
||||
#else
|
||||
GPIOINT_CallbackRegister(_GPIO_IEN_EM4WUIEN0_SHIFT + intNo, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup gpioint) */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GPIOINTERRUPT_H */
|
||||
359
Libs/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c
Normal file
359
Libs/platform/emdrv/gpiointerrupt/src/gpiointerrupt.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief GPIOINT API implementation
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "gpiointerrupt.h"
|
||||
#include "sl_assert.h"
|
||||
#include "sl_common.h"
|
||||
#include "sl_gpio.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup gpioint
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/*******************************************************************************
|
||||
******************************** DEFINES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/// Define for supporting gpiointerrupt porting
|
||||
#define SL_GPIO_PORT_INTERRUPT (0xFF)
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* STRUCTS ***********************************
|
||||
******************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
/* Pin interrupt number in range of 0 to 31 */
|
||||
uint32_t intNo;
|
||||
/* Pointer to the callback function */
|
||||
void *callback;
|
||||
/* Pointer to the callback context */
|
||||
void *context;
|
||||
/* True if callback takes a context */
|
||||
bool context_flag;
|
||||
} GPIOINT_CallbackDesc_t;
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
static void gpioint_map_callback (uint8_t int_no, void *context);
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** GLOBAL FUNCTIONS ******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialization of GPIOINT module.
|
||||
*
|
||||
******************************************************************************/
|
||||
void GPIOINT_Init(void)
|
||||
{
|
||||
sl_gpio_init();
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Registers user callback for given pin interrupt number.
|
||||
*
|
||||
* @details
|
||||
* Use this function to register a callback which shall be called upon
|
||||
* interrupt generated for a given pin interrupt number.
|
||||
* Interrupt itself must be configured externally. Function overwrites previously
|
||||
* registered callback.
|
||||
*
|
||||
* @param[in] intNo
|
||||
* Pin interrupt number for the callback.
|
||||
* @param[in] callbackPtr
|
||||
* A pointer to callback function.
|
||||
******************************************************************************/
|
||||
void GPIOINT_CallbackRegister(uint8_t intNo, GPIOINT_IrqCallbackPtr_t callbackPtr)
|
||||
{
|
||||
sl_gpio_t gpio;
|
||||
gpio.port = SL_GPIO_PORT_INTERRUPT;
|
||||
gpio.pin = -1;
|
||||
int32_t int_no = intNo;
|
||||
if (int_no <= GPIO_PIN_MAX) {
|
||||
sl_gpio_configure_external_interrupt(&gpio, &int_no, false, gpioint_map_callback, (void *)callbackPtr);
|
||||
} else {
|
||||
#if defined(_GPIO_IEN_EM4WUIEN_SHIFT)
|
||||
int_no = int_no - _GPIO_IEN_EM4WUIEN_SHIFT;
|
||||
#else
|
||||
int_no = int_no - _GPIO_IEN_EM4WUIEN0_SHIFT;
|
||||
#endif
|
||||
sl_gpio_configure_wakeup_em4_interrupt(&gpio, &int_no, false, gpioint_map_callback, (void *)callbackPtr);
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Registers user em4 wakeup callback for given port and pin interrupt number.
|
||||
*
|
||||
* @details
|
||||
* Use this function to register an EM4 wakeup callback with context which shall
|
||||
* be called upon interrupt generated for a given pin number.
|
||||
* The function will return an interrupt number if one is available and pin is
|
||||
* EM4WU compatible.
|
||||
* Interrupt itself must be configured externally.
|
||||
*
|
||||
* @param[in] port
|
||||
* GPIO Port for the callback.
|
||||
* @param[in] pin
|
||||
* Pin number for the callback.
|
||||
* @param[in] callbackPtr
|
||||
* A pointer to callback function.
|
||||
* @param[in] callbackCtx
|
||||
* A pointer to the callback context.
|
||||
*
|
||||
* @return
|
||||
* Interrupt number, or INTERRUPT_UNAVAILABLE if all are in use or pin doesn't
|
||||
* support em4 wakeup.
|
||||
******************************************************************************/
|
||||
unsigned int GPIOINT_EM4WUCallbackRegisterExt(GPIO_Port_TypeDef port,
|
||||
uint8_t pin,
|
||||
GPIOINT_IrqCallbackPtrExt_t callbackPtr,
|
||||
void *callbackCtx)
|
||||
{
|
||||
int32_t intNo = INTERRUPT_UNAVAILABLE;
|
||||
sl_gpio_t gpio;
|
||||
gpio.port = SL_GPIO_PORT_INTERRUPT;
|
||||
gpio.pin = -1;
|
||||
|
||||
if (false) {
|
||||
/* Check all the EM4WU Pins and check if given pin matches any of them. */
|
||||
#if defined(GPIO_EM4WU0_PORT)
|
||||
} else if (GPIO_EM4WU0_PORT == port && GPIO_EM4WU0_PIN == pin) {
|
||||
intNo = 0;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU1_PORT)
|
||||
} else if (GPIO_EM4WU1_PORT == port && GPIO_EM4WU1_PIN == pin) {
|
||||
intNo = 1;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU3_PORT)
|
||||
} else if (GPIO_EM4WU3_PORT == port && GPIO_EM4WU3_PIN == pin) {
|
||||
intNo = 3;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU4_PORT)
|
||||
} else if (GPIO_EM4WU4_PORT == port && GPIO_EM4WU4_PIN == pin) {
|
||||
intNo = 4;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU6_PORT)
|
||||
} else if (GPIO_EM4WU6_PORT == port && GPIO_EM4WU6_PIN == pin) {
|
||||
intNo = 6;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU7_PORT)
|
||||
} else if (GPIO_EM4WU7_PORT == port && GPIO_EM4WU7_PIN == pin) {
|
||||
intNo = 7;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU8_PORT)
|
||||
} else if (GPIO_EM4WU8_PORT == port && GPIO_EM4WU8_PIN == pin) {
|
||||
intNo = 8;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU9_PORT)
|
||||
} else if (GPIO_EM4WU9_PORT == port && GPIO_EM4WU9_PIN == pin) {
|
||||
intNo = 9;
|
||||
#endif
|
||||
#if defined(GPIO_EM4WU10_PORT)
|
||||
} else if (GPIO_EM4WU10_PORT == port && GPIO_EM4WU10_PIN == pin) {
|
||||
intNo = 10;
|
||||
#endif
|
||||
}
|
||||
|
||||
sl_status_t status = sl_gpio_configure_wakeup_em4_interrupt(&gpio, &intNo, false, (sl_gpio_irq_callback_t)callbackPtr, callbackCtx);
|
||||
|
||||
if (status == SL_STATUS_OK) {
|
||||
return intNo;
|
||||
} else {
|
||||
return INTERRUPT_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Registers user callback for given pin interrupt number.
|
||||
*
|
||||
* @details
|
||||
* Use this function to register a callback with context which shall be called upon
|
||||
* interrupt generated for a given pin number.
|
||||
* The function will return an interrupt number if one is available.
|
||||
* Interrupt itself must be configured externally.
|
||||
*
|
||||
* @param[in] pin
|
||||
* Pin number for the callback.
|
||||
* @param[in] callbackPtr
|
||||
* A pointer to callback function.
|
||||
* @param[in] callbackCtx
|
||||
* A pointer to the callback context.
|
||||
*
|
||||
* @return
|
||||
* Interrupt number, or INTERRUPT_UNAVAILABLE if all are in use
|
||||
******************************************************************************/
|
||||
unsigned int GPIOINT_CallbackRegisterExt(uint8_t pin, GPIOINT_IrqCallbackPtrExt_t callbackPtr, void *callbackCtx)
|
||||
{
|
||||
sl_gpio_t gpio;
|
||||
gpio.port = SL_GPIO_PORT_INTERRUPT;
|
||||
gpio.pin = pin;
|
||||
int32_t intNo = SL_GPIO_INTERRUPT_UNAVAILABLE;
|
||||
sl_status_t status = sl_gpio_configure_external_interrupt(&gpio, &intNo, false, (sl_gpio_irq_callback_t)callbackPtr, callbackCtx);
|
||||
if (status == SL_STATUS_OK) {
|
||||
return intNo;
|
||||
} else {
|
||||
return INTERRUPT_UNAVAILABLE;
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
************************** LOCAL FUNCTIONS *******************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Wrapper function to support porting gpiointerrupt
|
||||
*
|
||||
* @param[in] int_no
|
||||
* Interrupt number for callback
|
||||
* @param[in] context
|
||||
* A pointer to callback
|
||||
******************************************************************************/
|
||||
static void gpioint_map_callback(uint8_t int_no, void *context)
|
||||
{
|
||||
GPIOINT_IrqCallbackPtr_t old_callback = (GPIOINT_IrqCallbackPtr_t)context;
|
||||
if (old_callback != NULL) {
|
||||
old_callback(int_no);
|
||||
}
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
/** @} (end addtogroup gpioint) */
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
// ******* THE REST OF THE FILE IS DOCUMENTATION ONLY !************************
|
||||
/// @addtogroup gpioint GPIOINT - GPIO Interrupt
|
||||
/// @brief GPIOINT General Purpose Input/Output Interrupt dispatcher
|
||||
/// @{
|
||||
///
|
||||
/// @details
|
||||
/// The source files for the GPIO interrupt dispatcher library resides in the
|
||||
/// emdrv/gpiointerrupt folder, and are named gpiointerrupt.c and gpiointerrupt.h.
|
||||
///
|
||||
///
|
||||
/// @n @section gpioint_intro Introduction
|
||||
/// EFM32/EZR32/EFR32 has two GPIO interrupts lines, Odd and Even. If more
|
||||
/// than two interrupts are used then interrupt routine must dispatch from a callback
|
||||
/// register. This module provides small dispatcher for both GPIO interrupts enabling
|
||||
/// handling of up to 32 GPIO pin interrupts.
|
||||
///
|
||||
/// It is up to the user to configure and enable interrupt on given pin. This can be done
|
||||
/// using the GPIO library (emlib). This module handles the dispatch register and clearing of
|
||||
/// interrupt flags.
|
||||
///
|
||||
/// In order to use this dispatcher, it has to be initialized first by
|
||||
/// calling GPIOINT_Init(). Then each pin interrupt number must be configured by first
|
||||
/// registering the callback function for given interrupt number and then configure and
|
||||
/// enabling the interrupt number in the GPIO module.
|
||||
///
|
||||
/// The extended function GPIOINT_CallbackRegisterExt() may also be used to register a callback
|
||||
/// with context for a given pin number. The first available interrupt number will be returned.
|
||||
///
|
||||
/// @n @section gpioint_api The API
|
||||
/// This section contain brief descriptions of the functions in the API. You will
|
||||
/// find detailed information on parameters by clicking on the hyperlinked function names.
|
||||
///
|
||||
/// Your application code must include one header file: @em gpiointerrupt.h.
|
||||
///
|
||||
/// @ref GPIOINT_Init() @n
|
||||
/// This functions initializes the dispatcher register. Typically
|
||||
/// GPIOINT_Init() is called once in your startup code.
|
||||
///
|
||||
/// @ref GPIOINT_CallbackRegister() @n
|
||||
/// Register a callback function on a pin interrupt number.
|
||||
///
|
||||
/// @ref GPIOINT_CallbackUnRegister() @n
|
||||
/// Un-register a callback function on a pin interrupt number.
|
||||
///
|
||||
/// @ref GPIOINT_CallbackRegisterExt() @n
|
||||
/// Register a callback function with context on a pin number.
|
||||
///
|
||||
/// @n @section gpioint_example Example
|
||||
/// @code{.c}
|
||||
///
|
||||
///#include "gpiointerrupt.h"
|
||||
///
|
||||
///#include "em_chip.h"
|
||||
///#include "em_cmu.h"
|
||||
///#include "em_gpio.h"
|
||||
///
|
||||
///// An array to track if given pin callback was called
|
||||
///volatile uint8_t pinInt[32];
|
||||
///
|
||||
///// Gpio callbacks called when pin interrupt was triggered.
|
||||
///void gpioCallback1(uint8_t intNo)
|
||||
///{
|
||||
/// pinInt[intNo]++;
|
||||
///}
|
||||
///
|
||||
///void gpioCallback3(uint8_t intNo)
|
||||
///{
|
||||
/// pinInt[intNo]++;
|
||||
///}
|
||||
///
|
||||
///void gpioCallback8(uint8_t intNo)
|
||||
///{
|
||||
/// pinInt[intNo]++;
|
||||
///}
|
||||
///
|
||||
///int main(void)
|
||||
///{
|
||||
/// CHIP_Init();
|
||||
///
|
||||
/// // Enable clock for GPIO module, initialize GPIOINT
|
||||
/// CMU_ClockEnable(cmuClock_GPIO, true);
|
||||
/// GPIOINT_Init();
|
||||
///
|
||||
/// // Register callback functions and enable interrupts
|
||||
/// GPIOINT_CallbackRegister(1, gpioCallback1);
|
||||
/// GPIOINT_CallbackRegister(3, gpioCallback3);
|
||||
/// unsigned int intPin8 = GPIOINT_CallbackRegisterExt(8, gpioCallback8, (void *)callback8context);
|
||||
/// GPIO_IntEnable(1<<1 | 1<<3 | 1<<intPin8);
|
||||
///
|
||||
/// while(true);
|
||||
///}
|
||||
///
|
||||
/// @endcode
|
||||
///
|
||||
/// @} end group gpioint *******************************************************
|
||||
61
Libs/platform/emdrv/nvm3/config/nvm3_config.h
Normal file
61
Libs/platform/emdrv/nvm3/config/nvm3_config.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 configuration file.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef NVM3_CONFIG_H
|
||||
#define NVM3_CONFIG_H
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*** Driver instrumentation options */
|
||||
#define NVM3_TRACE_PORT_NONE 0 // Nothing is printed
|
||||
#define NVM3_TRACE_PORT_PRINTF 1 // Print is available
|
||||
#define NVM3_TRACE_PORT_UNITYPRINTF 2 // Unity print is available
|
||||
|
||||
#define NVM3_TRACE_PORT NVM3_TRACE_PORT_NONE
|
||||
|
||||
/*** Event level
|
||||
0 Critical: Trace only critical events
|
||||
1 Warning : Trace warning events and above
|
||||
2 Info : Trace info events and above
|
||||
*/
|
||||
#define NVM3_TRACE_LEVEL_ERROR 0
|
||||
#define NVM3_TRACE_LEVEL_WARNING 1
|
||||
#define NVM3_TRACE_LEVEL_INFO 2
|
||||
#define NVM3_TRACE_LEVEL_LOW 3
|
||||
|
||||
#define NVM3_TRACE_LEVEL NVM3_TRACE_LEVEL_WARNING
|
||||
|
||||
#define NVM3_ASSERT_ON_ERROR false
|
||||
|
||||
/** @} (end addtogroup nvm3) */
|
||||
|
||||
#endif /* NVM3_CONFIG_H */
|
||||
104
Libs/platform/emdrv/nvm3/inc/nvm3.h
Normal file
104
Libs/platform/emdrv/nvm3/inc/nvm3.h
Normal file
@@ -0,0 +1,104 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 API definition (Device Specific).
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_H
|
||||
#define NVM3_H
|
||||
|
||||
#ifndef NVM3_HOST_BUILD
|
||||
#include "em_device.h"
|
||||
#endif
|
||||
|
||||
#include "nvm3_generic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
#define NVM3_MIN_FRAGMENT_COUNT (2U) ///< The minimum number of fragments
|
||||
#if defined(FLASH_PAGE_SIZE)
|
||||
#define NVM3_MAX_OBJECT_SIZE_X (NVM3_MAX_OBJECT_SIZE + 8) // Adjust for an object header
|
||||
#define FLASH_PAGE_SIZE_X (FLASH_PAGE_SIZE - 20) // Adjust for a page header
|
||||
#define NVM3_FRAGMENT_COUNT (((NVM3_MAX_OBJECT_SIZE_X - 1) / FLASH_PAGE_SIZE_X) + NVM3_MIN_FRAGMENT_COUNT)
|
||||
#endif
|
||||
|
||||
typedef struct nvm3_ObjFrag {
|
||||
uint8_t idx; // Fragment index
|
||||
bool isFirstFragFound; // The object first fragment found
|
||||
bool isLastFragFound; // The object last fragment found
|
||||
#if defined(FLASH_PAGE_SIZE)
|
||||
nvm3_ObjFragDetail_t detail[NVM3_FRAGMENT_COUNT];
|
||||
#else
|
||||
nvm3_ObjFragDetail_t detail[NVM3_MIN_FRAGMENT_COUNT];
|
||||
#endif
|
||||
} nvm3_ObjFrag_t;
|
||||
|
||||
typedef struct nvm3_Obj {
|
||||
nvm3_ObjectKey_t key; // The object key
|
||||
struct nvm3_Obj *objAdr; // The object pointer
|
||||
struct nvm3_Obj *nextObjAdr; // The next object pointer
|
||||
const void *srcPtr; // May be used to carry the source address of the data
|
||||
size_t totalLen; // The object total length
|
||||
uint8_t objType; // The object type
|
||||
bool isHdrValid; // The object header is valid
|
||||
bool isValid; // The object is valid
|
||||
bool isFragmented; // The object is fragmented
|
||||
nvm3_ObjFrag_t frag; // The object fragment information
|
||||
} nvm3_Obj_t;
|
||||
|
||||
// Definition of NVM3 variables
|
||||
/// @brief A variable used by the NVM3 functions.
|
||||
extern nvm3_Obj_t nvm3_internalObjectHandleA;
|
||||
/// @brief A variable used by the NVM3 functions.
|
||||
extern nvm3_Obj_t nvm3_internalObjectHandleB;
|
||||
/// @brief A variable used by the NVM3 functions.
|
||||
extern nvm3_Obj_t nvm3_internalObjectHandleC;
|
||||
/// @brief A variable used by the NVM3 functions.
|
||||
extern nvm3_Obj_t nvm3_internalObjectHandleD;
|
||||
#if defined(NVM3_SECURITY)
|
||||
/// @brief A variable used by the NVM3 functions.
|
||||
extern nvm3_Obj_t nvm3_internalObjectHandleE;
|
||||
#endif
|
||||
/// @brief A variable that must contain the maximum number of object fragments.
|
||||
extern const uint8_t nvm3_maxFragmentCount;
|
||||
/// @brief A variable containing the object handle size in bytes.
|
||||
extern const size_t nvm3_objHandleSize;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @} end group nvm3 ****************************************************/
|
||||
|
||||
#endif /* NVM3_H */
|
||||
71
Libs/platform/emdrv/nvm3/inc/nvm3_cache.h
Normal file
71
Libs/platform/emdrv/nvm3/inc/nvm3_cache.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 object cache
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_CACHE_H
|
||||
#define NVM3_CACHE_H
|
||||
|
||||
#include "nvm3_config.h"
|
||||
#include "nvm3.h"
|
||||
#include "nvm3_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*******************************************************************************
|
||||
******************************* TYPES *************************************
|
||||
******************************************************************************/
|
||||
|
||||
typedef bool (*nvm3_CacheScanCallback_t)(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjGroup_t group, nvm3_ObjPtr_t obj, void *user);
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** PROTOTYPES ************************************
|
||||
******************************************************************************/
|
||||
|
||||
void nvm3_cacheOpen(nvm3_Cache_t *h, nvm3_CacheEntry_t *ptr, size_t count);
|
||||
void nvm3_cacheClear(nvm3_Cache_t *h);
|
||||
void nvm3_cacheDelete(nvm3_Cache_t *h, nvm3_ObjectKey_t key);
|
||||
nvm3_ObjPtr_t nvm3_cacheGet(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjGroup_t *group);
|
||||
void nvm3_cacheSet(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group);
|
||||
|
||||
void nvm3_cacheScan(nvm3_Cache_t *h, nvm3_CacheScanCallback_t cacheScanCallback, void *user);
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
sl_status_t nvm3_cacheSort(nvm3_Cache_t *h);
|
||||
bool nvm3_cacheUpdateEntry(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group);
|
||||
sl_status_t nvm3_cacheAddEntry(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group);
|
||||
sl_status_t nvm3_cacheGetIdx(nvm3_Cache_t *h, nvm3_ObjectKey_t key, size_t low, size_t high, size_t *idx);
|
||||
void nvm3_cacheOrganize(nvm3_Cache_t *h, size_t idx);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NVM3_CACHE_H */
|
||||
71
Libs/platform/emdrv/nvm3/inc/nvm3_default.h
Normal file
71
Libs/platform/emdrv/nvm3/inc/nvm3_default.h
Normal file
@@ -0,0 +1,71 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 definition of the default data structures.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_DEFAULT_H
|
||||
#define NVM3_DEFAULT_H
|
||||
#include "nvm3_generic.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3default NVM3 Default Instance
|
||||
* @brief NVM3 default instance functions and handles
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
extern nvm3_Handle_t *nvm3_defaultHandle; ///< The default handle.
|
||||
extern nvm3_Init_t *nvm3_defaultInit; ///< Default initialization data.
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Initialize the default NVM3 instance.
|
||||
* Once initialized the instance can be accessed through the NVM3 API using
|
||||
* nvm3_defaultHandle as the nvm3_Handle_t handle.
|
||||
*
|
||||
* @return
|
||||
* @ref SL_STATUS_OK on success and a NVM3 @ref sl_status_t on failure.
|
||||
******************************************************************************/
|
||||
sl_status_t nvm3_initDefault(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Deinit the default NVM3 instance.
|
||||
*
|
||||
* @return
|
||||
* @ref SL_STATUS_OK on success and a NVM3 @ref sl_status_t on failure.
|
||||
******************************************************************************/
|
||||
sl_status_t nvm3_deinitDefault(void);
|
||||
|
||||
/** @} (end addtogroup nvm3default) */
|
||||
/** @} (end addtogroup nvm3) */
|
||||
|
||||
#endif /* NVM3_DEFAULT_H */
|
||||
1078
Libs/platform/emdrv/nvm3/inc/nvm3_generic.h
Normal file
1078
Libs/platform/emdrv/nvm3/inc/nvm3_generic.h
Normal file
File diff suppressed because it is too large
Load Diff
249
Libs/platform/emdrv/nvm3/inc/nvm3_hal.h
Normal file
249
Libs/platform/emdrv/nvm3/inc/nvm3_hal.h
Normal file
@@ -0,0 +1,249 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 driver HAL
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_HAL_H
|
||||
#define NVM3_HAL_H
|
||||
|
||||
#include "sl_status.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
#include "nvm3_hal_host.h"
|
||||
#else
|
||||
#include "sl_assert.h"
|
||||
#include "sl_common.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3hal NVM3 HAL
|
||||
* @brief NVM3 Hardware Abstraction Layer
|
||||
* @{
|
||||
* @details
|
||||
* This module provides the interface to the NVM. By having all NVM access
|
||||
* functions in a separate file, it is possible to support different hardware
|
||||
* by substituting the functions in this module.
|
||||
*
|
||||
* @note These functions are used by the NVM3 and should not be used by
|
||||
* any applications.
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
****************************** MACROS **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
#define NVM3_HAL_WRITE_SIZE_32 0 ///< Only single writes are allowed
|
||||
#define NVM3_HAL_WRITE_SIZE_16 1 ///< Two writes are allowed
|
||||
|
||||
#define NVM3_HAL_NVM_ACCESS_NONE 0 ///< No access
|
||||
#define NVM3_HAL_NVM_ACCESS_RD 1 ///< Read access
|
||||
#define NVM3_HAL_NVM_ACCESS_RDWR 2 ///< Read and write access
|
||||
#define NVM3_HAL_NVM_ACCESS_NOP 3 ///< Ignore
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
#define nvm3_halOpen(hal, a, b) ((hal)->open((a), (b)))
|
||||
#define nvm3_halClose(hal) ((hal)->close())
|
||||
#define nvm3_halGetInfo(hal, a) ((hal)->getInfo(a))
|
||||
#define nvm3_halNvmAccess(hal, a) ((hal)->access(a))
|
||||
#define nvm3_halReadWords(hal, a, b, c) ((hal)->readWords((a), (b), (c)))
|
||||
#define nvm3_halWriteWords(hal, a, b, c) ((hal)->writeWords((a), (b), (c)))
|
||||
#define nvm3_halPageErase(hal, a) ((hal)->pageErase(a))
|
||||
|
||||
/// @endcond
|
||||
|
||||
/******************************************************************************
|
||||
****************************** TYPEDEFS **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
/// @brief Pointer to NVM
|
||||
typedef void *nvm3_HalPtr_t;
|
||||
|
||||
/// @brief Device NVM capabilities
|
||||
|
||||
typedef struct nvm3_HalInfo {
|
||||
uint16_t deviceFamilyPartNumber; ///< Device family or part number.
|
||||
uint8_t writeSize; ///< Write-size: 0=32-bit, 1=16-bit.
|
||||
uint8_t memoryMapped; ///< Memory-mapped: 0=not memory mapped, 1=memory mapped.
|
||||
size_t pageSize; ///< The data storage page size.
|
||||
uint64_t systemUnique; ///< Obsolete. Was used to support external flash.
|
||||
} nvm3_HalInfo_t;
|
||||
|
||||
typedef uint8_t nvm3_HalNvmAccessCode_t; ///< Definition of the access data type.
|
||||
|
||||
/*******************************************************************************
|
||||
***************************** PROTOTYPES **********************************
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Open the NVM3 HAL for usage.
|
||||
*
|
||||
* @details
|
||||
* This function must be run at initialization, before any other functions
|
||||
* are called. It is used to call necessary startup routines before the
|
||||
* hardware can be accessed.
|
||||
*
|
||||
* @param[in] nvmAdr
|
||||
* A pointer to the destination in NVM.
|
||||
*
|
||||
* @param[in] nvmSize
|
||||
* The total size of the NVM.
|
||||
*
|
||||
* @return
|
||||
* The result of the open call.
|
||||
* @ref SL_STATUS_OK on success or a NVM3 @ref sl_status_t on failure.
|
||||
******************************************************************************/
|
||||
typedef sl_status_t (*nvm3_HalOpen_t)(nvm3_HalPtr_t nvmAdr, size_t nvmSize);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Close the NVM3 HAL for usage.
|
||||
*
|
||||
* @details
|
||||
* This function should be called at program termination.
|
||||
* Should be done before any graceful halts.
|
||||
******************************************************************************/
|
||||
typedef void(*nvm3_HalClose_t)(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Retrieve device information.
|
||||
*
|
||||
* @details
|
||||
* This function is used to retrieve information about the device properties,
|
||||
* such as the device family, write size, whether the NVM is memory mapped or
|
||||
* not, and finally the NVM page size.
|
||||
*
|
||||
* @param[in] info
|
||||
* A pointer to a structure that will receive the device information.
|
||||
******************************************************************************/
|
||||
typedef sl_status_t (*nvm3_HalGetInfo_t)(nvm3_HalInfo_t *info);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Control read and write access to the NVM.
|
||||
*
|
||||
* @details
|
||||
* This function is used to control the access to the NVM. It can be either
|
||||
* read, write, or none.
|
||||
*
|
||||
* @param[in] access
|
||||
* The requested access.
|
||||
******************************************************************************/
|
||||
typedef void (*nvm3_HalNvmAccess_t)(nvm3_HalNvmAccessCode_t access);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Erase a page in the NVM.
|
||||
*
|
||||
* @details
|
||||
* This function is used to erase an NVM page.
|
||||
*
|
||||
* @param[in] nvmAdr
|
||||
* A memory address pointing to the start of the page to erase.
|
||||
*
|
||||
* @return
|
||||
* The result of the erase operation.
|
||||
******************************************************************************/
|
||||
typedef sl_status_t (*nvm3_HalPageErase_t)(nvm3_HalPtr_t nvmAdr);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Read data from NVM.
|
||||
*
|
||||
* @details
|
||||
* This function is used to read data from the NVM. It will be a
|
||||
* blocking call, since the thread asking for data to be read cannot continue
|
||||
* without the data.
|
||||
*
|
||||
* @param[in] nvmAdr
|
||||
* A memory address in NVM where data will be read.
|
||||
*
|
||||
* @param[in] *dst
|
||||
* A pointer to the destination buffer.
|
||||
*
|
||||
* @param[in] wordCnt
|
||||
* The number of words to read.
|
||||
******************************************************************************/
|
||||
typedef sl_status_t (*nvm3_HalReadWords_t)(nvm3_HalPtr_t nvmAdr, void *dst, size_t wordCnt);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Write data to the NVM.
|
||||
*
|
||||
* @details
|
||||
* This function is used to write data to the NVM. This is a blocking
|
||||
* function.
|
||||
*
|
||||
* @param[in] nvmAdr
|
||||
* A memory address in NVM where data will be written.
|
||||
*
|
||||
* @param[in] *pSrc
|
||||
* A pointer to the source data.
|
||||
*
|
||||
* @param[in] cnt
|
||||
* The number of words to write.
|
||||
*
|
||||
* @return
|
||||
* The result of the write operation.
|
||||
* @ref SL_STATUS_OK on success or a NVM3 @ref sl_status_t on failure.
|
||||
******************************************************************************/
|
||||
typedef sl_status_t (*nvm3_HalWriteWords_t)(nvm3_HalPtr_t nvmAdr, void const *pSrc, size_t cnt);
|
||||
|
||||
/// @brief The HAL handle definition.
|
||||
typedef struct {
|
||||
nvm3_HalOpen_t open; ///< Pointer to the open function
|
||||
nvm3_HalClose_t close; ///< Pointer to the close function
|
||||
nvm3_HalGetInfo_t getInfo; ///< Pointer to the get-info function
|
||||
nvm3_HalNvmAccess_t access; ///< Pointer to the access function
|
||||
nvm3_HalPageErase_t pageErase; ///< Pointer to the page-erase function
|
||||
nvm3_HalReadWords_t readWords; ///< Pointer to the read-words function
|
||||
nvm3_HalWriteWords_t writeWords; ///< Pointer to the write-words function
|
||||
} nvm3_HalHandle_t;
|
||||
|
||||
/** @} (end addtogroup nvm3hal) */
|
||||
/** @} (end addtogroup nvm3) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NVM3_HAL_H */
|
||||
68
Libs/platform/emdrv/nvm3/inc/nvm3_hal_flash.h
Normal file
68
Libs/platform/emdrv/nvm3/inc/nvm3_hal_flash.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 driver HAL for memory mapped FLASH
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_HAL_FLASH_H
|
||||
#define NVM3_HAL_FLASH_H
|
||||
|
||||
#include "nvm3_hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3hal
|
||||
* @{
|
||||
* @details
|
||||
* This module provides the NVM3 interface to the EFM and EFR Flash NVM.
|
||||
*
|
||||
* @note The features available through the handle are used by the NVM3 and
|
||||
* should not be used directly by any applications.
|
||||
******************************************************************************/
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** GLOBAL VARIABLES ******************************
|
||||
******************************************************************************/
|
||||
|
||||
extern const nvm3_HalHandle_t nvm3_halFlashHandle; ///< The HAL flash handle.
|
||||
|
||||
/** @} (end addtogroup nvm3hal) */
|
||||
/** @} (end addtogroup nvm3) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NVM3_HAL_FLASH_H */
|
||||
93
Libs/platform/emdrv/nvm3/inc/nvm3_lock.h
Normal file
93
Libs/platform/emdrv/nvm3/inc/nvm3_lock.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 data access lock API definition
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_LOCK_H
|
||||
#define NVM3_LOCK_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3lock NVM3 Lock
|
||||
* @brief NVM3 lock functions
|
||||
* @{
|
||||
* @details
|
||||
* This module provides data protection tools for NVM3.
|
||||
*
|
||||
* The functions in this module are the default protection tools for NVM3.
|
||||
* The application can substitute the nvm3_lockBegin and nvm3_lockEnd
|
||||
* functions as long as the NVM3 functions are protected from
|
||||
* being called re-entrant.
|
||||
*
|
||||
* @note These functions are used by the NVM3 and should not be used by
|
||||
* any applications.
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Create a mutex to lock and unlock section.
|
||||
******************************************************************************/
|
||||
void nvm3_lockCreateMutex(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Begin a lock section.
|
||||
******************************************************************************/
|
||||
void nvm3_lockBegin(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* End a lock section.
|
||||
******************************************************************************/
|
||||
void nvm3_lockEnd(void);
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Disable execution from data area.
|
||||
******************************************************************************/
|
||||
void nvm3_lockDisableExecute(void* address, size_t size);
|
||||
|
||||
/** @} (end addtogroup nvm3lock) */
|
||||
/** @} (end addtogroup nvm3) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif //NVM3_LOCK_H
|
||||
111
Libs/platform/emdrv/nvm3/inc/nvm3_object.h
Normal file
111
Libs/platform/emdrv/nvm3/inc/nvm3_object.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 object definition
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_OBJECT_H
|
||||
#define NVM3_OBJECT_H
|
||||
|
||||
#include "nvm3_hal.h"
|
||||
#include "nvm3_config.h"
|
||||
#include "nvm3.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
#define NVM3_OBJ_SMALL_MAX_SIZE 120U // Small object is limited to 120 bytes
|
||||
#define NVM3_OBJ_PTR_INVALID ((nvm3_ObjPtr_t)(-1L))
|
||||
#define NVM3_OBJ_HDR_PTR_INVALID ((nvm3_ObjHdrPtr_t)(-1L))
|
||||
#define NVM3_OBJ_HEADER_SIZE_LARGE (sizeof(nvm3_ObjHdrLarge_t))
|
||||
#define NVM3_OBJ_HEADER_SIZE_WLARGE (sizeof(nvm3_ObjHdrLarge_t) / sizeof(uint32_t))
|
||||
#define NVM3_OBJ_HEADER_SIZE_SMALL (sizeof(nvm3_ObjHdrSmall_t))
|
||||
#define NVM3_OBJ_HEADER_SIZE_WSMALL (sizeof(nvm3_ObjHdrSmall_t) / sizeof(uint32_t))
|
||||
#define NVM3_OBJ_HEADER_SIZE_COUNTER (NVM3_OBJ_HEADER_SIZE_LARGE)
|
||||
|
||||
typedef struct nvm3_ObjHeaderSmall {
|
||||
uint32_t oh1;
|
||||
} nvm3_ObjHdrSmall_t;
|
||||
|
||||
typedef struct nvm3_ObjHeaderLarge {
|
||||
uint32_t oh1;
|
||||
uint32_t oh2;
|
||||
} nvm3_ObjHdrLarge_t;
|
||||
|
||||
typedef nvm3_ObjHdrSmall_t *nvm3_ObjHdrSmallPtr_t;
|
||||
typedef nvm3_ObjHdrLarge_t *nvm3_ObjHdrLargePtr_t;
|
||||
|
||||
typedef enum {
|
||||
objTypeDataLarge = 0,
|
||||
objTypeCounterLarge = 1,
|
||||
objTypeCounterSmall = 2,
|
||||
objTypeDeleted = 3,
|
||||
objTypeRes_1 = 4,
|
||||
objTypeRes_2 = 5,
|
||||
objTypeRes_3 = 6,
|
||||
objTypeDataSmall = 7,
|
||||
} nvm3_ObjType_t;
|
||||
|
||||
typedef enum {
|
||||
objGroupUnknown,
|
||||
objGroupData,
|
||||
objGroupCounter,
|
||||
objGroupDeleted,
|
||||
} nvm3_ObjGroup_t;
|
||||
|
||||
typedef enum {
|
||||
fragTypeNone = 0,
|
||||
fragTypeFirst = 1,
|
||||
fragTypeNext = 2,
|
||||
fragTypeLast = 3,
|
||||
} nvm3_ObjFragType_t;
|
||||
|
||||
typedef nvm3_Obj_t *nvm3_ObjPtr_t;
|
||||
|
||||
void nvm3_objInit(nvm3_ObjPtr_t obj, nvm3_ObjPtr_t objAdr);
|
||||
size_t nvm3_objHdrInit(nvm3_ObjHdrLargePtr_t oh, nvm3_ObjectKey_t key, nvm3_ObjType_t objType, size_t len, bool isLarge, nvm3_ObjFragType_t fragTyp);
|
||||
size_t nvm3_objHdrLen(bool isLarge);
|
||||
bool nvm3_objHdrValidateSmall(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
bool nvm3_objHdrValidateLarge(nvm3_ObjHdrLargePtr_t objHdrLarge);
|
||||
bool nvm3_objHdrGetErased(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
nvm3_ObjFragType_t nvm3_objHdrGetFragTyp(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
nvm3_ObjectKey_t nvm3_objHdrGetKey(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
bool nvm3_objHdrGetHdrIsLarge(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
size_t nvm3_objHdrGetHdrLen(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
size_t nvm3_objHdrGetDatLen(nvm3_ObjHdrLargePtr_t objHdrLarge);
|
||||
nvm3_ObjType_t nvm3_objHdrGetType(nvm3_ObjHdrSmallPtr_t objHdrSmall);
|
||||
nvm3_ObjType_t nvm3_objGroupToType(nvm3_ObjGroup_t objGroup, bool hdrIsLarge);
|
||||
nvm3_ObjGroup_t nvm3_objTypeToGroup(nvm3_ObjType_t objType);
|
||||
/// @endcond
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NVM3_OBJECT_H */
|
||||
97
Libs/platform/emdrv/nvm3/inc/nvm3_page.h
Normal file
97
Libs/platform/emdrv/nvm3/inc/nvm3_page.h
Normal file
@@ -0,0 +1,97 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 page handling functions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_PAGE_H
|
||||
#define NVM3_PAGE_H
|
||||
|
||||
#include "nvm3_hal.h"
|
||||
#include "nvm3_object.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
#define NVM3_PAGE_COUNTER_SIZE 27U // 27 bits
|
||||
#define NVM3_PAGE_COUNTER_MASK ((1U << NVM3_PAGE_COUNTER_SIZE) - 1U)
|
||||
#define NVM3_PAGE_BCCB_SIZE 5U // 5 bits
|
||||
#define NVM3_PAGE_BCCB_MASK ((1U << NVM3_PAGE_BCCB_SIZE) - 1U)
|
||||
|
||||
#define NVM3_PAGE_HEADER_WORDS 5 // The number of words in the page header
|
||||
#define NVM3_PAGE_HEADER_SIZE (sizeof(nvm3_PageHdr_t))
|
||||
#define NVM3_PAGE_HEADER_WSIZE (sizeof(nvm3_PageHdr_t) / sizeof(uint32_t))
|
||||
#define NVM3_PAGE_H1_OFFSET (0 * sizeof(uint32_t))
|
||||
#define NVM3_PAGE_H2_OFFSET (1 * sizeof(uint32_t))
|
||||
#define NVM3_PAGE_H3_OFFSET (2 * sizeof(uint32_t))
|
||||
#define NVM3_PAGE_H4_OFFSET (3 * sizeof(uint32_t))
|
||||
#define NVM3_PAGE_H5_OFFSET (4 * sizeof(uint32_t))
|
||||
|
||||
#define NVM3_ERASE_COUNT_INVALID 0xFFFFFFFFU
|
||||
#define NVM3_PAGE_INDEX_INVALID 0xFFFFU
|
||||
|
||||
typedef struct nvm3_PageHdr {
|
||||
uint32_t data[NVM3_PAGE_HEADER_WORDS];
|
||||
} nvm3_PageHdr_t;
|
||||
|
||||
/// @endcond
|
||||
|
||||
typedef enum {
|
||||
nvm3_PageStateGood,
|
||||
nvm3_PageStateGoodEip,
|
||||
nvm3_PageStateBad,
|
||||
nvm3_PageStateInvalidErased,
|
||||
nvm3_PageStateInvalidUnknown,
|
||||
} nvm3_PageState_t;
|
||||
|
||||
#if defined(NVM3_SECURITY)
|
||||
sl_status_t nvm3_pageHeaderWrite(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo, nvm3_SecurityType_t secType);
|
||||
#else
|
||||
sl_status_t nvm3_pageHeaderWrite(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo);
|
||||
#endif
|
||||
void nvm3_pageSetBad(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr);
|
||||
sl_status_t nvm3_pageSetEip(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr);
|
||||
uint32_t nvm3_pageGetEraseCnt(nvm3_PageHdr_t *pageHdr);
|
||||
nvm3_PageState_t nvm3_pageGetState(nvm3_PageHdr_t *pageHdr);
|
||||
bool nvm3_pageStateIsGood(nvm3_PageState_t pageState);
|
||||
bool nvm3_pageStateIsInvalid(nvm3_PageState_t pageState);
|
||||
nvm3_ObjPtr_t nvm3_pageGetFirstObj(nvm3_HalPtr_t pageAdr);
|
||||
#if defined(NVM3_SECURITY)
|
||||
nvm3_SecurityType_t nvm3_pageGetSecType(nvm3_PageHdr_t *pageHdr);
|
||||
sl_status_t nvm3_pageErase(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo, nvm3_SecurityType_t secType);
|
||||
#else
|
||||
sl_status_t nvm3_pageErase(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NVM3_PAGE_H */
|
||||
74
Libs/platform/emdrv/nvm3/inc/nvm3_trace.h
Normal file
74
Libs/platform/emdrv/nvm3/inc/nvm3_trace.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 trace macros
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef NVM3_TRACE_H
|
||||
#define NVM3_TRACE_H
|
||||
|
||||
#include "nvm3_config.h"
|
||||
#include <stdint.h>
|
||||
#if (NVM3_TRACE_PORT == NVM3_TRACE_PORT_PRINTF)
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
#if NVM3_TRACE_PORT == NVM3_TRACE_PORT_UNITYPRINTF
|
||||
#include "unity.h"
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3trace NVM3 Trace
|
||||
* @brief NVM3 Trace functions
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/*** */
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
// Temporary solution, shoud use NVM3_TRACE_LEVEL as well
|
||||
#define NVM3_TRACE_ENABLED (NVM3_TRACE_PORT != NVM3_TRACE_PORT_NONE)
|
||||
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
#define UnityPrintf(...) nvm3_tracePrint(NVM3_TRACE_LEVEL, __VA_ARGS__)
|
||||
#define UNITY_PRINT_EOL() nvm3_tracePrint(NVM3_TRACE_LEVEL, "\n")
|
||||
#define TEST_PRINTF UnityPrintf
|
||||
#define TEST_MESSAGE UnityPrintf
|
||||
#define UNITY_OUTPUT_CHAR UnityPrintf
|
||||
#endif
|
||||
|
||||
#if (NVM3_TRACE_PORT == NVM3_TRACE_PORT_PRINTF)
|
||||
#define nvm3_tracePrint(lev, ...) do { if (lev <= NVM3_TRACE_LEVEL) { printf(__VA_ARGS__); } } while (0)
|
||||
#elif (NVM3_TRACE_PORT == NVM3_TRACE_PORT_UNITYPRINTF)
|
||||
#define nvm3_tracePrint(lev, ...) do { if (lev <= NVM3_TRACE_LEVEL) { UnityPrintf(__VA_ARGS__); } } while (0)
|
||||
#else
|
||||
#define nvm3_tracePrint(lev, ...)
|
||||
#endif
|
||||
|
||||
/// @endcond
|
||||
|
||||
/** @} (end addtogroup nvm3trace) */
|
||||
|
||||
#endif /* NVM3_TRACE_H */
|
||||
68
Libs/platform/emdrv/nvm3/inc/nvm3_utils.h
Normal file
68
Libs/platform/emdrv/nvm3/inc/nvm3_utils.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 utility functions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef NVM3_UTILS_H
|
||||
#define NVM3_UTILS_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* This function calculates the Berger Code of the supplied input variable.
|
||||
* The Berger Code is calculated by looking at the binary value of the variable
|
||||
* and counting the number of binary zeros.
|
||||
*
|
||||
* @param[in, out] pResult
|
||||
* A pointer to a variable that will accumulate the berger code for
|
||||
* the input variable specified in the next two variables.
|
||||
*
|
||||
* @param[in] pInput
|
||||
* A pointer to the variable that contains data that is used.
|
||||
*
|
||||
* @param[in] numberOfBits
|
||||
* The number of bits in the input variable used in the calculation.
|
||||
* The calculation is starting from the least significant bit in the input
|
||||
* variable.
|
||||
******************************************************************************/
|
||||
void nvm3_utilsComputeBergerCode(uint8_t *pResult, void *pInput, uint8_t numberOfBits);
|
||||
|
||||
/// @endcond
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* NVM3_UTILS_H */
|
||||
4089
Libs/platform/emdrv/nvm3/src/nvm3.c
Normal file
4089
Libs/platform/emdrv/nvm3/src/nvm3.c
Normal file
File diff suppressed because it is too large
Load Diff
672
Libs/platform/emdrv/nvm3/src/nvm3_cache.c
Normal file
672
Libs/platform/emdrv/nvm3/src/nvm3_cache.c
Normal file
@@ -0,0 +1,672 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 object cache
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "nvm3_cache.h"
|
||||
#include "nvm3_trace.h"
|
||||
|
||||
#if defined(__ICCARM__)
|
||||
#define SPEED_OPT _Pragma("optimize=speed")
|
||||
#elif defined(__GNUC__) && defined(__CORTEX_M)
|
||||
#define SPEED_OPT _Pragma("GCC optimize(\"O3\")")
|
||||
#else
|
||||
#define SPEED_OPT
|
||||
#endif
|
||||
|
||||
#define TRACE_LEVEL NVM3_TRACE_LEVEL_LOW
|
||||
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
#include "sl_memory_manager.h"
|
||||
#endif
|
||||
|
||||
//****************************************************************************
|
||||
|
||||
// isValid is implemented as a macro as this significantly improves
|
||||
// speed when using compiler settings that do not inline these functions.
|
||||
#define isValid(h, idx) (h->entryPtr[idx].key != NVM3_KEY_INVALID)
|
||||
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
uint32_t *L;
|
||||
uint32_t *H;
|
||||
uint32_t *P1;
|
||||
uint32_t *P2;
|
||||
uint32_t *K1;
|
||||
uint32_t *K2;
|
||||
#endif
|
||||
|
||||
static inline nvm3_ObjectKey_t entryGetKey(nvm3_Cache_t *h, size_t idx)
|
||||
{
|
||||
uint32_t tmp = (uint32_t)h->entryPtr[idx].key;
|
||||
return (nvm3_ObjectKey_t)(tmp & NVM3_KEY_MASK);
|
||||
}
|
||||
|
||||
static inline nvm3_ObjGroup_t entryGetGroup(nvm3_Cache_t *h, size_t idx)
|
||||
{
|
||||
uint32_t tmp = (uint32_t)h->entryPtr[idx].key;
|
||||
return (nvm3_ObjGroup_t)(tmp >> NVM3_KEY_SIZE);
|
||||
}
|
||||
|
||||
static inline nvm3_ObjPtr_t entryGetPtr(nvm3_Cache_t *h, size_t idx)
|
||||
{
|
||||
return h->entryPtr[idx].ptr;
|
||||
}
|
||||
|
||||
static inline void entrySetKey(nvm3_Cache_t *h, size_t idx, nvm3_ObjectKey_t key)
|
||||
{
|
||||
uint32_t tmp = (uint32_t)h->entryPtr[idx].key;
|
||||
tmp &= ~NVM3_KEY_MASK;
|
||||
tmp |= key;
|
||||
h->entryPtr[idx].key = (nvm3_ObjectKey_t)tmp;
|
||||
}
|
||||
|
||||
static inline void entrySetGroup(nvm3_Cache_t *h, size_t idx, nvm3_ObjGroup_t group)
|
||||
{
|
||||
uint32_t tmp = (uint32_t)h->entryPtr[idx].key;
|
||||
tmp &= NVM3_KEY_MASK;
|
||||
tmp |= (group << NVM3_KEY_SIZE);
|
||||
h->entryPtr[idx].key = (nvm3_ObjectKey_t)tmp;
|
||||
}
|
||||
|
||||
static inline void entrySetPtr(nvm3_Cache_t *h, size_t idx, nvm3_ObjPtr_t obj)
|
||||
{
|
||||
h->entryPtr[idx].ptr = obj;
|
||||
}
|
||||
|
||||
static inline void setInvalid(nvm3_Cache_t *h, size_t idx)
|
||||
{
|
||||
h->entryPtr[idx].key = NVM3_KEY_INVALID;
|
||||
h->entryPtr[idx].ptr = NVM3_OBJ_PTR_INVALID;
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
|
||||
void nvm3_cacheOpen(nvm3_Cache_t *h, nvm3_CacheEntry_t *ptr, size_t count)
|
||||
{
|
||||
h->entryPtr = ptr;
|
||||
h->entryCount = count;
|
||||
nvm3_cacheClear(h);
|
||||
}
|
||||
|
||||
void nvm3_cacheClear(nvm3_Cache_t *h)
|
||||
{
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheClear.\n");
|
||||
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
setInvalid(h, idx);
|
||||
}
|
||||
h->overflow = false;
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
h->usedCount = 0U;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
/******************************************************************************************************//**
|
||||
* Find index of the key in cache using binary search.
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @param[in] key A 20-bit object identifier.
|
||||
*
|
||||
* @param[out] idx A pointer to the location where key idx will be placed.
|
||||
*
|
||||
* @return Returns SL_STATUS_OK on success or SL_STATUS_NOT_FOUND on failure.
|
||||
*********************************************************************************************************/
|
||||
static sl_status_t cacheSearch(nvm3_Cache_t *h, nvm3_ObjectKey_t key, size_t *idx)
|
||||
{
|
||||
if (h->usedCount <= 0U) {
|
||||
return SL_STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
size_t low = 0U;
|
||||
size_t high = h->usedCount - 1;
|
||||
size_t mid = 0U;
|
||||
while (low <= high) {
|
||||
mid = (low + high) / 2;
|
||||
if (entryGetKey(h, mid) == key) {
|
||||
*idx = mid;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
if (entryGetKey(h, mid) < key) {
|
||||
low = mid + 1;
|
||||
} else {
|
||||
if (mid != 0U) {
|
||||
high = mid - 1;
|
||||
} else {
|
||||
return SL_STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SL_STATUS_NOT_FOUND;
|
||||
}
|
||||
|
||||
/******************************************************************************************************//**
|
||||
* Merge two cache subarrays. Merges the two haves arr[low..mid] and arr[mid+1..high] of cache subarrays.
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @param[in] low Left index of cache subarray.
|
||||
*
|
||||
* @param[in] mid Mid index of cache subarray.
|
||||
*
|
||||
* @param[in] high Right index of cache subarray.
|
||||
*
|
||||
* @return Returns SL_STATUS_OK on success or SL_STATUS_ALLOCATION_FAILED on failure.
|
||||
*********************************************************************************************************/
|
||||
static sl_status_t cacheMerge(nvm3_Cache_t *h, uint32_t low, uint32_t mid, uint32_t high)
|
||||
{
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
|
||||
if ((low > mid) || (mid >= high)) {
|
||||
return SL_STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
uint32_t i, j, k;
|
||||
uint32_t a1 = mid - low + 1;
|
||||
uint32_t a2 = high - mid;
|
||||
|
||||
if ((L != NULL) && (H != NULL) && (P1 != NULL) && (P2 != NULL) && (K1 != NULL) && (K2 != NULL)) {
|
||||
// Copy cache key and pointer data into subarrays
|
||||
for (i = 0; i < a1; i++) {
|
||||
L[i] = entryGetKey(h, low + i);
|
||||
P1[i] = (uint32_t)h->entryPtr[low + i].ptr;
|
||||
K1[i] = h->entryPtr[low + i].key;
|
||||
}
|
||||
for (j = 0; j < a2; j++) {
|
||||
H[j] = entryGetKey(h, mid + 1 + j);
|
||||
P2[j] = (uint32_t)h->entryPtr[mid + 1 + j].ptr;
|
||||
K2[j] = h->entryPtr[mid + 1 + j].key;
|
||||
}
|
||||
|
||||
// Index of first, second and merged subarrays
|
||||
i = 0;
|
||||
j = 0;
|
||||
k = low;
|
||||
|
||||
// Merge cache subarrays
|
||||
while (i < a1 && j < a2) {
|
||||
if (L[i] <= H[j]) {
|
||||
h->entryPtr[k].key = K1[i];
|
||||
h->entryPtr[k].ptr = (uint32_t*)P1[i];
|
||||
i++;
|
||||
} else {
|
||||
h->entryPtr[k].key = K2[j];
|
||||
h->entryPtr[k].ptr = (uint32_t*)P2[j];
|
||||
j++;
|
||||
}
|
||||
k++;
|
||||
}
|
||||
|
||||
// Copy remaining cache elements of L subarray
|
||||
while (i < a1) {
|
||||
h->entryPtr[k].key = K1[i];
|
||||
h->entryPtr[k].ptr = (uint32_t*)P1[i];
|
||||
i++;
|
||||
k++;
|
||||
}
|
||||
|
||||
// Copy remaining cache elements of H subarray
|
||||
while (j < a2) {
|
||||
h->entryPtr[k].key = K2[j];
|
||||
h->entryPtr[k].ptr = (uint32_t*)P2[j];
|
||||
j++;
|
||||
k++;
|
||||
}
|
||||
} else {
|
||||
status = SL_STATUS_ALLOCATION_FAILED;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/******************************************************************************************************//**
|
||||
* Sort cache entries using merge sort.
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @return Returns SL_STATUS_OK on success or SL_STATUS_ALLOCATION_FAILED on failure.
|
||||
*********************************************************************************************************/
|
||||
sl_status_t nvm3_cacheSort(nvm3_Cache_t *h)
|
||||
{
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
uint32_t cacheSize = h->usedCount; // size of cache array
|
||||
uint32_t currSize; // current size of subarray
|
||||
uint32_t leftStart; // starting index of left subarray
|
||||
|
||||
// Allocate memory for cache subarrays
|
||||
L = sl_malloc(cacheSize * sizeof(uint32_t));
|
||||
H = sl_malloc(cacheSize * sizeof(uint32_t));
|
||||
P1 = sl_malloc(cacheSize * sizeof(uint32_t));
|
||||
P2 = sl_malloc(cacheSize * sizeof(uint32_t));
|
||||
K1 = sl_malloc(cacheSize * sizeof(uint32_t));
|
||||
K2 = sl_malloc(cacheSize * sizeof(uint32_t));
|
||||
|
||||
// Merge cache subarrays using bottom up approach.
|
||||
for (currSize = 1; currSize <= cacheSize - 1; currSize = (currSize * 2U)) {
|
||||
// Pick starting point of different subarrays of current size
|
||||
for (leftStart = 0; leftStart < cacheSize - 1; leftStart += (currSize * 2U)) {
|
||||
// Find ending point of left subarray. mid+1 is starting point of right
|
||||
uint32_t mid = SL_MIN(leftStart + currSize - 1, cacheSize - 1);
|
||||
uint32_t rightEnd = SL_MIN(leftStart + (2U * currSize - 1), cacheSize - 1);
|
||||
// Merge cache subarrays arr[leftStart...mid] & arr[mid+1...rightEnd]
|
||||
status = cacheMerge(h, leftStart, mid, rightEnd);
|
||||
}
|
||||
}
|
||||
|
||||
sl_free(L);
|
||||
sl_free(H);
|
||||
sl_free(K1);
|
||||
sl_free(P1);
|
||||
sl_free(K2);
|
||||
sl_free(P2);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/******************************************************************************************************//**
|
||||
* Update existing cache entry.
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @param[in] key A 20-bit object identifier.
|
||||
*
|
||||
* @param[in] obj A pointer to object struct.
|
||||
*
|
||||
* @param[in] group Object group.
|
||||
*
|
||||
* @return Returns true on success or false on failure.
|
||||
*********************************************************************************************************/
|
||||
bool nvm3_cacheUpdateEntry(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group)
|
||||
{
|
||||
size_t idx = 0;
|
||||
bool res = false;
|
||||
|
||||
if ((h->usedCount > 0U) && (h->usedCount <= h->entryCount)) {
|
||||
if (cacheSearch(h, key, &idx) == SL_STATUS_OK) {
|
||||
if (isValid(h, idx)) {
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
res = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheUpdateEntry, key=%5u, grp=%u, obj=%p, idx=%u.\n", key, group, obj, idx);
|
||||
return res;
|
||||
}
|
||||
|
||||
/******************************************************************************************************//**
|
||||
* Add new cache entry
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @param[in] key A 20-bit object identifier.
|
||||
*
|
||||
* @param[in] obj A pointer to object struct.
|
||||
*
|
||||
* @param[in] group Object type.
|
||||
*
|
||||
* @return Returns SL_STATUS_OK on success or SL_STATUS_ALLOCATION_FAILED on failure.
|
||||
*********************************************************************************************************/
|
||||
sl_status_t nvm3_cacheAddEntry(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group)
|
||||
{
|
||||
sl_status_t status = SL_STATUS_OK;
|
||||
bool cacheSet = false;
|
||||
|
||||
if (h->usedCount < h->entryCount) {
|
||||
size_t idx = 0;
|
||||
if (h->usedCount > 0U) {
|
||||
if (nvm3_cacheGetIdx(h, key, 0U, h->usedCount - 1, &idx) == SL_STATUS_OK) {
|
||||
nvm3_cacheOrganize(h, idx);
|
||||
}
|
||||
}
|
||||
setInvalid(h, idx);
|
||||
entrySetKey(h, idx, key);
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
cacheSet = true;
|
||||
h->usedCount++;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheAddEntry(1), key=%5u, grp=%u, obj=%p, idx=%u.\n", key, group, obj, idx);
|
||||
}
|
||||
|
||||
// Prioritize data over deleted objects, force an overwrite if possible
|
||||
if ((!cacheSet) && (group != objGroupDeleted)) {
|
||||
for (size_t idx1 = 0; idx1 < h->entryCount; idx1++) {
|
||||
nvm3_ObjGroup_t cacheGroup = entryGetGroup(h, idx1);
|
||||
if (cacheGroup == objGroupDeleted) {
|
||||
entrySetKey(h, idx1, key);
|
||||
entrySetGroup(h, idx1, group);
|
||||
entrySetPtr(h, idx1, obj);
|
||||
cacheSet = true;
|
||||
if (h->usedCount > 1U) {
|
||||
status = nvm3_cacheSort(h);
|
||||
}
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheAddEntry(2), cache overflow for key=%u, grp=%u, obj=%p, inserted at idx=%u.\n", key, group, obj, idx1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!cacheSet) {
|
||||
h->overflow = true;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheAddEntry(3), cache overflow for key=%u, grp=%u, obj=%p.\n", key, group, obj);
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/******************************************************************************************************//**
|
||||
* Get cache idx to add new entry
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @param[in] key A 20-bit object identifier.
|
||||
*
|
||||
* @param[in] low Left index of cache subarray.
|
||||
*
|
||||
* @param[in] high Right index of cache subarray.
|
||||
*
|
||||
* @param[out] idx A pointer to the location where key idx will be placed.
|
||||
*
|
||||
* @return Returns SL_STATUS_OK on success or SL_STATUS_NOT_FOUND on failure.
|
||||
*********************************************************************************************************/
|
||||
sl_status_t nvm3_cacheGetIdx(nvm3_Cache_t *h, nvm3_ObjectKey_t key, size_t low, size_t high, size_t *idx)
|
||||
{
|
||||
if (high <= low) {
|
||||
*idx = (key > entryGetKey(h, low)) ? (low + 1) : low;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
if (key > entryGetKey(h, high)) {
|
||||
*idx = high + 1;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
if (key < entryGetKey(h, low)) {
|
||||
*idx = low;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
size_t mid = (low + high) / 2;
|
||||
if (key == entryGetKey(h, mid)) {
|
||||
*idx = mid + 1;
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
if (key > entryGetKey(h, mid)) {
|
||||
return nvm3_cacheGetIdx(h, key, mid + 1, high, idx);
|
||||
}
|
||||
if (mid != 0U) {
|
||||
return nvm3_cacheGetIdx(h, key, low, mid - 1, idx);
|
||||
} else {
|
||||
return SL_STATUS_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************************************//**
|
||||
* Arrange cache entries
|
||||
*
|
||||
* @param[in] h A pointer to NVM3 cache data.
|
||||
*
|
||||
* @param[in] idx Index of the key to arrange the cache entries.
|
||||
*
|
||||
*********************************************************************************************************/
|
||||
void nvm3_cacheOrganize(nvm3_Cache_t *h, size_t idx)
|
||||
{
|
||||
size_t lastIdx = h->usedCount - 1;
|
||||
// Move all cache entries from idx to end
|
||||
for (; (lastIdx >= idx) && (lastIdx != 0); lastIdx--) {
|
||||
h->entryPtr[lastIdx + 1].key = h->entryPtr[lastIdx].key;
|
||||
h->entryPtr[lastIdx + 1].ptr = h->entryPtr[lastIdx].ptr;
|
||||
}
|
||||
if ((lastIdx == 0) && (idx == 0)) {
|
||||
h->entryPtr[lastIdx + 1].key = h->entryPtr[lastIdx].key;
|
||||
h->entryPtr[lastIdx + 1].ptr = h->entryPtr[lastIdx].ptr;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
void nvm3_cacheDelete(nvm3_Cache_t *h, nvm3_ObjectKey_t key)
|
||||
{
|
||||
bool found = false;
|
||||
size_t idx = 0;
|
||||
|
||||
if ((h->usedCount > 0U) && (h->usedCount <= h->entryCount)) {
|
||||
if (cacheSearch(h, key, &idx) == SL_STATUS_OK) {
|
||||
if (isValid(h, idx)) {
|
||||
if (entryGetKey(h, idx) == key) {
|
||||
setInvalid(h, idx);
|
||||
found = true;
|
||||
size_t lastIdx = h->usedCount - 1;
|
||||
// Arrange cache entries after cache obj deletion
|
||||
for (; idx < lastIdx; idx++) {
|
||||
h->entryPtr[idx].key = h->entryPtr[idx + 1].key;
|
||||
h->entryPtr[idx].ptr = h->entryPtr[idx + 1].ptr;
|
||||
}
|
||||
if (h->usedCount > 0) {
|
||||
h->usedCount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheDelete, key=%u, found=%d.\n", key, found ? 1 : 0);
|
||||
(void)found;
|
||||
}
|
||||
#else
|
||||
void nvm3_cacheDelete(nvm3_Cache_t *h, nvm3_ObjectKey_t key)
|
||||
{
|
||||
bool found = false;
|
||||
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
if (isValid(h, idx)) {
|
||||
if (entryGetKey(h, idx) == key) {
|
||||
setInvalid(h, idx);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheDelete, key=%u, found=%d.\n", key, found ? 1 : 0);
|
||||
(void)found;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
nvm3_ObjPtr_t nvm3_cacheGet(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjGroup_t *group)
|
||||
{
|
||||
nvm3_ObjPtr_t obj = NVM3_OBJ_PTR_INVALID;
|
||||
#if NVM3_TRACE_PORT
|
||||
int tmp = -1;
|
||||
#endif
|
||||
|
||||
size_t idx = 0;
|
||||
if ((h->usedCount > 0U) && (h->usedCount <= h->entryCount)) {
|
||||
if (cacheSearch(h, key, &idx) == SL_STATUS_OK) {
|
||||
if (isValid(h, idx)) {
|
||||
*group = entryGetGroup(h, idx);
|
||||
obj = entryGetPtr(h, idx);
|
||||
#if NVM3_TRACE_PORT
|
||||
tmp = (int)idx;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheGet, key=%5u, grp=%d, obj=%p, idx=%d.\n", key, (obj != NVM3_OBJ_PTR_INVALID) ? *group : -1, obj, tmp);
|
||||
|
||||
return obj;
|
||||
}
|
||||
#else
|
||||
nvm3_ObjPtr_t nvm3_cacheGet(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjGroup_t *group)
|
||||
{
|
||||
nvm3_ObjPtr_t obj = NVM3_OBJ_PTR_INVALID;
|
||||
#if NVM3_TRACE_PORT
|
||||
int tmp = -1;
|
||||
#endif
|
||||
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
if (isValid(h, idx)) {
|
||||
if (entryGetKey(h, idx) == key) {
|
||||
*group = entryGetGroup(h, idx);
|
||||
obj = entryGetPtr(h, idx);
|
||||
#if NVM3_TRACE_PORT
|
||||
tmp = (int)idx;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheGet, key=%5u, grp=%d, obj=%p, idx=%d.\n", key, (obj != NVM3_OBJ_PTR_INVALID) ? *group : -1, obj, tmp);
|
||||
|
||||
return obj;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(NVM3_OPTIMIZATION) && (NVM3_OPTIMIZATION == 1)
|
||||
SPEED_OPT
|
||||
void nvm3_cacheSet(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group)
|
||||
{
|
||||
bool bSet = false;
|
||||
|
||||
// Update existing entry
|
||||
size_t idx = 0;
|
||||
if ((h->usedCount > 0U) && (h->usedCount <= h->entryCount)) {
|
||||
for (idx = 0; idx < h->usedCount; idx++) {
|
||||
if (isValid(h, idx)) {
|
||||
if (entryGetKey(h, idx) == key) {
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(1), key=%5u, grp=%u, obj=%p, idx=%u.\n", key, group, obj, idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add new Entry
|
||||
if (h->usedCount < h->entryCount) {
|
||||
idx = h->usedCount;
|
||||
if (!isValid(h, idx)) {
|
||||
entrySetKey(h, idx, key);
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
bSet = true;
|
||||
h->usedCount++;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(2), key=%5u, grp=%u, obj=%p, idx=%u.\n", key, group, obj, idx);
|
||||
}
|
||||
}
|
||||
|
||||
// Full, prioritize data over deleted objects, force an overwrite if possible
|
||||
if ((!bSet) && (group != objGroupDeleted)) {
|
||||
for (size_t idx1 = 0; idx1 < h->entryCount; idx1++) {
|
||||
nvm3_ObjGroup_t cacheGroup = entryGetGroup(h, idx1);
|
||||
if (cacheGroup == objGroupDeleted) {
|
||||
entrySetKey(h, idx1, key);
|
||||
entrySetGroup(h, idx1, group);
|
||||
entrySetPtr(h, idx1, obj);
|
||||
bSet = true;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(3), cache overflow for key=%u, grp=%u, obj=%p, inserted at idx=%u.\n", key, group, obj, idx1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSet) {
|
||||
h->overflow = true;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(4), cache overflow for key=%u, grp=%u, obj=%p.\n", key, group, obj);
|
||||
}
|
||||
}
|
||||
#else
|
||||
SPEED_OPT
|
||||
void nvm3_cacheSet(nvm3_Cache_t *h, nvm3_ObjectKey_t key, nvm3_ObjPtr_t obj, nvm3_ObjGroup_t group)
|
||||
{
|
||||
bool bSet = false;
|
||||
|
||||
// Update existing entry
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
if (isValid(h, idx)) {
|
||||
if (entryGetKey(h, idx) == key) {
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(1), key=%5u, grp=%u, obj=%p, idx=%u.\n", key, group, obj, idx);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add new Entry
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
if (!isValid(h, idx)) {
|
||||
entrySetKey(h, idx, key);
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
bSet = true;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(2), key=%5u, grp=%u, obj=%p, idx=%u.\n", key, group, obj, idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Full, prioritize data over deleted objects, force an overwrite if possible
|
||||
if ((!bSet) && (group != objGroupDeleted)) {
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
nvm3_ObjGroup_t cacheGroup = entryGetGroup(h, idx);
|
||||
if (cacheGroup == objGroupDeleted) {
|
||||
entrySetKey(h, idx, key);
|
||||
entrySetGroup(h, idx, group);
|
||||
entrySetPtr(h, idx, obj);
|
||||
bSet = true;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(3), cache overflow for key=%u, grp=%u, obj=%p, inserted at idx=%u.\n", key, group, obj, idx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!bSet) {
|
||||
h->overflow = true;
|
||||
nvm3_tracePrint(TRACE_LEVEL, " nvm3_cacheSet(4), cache overflow for key=%u, grp=%u, obj=%p.\n", key, group, obj);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void nvm3_cacheScan(nvm3_Cache_t *h, nvm3_CacheScanCallback_t cacheScanCallback, void *user)
|
||||
{
|
||||
bool keepGoing;
|
||||
for (size_t idx = 0; idx < h->entryCount; idx++) {
|
||||
if (isValid(h, idx)) {
|
||||
// Found an object.
|
||||
nvm3_ObjectKey_t key = entryGetKey(h, idx);
|
||||
nvm3_ObjGroup_t group = entryGetGroup(h, idx);
|
||||
nvm3_ObjPtr_t obj = entryGetPtr(h, idx);
|
||||
keepGoing = cacheScanCallback(h, key, group, obj, user);
|
||||
if (!keepGoing) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
100
Libs/platform/emdrv/nvm3/src/nvm3_default_common_linker.c
Normal file
100
Libs/platform/emdrv/nvm3/src/nvm3_default_common_linker.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 definition of the default data structures.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "nvm3.h"
|
||||
#include "nvm3_hal_flash.h"
|
||||
#include "nvm3_default_config.h"
|
||||
#if defined(NVM3_SECURITY)
|
||||
#include "nvm3_hal_crypto_handle.h"
|
||||
#endif
|
||||
|
||||
#if defined(NVM3_BASE)
|
||||
/* Manually control the NVM3 address and size */
|
||||
|
||||
#elif defined (__ICCARM__)
|
||||
|
||||
__root __no_init uint8_t nvm3_default_storage[NVM3_DEFAULT_NVM_SIZE] @ "SIMEE";
|
||||
#define NVM3_BASE (nvm3_default_storage)
|
||||
|
||||
#elif defined (__GNUC__)
|
||||
|
||||
extern char linker_nvm_begin;
|
||||
|
||||
__attribute__((used)) uint8_t nvm3_default_storage[NVM3_DEFAULT_NVM_SIZE] __attribute__ ((section(".simee")));
|
||||
#define NVM3_BASE (&linker_nvm_begin)
|
||||
|
||||
#else
|
||||
#error "Unsupported toolchain"
|
||||
#endif
|
||||
|
||||
nvm3_Handle_t nvm3_defaultHandleData;
|
||||
nvm3_Handle_t *nvm3_defaultHandle = &nvm3_defaultHandleData;
|
||||
|
||||
#if (NVM3_DEFAULT_CACHE_SIZE != 0)
|
||||
static nvm3_CacheEntry_t defaultCache[NVM3_DEFAULT_CACHE_SIZE];
|
||||
#endif
|
||||
|
||||
// Compile time checks for NVM3 max object size macros
|
||||
#if NVM3_DEFAULT_MAX_OBJECT_SIZE > NVM3_MAX_OBJECT_SIZE_HIGH_LIMIT
|
||||
#error "NVM3_DEFAULT_MAX_OBJECT_SIZE is greater than max value supported"
|
||||
#elif NVM3_DEFAULT_MAX_OBJECT_SIZE < NVM3_MAX_OBJECT_SIZE_LOW_LIMIT
|
||||
#error "NVM3_DEFAULT_MAX_OBJECT_SIZE is less than min value supported"
|
||||
#endif
|
||||
|
||||
nvm3_Init_t nvm3_defaultInitData =
|
||||
{
|
||||
(nvm3_HalPtr_t)NVM3_BASE,
|
||||
NVM3_DEFAULT_NVM_SIZE,
|
||||
#if (NVM3_DEFAULT_CACHE_SIZE != 0)
|
||||
defaultCache,
|
||||
#else
|
||||
NULL,
|
||||
#endif
|
||||
NVM3_DEFAULT_CACHE_SIZE,
|
||||
NVM3_DEFAULT_MAX_OBJECT_SIZE,
|
||||
NVM3_DEFAULT_REPACK_HEADROOM,
|
||||
&nvm3_halFlashHandle,
|
||||
#if defined(NVM3_SECURITY)
|
||||
&nvm3_halCryptoHandle,
|
||||
NVM3_DEFAULT_SECURITY_TYPE,
|
||||
#endif
|
||||
};
|
||||
|
||||
nvm3_Init_t *nvm3_defaultInit = &nvm3_defaultInitData;
|
||||
|
||||
sl_status_t nvm3_initDefault(void)
|
||||
{
|
||||
return nvm3_open(nvm3_defaultHandle, nvm3_defaultInit);
|
||||
}
|
||||
|
||||
sl_status_t nvm3_deinitDefault(void)
|
||||
{
|
||||
return nvm3_close(nvm3_defaultHandle);
|
||||
}
|
||||
231
Libs/platform/emdrv/nvm3/src/nvm3_hal_flash.c
Normal file
231
Libs/platform/emdrv/nvm3/src/nvm3_hal_flash.c
Normal file
@@ -0,0 +1,231 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief Non-Volatile Memory Wear-Leveling driver HAL implementation
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include "nvm3.h"
|
||||
#include "nvm3_hal_flash.h"
|
||||
#include "em_system.h"
|
||||
#include "em_msc.h"
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3hal
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
****************************** MACROS **********************************
|
||||
*****************************************************************************/
|
||||
|
||||
#define CHECK_DATA 1 ///< Macro defining if data should be checked
|
||||
|
||||
/******************************************************************************
|
||||
*************************** LOCAL VARIABLES ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/******************************************************************************
|
||||
*************************** LOCAL FUNCTIONS ******************************
|
||||
*****************************************************************************/
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* Convert return type.
|
||||
*
|
||||
* @details
|
||||
* This function converts between the return type of the emlib and the
|
||||
* NVM3 API.
|
||||
*
|
||||
* @param[in] result
|
||||
* Operation result.
|
||||
*
|
||||
* @return
|
||||
* Returns remapped status code.
|
||||
******************************************************************************/
|
||||
static sl_status_t convertMscStatusToNvm3Status(MSC_Status_TypeDef result)
|
||||
{
|
||||
sl_status_t ret;
|
||||
|
||||
switch (result) {
|
||||
case mscReturnOk:
|
||||
ret = SL_STATUS_OK;
|
||||
break;
|
||||
case mscReturnInvalidAddr:
|
||||
ret = SL_STATUS_NVM3_INVALID_ADDR;
|
||||
break;
|
||||
default:
|
||||
ret = SL_STATUS_NVM3_EMULATOR;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Check if the page is erased.
|
||||
static bool isErased(void *adr, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
size_t cnt;
|
||||
uint32_t *dat = adr;
|
||||
|
||||
cnt = len / sizeof(uint32_t);
|
||||
for (i = 0U; i < cnt; i++) {
|
||||
if (*dat != 0xFFFFFFFFUL) {
|
||||
return false;
|
||||
}
|
||||
dat++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @endcond */
|
||||
|
||||
static sl_status_t nvm3_halFlashOpen(nvm3_HalPtr_t nvmAdr, size_t flashSize)
|
||||
{
|
||||
(void)nvmAdr;
|
||||
(void)flashSize;
|
||||
MSC_Init();
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
static void nvm3_halFlashClose(void)
|
||||
{
|
||||
MSC_Deinit();
|
||||
}
|
||||
|
||||
static sl_status_t nvm3_halFlashGetInfo(nvm3_HalInfo_t *halInfo)
|
||||
{
|
||||
SYSTEM_ChipRevision_TypeDef chipRev;
|
||||
|
||||
SYSTEM_ChipRevisionGet(&chipRev);
|
||||
#if defined(_SYSCFG_CHIPREV_PARTNUMBER_MASK)
|
||||
halInfo->deviceFamilyPartNumber = chipRev.partNumber;
|
||||
#else
|
||||
halInfo->deviceFamilyPartNumber = chipRev.family;
|
||||
#endif
|
||||
halInfo->memoryMapped = 1;
|
||||
#if defined(_SILICON_LABS_32B_SERIES_2)
|
||||
halInfo->writeSize = NVM3_HAL_WRITE_SIZE_32;
|
||||
#else
|
||||
halInfo->writeSize = NVM3_HAL_WRITE_SIZE_16;
|
||||
#endif
|
||||
halInfo->pageSize = SYSTEM_GetFlashPageSize();
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
static void nvm3_halFlashAccess(nvm3_HalNvmAccessCode_t access)
|
||||
{
|
||||
(void)access;
|
||||
}
|
||||
|
||||
static sl_status_t nvm3_halFlashReadWords(nvm3_HalPtr_t nvmAdr, void *dst, size_t wordCnt)
|
||||
{
|
||||
uint32_t *pSrc = (uint32_t *)nvmAdr;
|
||||
uint32_t *pDst = dst;
|
||||
|
||||
if ((((size_t)pSrc % 4) == 0) && (((size_t)pDst % 4) == 0)) {
|
||||
while (wordCnt > 0U) {
|
||||
*pDst++ = *pSrc++;
|
||||
wordCnt--;
|
||||
}
|
||||
} else {
|
||||
(void)memcpy(dst, nvmAdr, wordCnt * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
return SL_STATUS_OK;
|
||||
}
|
||||
|
||||
static sl_status_t nvm3_halFlashWriteWords(nvm3_HalPtr_t nvmAdr, void const *src, size_t wordCnt)
|
||||
{
|
||||
const uint32_t *pSrc = src;
|
||||
uint32_t *pDst = (uint32_t *)nvmAdr;
|
||||
MSC_Status_TypeDef mscSta;
|
||||
sl_status_t halSta;
|
||||
size_t byteCnt;
|
||||
|
||||
byteCnt = wordCnt * sizeof(uint32_t);
|
||||
mscSta = MSC_WriteWord(pDst, pSrc, byteCnt);
|
||||
halSta = convertMscStatusToNvm3Status(mscSta);
|
||||
|
||||
#if CHECK_DATA
|
||||
if (halSta == SL_STATUS_OK) {
|
||||
if (memcmp(pDst, pSrc, byteCnt) != 0) {
|
||||
halSta = SL_STATUS_FLASH_PROGRAM_FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return halSta;
|
||||
}
|
||||
|
||||
static sl_status_t nvm3_halFlashPageErase(nvm3_HalPtr_t nvmAdr)
|
||||
{
|
||||
MSC_Status_TypeDef mscSta;
|
||||
sl_status_t halSta;
|
||||
|
||||
mscSta = MSC_ErasePage((uint32_t *)nvmAdr);
|
||||
halSta = convertMscStatusToNvm3Status(mscSta);
|
||||
|
||||
#if CHECK_DATA
|
||||
if (halSta == SL_STATUS_OK) {
|
||||
if (!isErased(nvmAdr, SYSTEM_GetFlashPageSize())) {
|
||||
halSta = SL_STATUS_FLASH_ERASE_FAILED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return halSta;
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
*************************** GLOBAL VARIABLES ******************************
|
||||
******************************************************************************/
|
||||
|
||||
const nvm3_HalHandle_t nvm3_halFlashHandle = {
|
||||
.open = nvm3_halFlashOpen, ///< Set the open function
|
||||
.close = nvm3_halFlashClose, ///< Set the close function
|
||||
.getInfo = nvm3_halFlashGetInfo, ///< Set the get-info function
|
||||
.access = nvm3_halFlashAccess, ///< Set the access function
|
||||
.pageErase = nvm3_halFlashPageErase, ///< Set the page-erase function
|
||||
.readWords = nvm3_halFlashReadWords, ///< Set the read-words function
|
||||
.writeWords = nvm3_halFlashWriteWords, ///< Set the write-words function
|
||||
};
|
||||
|
||||
/** @} (end addtogroup nvm3hal) */
|
||||
/** @} (end addtogroup nvm3) */
|
||||
207
Libs/platform/emdrv/nvm3/src/nvm3_lock.c
Normal file
207
Libs/platform/emdrv/nvm3/src/nvm3_lock.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 data access lock API implementation
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "nvm3_lock.h"
|
||||
#include "nvm3.h"
|
||||
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
#include "nvm3_config.h"
|
||||
#include "nvm3_trace.h"
|
||||
#include "nvm3_hal.h"
|
||||
#else
|
||||
#include "sl_core.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_MPU_PRESENT)
|
||||
#include "sl_mpu.h"
|
||||
#endif
|
||||
|
||||
#if defined(SL_CATALOG_KERNEL_PRESENT)
|
||||
#include "cmsis_os2.h"
|
||||
#endif
|
||||
|
||||
//****************************************************************************
|
||||
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
#define SL_WEAK
|
||||
#endif
|
||||
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
static int lockCount = 0;
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
#elif defined(SL_CATALOG_KERNEL_PRESENT) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
static osMutexId_t nvm3_mutex; ///< NVM3 Lock Mutex
|
||||
#define NVM3_ERROR_ASSERT() do { EFM_ASSERT(false); } while (0)
|
||||
#else
|
||||
CORE_DECLARE_IRQ_STATE;
|
||||
/// @endcond
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
nvm3_Obj_t nvm3_internalObjectHandleA;
|
||||
nvm3_Obj_t nvm3_internalObjectHandleB;
|
||||
nvm3_Obj_t nvm3_internalObjectHandleC;
|
||||
nvm3_Obj_t nvm3_internalObjectHandleD;
|
||||
#if defined(NVM3_SECURITY)
|
||||
nvm3_Obj_t nvm3_internalObjectHandleE;
|
||||
#endif
|
||||
const uint8_t nvm3_maxFragmentCount = NVM3_FRAGMENT_COUNT;
|
||||
const size_t nvm3_objHandleSize = sizeof(nvm3_Obj_t);
|
||||
|
||||
/// @endcond
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup nvm3lock
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @details
|
||||
* The Mutex creation for lock enable and disable.
|
||||
*
|
||||
* It provides options for using "mutexes" for RTOS users
|
||||
* and "core_critical" APIs for bare-metal users.
|
||||
*
|
||||
* @note RTOS users should avoid invoking the nvm3_lock APIs from within
|
||||
* critical sections, as this may result in unexpected behavior.
|
||||
* Please, ensure that kernel has been initialized before this API call.
|
||||
******************************************************************************/
|
||||
SL_WEAK void nvm3_lockCreateMutex(void)
|
||||
{
|
||||
#if defined(SL_CATALOG_KERNEL_PRESENT) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
if (nvm3_mutex == NULL) {
|
||||
const osMutexAttr_t mutex_attr = {
|
||||
" NVM3 Mutex",
|
||||
osMutexRecursive | osMutexPrioInherit,
|
||||
NULL,
|
||||
0
|
||||
};
|
||||
nvm3_mutex = osMutexNew(&mutex_attr);
|
||||
if (nvm3_mutex == NULL) {
|
||||
NVM3_ERROR_ASSERT();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @details
|
||||
* The default lock-begin implementation.
|
||||
* @note RTOS users should avoid invoking the nvm3_lock APIs from within
|
||||
* critical sections, as this may result in unexpected behavior.
|
||||
* Please, ensure that kernel has been initialized before this API call.
|
||||
******************************************************************************/
|
||||
SL_WEAK void nvm3_lockBegin(void)
|
||||
{
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
lockCount++;
|
||||
// In apps running on micrium OS on Ser2, the app is acquiring the mutex within
|
||||
// a critical section while invoking bootloader APIs
|
||||
#elif defined(SL_CATALOG_KERNEL_PRESENT) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
osStatus_t os_status = osError;
|
||||
// Bypass the lock if kernel is not running
|
||||
if (osKernelGetState() == osKernelRunning) {
|
||||
if (nvm3_mutex == NULL) {
|
||||
nvm3_lockCreateMutex();
|
||||
}
|
||||
os_status = osMutexAcquire(nvm3_mutex, osWaitForever);
|
||||
if (os_status != osErrorISR && os_status != osOK) {
|
||||
NVM3_ERROR_ASSERT();
|
||||
}
|
||||
}
|
||||
#else
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
CORE_ENTER_CRITICAL();
|
||||
/// @endcond
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @details
|
||||
* The default lock-end implementation.
|
||||
* @note RTOS users should avoid invoking the nvm3_lock APIs from within
|
||||
* critical sections, as this may result in unexpected behavior.
|
||||
* Please, ensure that kernel has been initialized before this API call.
|
||||
******************************************************************************/
|
||||
SL_WEAK void nvm3_lockEnd(void)
|
||||
{
|
||||
#ifdef NVM3_HOST_BUILD
|
||||
if (lockCount == 0) {
|
||||
nvm3_tracePrint(NVM3_TRACE_LEVEL_ERROR, "NVM3 ERROR - lockEnd: invalid lock count.\n");
|
||||
}
|
||||
lockCount--;
|
||||
#elif defined(SL_CATALOG_KERNEL_PRESENT) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
osStatus_t os_status = osError;
|
||||
// Bypass the lock if kernel is not running
|
||||
if (osKernelGetState() == osKernelRunning) {
|
||||
os_status = osMutexRelease(nvm3_mutex);
|
||||
if (os_status != osErrorISR && os_status != osOK) {
|
||||
NVM3_ERROR_ASSERT();
|
||||
}
|
||||
}
|
||||
#else
|
||||
CORE_EXIT_CRITICAL();
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************//**
|
||||
* @details
|
||||
* Disable execution from data area.
|
||||
*
|
||||
* @param[in] address Start of memory range
|
||||
*
|
||||
* @param[in] size Size of memory range.
|
||||
******************************************************************************/
|
||||
void nvm3_lockDisableExecute(void *address, size_t size)
|
||||
{
|
||||
#if defined(__MPU_PRESENT) && (__MPU_PRESENT == 1U) \
|
||||
&& defined(SL_CATALOG_MPU_PRESENT) \
|
||||
&& !defined(SL_TRUSTZONE_SECURE)
|
||||
// The memory range used by nvm3 may not be compatible with the mpu.
|
||||
// Just ignore errors.
|
||||
sl_mpu_disable_execute((uint32_t)address, (uint32_t)address + size - 1, size);
|
||||
#else
|
||||
(void)address;
|
||||
(void)size;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** @} (end addtogroup nvm3lock) */
|
||||
/** @} (end addtogroup nvm3) */
|
||||
267
Libs/platform/emdrv/nvm3/src/nvm3_object.c
Normal file
267
Libs/platform/emdrv/nvm3/src/nvm3_object.c
Normal file
@@ -0,0 +1,267 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 object handling functions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "nvm3_object.h"
|
||||
#include "nvm3_utils.h"
|
||||
#include <string.h>
|
||||
|
||||
#define NVM3_OBJ_LEN_SIZE 7U // 7 bits
|
||||
#define NVM3_OBJ_LEN_MASK ((1U << NVM3_OBJ_LEN_SIZE) - 1U)
|
||||
#define NVM3_OBJ_LLEN_SIZE 26U // 26 bits: large obj length
|
||||
#define NVM3_OBJ_LLEN_MASK ((1U << NVM3_OBJ_LLEN_SIZE) - 1U)
|
||||
#define NVM3_OBJ_BCCB_SIZE 5U // 5 bits: small obj berger code
|
||||
#define NVM3_OBJ_BCCB_MASK ((1U << NVM3_OBJ_BCCB_SIZE) - 1U)
|
||||
#define NVM3_OBJ_LBCCB_SIZE 6U // 6 bits: large obj berger code
|
||||
#define NVM3_OBJ_LBCCB_MASK ((1U << NVM3_OBJ_LBCCB_SIZE) - 1U)
|
||||
#define NVM3_OBJ_F_SIZE 2U // 2 bits: fragment field
|
||||
#define NVM3_OBJ_F_MASK ((1U << NVM3_OBJ_F_SIZE) - 1U)
|
||||
#define NVM3_OBJ_U_SIZE 3U // 3 bits: unused field
|
||||
#define NVM3_OBJ_U_MASK ((1U << NVM3_OBJ_U_SIZE) - 1U)
|
||||
#define NVM3_OBJ_KEY_OFFSET (NVM3_OBJ_LEN_SIZE)
|
||||
#define NVM3_OBJ_F_OFFSET (NVM3_OBJ_LEN_SIZE + NVM3_KEY_SIZE)
|
||||
#define NVM3_OBJ_U_OFFSET (NVM3_OBJ_LEN_SIZE + NVM3_KEY_SIZE + NVM3_OBJ_F_SIZE)
|
||||
#define NVM3_OBJ_BCCB_OFFSET (NVM3_OBJ_LEN_SIZE + NVM3_KEY_SIZE)
|
||||
#define NVM3_OBJ_LBCCB_OFFSET (NVM3_OBJ_LLEN_SIZE)
|
||||
|
||||
//****************************************************************************
|
||||
|
||||
__STATIC_INLINE uint32_t hdrSmallGetBergerCode(nvm3_ObjHdrSmall_t *oh)
|
||||
{
|
||||
return (((oh)->oh1 >> NVM3_OBJ_BCCB_OFFSET) & NVM3_OBJ_BCCB_MASK);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t hdrLargeGetBergerCode(nvm3_ObjHdrLarge_t *oh)
|
||||
{
|
||||
return (((oh)->oh2 >> NVM3_OBJ_LBCCB_OFFSET) & NVM3_OBJ_LBCCB_MASK);
|
||||
}
|
||||
|
||||
__STATIC_INLINE nvm3_ObjType_t toObjType(uint32_t value)
|
||||
{
|
||||
int type = (int)value;
|
||||
return (nvm3_ObjType_t)type;
|
||||
}
|
||||
|
||||
__STATIC_INLINE nvm3_ObjFragType_t toObjFragType(uint32_t value)
|
||||
{
|
||||
int type = (int)value;
|
||||
return (nvm3_ObjFragType_t)type;
|
||||
}
|
||||
|
||||
__STATIC_INLINE nvm3_ObjType_t hdrGetType(nvm3_ObjHdrSmall_t *oh)
|
||||
{
|
||||
return toObjType(oh->oh1 & NVM3_OBJ_LEN_MASK);
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool hdrIsLarge(nvm3_ObjHdrSmall_t *oh)
|
||||
{
|
||||
nvm3_ObjType_t objTyp = hdrGetType(oh);
|
||||
return ((objTyp == objTypeCounterLarge) || (objTyp == objTypeDataLarge));
|
||||
}
|
||||
|
||||
//****************************************************************************
|
||||
|
||||
/*** Initialize object header */
|
||||
size_t nvm3_objHdrInit(nvm3_ObjHdrLargePtr_t oh, nvm3_ObjectKey_t key, nvm3_ObjType_t objType,
|
||||
size_t len, bool isLarge, nvm3_ObjFragType_t fragTyp)
|
||||
{
|
||||
uint8_t BCCB = 0;
|
||||
|
||||
oh->oh1 = (key & NVM3_KEY_MASK) << NVM3_OBJ_KEY_OFFSET;
|
||||
oh->oh2 = (len & NVM3_OBJ_LLEN_MASK);
|
||||
switch (objType) {
|
||||
case objTypeCounterLarge:
|
||||
/* Intented fall-through */
|
||||
case objTypeDataLarge:
|
||||
oh->oh1 |= (uint32_t)objType;
|
||||
oh->oh1 |= ((uint32_t)NVM3_OBJ_U_MASK << NVM3_OBJ_U_OFFSET);
|
||||
oh->oh1 |= ((uint32_t)fragTyp & NVM3_OBJ_F_MASK) << NVM3_OBJ_F_OFFSET;
|
||||
break;
|
||||
case objTypeCounterSmall:
|
||||
/* Intented fall-through*/
|
||||
case objTypeDeleted:
|
||||
oh->oh1 |= (uint32_t)objType;
|
||||
break;
|
||||
default:
|
||||
oh->oh1 |= ((len + (uint32_t)objTypeDataSmall) & NVM3_OBJ_LEN_MASK);
|
||||
break;
|
||||
}
|
||||
if (isLarge) {
|
||||
nvm3_utilsComputeBergerCode(&BCCB, &oh->oh1, 32);
|
||||
nvm3_utilsComputeBergerCode(&BCCB, &oh->oh2, NVM3_OBJ_LLEN_SIZE);
|
||||
oh->oh2 |= ((uint32_t)BCCB & NVM3_OBJ_LBCCB_MASK) << NVM3_OBJ_LBCCB_OFFSET;
|
||||
} else {
|
||||
nvm3_utilsComputeBergerCode(&BCCB, &oh->oh1, (uint8_t)(NVM3_OBJ_LEN_SIZE + NVM3_KEY_SIZE));
|
||||
oh->oh1 |= ((uint32_t)BCCB & NVM3_OBJ_BCCB_MASK) << NVM3_OBJ_BCCB_OFFSET;
|
||||
}
|
||||
|
||||
return nvm3_objHdrLen(isLarge);
|
||||
}
|
||||
|
||||
size_t nvm3_objHdrLen(bool isLarge)
|
||||
{
|
||||
return isLarge ? NVM3_OBJ_HEADER_SIZE_LARGE : NVM3_OBJ_HEADER_SIZE_SMALL;
|
||||
}
|
||||
|
||||
bool nvm3_objHdrValidateSmall(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
uint8_t codReq = 0;
|
||||
uint8_t codAct;
|
||||
bool res = false;
|
||||
|
||||
nvm3_utilsComputeBergerCode(&codReq, &objHdrSmall->oh1, (uint8_t)(NVM3_OBJ_LEN_SIZE + NVM3_KEY_SIZE));
|
||||
codAct = (uint8_t)hdrSmallGetBergerCode(objHdrSmall);
|
||||
if (codReq == codAct) {
|
||||
res = true;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool nvm3_objHdrValidateLarge(nvm3_ObjHdrLargePtr_t objHdrLarge)
|
||||
{
|
||||
uint8_t codReq = 0;
|
||||
uint8_t codAct;
|
||||
bool res = false;
|
||||
|
||||
nvm3_utilsComputeBergerCode(&codReq, &objHdrLarge->oh1, 32);
|
||||
nvm3_utilsComputeBergerCode(&codReq, &objHdrLarge->oh2, NVM3_OBJ_LLEN_SIZE);
|
||||
codAct = (uint8_t)hdrLargeGetBergerCode(objHdrLarge);
|
||||
if (codReq == codAct) {
|
||||
res = true;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
bool nvm3_objHdrGetErased(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
return objHdrSmall->oh1 == 0xFFFFFFFFU;
|
||||
}
|
||||
|
||||
nvm3_ObjFragType_t nvm3_objHdrGetFragTyp(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
nvm3_ObjFragType_t fragTyp = toObjFragType((objHdrSmall->oh1 >> NVM3_OBJ_F_OFFSET) & NVM3_OBJ_F_MASK);
|
||||
|
||||
return hdrIsLarge(objHdrSmall) ? fragTyp : fragTypeNone;
|
||||
}
|
||||
|
||||
nvm3_ObjectKey_t nvm3_objHdrGetKey(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
return (nvm3_ObjectKey_t)((objHdrSmall->oh1 >> NVM3_OBJ_KEY_OFFSET) & NVM3_KEY_MASK);
|
||||
}
|
||||
|
||||
bool nvm3_objHdrGetHdrIsLarge(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
return hdrIsLarge(objHdrSmall);
|
||||
}
|
||||
|
||||
size_t nvm3_objHdrGetHdrLen(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
return nvm3_objHdrLen(hdrIsLarge(objHdrSmall));
|
||||
}
|
||||
|
||||
size_t nvm3_objHdrGetDatLen(nvm3_ObjHdrLargePtr_t objHdrLarge)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (hdrIsLarge((nvm3_ObjHdrSmallPtr_t)objHdrLarge)) {
|
||||
len = objHdrLarge->oh2 & NVM3_OBJ_LLEN_MASK;
|
||||
} else {
|
||||
len = objHdrLarge->oh1 & NVM3_OBJ_LEN_MASK;
|
||||
len = (len > (size_t)objTypeDataSmall) ? (len - (size_t)objTypeDataSmall) : 0U;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
nvm3_ObjType_t nvm3_objHdrGetType(nvm3_ObjHdrSmallPtr_t objHdrSmall)
|
||||
{
|
||||
return hdrGetType(objHdrSmall);
|
||||
}
|
||||
|
||||
void nvm3_objInit(nvm3_ObjPtr_t obj, nvm3_ObjPtr_t objAdr)
|
||||
{
|
||||
// The sizeof(nvm3_Obj_t) is dependent on the page size.
|
||||
(void)memset(obj, 0, nvm3_objHandleSize);
|
||||
obj->key = NVM3_KEY_INVALID;
|
||||
obj->objAdr = objAdr;
|
||||
obj->isValid = false;
|
||||
obj->totalLen = 0;
|
||||
obj->nextObjAdr = NVM3_OBJ_PTR_INVALID;
|
||||
obj->isFragmented = false;
|
||||
obj->frag.isFirstFragFound = false;
|
||||
obj->frag.isLastFragFound = false;
|
||||
obj->frag.idx = 0;
|
||||
}
|
||||
|
||||
nvm3_ObjType_t nvm3_objGroupToType(nvm3_ObjGroup_t objGroup, bool hdrIsLarge)
|
||||
{
|
||||
nvm3_ObjType_t objType;
|
||||
|
||||
if (objGroup == objGroupDeleted) {
|
||||
objType = objTypeDeleted;
|
||||
} else if (objGroup == objGroupCounter) {
|
||||
objType = hdrIsLarge ? objTypeCounterLarge : objTypeCounterSmall;
|
||||
} else {
|
||||
objType = hdrIsLarge ? objTypeDataLarge : objTypeDataSmall;
|
||||
}
|
||||
|
||||
return objType;
|
||||
}
|
||||
|
||||
nvm3_ObjGroup_t nvm3_objTypeToGroup(nvm3_ObjType_t objType)
|
||||
{
|
||||
nvm3_ObjGroup_t objGroup;
|
||||
|
||||
switch (objType) {
|
||||
case objTypeCounterSmall:
|
||||
objGroup = objGroupCounter;
|
||||
break;
|
||||
case objTypeCounterLarge:
|
||||
objGroup = objGroupCounter;
|
||||
break;
|
||||
case objTypeDataLarge:
|
||||
objGroup = objGroupData;
|
||||
break;
|
||||
case objTypeRes_1:
|
||||
case objTypeRes_2:
|
||||
case objTypeRes_3:
|
||||
objGroup = objGroupUnknown;
|
||||
break;
|
||||
case objTypeDeleted:
|
||||
objGroup = objGroupDeleted;
|
||||
break;
|
||||
default:
|
||||
objGroup = objGroupData;
|
||||
break;
|
||||
}
|
||||
|
||||
return objGroup;
|
||||
}
|
||||
375
Libs/platform/emdrv/nvm3/src/nvm3_page.c
Normal file
375
Libs/platform/emdrv/nvm3/src/nvm3_page.c
Normal file
@@ -0,0 +1,375 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 page handling functions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include "nvm3_page.h"
|
||||
#include "nvm3_object.h"
|
||||
#include "nvm3_utils.h"
|
||||
#include "nvm3_trace.h"
|
||||
|
||||
/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
|
||||
|
||||
//============================================================================
|
||||
|
||||
#define H1_MAGIC_SHIFT 16 // The magic shift
|
||||
#define H1_MAGIC_V1 0xB29AU // The magic marker
|
||||
#define H1_VERSION_V1 0x01U // The first version of NVM3
|
||||
#define H4_BAD_MASK 0xffff0000U // The BAD mask
|
||||
#define H4_BAD_SHIFT 16 // The BAD shift
|
||||
#define H4_BAD_GOOD 0xFFFFU // The page is good
|
||||
#define H4_BAD_NOTGOOD 0x0000U // The page is not good
|
||||
#define H4_EIP_MASK 0xffffU // The EIP mask
|
||||
#define H4_EIP_SET 0xA5A5U // The page is scheduled for erase
|
||||
#define H4_EIP_CLEAR 0xFFFFU // The page is not sceduled for erase
|
||||
#define H5_DEVICE_FAMILY_MASK 0x07FFU
|
||||
#define H5_WRITESIZE_SHIFT 11
|
||||
#define H5_WRITESIZE_MASK 0x0800U
|
||||
#define H5_MEMORYMAPPED_SHIFT 12
|
||||
#define H5_MEMORYMAPPED_MASK 0x1000U
|
||||
#define H5_PAGESIZE_SHIFT 13
|
||||
#define H5_PAGESIZE_MASK 0xE000U
|
||||
#define H5_DEVINFO_MASK (H5_DEVICE_FAMILY_MASK | H5_WRITESIZE_MASK | H5_MEMORYMAPPED_MASK | H5_PAGESIZE_MASK)
|
||||
#if defined(NVM3_SECURITY)
|
||||
#define H5_SECTYPE_AEAD_SHIFT 16 // The AEAD shift
|
||||
#define H5_SECTYPE_AEAD_MASK 0x10000U // The AEAD mask
|
||||
#define H5_SECTYPE_ENC_SHIFT 17 // The encryption shift
|
||||
#define H5_SECTYPE_ENC_MASK 0x20000U // The encryption mask
|
||||
#endif
|
||||
|
||||
//============================================================================
|
||||
|
||||
typedef enum {
|
||||
eraseCntNormal,
|
||||
eraseCntInverted
|
||||
} EraseCnt_t;
|
||||
|
||||
//============================================================================
|
||||
|
||||
__STATIC_INLINE bool pageHdrErased(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
return (pageHdr->data[0] == 0xFFFFFFFFU);
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool pageHdrMagicAndVersion(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
uint16_t magic, version;
|
||||
|
||||
magic = (uint16_t)(pageHdr->data[0] >> H1_MAGIC_SHIFT);
|
||||
version = (uint16_t)pageHdr->data[0];
|
||||
return (magic == H1_MAGIC_V1) && (version == H1_VERSION_V1);
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool pageHdrIsPageBad(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
uint32_t badPage = (pageHdr->data[3] & H4_BAD_MASK) >> H4_BAD_SHIFT;
|
||||
|
||||
return badPage != H4_BAD_GOOD;
|
||||
}
|
||||
|
||||
__STATIC_INLINE bool pageHdrIsEraseInProgress(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
uint16_t EIP = (pageHdr->data[3]);
|
||||
|
||||
return EIP != H4_EIP_CLEAR;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t pageHdrGetCounterBcod(uint32_t h)
|
||||
{
|
||||
return (h >> NVM3_PAGE_COUNTER_SIZE) & NVM3_PAGE_BCCB_MASK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t pageHdrGetCounterVal(uint32_t h, EraseCnt_t level)
|
||||
{
|
||||
uint32_t cnt = (level == eraseCntInverted) ? ~h : h;
|
||||
return cnt & NVM3_PAGE_COUNTER_MASK;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t pageHdrCounterMake(uint32_t cnt, EraseCnt_t level)
|
||||
{
|
||||
uint8_t BCCB;
|
||||
|
||||
if (level == eraseCntInverted) {
|
||||
cnt = ~cnt;
|
||||
}
|
||||
cnt &= NVM3_PAGE_COUNTER_MASK;
|
||||
BCCB = 0;
|
||||
nvm3_utilsComputeBergerCode(&BCCB, &cnt, NVM3_PAGE_COUNTER_SIZE);
|
||||
return ((uint32_t)BCCB << NVM3_PAGE_COUNTER_SIZE) | cnt;
|
||||
}
|
||||
|
||||
// The page size field has a value from 0 to 7 describing page sizes from 512
|
||||
// to 65536 bytes. Note: The page size must be a power of 2.
|
||||
static uint16_t pageSizeToField(size_t pageSize)
|
||||
{
|
||||
uint16_t field = 0U;
|
||||
|
||||
pageSize /= 512U;
|
||||
for (;; ) {
|
||||
pageSize /= 2U;
|
||||
if (pageSize == 0U) {
|
||||
break;
|
||||
}
|
||||
field++;
|
||||
}
|
||||
|
||||
return field;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
#if defined(NVM3_SECURITY)
|
||||
sl_status_t nvm3_pageHeaderWrite(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo, nvm3_SecurityType_t secType)
|
||||
#else
|
||||
sl_status_t nvm3_pageHeaderWrite(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo)
|
||||
#endif
|
||||
{
|
||||
nvm3_PageHdr_t pageHdr;
|
||||
uint32_t devInfo;
|
||||
uint32_t formatInfo;
|
||||
size_t ofs;
|
||||
nvm3_HalPtr_t adr;
|
||||
sl_status_t staWrite;
|
||||
sl_status_t sta = SL_STATUS_OK;
|
||||
|
||||
// Create header
|
||||
devInfo = ((pageSizeToField(halInfo->pageSize) << H5_PAGESIZE_SHIFT) & H5_PAGESIZE_MASK)
|
||||
+ (((halInfo->memoryMapped) << H5_MEMORYMAPPED_SHIFT) & H5_MEMORYMAPPED_MASK)
|
||||
+ (((halInfo->writeSize) << H5_WRITESIZE_SHIFT) & H5_WRITESIZE_MASK)
|
||||
+ ((halInfo->deviceFamilyPartNumber) & H5_DEVICE_FAMILY_MASK);
|
||||
#if defined(NVM3_SECURITY)
|
||||
formatInfo = ((secType == NVM3_SECURITY_AEAD) ? 0 : 1) + 0xFFFEU;
|
||||
#else
|
||||
formatInfo = 0xFFFFU;
|
||||
#endif
|
||||
pageHdr.data[0] = (H1_MAGIC_V1 << H1_MAGIC_SHIFT) | H1_VERSION_V1;
|
||||
pageHdr.data[1] = pageHdrCounterMake(eraseCnt, eraseCntNormal);
|
||||
pageHdr.data[2] = pageHdrCounterMake(eraseCnt, eraseCntInverted);
|
||||
pageHdr.data[3] = 0xffffffffU;
|
||||
pageHdr.data[4] = (formatInfo << 16) | (devInfo);
|
||||
//printf("-> hdrWr: adr=%p, cnt=%u, 1=0x%08x, 2=0x%08x\n", pageAdr, eraseCnt, pageHdr.data[1], pageHdr.data[2]);
|
||||
|
||||
// Write header in the following order: H5 -> H3 -> H2 -> H1
|
||||
// Write H5
|
||||
ofs = 4 * sizeof(uint32_t);
|
||||
adr = (nvm3_HalPtr_t)((size_t)pageAdr + ofs);
|
||||
staWrite = nvm3_halWriteWords(hal, adr, &(pageHdr.data[4]), 1);
|
||||
if (staWrite != SL_STATUS_OK) {
|
||||
sta = staWrite;
|
||||
}
|
||||
|
||||
// Write H4
|
||||
// Do not write 0xffffffff
|
||||
|
||||
// Write H3
|
||||
ofs = 2 * sizeof(uint32_t);
|
||||
adr = (nvm3_HalPtr_t)((size_t)pageAdr + ofs);
|
||||
staWrite = nvm3_halWriteWords(hal, adr, &(pageHdr.data[2]), 1);
|
||||
if (staWrite != SL_STATUS_OK) {
|
||||
sta = staWrite;
|
||||
}
|
||||
|
||||
// Write H2
|
||||
ofs = 1 * sizeof(uint32_t);
|
||||
adr = (nvm3_HalPtr_t)((size_t)pageAdr + ofs);
|
||||
staWrite = nvm3_halWriteWords(hal, adr, &(pageHdr.data[1]), 1);
|
||||
if (staWrite != SL_STATUS_OK) {
|
||||
sta = staWrite;
|
||||
}
|
||||
|
||||
// Write H1
|
||||
ofs = 0;
|
||||
adr = (nvm3_HalPtr_t)((size_t)pageAdr + ofs);
|
||||
staWrite = nvm3_halWriteWords(hal, adr, &(pageHdr.data[0]), 1);
|
||||
if (staWrite != SL_STATUS_OK) {
|
||||
sta = staWrite;
|
||||
}
|
||||
|
||||
return sta;
|
||||
}
|
||||
|
||||
/*** Mark page as bad page */
|
||||
void nvm3_pageSetBad(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr)
|
||||
{
|
||||
uint32_t h4Rd;
|
||||
uint32_t h4Wr;
|
||||
nvm3_HalPtr_t adr;
|
||||
|
||||
nvm3_tracePrint(NVM3_TRACE_LEVEL_WARNING, "nvm3_pageSetBad, pageAdr=0x%p.\n", pageAdr);
|
||||
|
||||
adr = (nvm3_HalPtr_t)((size_t)pageAdr + NVM3_PAGE_H4_OFFSET);
|
||||
nvm3_halReadWords(hal, adr, &h4Rd, 1);
|
||||
|
||||
h4Wr = h4Rd & ~H4_BAD_MASK;
|
||||
h4Wr |= (H4_BAD_NOTGOOD << H4_BAD_SHIFT);
|
||||
(void)nvm3_halWriteWords(hal, adr, &h4Wr, 1);
|
||||
|
||||
// There is no recovery from a write error at this point.
|
||||
}
|
||||
|
||||
sl_status_t nvm3_pageSetEip(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr)
|
||||
{
|
||||
uint32_t h4Rd;
|
||||
uint32_t h4Wr;
|
||||
nvm3_HalPtr_t adr;
|
||||
sl_status_t sta = SL_STATUS_OK;
|
||||
|
||||
nvm3_tracePrint(NVM3_TRACE_LEVEL_LOW, " nvm3_pageSetEip, pageAdr=0x%p.\n", pageAdr);
|
||||
|
||||
adr = (nvm3_HalPtr_t)((size_t)pageAdr + NVM3_PAGE_H4_OFFSET);
|
||||
nvm3_halReadWords(hal, adr, &h4Rd, 1);
|
||||
if ((h4Rd & H4_EIP_MASK) == H4_EIP_CLEAR) {
|
||||
h4Wr = (h4Rd & ~H4_EIP_MASK);
|
||||
h4Wr |= H4_EIP_SET;
|
||||
sta = nvm3_halWriteWords(hal, adr, &h4Wr, 1);
|
||||
}
|
||||
|
||||
return sta;
|
||||
}
|
||||
|
||||
uint32_t nvm3_pageGetEraseCnt(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
uint8_t BCCB;
|
||||
|
||||
BCCB = 0;
|
||||
nvm3_utilsComputeBergerCode(&BCCB, &(pageHdr->data[1]), NVM3_PAGE_COUNTER_SIZE);
|
||||
if (BCCB == pageHdrGetCounterBcod(pageHdr->data[1])) {
|
||||
return pageHdrGetCounterVal(pageHdr->data[1], eraseCntNormal);
|
||||
}
|
||||
|
||||
BCCB = 0;
|
||||
nvm3_utilsComputeBergerCode(&BCCB, &(pageHdr->data[2]), NVM3_PAGE_COUNTER_SIZE);
|
||||
if (BCCB == pageHdrGetCounterBcod(pageHdr->data[2])) {
|
||||
return pageHdrGetCounterVal(pageHdr->data[2], eraseCntInverted);
|
||||
}
|
||||
|
||||
//printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ERROR: getEraseCount failed!\n");
|
||||
return NVM3_ERASE_COUNT_INVALID;
|
||||
}
|
||||
|
||||
nvm3_PageState_t nvm3_pageGetState(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
nvm3_PageState_t pageState;
|
||||
uint32_t eraseCnt = NVM3_ERASE_COUNT_INVALID;
|
||||
bool pageHdrValid;
|
||||
|
||||
pageHdrValid = pageHdrMagicAndVersion(pageHdr);
|
||||
|
||||
if (pageHdrValid) {
|
||||
eraseCnt = nvm3_pageGetEraseCnt(pageHdr);
|
||||
}
|
||||
|
||||
if (eraseCnt != NVM3_ERASE_COUNT_INVALID) {
|
||||
if (pageHdrIsPageBad(pageHdr)) {
|
||||
pageState = nvm3_PageStateBad;
|
||||
} else if (pageHdrIsEraseInProgress(pageHdr)) {
|
||||
pageState = nvm3_PageStateGoodEip;
|
||||
} else {
|
||||
pageState = nvm3_PageStateGood;
|
||||
}
|
||||
} else {
|
||||
if (pageHdrErased(pageHdr)) {
|
||||
pageState = nvm3_PageStateInvalidErased;
|
||||
} else {
|
||||
pageState = nvm3_PageStateInvalidUnknown;
|
||||
}
|
||||
}
|
||||
|
||||
return pageState;
|
||||
}
|
||||
|
||||
bool nvm3_pageStateIsGood(nvm3_PageState_t pageState)
|
||||
{
|
||||
return ((pageState == nvm3_PageStateGood) || (pageState == nvm3_PageStateGoodEip));
|
||||
}
|
||||
|
||||
bool nvm3_pageStateIsInvalid(nvm3_PageState_t pageState)
|
||||
{
|
||||
return ((pageState == nvm3_PageStateInvalidErased) || (pageState == nvm3_PageStateInvalidUnknown));
|
||||
}
|
||||
|
||||
nvm3_ObjPtr_t nvm3_pageGetFirstObj(nvm3_HalPtr_t pageAdr)
|
||||
{
|
||||
return (nvm3_ObjPtr_t)((size_t)pageAdr + NVM3_PAGE_HEADER_SIZE);
|
||||
}
|
||||
|
||||
#if defined(NVM3_SECURITY)
|
||||
sl_status_t nvm3_pageErase(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo, nvm3_SecurityType_t secType)
|
||||
#else
|
||||
sl_status_t nvm3_pageErase(const nvm3_HalHandle_t *hal, nvm3_HalPtr_t pageAdr, uint32_t eraseCnt, nvm3_HalInfo_t *halInfo)
|
||||
#endif
|
||||
{
|
||||
sl_status_t sta;
|
||||
|
||||
nvm3_tracePrint(NVM3_TRACE_LEVEL_LOW, " nvm3_pageErase: adr=0x%p, eraseCnt=%u.\n", pageAdr, eraseCnt);
|
||||
|
||||
// Erase
|
||||
sta = nvm3_halPageErase(hal, pageAdr);
|
||||
if (sta == SL_STATUS_OK) {
|
||||
// Create new page header
|
||||
#if defined(NVM3_SECURITY)
|
||||
sta = nvm3_pageHeaderWrite(hal, pageAdr, eraseCnt, halInfo, secType);
|
||||
#else
|
||||
sta = nvm3_pageHeaderWrite(hal, pageAdr, eraseCnt, halInfo);
|
||||
#endif
|
||||
if (sta != SL_STATUS_OK) {
|
||||
nvm3_tracePrint(NVM3_TRACE_LEVEL_WARNING, " erasePage: adr=0x%p, Write hdr ERROR, mark page as BAD.\n", pageAdr);
|
||||
nvm3_pageSetBad(hal, pageAdr);
|
||||
}
|
||||
} else {
|
||||
// Erasure failed, mark page as BAD
|
||||
nvm3_tracePrint(NVM3_TRACE_LEVEL_WARNING, " erasePage: adr=0x%p, Erase ERROR, page is marked as BAD.\n", pageAdr);
|
||||
nvm3_pageSetBad(hal, pageAdr);
|
||||
}
|
||||
|
||||
//nvm3_tracePrint(" erasePage: sta=%u.\n", sta);
|
||||
return sta;
|
||||
}
|
||||
|
||||
#if defined(NVM3_SECURITY)
|
||||
/***************************************************************************//**
|
||||
* Get NVM3 security type.
|
||||
*
|
||||
* @param[in] pageHdr Page header of a valid page.
|
||||
*
|
||||
* @return Returns NVM3 security type.
|
||||
******************************************************************************/
|
||||
nvm3_SecurityType_t nvm3_pageGetSecType(nvm3_PageHdr_t *pageHdr)
|
||||
{
|
||||
nvm3_SecurityType_t secType = NVM3_SECURITY_INVALID;
|
||||
|
||||
if (((pageHdr->data[4] & H5_SECTYPE_AEAD_MASK) >> H5_SECTYPE_AEAD_SHIFT) == 0) {
|
||||
secType = NVM3_SECURITY_AEAD;
|
||||
}
|
||||
|
||||
return secType;
|
||||
}
|
||||
#endif
|
||||
/** @endcond */
|
||||
57
Libs/platform/emdrv/nvm3/src/nvm3_utils.c
Normal file
57
Libs/platform/emdrv/nvm3/src/nvm3_utils.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief NVM3 utility functions
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#include "nvm3_utils.h"
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
|
||||
void nvm3_utilsComputeBergerCode(uint8_t *pResult, void *pInput, uint8_t numberOfBits)
|
||||
{
|
||||
uint8_t sum;
|
||||
uint32_t word = *((uint32_t *)pInput);
|
||||
uint32_t mask;
|
||||
|
||||
// Clear bits that are outside the wanted bits
|
||||
if (numberOfBits < 32U) {
|
||||
mask = (1UL << numberOfBits) - 1U;
|
||||
word = word & mask;
|
||||
}
|
||||
|
||||
// Count bits set:
|
||||
// From http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetNaive
|
||||
word = word - ((word >> 1) & 0x55555555U);
|
||||
word = (word & 0x33333333U) + ((word >> 2) & 0x33333333U);
|
||||
sum = (uint8_t)((((word + (word >> 4)) & 0xF0F0F0FU) * 0x1010101U) >> 24U);
|
||||
|
||||
// Count bit cleared and accumulate
|
||||
*pResult = *pResult + (numberOfBits - sum);
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
470
Libs/platform/emdrv/uartdrv/inc/uartdrv.h
Normal file
470
Libs/platform/emdrv/uartdrv/inc/uartdrv.h
Normal file
@@ -0,0 +1,470 @@
|
||||
/***************************************************************************//**
|
||||
* @file
|
||||
* @brief UARTDRV API definition.
|
||||
*******************************************************************************
|
||||
* # License
|
||||
* <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
|
||||
*******************************************************************************
|
||||
*
|
||||
* SPDX-License-Identifier: Zlib
|
||||
*
|
||||
* The licensor of this software is Silicon Laboratories Inc.
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||
* misrepresented as being the original software.
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef UARTDRV_H
|
||||
#define UARTDRV_H
|
||||
|
||||
#if defined(SL_COMPONENT_CATALOG_PRESENT)
|
||||
#include "sl_component_catalog.h"
|
||||
#endif
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT)
|
||||
#include "sl_power_manager.h"
|
||||
#endif
|
||||
|
||||
#include "em_device.h"
|
||||
#include "sl_device_peripheral.h"
|
||||
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
|
||||
#include "em_usart.h"
|
||||
#endif
|
||||
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0)
|
||||
#include "em_leuart.h"
|
||||
#elif (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
|
||||
|
||||
#if (_SILICON_LABS_32B_SERIES > 2)
|
||||
#define UARTDRV_USE_PERIPHERAL
|
||||
#include "sl_hal_eusart.h"
|
||||
#else
|
||||
#include "em_eusart.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "sl_gpio.h"
|
||||
#include "sl_clock_manager.h"
|
||||
#include "ecode.h"
|
||||
#include "uartdrv_config.h"
|
||||
#include "dmadrv.h"
|
||||
#include "sl_enum.h"
|
||||
#include "sl_sleeptimer.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup uartdrv
|
||||
* @{
|
||||
******************************************************************************/
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup uartdrv_error_codes Error Codes
|
||||
* @{
|
||||
******************************************************************************/
|
||||
#define ECODE_EMDRV_UARTDRV_OK (ECODE_OK) ///< A successful return value.
|
||||
#define ECODE_EMDRV_UARTDRV_WAITING (ECODE_EMDRV_UARTDRV_BASE | 0x00000001) ///< An operation is waiting in queue.
|
||||
#define ECODE_EMDRV_UARTDRV_ILLEGAL_HANDLE (ECODE_EMDRV_UARTDRV_BASE | 0x00000002) ///< An illegal UART handle.
|
||||
#define ECODE_EMDRV_UARTDRV_PARAM_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x00000003) ///< An illegal input parameter.
|
||||
#define ECODE_EMDRV_UARTDRV_BUSY (ECODE_EMDRV_UARTDRV_BASE | 0x00000004) ///< The UART port is busy.
|
||||
#define ECODE_EMDRV_UARTDRV_ILLEGAL_OPERATION (ECODE_EMDRV_UARTDRV_BASE | 0x00000005) ///< An illegal operation on the UART port.
|
||||
#define ECODE_EMDRV_UARTDRV_IDLE (ECODE_EMDRV_UARTDRV_BASE | 0x00000008) ///< No UART transfer is in progress.
|
||||
#define ECODE_EMDRV_UARTDRV_ABORTED (ECODE_EMDRV_UARTDRV_BASE | 0x00000009) ///< A UART transfer has been aborted.
|
||||
#define ECODE_EMDRV_UARTDRV_QUEUE_FULL (ECODE_EMDRV_UARTDRV_BASE | 0x0000000A) ///< A UART operation queue is full.
|
||||
#define ECODE_EMDRV_UARTDRV_QUEUE_EMPTY (ECODE_EMDRV_UARTDRV_BASE | 0x0000000B) ///< A UART operation queue is empty.
|
||||
#define ECODE_EMDRV_UARTDRV_PARITY_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000C) ///< A UART parity error frame. Data is ignored.
|
||||
#define ECODE_EMDRV_UARTDRV_FRAME_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000D) ///< A UART frame error. Data is ignored.
|
||||
#define ECODE_EMDRV_UARTDRV_DMA_ALLOC_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000E) ///< Unable to allocate DMA channels.
|
||||
#define ECODE_EMDRV_UARTDRV_CLOCK_ERROR (ECODE_EMDRV_UARTDRV_BASE | 0x0000000F) ///< Unable to set a desired baudrate.
|
||||
/** @} (end addtogroup error codes) */
|
||||
|
||||
/***************************************************************************//**
|
||||
* @addtogroup uartdrv_status_codes Status Codes
|
||||
* @{
|
||||
******************************************************************************/
|
||||
#define UARTDRV_STATUS_RXEN (1 << 0) ///< The receiver is enabled.
|
||||
#define UARTDRV_STATUS_TXEN (1 << 1) ///< The transmitter is enabled.
|
||||
#define UARTDRV_STATUS_RXBLOCK (1 << 3) ///< The receiver is blocked; incoming frames will be discarded.
|
||||
#define UARTDRV_STATUS_TXTRI (1 << 4) ///< The transmitter is tristated.
|
||||
#define UARTDRV_STATUS_TXC (1 << 5) ///< A transmit operation is complete. No more data is available in the transmit buffer and shift register.
|
||||
#define UARTDRV_STATUS_TXBL (1 << 6) ///< The transmit buffer is empty.
|
||||
#define UARTDRV_STATUS_RXDATAV (1 << 7) ///< Data is available in the receive buffer.
|
||||
#define UARTDRV_STATUS_RXFULL (1 << 8) ///< The receive buffer is full.
|
||||
#if defined(EUSART_STATUS_TXCANDTXIDLE)
|
||||
#define UARTDRV_STATUS_TXCANDTXIDLE (1 << 9) ///< Set when both TXC and TXIDLE are set.
|
||||
#endif
|
||||
#define UARTDRV_STATUS_TXIDLE (1 << 13) ///< The transmitter is idle.
|
||||
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
|
||||
#define UARTDRV_STATUS_RXIDLE (1 << 12) ///< The Receiver is idle.
|
||||
#endif
|
||||
/** @} (end addtogroup status codes) */
|
||||
|
||||
typedef uint32_t UARTDRV_Count_t; ///< A UART transfer count
|
||||
typedef uint32_t UARTDRV_Status_t; ///< A UART status return type. Bitfield of UARTDRV_STATUS_* values.
|
||||
|
||||
/**
|
||||
* @enum UARTDRV_FlowControlType_t
|
||||
* @brief UARTDRV Flow Control method.
|
||||
*/
|
||||
SL_ENUM(UARTDRV_FlowControlType_t) {
|
||||
uartdrvFlowControlNone = 0, ///< None
|
||||
uartdrvFlowControlSw = 1, ///< Software XON/XOFF
|
||||
uartdrvFlowControlHw = 2, ///< nRTS/nCTS hardware handshake
|
||||
uartdrvFlowControlHwUart = 3 ///< UART peripheral controls nRTS/nCTS
|
||||
};
|
||||
|
||||
/// Flow Control state
|
||||
SL_ENUM(UARTDRV_FlowControlState_t) {
|
||||
uartdrvFlowControlOn = 0, ///< XON or nRTS/nCTS low
|
||||
uartdrvFlowControlOff = 1, ///< XOFF or nRTS/nCTS high
|
||||
uartdrvFlowControlAuto = 2 ///< This driver controls the state.
|
||||
};
|
||||
|
||||
/// Transfer abort type
|
||||
SL_ENUM(UARTDRV_AbortType_t) {
|
||||
uartdrvAbortTransmit = 1, ///< Abort current and queued transmit operations
|
||||
uartdrvAbortReceive = 2, ///< Abort current and queued receive operations
|
||||
uartdrvAbortAll = 3 ///< Abort all current and queued operations
|
||||
};
|
||||
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
/// Type of a UART peripheral
|
||||
SL_ENUM(UARTDRV_UartType_t) {
|
||||
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
|
||||
uartdrvUartTypeUart = 0, ///< USART/UART peripheral
|
||||
#endif
|
||||
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0)
|
||||
uartdrvUartTypeLeuart = 1 ///< LEUART peripheral
|
||||
#elif (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
|
||||
uartdrvUartTypeEuart = 2 ///< EUART peripheral
|
||||
#endif
|
||||
};
|
||||
/// @endcond
|
||||
|
||||
struct UARTDRV_HandleData;
|
||||
|
||||
/***************************************************************************//**
|
||||
* @brief
|
||||
* UARTDRV transfer completion callback function.
|
||||
*
|
||||
* @details
|
||||
* Called when a transfer is complete. An
|
||||
* application should check the transferStatus and itemsTransferred values.
|
||||
*
|
||||
* @param[in] handle
|
||||
* The UARTDRV device handle used to start the transfer.
|
||||
*
|
||||
* @param[in] transferStatus
|
||||
* Completion status of the transfer operation.
|
||||
*
|
||||
* @param[in] data
|
||||
* A pointer to the transfer data buffer.
|
||||
*
|
||||
* @param[in] transferCount
|
||||
* A number of bytes transferred.
|
||||
******************************************************************************/
|
||||
typedef void (*UARTDRV_Callback_t)(struct UARTDRV_HandleData *handle,
|
||||
Ecode_t transferStatus,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t transferCount);
|
||||
|
||||
/// UART transfer buffer
|
||||
typedef struct {
|
||||
uint8_t *data; ///< Transfer data buffer
|
||||
UARTDRV_Count_t transferCount; ///< Transfer item count
|
||||
volatile UARTDRV_Count_t itemsRemaining; ///< Transfer items remaining
|
||||
UARTDRV_Callback_t callback; ///< Completion callback
|
||||
Ecode_t transferStatus; ///< Completion status of the transfer operation
|
||||
} UARTDRV_Buffer_t;
|
||||
|
||||
/// Transfer operation FIFO queue typedef
|
||||
typedef struct {
|
||||
volatile uint16_t head; ///< An index of the next byte to send.
|
||||
volatile uint16_t tail; ///< An index of the location to enqueue the next message.
|
||||
volatile uint16_t used; ///< A number of bytes queued.
|
||||
const uint16_t size; ///< FIFO size.
|
||||
UARTDRV_Buffer_t fifo[1]; ///< FIFO of queued data. Actual size varies.
|
||||
} UARTDRV_Buffer_FifoQueue_t;
|
||||
|
||||
/// Macros to define FIFO and buffer queues. typedef can't be used because the size
|
||||
/// of the FIFO array in the queues can change.
|
||||
#define DEFINE_BUF_QUEUE(qSize, qName) \
|
||||
typedef struct { \
|
||||
uint16_t head; \
|
||||
uint16_t tail; \
|
||||
volatile uint16_t used; \
|
||||
const uint16_t size; \
|
||||
UARTDRV_Buffer_t fifo[qSize]; \
|
||||
} _##qName; \
|
||||
static volatile _##qName qName = \
|
||||
{ \
|
||||
.head = 0, \
|
||||
.tail = 0, \
|
||||
.used = 0, \
|
||||
.size = qSize, \
|
||||
}
|
||||
|
||||
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
|
||||
/**
|
||||
* @struct UARTDRV_InitUart_t
|
||||
* @brief A UART driver instance initialization structure.
|
||||
* LEUART driver instance initialization structure.
|
||||
* Contains a number of UARTDRV configuration options.
|
||||
* It is required for driver instance initialization.
|
||||
* This structure is passed to @ref UARTDRV_Init() when initializing a UARTDRV
|
||||
* instance.
|
||||
*/
|
||||
typedef struct {
|
||||
USART_TypeDef *port; ///< The peripheral used for UART
|
||||
uint32_t baudRate; ///< UART baud rate
|
||||
#if defined(_USART_ROUTELOC0_MASK)
|
||||
uint8_t portLocationTx; ///< A location number for UART Tx pin.
|
||||
uint8_t portLocationRx; ///< A location number for UART Rx pin.
|
||||
#elif defined(_USART_ROUTE_MASK)
|
||||
uint8_t portLocation; ///< A location number for UART pins.
|
||||
#elif defined(_GPIO_USART_ROUTEEN_MASK)
|
||||
sl_gpio_port_t txPort; ///< Port for UART Tx pin.
|
||||
sl_gpio_port_t rxPort; ///< Port for UART Rx pin.
|
||||
uint8_t txPin; ///< Pin number for UART Tx.
|
||||
uint8_t rxPin; ///< Pin number for UART Rx.
|
||||
uint8_t uartNum; ///< UART instance number.
|
||||
#endif
|
||||
USART_Stopbits_TypeDef stopBits; ///< A number of stop bits.
|
||||
USART_Parity_TypeDef parity; ///< Parity configuration.
|
||||
USART_OVS_TypeDef oversampling; ///< Oversampling mode.
|
||||
#if defined(USART_CTRL_MVDIS)
|
||||
bool mvdis; ///< Majority Vote Disable for 16x, 8x and 6x oversampling modes.
|
||||
#endif
|
||||
UARTDRV_FlowControlType_t fcType; ///< Flow control mode.
|
||||
sl_gpio_port_t ctsPort; ///< A CTS pin port number.
|
||||
uint8_t ctsPin; ///< A CTS pin number.
|
||||
sl_gpio_port_t rtsPort; ///< An RTS pin port number.
|
||||
uint8_t rtsPin; ///< An RTS pin number.
|
||||
UARTDRV_Buffer_FifoQueue_t *rxQueue; ///< A receive operation queue.
|
||||
UARTDRV_Buffer_FifoQueue_t *txQueue; ///< T transmit operation queue.
|
||||
#if defined(_USART_ROUTELOC1_MASK)
|
||||
uint8_t portLocationCts; ///< A location number for the UART CTS pin.
|
||||
uint8_t portLocationRts; ///< A location number for the UART RTS pin.
|
||||
#endif
|
||||
} UARTDRV_InitUart_t;
|
||||
#endif
|
||||
|
||||
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
/**
|
||||
* @struct UARTDRV_InitLeuart_t
|
||||
* @brief LEUART driver instance initialization structure.
|
||||
* LEUART driver instance initialization structure.
|
||||
* Contains a number of UARTDRV configuration options.
|
||||
* It is required to initialize a driver instance.
|
||||
* This structure is passed to @ref UARTDRV_InitLeuart() when initializing a UARTDRV
|
||||
* instance.
|
||||
*/
|
||||
typedef struct {
|
||||
LEUART_TypeDef *port; ///< The peripheral used for LEUART
|
||||
uint32_t baudRate; ///< UART baud rate
|
||||
#if defined(_LEUART_ROUTELOC0_MASK)
|
||||
uint8_t portLocationTx; ///< Location number for LEUART Tx pin.
|
||||
uint8_t portLocationRx; ///< Location number for LEUART Rx pin.
|
||||
#else
|
||||
uint8_t portLocation; ///< Location number for LEUART pins
|
||||
#endif
|
||||
LEUART_Stopbits_TypeDef stopBits; ///< Number of stop bits
|
||||
LEUART_Parity_TypeDef parity; ///< Parity configuration
|
||||
UARTDRV_FlowControlType_t fcType; ///< Flow control mode
|
||||
sl_gpio_port_t ctsPort; ///< CTS pin port number
|
||||
uint8_t ctsPin; ///< CTS pin number
|
||||
sl_gpio_port_t rtsPort; ///< RTS pin port number
|
||||
uint8_t rtsPin; ///< RTS pin number
|
||||
UARTDRV_Buffer_FifoQueue_t *rxQueue; ///< Receive operation queue
|
||||
UARTDRV_Buffer_FifoQueue_t *txQueue; ///< Transmit operation queue
|
||||
} UARTDRV_InitLeuart_t;
|
||||
#endif
|
||||
|
||||
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
|
||||
/// UART driver instance initialization structure.
|
||||
/// Contains a number of UARTDRV configuration options.
|
||||
/// It is required to initialize a driver instance.
|
||||
/// This structure is passed to @ref UARTDRV_InitEuart() when initializing a UARTDRV
|
||||
typedef struct {
|
||||
EUSART_TypeDef *port; ///< The peripheral used for EUART
|
||||
bool useLowFrequencyMode; ///< Clock configuration of the EUART
|
||||
uint32_t baudRate; ///< EUART baud rate
|
||||
sl_gpio_port_t txPort; ///< Port for UART Tx pin.
|
||||
sl_gpio_port_t rxPort; ///< Port for UART Rx pin.
|
||||
uint8_t txPin; ///< Pin number for UART Tx.
|
||||
uint8_t rxPin; ///< Pin number for UART Rx.
|
||||
uint8_t uartNum; ///< EUART instance number.
|
||||
#if defined(UARTDRV_USE_PERIPHERAL)
|
||||
sl_hal_eusart_stop_bits_t stopBits; ///< Number of stop bits
|
||||
sl_hal_eusart_parity_t parity; ///< Parity configuration
|
||||
sl_hal_eusart_ovs_t oversampling; ///< Oversampling mode.
|
||||
sl_hal_eusart_majority_vote_t mvdis; ///< Majority Vote Disable for 16x, 8x and 6x oversampling modes.
|
||||
#else
|
||||
EUSART_Stopbits_TypeDef stopBits; ///< Number of stop bits
|
||||
EUSART_Parity_TypeDef parity; ///< Parity configuration
|
||||
EUSART_OVS_TypeDef oversampling; ///< Oversampling mode.
|
||||
EUSART_MajorityVote_TypeDef mvdis; ///< Majority Vote Disable for 16x, 8x and 6x oversampling modes.
|
||||
#endif
|
||||
UARTDRV_FlowControlType_t fcType; ///< Flow control mode
|
||||
sl_gpio_port_t ctsPort; ///< CTS pin port number
|
||||
uint8_t ctsPin; ///< CTS pin number
|
||||
sl_gpio_port_t rtsPort; ///< RTS pin port number
|
||||
uint8_t rtsPin; ///< RTS pin number
|
||||
UARTDRV_Buffer_FifoQueue_t *rxQueue; ///< Receive operation queue
|
||||
UARTDRV_Buffer_FifoQueue_t *txQueue; ///< Transmit operation queue
|
||||
} UARTDRV_InitEuart_t;
|
||||
#endif
|
||||
|
||||
/// A UART driver instance handle data structure.
|
||||
/// Allocated by the application using UARTDRV.
|
||||
/// Several concurrent driver instances may exist in an application. The application must
|
||||
/// not modify the contents of this handle and should not depend on its values.
|
||||
typedef struct UARTDRV_HandleData{
|
||||
/// @cond DO_NOT_INCLUDE_WITH_DOXYGEN
|
||||
union {
|
||||
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
|
||||
USART_TypeDef * uart;
|
||||
#endif
|
||||
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
LEUART_TypeDef * leuart;
|
||||
#endif
|
||||
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
|
||||
EUSART_TypeDef * euart;
|
||||
#endif
|
||||
void * __reserved_space;
|
||||
} peripheral;
|
||||
uint8_t uartNum; // UART instance number
|
||||
unsigned int txDmaCh; // A DMA ch assigned to Tx
|
||||
unsigned int rxDmaCh; // A DMA ch assigned to Rx
|
||||
DMADRV_PeripheralSignal_t txDmaSignal; // A DMA Tx trigger source signal
|
||||
DMADRV_PeripheralSignal_t rxDmaSignal; // A DMA Rx trigger source signal
|
||||
UARTDRV_FlowControlState_t fcSelfState; // A current self flow control state
|
||||
UARTDRV_FlowControlState_t fcSelfCfg; // A self flow control override configuration
|
||||
UARTDRV_FlowControlState_t fcPeerState; // A current peer flow control state
|
||||
|
||||
sl_gpio_port_t txPort; // A Tx pin port number
|
||||
sl_gpio_port_t rxPort; // An Rx pin port number
|
||||
sl_gpio_port_t ctsPort; // A CTS pin port number
|
||||
sl_gpio_port_t rtsPort; // An RTS pin port number
|
||||
uint8_t txPin; // A Tx pin number
|
||||
uint8_t rxPin; // An Tx pin number
|
||||
uint8_t ctsPin; // A CTS pin number
|
||||
uint8_t rtsPin; // An RTS pin number
|
||||
sl_peripheral_t usartPeripheral; // Usart peripheral select
|
||||
UARTDRV_Buffer_FifoQueue_t *rxQueue; // A receive operation queue
|
||||
UARTDRV_Buffer_FifoQueue_t *txQueue; // A transmit operation queue
|
||||
volatile bool rxDmaActive; // A receive DMA is currently active
|
||||
volatile bool txDmaActive; // A transmit DMA is currently active
|
||||
volatile uint8_t txDmaPaused; // A transmit DMA pause counter
|
||||
bool IgnoreRestrain; // A transmit does not respect uartdrvFlowControlOff
|
||||
bool hasTransmitted; // Indicates whether the handle has transmitted data
|
||||
UARTDRV_FlowControlType_t fcType; // A flow control mode
|
||||
UARTDRV_UartType_t type; // A type of UART
|
||||
volatile int em1RequestCount; // A EM1 request count for the handle
|
||||
sl_sleeptimer_timer_handle_t delayedTxTimer; // A timer to wait for the last byte out
|
||||
size_t sleep; // Sleep state on isr return
|
||||
/// @endcond
|
||||
} UARTDRV_HandleData_t;
|
||||
|
||||
/// Handle pointer
|
||||
typedef UARTDRV_HandleData_t * UARTDRV_Handle_t;
|
||||
|
||||
#if (defined(UART_COUNT) && (UART_COUNT > 0)) || (defined(USART_COUNT) && (USART_COUNT > 0))
|
||||
Ecode_t UARTDRV_InitUart(UARTDRV_Handle_t handle,
|
||||
const UARTDRV_InitUart_t * initData);
|
||||
#endif
|
||||
|
||||
#if defined(LEUART_COUNT) && (LEUART_COUNT > 0) && !defined(_SILICON_LABS_32B_SERIES_2)
|
||||
Ecode_t UARTDRV_InitLeuart(UARTDRV_Handle_t handle,
|
||||
const UARTDRV_InitLeuart_t * initData);
|
||||
#endif
|
||||
|
||||
#if (defined(EUART_COUNT) && (EUART_COUNT > 0)) || (defined(EUSART_COUNT) && (EUSART_COUNT > 0))
|
||||
Ecode_t UARTDRV_InitEuart(UARTDRV_Handle_t handle,
|
||||
const UARTDRV_InitEuart_t * initData);
|
||||
#endif
|
||||
Ecode_t UARTDRV_DeInit(UARTDRV_Handle_t handle);
|
||||
|
||||
UARTDRV_Status_t UARTDRV_GetPeripheralStatus(UARTDRV_Handle_t handle);
|
||||
|
||||
UARTDRV_Status_t UARTDRV_GetReceiveStatus(UARTDRV_Handle_t handle,
|
||||
uint8_t **buffer,
|
||||
UARTDRV_Count_t *bytesReceived,
|
||||
UARTDRV_Count_t *bytesRemaining);
|
||||
|
||||
UARTDRV_Status_t UARTDRV_GetTransmitStatus(UARTDRV_Handle_t handle,
|
||||
uint8_t **buffer,
|
||||
UARTDRV_Count_t *bytesSent,
|
||||
UARTDRV_Count_t *bytesRemaining);
|
||||
|
||||
uint8_t UARTDRV_GetReceiveDepth(UARTDRV_Handle_t handle);
|
||||
|
||||
uint8_t UARTDRV_GetTransmitDepth(UARTDRV_Handle_t handle);
|
||||
|
||||
Ecode_t UARTDRV_Transmit(UARTDRV_Handle_t handle,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t count,
|
||||
UARTDRV_Callback_t callback);
|
||||
|
||||
Ecode_t UARTDRV_Receive(UARTDRV_Handle_t handle,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t count,
|
||||
UARTDRV_Callback_t callback);
|
||||
|
||||
Ecode_t UARTDRV_TransmitB(UARTDRV_Handle_t handle,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t count);
|
||||
|
||||
Ecode_t UARTDRV_ReceiveB(UARTDRV_Handle_t handle,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t count);
|
||||
|
||||
Ecode_t UARTDRV_ForceTransmit(UARTDRV_Handle_t handle,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t count);
|
||||
|
||||
UARTDRV_Count_t UARTDRV_ForceReceive(UARTDRV_Handle_t handle,
|
||||
uint8_t *data,
|
||||
UARTDRV_Count_t maxLength);
|
||||
|
||||
Ecode_t UARTDRV_Abort(UARTDRV_Handle_t handle, UARTDRV_AbortType_t type);
|
||||
|
||||
Ecode_t UARTDRV_PauseTransmit(UARTDRV_Handle_t handle);
|
||||
|
||||
Ecode_t UARTDRV_ResumeTransmit(UARTDRV_Handle_t handle);
|
||||
|
||||
UARTDRV_FlowControlState_t UARTDRV_FlowControlGetSelfStatus(UARTDRV_Handle_t handle);
|
||||
|
||||
UARTDRV_FlowControlState_t UARTDRV_FlowControlGetPeerStatus(UARTDRV_Handle_t handle);
|
||||
|
||||
Ecode_t UARTDRV_FlowControlSet(UARTDRV_Handle_t handle, UARTDRV_FlowControlState_t state);
|
||||
|
||||
Ecode_t UARTDRV_FlowControlSetPeerStatus(UARTDRV_Handle_t handle, UARTDRV_FlowControlState_t state);
|
||||
|
||||
Ecode_t UARTDRV_FlowControlIgnoreRestrain(UARTDRV_Handle_t handle);
|
||||
|
||||
#if defined(SL_CATALOG_POWER_MANAGER_PRESENT) && !defined(SL_CATALOG_KERNEL_PRESENT)
|
||||
SL_CODE_CLASSIFY(SL_CODE_COMPONENT_UARTDRV, SL_CODE_CLASS_TIME_CRITICAL)
|
||||
sl_power_manager_on_isr_exit_t sl_uartdrv_sleep_on_isr_exit(void);
|
||||
#endif
|
||||
|
||||
/** @} (end addtogroup uartdrv) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif // UARTDRV_H
|
||||
3113
Libs/platform/emdrv/uartdrv/src/uartdrv.c
Normal file
3113
Libs/platform/emdrv/uartdrv/src/uartdrv.c
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user