CC2538 Flash Driver (#772)

* CC2538 flash driver
This commit is contained in:
Lu Wang
2016-10-08 22:26:46 -07:00
committed by Jonathan Hui
parent 3ebef251eb
commit 59f4ec8ae8
5 changed files with 249 additions and 3 deletions
+4 -2
View File
@@ -38,13 +38,14 @@ libopenthread_cc2538_a_CPPFLAGS = \
libopenthread_cc2538_a_SOURCES = \
alarm.c \
misc.c \
flash.c \
logging.c \
misc.c \
platform.c \
radio.c \
random.c \
uart.c \
startup-gcc.c \
uart.c \
$(NULL)
if OPENTHREAD_ENABLE_DIAG
@@ -56,6 +57,7 @@ endif
noinst_HEADERS = \
cc2538-reg.h \
platform-cc2538.h \
rom-utility.h \
$(NULL)
if OPENTHREAD_BUILD_COVERAGE
+4
View File
@@ -201,4 +201,8 @@
#define SOC_ADC_ADCCON1_RCTRL0 0x00000004 // ADCCON1 RCTRL bit 0
#define SOC_ADC_ADCCON1_RCTRL1 0x00000008 // ADCCON1 RCTRL bit 1
#define FLASH_BASE 0x00200000 // Flash base address
#define FLASH_CTRL_FCTL 0x400D3008 // Flash control
#define FLASH_CTRL_DIECFG0 0x400D3014 // Flash information
#endif
+168
View File
@@ -0,0 +1,168 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <openthread-config.h>
#include <platform/alarm.h>
#include <platform/flash.h>
#include <common/code_utils.hpp>
#include "platform-cc2538.h"
#include "rom-utility.h"
#define FLASH_CTRL_FCTL_BUSY 0x00000080
enum
{
FLASH_PAGE_SIZE = 0x800,
};
static ThreadError romStatusToThread(int32_t aStatus)
{
ThreadError error = kThreadError_None;
switch (aStatus)
{
case 0:
error = kThreadError_None;
break;
case -1:
error = kThreadError_Failed;
break;
case -2:
error = kThreadError_InvalidArgs;
break;
default:
error = kThreadError_Abort;
}
return error;
}
ThreadError otPlatFlashInit(void)
{
return kThreadError_None;
}
uint32_t otPlatFlashGetSize(void)
{
uint32_t reg = (HWREG(FLASH_CTRL_DIECFG0) & 0x00000070) >> 4;
return reg ? (0x20000 * reg) : 0x10000;
}
ThreadError otPlatFlashErasePage(uint32_t aAddress)
{
ThreadError error = kThreadError_None;
int32_t status;
uint32_t address;
VerifyOrExit(aAddress < otPlatFlashGetSize(), error = kThreadError_InvalidArgs);
address = FLASH_BASE + aAddress - (aAddress & (FLASH_PAGE_SIZE - 1));
status = ROM_PageErase(address, FLASH_PAGE_SIZE);
error = romStatusToThread(status);
exit:
return error;
}
ThreadError otPlatFlashStatusWait(uint32_t aTimeout)
{
ThreadError error = kThreadError_None;
uint32_t start = otPlatAlarmGetNow();
uint32_t busy = 1;
while (busy && ((otPlatAlarmGetNow() - start) < aTimeout))
{
busy = HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY;
}
VerifyOrExit(!busy, error = kThreadError_Busy);
exit:
return error;
}
uint32_t otPlatFlashWrite(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
int32_t status;
uint32_t busy = 1;
VerifyOrExit(((aAddress + aSize) < otPlatFlashGetSize()) &&
(!(aAddress & 3)) && (!(aSize & 3)), aSize = 0);
status = ROM_ProgramFlash((uint32_t *)aData, aAddress + FLASH_BASE, aSize);
while (busy)
{
busy = HWREG(FLASH_CTRL_FCTL) & FLASH_CTRL_FCTL_BUSY;
}
VerifyOrExit(romStatusToThread(status) == kThreadError_None, aSize = 0);
exit:
return aSize;
}
uint32_t otPlatFlashRead(uint32_t aAddress, uint8_t *aData, uint32_t aSize)
{
uint32_t size = 0;
VerifyOrExit((aAddress + aSize) < otPlatFlashGetSize(), ;);
while (size <= aSize)
{
uint32_t reg = HWREG(aAddress + FLASH_BASE);
uint8_t *byte = (uint8_t *)&reg;
uint8_t maxIndex = 4;
if (size == (aSize - aSize % 4))
{
maxIndex = aSize % 4;
}
for (uint8_t index = 0; index < maxIndex; index++, byte++, aData++)
{
*aData = *byte;
}
size += maxIndex;
aAddress += maxIndex;
}
exit:
return size;
}
+72
View File
@@ -0,0 +1,72 @@
/*
* Copyright (c) 2016, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ROM_UTILITY_H_
#define ROM_UTILITY_H_
#define ROM_API_TABLE_ADDR 0x00000048
typedef uint32_t (* volatile FPTR_CRC32_T)(uint8_t * /*pData*/, uint32_t /*byteCount*/);
typedef uint32_t (* volatile FPTR_GETFLSIZE_T)(void);
typedef uint32_t (* volatile FPTR_GETCHIPID_T)(void);
typedef int32_t (* volatile FPTR_PAGEERASE_T)(uint32_t /*FlashAddr*/, uint32_t /*Size*/);
typedef int32_t (* volatile FPTR_PROGFLASH_T)(uint32_t * /*pRamData*/, uint32_t /*FlashAdr*/, uint32_t /*ByteCount*/);
typedef void (* volatile FPTR_RESETDEV_T)(void);
typedef void *(* volatile FPTR_MEMSET_T)(void * /*s*/, int32_t /*c*/, uint32_t /*n*/);
typedef void *(* volatile FPTR_MEMCPY_T)(void * /*s1*/, const void * /*s2*/, uint32_t /*n*/);
typedef int32_t (* volatile FPTR_MEMCMP_T)(const void * /*s1*/, const void * /*s2*/, uint32_t /*n*/);
typedef void *(* volatile FPTR_MEMMOVE_T)(void * /*s1*/, const void * /*s2*/, uint32_t /*n*/);
typedef struct
{
FPTR_CRC32_T Crc32;
FPTR_GETFLSIZE_T GetFlashSize;
FPTR_GETCHIPID_T GetChipId;
FPTR_PAGEERASE_T PageErase;
FPTR_PROGFLASH_T ProgramFlash;
FPTR_RESETDEV_T ResetDevice;
FPTR_MEMSET_T memset;
FPTR_MEMCPY_T memcpy;
FPTR_MEMCMP_T memcmp;
FPTR_MEMMOVE_T memmove;
} ROM_API_T;
#define P_ROM_API ((ROM_API_T*) ROM_API_TABLE_ADDR)
#define ROM_Crc32(a,b) P_ROM_API->Crc32(a,b)
#define ROM_GetFlashSize() P_ROM_API->GetFlashSize()
#define ROM_GetChipId() P_ROM_API->GetChipId()
#define ROM_PageErase(a,b) P_ROM_API->PageErase(a,b)
#define ROM_ProgramFlash(a,b,c) P_ROM_API->ProgramFlash(a,b,c)
#define ROM_ResetDevice() P_ROM_API->ResetDevice()
#define ROM_Memset(a,b,c) P_ROM_API->memset(a,b,c)
#define ROM_Memcpy(a,b,c) P_ROM_API->memcpy(a,b,c)
#define ROM_Memcmp(a,b,c) P_ROM_API->memcmp(a,b,c)
#define ROM_Memmove(a,b,c) P_ROM_API->memmove(a,b,c)
#endif // ROM_UTILITY_H_
+1 -1
View File
@@ -78,7 +78,7 @@ ThreadError otPlatFlashErasePage(uint32_t aAddress);
/**
* Check whether flash is ready or busy.
*
* @param[in] aTimeout The interval waiting for the flash operation to be done and become ready again.
* @param[in] aTimeout The interval in milliseconds waiting for the flash operation to be done and become ready again.
* zero indicates that it is a polling function, and returns current status of flash immediately.
* non-zero indicates that it is blocking there until the operation is done and become ready, or timeout expires.
*