[efr32mg12] implement otPlatFlash APIs (#4552)

This commit is contained in:
Jonathan Hui
2020-03-18 20:51:41 -07:00
parent 2dcbd3926c
commit 64ac0ff38d
2 changed files with 41 additions and 104 deletions
+36 -85
View File
@@ -31,114 +31,65 @@
* This file implements the OpenThread platform abstraction for the non-volatile storage.
*/
#include <openthread-core-config.h>
#include <string.h>
#include <openthread/config.h>
#include <openthread/platform/alarm-milli.h>
#include "utils/code_utils.h"
#include "utils/flash.h"
#include <openthread/instance.h>
#include "em_msc.h"
// clang-format off
#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * SETTINGS_CONFIG_PAGE_NUM))
// clang-format on
#define FLASH_PAGE_NUM 4
#define FLASH_DATA_END_ADDR (FLASH_BASE + FLASH_SIZE)
#define FLASH_DATA_START_ADDR (FLASH_DATA_END_ADDR - (FLASH_PAGE_SIZE * FLASH_PAGE_NUM))
#define FLASH_SWAP_SIZE (FLASH_PAGE_SIZE * (FLASH_PAGE_NUM / 2))
static inline uint32_t mapAddress(uint32_t aAddress)
static inline uint32_t mapAddress(uint8_t aSwapIndex, uint32_t aOffset)
{
return aAddress + FLASH_DATA_START_ADDR;
}
uint32_t address;
static otError returnTypeConvert(int32_t aStatus)
{
otError error = OT_ERROR_NONE;
address = FLASH_DATA_START_ADDR + aOffset;
switch (aStatus)
if (aSwapIndex)
{
case mscReturnOk:
error = OT_ERROR_NONE;
break;
case mscReturnInvalidAddr:
case mscReturnUnaligned:
error = OT_ERROR_INVALID_ARGS;
break;
default:
error = OT_ERROR_FAILED;
address += FLASH_SWAP_SIZE;
}
return error;
return address;
}
otError utilsFlashInit(void)
void otPlatFlashInit(otInstance *aInstance)
{
OT_UNUSED_VARIABLE(aInstance);
MSC_Init();
return OT_ERROR_NONE;
}
uint32_t utilsFlashGetSize(void)
uint32_t otPlatFlashGetSwapSize(otInstance *aInstance)
{
return FLASH_DATA_END_ADDR - FLASH_DATA_START_ADDR;
OT_UNUSED_VARIABLE(aInstance);
return FLASH_SWAP_SIZE;
}
otError utilsFlashErasePage(uint32_t aAddress)
void otPlatFlashErase(otInstance *aInstance, uint8_t aSwapIndex)
{
int32_t status;
OT_UNUSED_VARIABLE(aInstance);
status = MSC_ErasePage((uint32_t *)mapAddress(aAddress));
return returnTypeConvert(status);
}
otError utilsFlashStatusWait(uint32_t aTimeout)
{
otError error = OT_ERROR_BUSY;
uint32_t start = otPlatAlarmMilliGetNow();
do
MSC_ErasePage((uint32_t *)mapAddress(aSwapIndex, 0));
while ((MSC->STATUS & MSC_STATUS_WDATAREADY) == 0)
{
if (MSC->STATUS & MSC_STATUS_WDATAREADY)
{
error = OT_ERROR_NONE;
break;
}
} while (aTimeout && ((otPlatAlarmMilliGetNow() - start) < aTimeout));
return error;
}
uint32_t utilsFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t rval = aSize;
int32_t status;
otEXPECT_ACTION(aData, rval = 0);
otEXPECT_ACTION(((aAddress + aSize) < utilsFlashGetSize()) && (!(aAddress & 3)) && (!(aSize & 3)), rval = 0);
status = MSC_WriteWord((uint32_t *)mapAddress(aAddress), aData, aSize);
otEXPECT_ACTION(returnTypeConvert(status) == OT_ERROR_NONE, rval = 0);
exit:
return rval;
}
uint32_t utilsFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t rval = aSize;
uint32_t pAddress = mapAddress(aAddress);
uint8_t *byte = aData;
otEXPECT_ACTION(aData, rval = 0);
otEXPECT_ACTION((aAddress + aSize) < utilsFlashGetSize(), rval = 0);
while (aSize--)
{
*byte++ = (*(uint8_t *)(pAddress++));
}
}
exit:
return rval;
void otPlatFlashWrite(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, const void *aData, uint32_t aSize)
{
OT_UNUSED_VARIABLE(aInstance);
MSC_WriteWord((uint32_t *)mapAddress(aSwapIndex, aOffset), aData, aSize);
}
void otPlatFlashRead(otInstance *aInstance, uint8_t aSwapIndex, uint32_t aOffset, void *aData, uint32_t aSize)
{
OT_UNUSED_VARIABLE(aInstance);
memcpy(aData, (uint8_t *)mapAddress(aSwapIndex, aOffset), aSize);
}
@@ -104,28 +104,14 @@
#define OPENTHREAD_CONFIG_SOFTWARE_ENERGY_SCAN_ENABLE 0
/**
* @def SETTINGS_CONFIG_BASE_ADDRESS
* @def OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE
*
* The base address of settings.
* Define to 1 to enable otPlatFlash* APIs to support non-volatile storage.
*
* When defined to 1, the platform MUST implement the otPlatFlash* APIs instead of the otPlatSettings* APIs.
*
*/
#define SETTINGS_CONFIG_BASE_ADDRESS 0
/**
* @def SETTINGS_CONFIG_PAGE_SIZE
*
* The page size of settings.
*
*/
#define SETTINGS_CONFIG_PAGE_SIZE FLASH_PAGE_SIZE
/**
* @def SETTINGS_CONFIG_PAGE_NUM
*
* The page number of settings.
*
*/
#define SETTINGS_CONFIG_PAGE_NUM 4
#define OPENTHREAD_CONFIG_PLATFORM_FLASH_API_ENABLE 1
/**
* @def OPENTHREAD_CONFIG_NCP_UART_ENABLE