mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #4565 from Archcady/flash
Add FlashIAP support for REALTEK_RTL8195AMpull/4691/head
commit
c826e2f8b7
|
@ -13,555 +13,58 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
#include "flash_ext.h"
|
||||||
|
|
||||||
|
#define FLASH_START (SPI_FLASH_BASE + FLASH_OFS_START)
|
||||||
|
#define FLASH_END (SPI_FLASH_BASE + FLASH_OFS_END)
|
||||||
|
#define FLASH_OFS(addr) ((addr) - SPI_FLASH_BASE)
|
||||||
|
|
||||||
#include "objects.h"
|
int32_t flash_init(flash_t *obj)
|
||||||
#include "PinNames.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "pinmap.h"
|
|
||||||
|
|
||||||
#include "rtl8195a.h"
|
|
||||||
#include "hal_spi_flash.h"
|
|
||||||
#include "hal_platform.h"
|
|
||||||
#include "rtl8195a_spi_flash.h"
|
|
||||||
#include "hal_api.h"
|
|
||||||
#include "flash_api.h"
|
|
||||||
|
|
||||||
extern u32 ConfigDebugInfo;
|
|
||||||
extern SPIC_INIT_PARA SpicInitParaAllClk[3][CPU_CLK_TYPE_NO];
|
|
||||||
|
|
||||||
_LONG_CALL_
|
|
||||||
extern VOID SpicWaitBusyDoneRtl8195A(VOID);
|
|
||||||
|
|
||||||
static int isinit = 0;
|
|
||||||
static flash_t flashobj;
|
|
||||||
|
|
||||||
static void flash_init(flash_t * obj);
|
|
||||||
static void flash_turnon();
|
|
||||||
/**
|
|
||||||
* global data structure
|
|
||||||
*/
|
|
||||||
//flash_t flash;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Control the flash chip write protect enable/disable
|
|
||||||
* @param protect: 1/0: protect/unprotect
|
|
||||||
* @retval none
|
|
||||||
*/
|
|
||||||
void flash_write_protect(flash_t *obj, uint32_t protect)
|
|
||||||
{
|
{
|
||||||
flash_turnon();
|
__flash_ext_turnon();
|
||||||
|
|
||||||
if(isinit == 0)
|
return 0;
|
||||||
flash_init(&flashobj);
|
|
||||||
SpicWriteProtectFlashRtl8195A(protect);
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int32_t flash_free(flash_t *obj)
|
||||||
* @brief Init Flash
|
|
||||||
* @param obj: address of the flash object
|
|
||||||
* @retval none
|
|
||||||
*/
|
|
||||||
void flash_init(flash_t *obj)
|
|
||||||
{
|
{
|
||||||
//SPIC_INIT_PARA spic_init_para;
|
__flash_ext_turnoff();
|
||||||
|
|
||||||
// Init SPI Flash Controller
|
return 0;
|
||||||
// DBG_8195A("Initial Spi Flash Controller\n");
|
|
||||||
//SPI_FLASH_PIN_FCTRL(ON);
|
|
||||||
|
|
||||||
if (!SpicFlashInitRtl8195A(SpicOneBitMode)){
|
|
||||||
|
|
||||||
DBG_8195A("SPI Init Fail!!!!!!\n");
|
|
||||||
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3)|0xf);
|
|
||||||
} else {
|
|
||||||
isinit = 1;
|
|
||||||
}
|
|
||||||
flashobj.SpicInitPara.flashtype = SpicInitParaAllClk[0][0].flashtype;
|
|
||||||
|
|
||||||
}
|
|
||||||
void flash_turnon()
|
|
||||||
{
|
|
||||||
SPI_FLASH_PIN_FCTRL(ON);
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
int32_t flash_erase_sector(flash_t *obj, uint32_t address)
|
||||||
* @brief Erase flash sector
|
|
||||||
* @param address: Specifies the starting address to be erased.
|
|
||||||
* @retval none
|
|
||||||
*/
|
|
||||||
void flash_erase_sector(flash_t *obj, uint32_t address)
|
|
||||||
{
|
{
|
||||||
flash_turnon();
|
__flash_ext_erase_sector(obj, FLASH_OFS(address));
|
||||||
|
|
||||||
if(isinit == 0)
|
return 0;
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address);
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void flash_erase_block(flash_t *obj, uint32_t address)
|
int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t size)
|
||||||
{
|
{
|
||||||
flash_turnon();
|
return __flash_ext_stream_write(obj, FLASH_OFS(address), size, data);
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address);
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address)
|
||||||
/**
|
|
||||||
* @brief Read a word from specified address
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param address: Specifies the address to be read.
|
|
||||||
* @param data: Specified the address to save the readback data.
|
|
||||||
* @retval status: Success:1 or Failure: Others.
|
|
||||||
*/
|
|
||||||
int flash_read_word(flash_t *obj, uint32_t address, uint32_t * data)
|
|
||||||
{
|
{
|
||||||
|
if (address < FLASH_START || address >= FLASH_END)
|
||||||
flash_turnon();
|
return 0;
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
* data = HAL_READ32(SPI_FLASH_BASE, address);
|
return FLASH_SECTOR_SIZE;
|
||||||
SpicDisableRtl8195A();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
uint32_t flash_get_page_size(const flash_t *obj)
|
||||||
* @brief Write a word to specified address
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param address: Specifies the address to be programmed.
|
|
||||||
* @param data: Specified the data to be programmed.
|
|
||||||
* @retval status: Success:1 or Failure: Others.
|
|
||||||
*/
|
|
||||||
int flash_write_word(flash_t *obj, uint32_t address, uint32_t data)
|
|
||||||
{
|
{
|
||||||
u8 flashtype = 0;
|
return FLASH_PAGE_SIZE;
|
||||||
|
|
||||||
flash_turnon();
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
|
|
||||||
flashtype = flashobj.SpicInitPara.flashtype;
|
|
||||||
|
|
||||||
//Write word
|
|
||||||
HAL_WRITE32(SPI_FLASH_BASE, address, data);
|
|
||||||
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t flash_get_start_address(const flash_t *obj)
|
||||||
/**
|
|
||||||
* @brief Read a stream of data from specified address
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param address: Specifies the address to be read.
|
|
||||||
* @param len: Specifies the length of the data to read.
|
|
||||||
* @param data: Specified the address to save the readback data.
|
|
||||||
* @retval status: Success:1 or Failure: Others.
|
|
||||||
*/
|
|
||||||
int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len, uint8_t * data)
|
|
||||||
{
|
{
|
||||||
u32 offset_to_align;
|
return FLASH_START;
|
||||||
u32 i;
|
|
||||||
u32 read_word;
|
|
||||||
uint8_t *ptr;
|
|
||||||
uint8_t *pbuf;
|
|
||||||
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
offset_to_align = address & 0x03;
|
|
||||||
pbuf = data;
|
|
||||||
if (offset_to_align != 0) {
|
|
||||||
// the start address is not 4-bytes aligned
|
|
||||||
read_word = HAL_READ32(SPI_FLASH_BASE, (address - offset_to_align));
|
|
||||||
ptr = (uint8_t*)&read_word + offset_to_align;
|
|
||||||
offset_to_align = 4 - offset_to_align;
|
|
||||||
for (i=0;i<offset_to_align;i++) {
|
|
||||||
*pbuf = *(ptr+i);
|
|
||||||
pbuf++;
|
|
||||||
len--;
|
|
||||||
if (len == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
address = (((address-1) >> 2) + 1) << 2; // address = next 4-bytes aligned
|
|
||||||
|
|
||||||
ptr = (uint8_t*)&read_word;
|
|
||||||
if ((u32)pbuf & 0x03) {
|
|
||||||
while (len >= 4) {
|
|
||||||
read_word = HAL_READ32(SPI_FLASH_BASE, address);
|
|
||||||
for (i=0;i<4;i++) {
|
|
||||||
*pbuf = *(ptr+i);
|
|
||||||
pbuf++;
|
|
||||||
}
|
|
||||||
address += 4;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (len >= 4) {
|
|
||||||
*((u32 *)pbuf) = HAL_READ32(SPI_FLASH_BASE, address);
|
|
||||||
pbuf += 4;
|
|
||||||
address += 4;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
read_word = HAL_READ32(SPI_FLASH_BASE, address);
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
*pbuf = *(ptr+i);
|
|
||||||
pbuf++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
uint32_t flash_get_size(const flash_t *obj)
|
||||||
* @brief Write a stream of data to specified address
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param address: Specifies the address to be read.
|
|
||||||
* @param len: Specifies the length of the data to write.
|
|
||||||
* @param data: Specified the pointer of the data to be written.
|
|
||||||
* @retval status: Success:1 or Failure: Others.
|
|
||||||
*/
|
|
||||||
int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t * data)
|
|
||||||
{
|
{
|
||||||
u32 offset_to_align;
|
return FLASH_SIZE;
|
||||||
u32 align_addr;
|
|
||||||
u32 i;
|
|
||||||
u32 write_word;
|
|
||||||
uint8_t *ptr;
|
|
||||||
uint8_t *pbuf;
|
|
||||||
u8 flashtype = 0;
|
|
||||||
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
flashtype = flashobj.SpicInitPara.flashtype;
|
|
||||||
offset_to_align = address & 0x03;
|
|
||||||
pbuf = data;
|
|
||||||
if (offset_to_align != 0) {
|
|
||||||
// the start address is not 4-bytes aligned
|
|
||||||
align_addr = (address - offset_to_align);
|
|
||||||
write_word = HAL_READ32(SPI_FLASH_BASE, align_addr);
|
|
||||||
ptr = (uint8_t*)&write_word + offset_to_align;
|
|
||||||
offset_to_align = 4 - offset_to_align;
|
|
||||||
for (i=0;i<offset_to_align;i++) {
|
|
||||||
*(ptr+i) = *pbuf;
|
|
||||||
pbuf++;
|
|
||||||
len--;
|
|
||||||
if (len == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//Write word
|
|
||||||
HAL_WRITE32(SPI_FLASH_BASE, align_addr, write_word);
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
address = (((address-1) >> 2) + 1) << 2; // address = next 4-bytes aligned
|
|
||||||
|
|
||||||
if ((u32)pbuf & 0x03) {
|
|
||||||
while (len >= 4) {
|
|
||||||
write_word = (u32)(*pbuf) | ((u32)(*(pbuf+1)) << 8) | ((u32)(*(pbuf+2)) << 16) | ((u32)(*(pbuf+3)) << 24);
|
|
||||||
//Write word
|
|
||||||
HAL_WRITE32(SPI_FLASH_BASE, address, write_word);
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
pbuf += 4;
|
|
||||||
address += 4;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while (len >= 4) {
|
|
||||||
//Write word
|
|
||||||
HAL_WRITE32(SPI_FLASH_BASE, address, (u32)*((u32 *)pbuf));
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
pbuf += 4;
|
|
||||||
address += 4;
|
|
||||||
len -= 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len > 0) {
|
|
||||||
write_word = HAL_READ32(SPI_FLASH_BASE, address);
|
|
||||||
ptr = (uint8_t*)&write_word;
|
|
||||||
for (i=0;i<len;i++) {
|
|
||||||
*(ptr+i) = *pbuf;
|
|
||||||
pbuf++;
|
|
||||||
}
|
|
||||||
//Write word
|
|
||||||
HAL_WRITE32(SPI_FLASH_BASE, address, write_word);
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function Description:
|
|
||||||
This function performans the same functionality as the function flash_stream_write.
|
|
||||||
It enhances write performance by reducing overheads.
|
|
||||||
Users can use either of functions depending on their needs.
|
|
||||||
|
|
||||||
* @brief Write a stream of data to specified address
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param address: Specifies the address to be read.
|
|
||||||
* @param Length: Specifies the length of the data to write.
|
|
||||||
* @param data: Specified the pointer of the data to be written.
|
|
||||||
* @retval status: Success:1 or Failure: Others.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
int flash_burst_write(flash_t *obj, uint32_t address ,uint32_t Length, uint8_t * data)
|
|
||||||
{
|
|
||||||
|
|
||||||
u32 OccuSize;
|
|
||||||
u32 ProgramSize;
|
|
||||||
u32 PageSize;
|
|
||||||
u8 flashtype = 0;
|
|
||||||
|
|
||||||
PageSize = 256;
|
|
||||||
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
flashtype = flashobj.SpicInitPara.flashtype;
|
|
||||||
|
|
||||||
OccuSize = address & 0xFF;
|
|
||||||
if((Length >= PageSize) ||((Length + OccuSize) >= PageSize)){
|
|
||||||
ProgramSize = PageSize - OccuSize;
|
|
||||||
} else {
|
|
||||||
ProgramSize = Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
flashobj.Length = Length;
|
|
||||||
while(Length > 0){
|
|
||||||
if(OccuSize){
|
|
||||||
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
address += ProgramSize;
|
|
||||||
data+= ProgramSize;
|
|
||||||
Length -= ProgramSize;
|
|
||||||
OccuSize = 0;
|
|
||||||
} else{
|
|
||||||
while((flashobj.Length) >= PageSize){
|
|
||||||
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
address += PageSize;
|
|
||||||
data+=PageSize;
|
|
||||||
Length -= PageSize;
|
|
||||||
}
|
|
||||||
flashobj.Length = Length;
|
|
||||||
if((flashobj.Length) > 0){
|
|
||||||
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
|
|
||||||
// Wait spic busy done
|
|
||||||
SpicWaitBusyDoneRtl8195A();
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
if(flashtype == FLASH_MICRON){
|
|
||||||
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
|
||||||
} else
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
flashobj.Length = Length;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @brief Read a stream of data from specified address
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param address: Specifies the address to be read.
|
|
||||||
* @param len: Specifies the length of the data to read.
|
|
||||||
* @param data: Specified the address to save the readback data.
|
|
||||||
* @retval status: Success:1 or Failure: Others.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int flash_burst_read(flash_t *obj, uint32_t address, uint32_t Length, uint8_t * data)
|
|
||||||
{
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
// Wait flash busy done (wip=0)
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
SpicUserReadRtl8195A(Length, address, data, SpicOneBitMode);
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int flash_get_status(flash_t *obj)
|
|
||||||
{
|
|
||||||
u8 Status = 0;
|
|
||||||
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
Status = SpicGetFlashStatusRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function Description:
|
|
||||||
Please refer to the datatsheet of flash for more details of the content of status register.
|
|
||||||
The block protected area and the corresponding control bits are provided in the flash datasheet.
|
|
||||||
|
|
||||||
* @brief Set Status register to enable desired operation
|
|
||||||
* @param obj: Specifies the parameter of flash object.
|
|
||||||
* @param data: Specifies which bit users like to set
|
|
||||||
ex: if users want to set the third bit, data = 0x8.
|
|
||||||
|
|
||||||
*/
|
|
||||||
int flash_set_status(flash_t *obj, uint32_t data)
|
|
||||||
{
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
SpicSetFlashStatusRefinedRtl8195A(data, flashobj.SpicInitPara);
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
DBG_8195A("Status Register After Setting= %x\n", flash_get_status(&flashobj));
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Function Description:
|
|
||||||
This function aims to reset the status register, please make sure the operation is appropriate.
|
|
||||||
*/
|
|
||||||
void flash_reset_status(flash_t *obj)
|
|
||||||
{
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
SpicSetFlashStatusRefinedRtl8195A(0, flashobj.SpicInitPara);
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
Function Description:
|
|
||||||
This function is only for Micron 512Mbit flash to access beyond 128Mbit by switching between four 128 Mbit area.
|
|
||||||
Please refer to flash datasheet for more information about memory mapping.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int flash_set_extend_addr(flash_t *obj, uint32_t data)
|
|
||||||
{
|
|
||||||
flash_turnon();
|
|
||||||
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
|
|
||||||
SpicSetExtendAddrRtl8195A(data, flashobj.SpicInitPara);
|
|
||||||
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
|
||||||
DBG_8195A("Extended Address Register After Setting= %x\n", flash_get_extend_addr(&flashobj));
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int flash_get_extend_addr(flash_t *obj)
|
|
||||||
{
|
|
||||||
u8 Status = 0;
|
|
||||||
|
|
||||||
flash_turnon();
|
|
||||||
if(isinit == 0)
|
|
||||||
flash_init(&flashobj);
|
|
||||||
Status = SpicGetExtendAddrRtl8195A(flashobj.SpicInitPara);
|
|
||||||
|
|
||||||
SpicDisableRtl8195A();
|
|
||||||
return Status;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,59 +0,0 @@
|
||||||
/* mbed Microcontroller Library
|
|
||||||
* Copyright (c) 2013-2016 Realtek Semiconductor Corp.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef MBED_EXT_FLASH_API_EXT_H
|
|
||||||
#define MBED_EXT_FLASH_API_EXT_H
|
|
||||||
|
|
||||||
#include "device.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct flash_s flash_t;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* global data structure
|
|
||||||
*/
|
|
||||||
extern flash_t flash;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
FLASH_COMPLETE = 0,
|
|
||||||
FLASH_ERROR_2 = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
//void flash_init (flash_t *obj);
|
|
||||||
void flash_erase_sector (flash_t *obj, uint32_t address);
|
|
||||||
void flash_erase_block(flash_t * obj, uint32_t address);
|
|
||||||
int flash_read_word (flash_t *obj, uint32_t address, uint32_t * data);
|
|
||||||
int flash_write_word (flash_t *obj, uint32_t address, uint32_t data);
|
|
||||||
int flash_stream_read (flash_t *obj, uint32_t address, uint32_t len, uint8_t * data);
|
|
||||||
int flash_stream_write (flash_t *obj, uint32_t address, uint32_t len, uint8_t * data);
|
|
||||||
void flash_write_protect (flash_t *obj, uint32_t protect);
|
|
||||||
int flash_get_status(flash_t * obj);
|
|
||||||
int flash_set_status(flash_t * obj, uint32_t data);
|
|
||||||
void flash_reset_status(flash_t * obj);
|
|
||||||
int flash_burst_write(flash_t * obj, uint32_t address, uint32_t Length, uint8_t * data);
|
|
||||||
int flash_burst_read(flash_t * obj, uint32_t address, uint32_t Length, uint8_t * data);
|
|
||||||
int flash_set_extend_addr(flash_t * obj, uint32_t data);
|
|
||||||
int flash_get_extend_addr(flash_t * obj);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -0,0 +1,467 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* Copyright (c) 2013-2016 Realtek Semiconductor Corp.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#include "objects.h"
|
||||||
|
#include "PinNames.h"
|
||||||
|
#include "pinmap.h"
|
||||||
|
|
||||||
|
#include "rtl8195a.h"
|
||||||
|
#include "flash_ext.h"
|
||||||
|
|
||||||
|
extern u32 ConfigDebugInfo;
|
||||||
|
extern SPIC_INIT_PARA SpicInitParaAllClk[3][CPU_CLK_TYPE_NO];
|
||||||
|
|
||||||
|
static int flash_inited = 0;
|
||||||
|
static flash_t flashobj;
|
||||||
|
static void flash_ext_init(void)
|
||||||
|
{
|
||||||
|
if (!SpicFlashInitRtl8195A(SpicOneBitMode)){
|
||||||
|
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3)|0xf);
|
||||||
|
} else {
|
||||||
|
flash_inited = 1;
|
||||||
|
}
|
||||||
|
flashobj.SpicInitPara.flashtype = SpicInitParaAllClk[0][0].flashtype;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __flash_ext_turnon(void)
|
||||||
|
{
|
||||||
|
SPI_FLASH_PIN_FCTRL(ON);
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
|
||||||
|
if (flash_inited == 0) {
|
||||||
|
flash_ext_init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __flash_ext_turnoff(void)
|
||||||
|
{
|
||||||
|
SpicDisableRtl8195A();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_ext_write_protect(flash_t *obj, uint32_t protect)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
SpicWriteProtectFlashRtl8195A(protect);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
void __flash_ext_erase_sector(flash_t *obj, uint32_t address)
|
||||||
|
{
|
||||||
|
SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE+address);
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_ext_erase_sector(flash_t *obj, uint32_t address)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
__flash_ext_erase_sector(obj, address);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flash_ext_erase_block(flash_t *obj, uint32_t address)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE+address);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_ext_read_word(flash_t *obj, uint32_t address, uint32_t *data)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
*data = HAL_READ32(SPI_FLASH_BASE, address);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a word to specified address
|
||||||
|
* @param obj: Specifies the parameter of flash object.
|
||||||
|
* @param address: Specifies the address to be programmed.
|
||||||
|
* @param data: Specified the data to be programmed.
|
||||||
|
* @retval status: Success:1 or Failure: Others.
|
||||||
|
*/
|
||||||
|
int flash_ext_write_word(flash_t *obj, uint32_t address, uint32_t data)
|
||||||
|
{
|
||||||
|
u8 flashtype = 0;
|
||||||
|
__flash_ext_turnon();
|
||||||
|
|
||||||
|
flashtype = flashobj.SpicInitPara.flashtype;
|
||||||
|
HAL_WRITE32(SPI_FLASH_BASE, address, data);
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a stream of data from specified address
|
||||||
|
* @param obj: Specifies the parameter of flash object.
|
||||||
|
* @param address: Specifies the address to be read.
|
||||||
|
* @param len: Specifies the length of the data to read.
|
||||||
|
* @param data: Specified the address to save the readback data.
|
||||||
|
* @retval status: Success:1 or Failure: Others.
|
||||||
|
*/
|
||||||
|
int flash_ext_stream_read(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data)
|
||||||
|
{
|
||||||
|
uint32_t i, offset, word;
|
||||||
|
uint8_t *ptr, *pbuf;
|
||||||
|
|
||||||
|
__flash_ext_turnon();
|
||||||
|
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
|
||||||
|
offset = addr & 0x03;
|
||||||
|
addr = addr & ~0x03;
|
||||||
|
pbuf = data;
|
||||||
|
if (offset != 0) {
|
||||||
|
word = HAL_READ32(SPI_FLASH_BASE, addr);
|
||||||
|
ptr = (uint8_t *)&word + offset;
|
||||||
|
offset = 4 - offset;
|
||||||
|
for (i = 0; i < offset && len > 0; i++, len--) {
|
||||||
|
*pbuf = *ptr;
|
||||||
|
pbuf++;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
addr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (uint8_t *)&word;
|
||||||
|
if ((uint32_t)pbuf & 0x03) {
|
||||||
|
while (len >= 4) {
|
||||||
|
word = HAL_READ32(SPI_FLASH_BASE, addr);
|
||||||
|
for (i = 0; i < 4; i++) {
|
||||||
|
*pbuf = *(ptr+i);
|
||||||
|
pbuf++;
|
||||||
|
}
|
||||||
|
addr += 4;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (len >= 4) {
|
||||||
|
*((uint32_t *)pbuf) = HAL_READ32(SPI_FLASH_BASE, addr);
|
||||||
|
pbuf += 4;
|
||||||
|
addr += 4;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
word = HAL_READ32(SPI_FLASH_BASE, addr);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
*pbuf = *(ptr+i);
|
||||||
|
pbuf++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a stream of data to specified address
|
||||||
|
* @param obj: Specifies the parameter of flash object.
|
||||||
|
* @param address: Specifies the address to be read.
|
||||||
|
* @param len: Specifies the length of the data to write.
|
||||||
|
* @param data: Specified the pointer of the data to be written.
|
||||||
|
* @retval status: Success:1 or Failure: Others.
|
||||||
|
*/
|
||||||
|
int __flash_ext_stream_write(flash_t *obj, uint32_t addr, uint32_t len, const uint8_t *data)
|
||||||
|
{
|
||||||
|
uint32_t i, offset, word;
|
||||||
|
const uint8_t*pbuf;
|
||||||
|
uint8_t *ptr;
|
||||||
|
u8 flashtype = 0;
|
||||||
|
|
||||||
|
offset = addr & 0x03;
|
||||||
|
addr = addr & ~0x03;
|
||||||
|
pbuf = data;
|
||||||
|
flashtype = flashobj.SpicInitPara.flashtype;
|
||||||
|
|
||||||
|
if (offset != 0) {
|
||||||
|
word = HAL_READ32(SPI_FLASH_BASE, addr);
|
||||||
|
ptr = (uint8_t *)&word + offset;
|
||||||
|
offset = 4 - offset;
|
||||||
|
for (i = 0; i < offset && len > 0; i++, len--) {
|
||||||
|
*ptr = *pbuf;
|
||||||
|
pbuf++;
|
||||||
|
ptr++;
|
||||||
|
}
|
||||||
|
HAL_WRITE32(SPI_FLASH_BASE, addr, word);
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
addr += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((uint32_t)pbuf & 0x03) {
|
||||||
|
while (len >= 4) {
|
||||||
|
word = (uint32_t)(*pbuf) | ((uint32_t)(*(pbuf+1)) << 8)|
|
||||||
|
((uint32_t)(*(pbuf+2)) << 16) | ((uint32_t)(*(pbuf+3)) << 24);
|
||||||
|
HAL_WRITE32(SPI_FLASH_BASE, addr, word);
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf += 4;
|
||||||
|
addr += 4;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
while (len >= 4) {
|
||||||
|
HAL_WRITE32(SPI_FLASH_BASE, addr, (uint32_t)*((uint32_t *)pbuf));
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
pbuf += 4;
|
||||||
|
addr += 4;
|
||||||
|
len -= 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
word = HAL_READ32(SPI_FLASH_BASE, addr);
|
||||||
|
ptr = (uint8_t*)&word;
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
*(ptr+i) = *pbuf;
|
||||||
|
pbuf++;
|
||||||
|
}
|
||||||
|
|
||||||
|
HAL_WRITE32(SPI_FLASH_BASE, addr, word);
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_ext_stream_write(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data)
|
||||||
|
{
|
||||||
|
int32_t status;
|
||||||
|
|
||||||
|
__flash_ext_turnon();
|
||||||
|
status = __flash_ext_stream_write(obj, addr, len, data);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_stream_read(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data)
|
||||||
|
{
|
||||||
|
return flash_ext_stream_read(obj, addr, len, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_stream_write(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data)
|
||||||
|
{
|
||||||
|
return flash_ext_stream_write(obj, addr, len, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function Description:
|
||||||
|
This function performans the same functionality as the function flash_stream_write.
|
||||||
|
It enhances write performance by reducing overheads.
|
||||||
|
Users can use either of functions depending on their needs.
|
||||||
|
|
||||||
|
* @brief Write a stream of data to specified address
|
||||||
|
* @param obj: Specifies the parameter of flash object.
|
||||||
|
* @param address: Specifies the address to be read.
|
||||||
|
* @param length: Specifies the length of the data to write.
|
||||||
|
* @param data: Specified the pointer of the data to be written.
|
||||||
|
* @retval status: Success:1 or Failure: Others.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
int flash_ext_burst_write(flash_t *obj, uint32_t address ,uint32_t length, uint8_t *data)
|
||||||
|
{
|
||||||
|
u32 OccuSize;
|
||||||
|
u32 ProgramSize;
|
||||||
|
u32 PageSize;
|
||||||
|
u8 flashtype = 0;
|
||||||
|
|
||||||
|
PageSize = 256;
|
||||||
|
|
||||||
|
__flash_ext_turnon();
|
||||||
|
|
||||||
|
flashtype = flashobj.SpicInitPara.flashtype;
|
||||||
|
OccuSize = address & 0xFF;
|
||||||
|
if((length >= PageSize) ||((length + OccuSize) >= PageSize)){
|
||||||
|
ProgramSize = PageSize - OccuSize;
|
||||||
|
} else {
|
||||||
|
ProgramSize = length;
|
||||||
|
}
|
||||||
|
|
||||||
|
flashobj.Length = length;
|
||||||
|
while(length > 0){
|
||||||
|
if(OccuSize){
|
||||||
|
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
|
||||||
|
// Wait spic busy done
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
// Wait flash busy done (wip=0)
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
address += ProgramSize;
|
||||||
|
data += ProgramSize;
|
||||||
|
length -= ProgramSize;
|
||||||
|
OccuSize = 0;
|
||||||
|
} else{
|
||||||
|
while((flashobj.Length) >= PageSize){
|
||||||
|
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
|
||||||
|
// Wait spic busy done
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
// Wait flash busy done (wip=0)
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
address += PageSize;
|
||||||
|
data += PageSize;
|
||||||
|
length -= PageSize;
|
||||||
|
}
|
||||||
|
flashobj.Length = length;
|
||||||
|
if((flashobj.Length) > 0){
|
||||||
|
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
|
||||||
|
// Wait spic busy done
|
||||||
|
SpicWaitBusyDoneRtl8195A();
|
||||||
|
// Wait flash busy done (wip=0)
|
||||||
|
if(flashtype == FLASH_MICRON){
|
||||||
|
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
|
||||||
|
} else {
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flashobj.Length = length;
|
||||||
|
}
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @brief Read a stream of data from specified address
|
||||||
|
* @param obj: Specifies the parameter of flash object.
|
||||||
|
* @param address: Specifies the address to be read.
|
||||||
|
* @param len: Specifies the length of the data to read.
|
||||||
|
* @param data: Specified the address to save the readback data.
|
||||||
|
* @retval status: Success:1 or Failure: Others.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int flash_ext_burst_read(flash_t *obj, uint32_t address, uint32_t length, uint8_t *data)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
SpicUserReadRtl8195A(length, address, data, SpicOneBitMode);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_ext_get_status(flash_t *obj)
|
||||||
|
{
|
||||||
|
uint8_t status = 0;
|
||||||
|
|
||||||
|
__flash_ext_turnon();
|
||||||
|
status = SpicGetFlashStatusRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function Description:
|
||||||
|
Please refer to the datatsheet of flash for more details of the content of status register.
|
||||||
|
The block protected area and the corresponding control bits are provided in the flash datasheet.
|
||||||
|
|
||||||
|
* @brief Set Status register to enable desired operation
|
||||||
|
* @param obj: Specifies the parameter of flash object.
|
||||||
|
* @param data: Specifies which bit users like to set
|
||||||
|
ex: if users want to set the third bit, data = 0x8.
|
||||||
|
|
||||||
|
*/
|
||||||
|
int flash_ext_set_status(flash_t *obj, uint32_t data)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
SpicSetFlashStatusRefinedRtl8195A(data, flashobj.SpicInitPara);
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Function Description:
|
||||||
|
This function aims to reset the status register, please make sure the operation is appropriate.
|
||||||
|
*/
|
||||||
|
void flash_ext_reset_status(flash_t *obj)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
SpicSetFlashStatusRefinedRtl8195A(0, flashobj.SpicInitPara);
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
}
|
||||||
|
|
||||||
|
int flash_ext_get_extend_addr(flash_t *obj)
|
||||||
|
{
|
||||||
|
uint8_t addr = 0;
|
||||||
|
|
||||||
|
__flash_ext_turnon();
|
||||||
|
addr = SpicGetExtendAddrRtl8195A(flashobj.SpicInitPara);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
Function Description:
|
||||||
|
This function is only for Micron 512Mbit flash to access beyond 128Mbit by switching between four 128 Mbit area.
|
||||||
|
Please refer to flash datasheet for more information about memory mapping.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int flash_ext_set_extend_addr(flash_t *obj, uint32_t data)
|
||||||
|
{
|
||||||
|
__flash_ext_turnon();
|
||||||
|
SpicSetExtendAddrRtl8195A(data, flashobj.SpicInitPara);
|
||||||
|
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
|
||||||
|
__flash_ext_turnoff();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* mbed Microcontroller Library
|
||||||
|
* Copyright (c) 2013-2016 Realtek Semiconductor Corp.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
#ifndef MBED_FLASH_EXT_H
|
||||||
|
#define MBED_FLASH_EXT_H
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
#include "flash_api.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FLASH_PAGE_SIZE 256
|
||||||
|
#define FLASH_SIZE 0x100000
|
||||||
|
#define FLASH_OFS_START 0xc0000
|
||||||
|
#define FLASH_OFS_END (FLASH_OFS_START + FLASH_SIZE)
|
||||||
|
|
||||||
|
extern void flash_ext_erase_sector(flash_t *obj, uint32_t address);
|
||||||
|
extern void flash_ext_erase_block(flash_t * obj, uint32_t address);
|
||||||
|
extern int flash_ext_read_word(flash_t *obj, uint32_t address, uint32_t * data);
|
||||||
|
extern int flash_ext_write_word(flash_t *obj, uint32_t address, uint32_t data);
|
||||||
|
extern int flash_ext_stream_read(flash_t *obj, uint32_t address, uint32_t len, uint8_t * data);
|
||||||
|
extern int flash_ext_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t * data);
|
||||||
|
extern int flash_stream_read(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data);
|
||||||
|
extern int flash_stream_write(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data);
|
||||||
|
extern void flash_ext_write_protect(flash_t *obj, uint32_t protect);
|
||||||
|
extern int flash_ext_get_status(flash_t *obj);
|
||||||
|
extern int flash_ext_set_status(flash_t *obj, uint32_t data);
|
||||||
|
extern void flash_ext_reset_status(flash_t *obj);
|
||||||
|
|
||||||
|
/* Internal functions for flash API */
|
||||||
|
extern void __flash_ext_turnon(void);
|
||||||
|
extern void __flash_ext_turnoff(void);
|
||||||
|
extern void __flash_ext_erase_sector(flash_t *obj, uint32_t address);
|
||||||
|
extern int __flash_ext_stream_write(flash_t *obj, uint32_t addr, uint32_t len, const uint8_t *data);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -2972,7 +2972,7 @@
|
||||||
"extra_labels": ["Realtek", "AMEBA", "RTL8195A"],
|
"extra_labels": ["Realtek", "AMEBA", "RTL8195A"],
|
||||||
"macros": ["__RTL8195A__","CONFIG_PLATFORM_8195A","CONFIG_MBED_ENABLED","PLATFORM_CMSIS_RTOS"],
|
"macros": ["__RTL8195A__","CONFIG_PLATFORM_8195A","CONFIG_MBED_ENABLED","PLATFORM_CMSIS_RTOS"],
|
||||||
"supported_toolchains": ["GCC_ARM", "ARM", "IAR"],
|
"supported_toolchains": ["GCC_ARM", "ARM", "IAR"],
|
||||||
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SPI", "TRNG", "EMAC"],
|
"device_has": ["ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SPI", "TRNG", "EMAC", "FLASH"],
|
||||||
"features": ["LWIP"],
|
"features": ["LWIP"],
|
||||||
"post_binary_hook": {
|
"post_binary_hook": {
|
||||||
"function": "RTL8195ACode.binary_hook",
|
"function": "RTL8195ACode.binary_hook",
|
||||||
|
|
Loading…
Reference in New Issue