This commit is contained in:
pvvx 2017-02-01 13:57:59 +03:00
parent e98a546513
commit 85ad19d2b9

View file

@ -8,11 +8,9 @@
*******************************************************************************
*/
#include "objects.h"
#include "PinNames.h"
#include "pinmap.h"
#include "rtl8195a.h"
@ -35,14 +33,12 @@ flash_t flashobj;
* 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)
{
void flash_write_protect(flash_t *obj, uint32_t protect) {
flash_turnon();
if (fspic_isinit == 0)
@ -56,32 +52,50 @@ void flash_write_protect(flash_t *obj, uint32_t protect)
* @param obj: address of the flash object
* @retval none
*/
void flash_init(flash_t *obj)
{
void flash_init(flash_t *obj) {
//SPIC_INIT_PARA spic_init_para;
// Init SPI Flash Controller
// DBG_8195A("Initial Spi Flash Controller\n");
//SPI_FLASH_PIN_FCTRL(ON);
if (!SpicFlashInitRtl8195A(SpicDualBitMode)) {// SpicOneBitMode)){
DBG_8195A("SPI Init Fail!\n"); // DBG_SPIF_ERR?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3, HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3)|0xf);
}
else {
#if CONFIG_DEBUG_LOG > 4
DBG_8195A("Initial Spi Flash Controller\n");
#endif
u8 flmode;
SPI_FLASH_PIN_FCTRL(ON);
#if 0
if (SpicFlashInitRtl8195A(SpicQuadBitMode)) {
flmode = SpicQuadBitMode;
fspic_isinit = 1;
}
flashobj.SpicInitPara.flashtype = SpicInitParaAllClk[0][0].flashtype;
/*
DBG_SPIF_INFO("Flash ID: %02x%02x%02x\n",SpicInitParaAllClk[0][0].id[0],SpicInitParaAllClk[0][0].id[1],SpicInitParaAllClk[0][0].id[2]);
DBG_SPIF_INFO("Flash Mode:%x; BaudRate:%x; RdDummyCyle:%x; DelayLine:%x\n",
SpicInitParaAllClk[0][0].Mode, SpicInitParaAllClk[0][0].BaudRate, SpicInitParaAllClk[0][0].RdDummyCyle, SpicInitParaAllClk[0][0].DelayLine);
*/
else
#endif
if (SpicFlashInitRtl8195A(SpicDualBitMode)) { // SpicFlashInitRtl8195A(SpicQuadBitMode)
flmode = SpicDualBitMode;
fspic_isinit = 1;
} else if (SpicFlashInitRtl8195A(SpicOneBitMode)) {
flmode = SpicOneBitMode;
fspic_isinit = 1;
} else {
DBG_8195A("SPI Init Fail!\n"); // DBG_SPIF_ERR?
HAL_WRITE32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3,
HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_DSTBY_INFO3) | 0xf);
// flmode = SpicOneBitMode;
return;
}
u8 curclk = (HAL_READ32(SYSTEM_CTRL_BASE, REG_SYS_CLK_CTRL1)
>> BIT_SHIFT_PESOC_OCP_CPU_CK_SEL) & BIT_MASK_PESOC_OCP_CPU_CK_SEL;
flashobj.SpicInitPara = SpicInitParaAllClk[flmode][curclk];
flashobj.SpicInitPara.Mode.CpuClk = curclk;
flashobj.SpicInitPara.Mode.BitMode = flmode;
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("Flash ID: %02x%02x%02x\n", flashobj.SpicInitPara.id[0], flashobj.SpicInitPara.id[1], flashobj.SpicInitPara.id[2]);
DBG_SPIF_INFO("Flash Mode: 0x%02x; BaudRate:%d; RdDummyCyle:%d; DelayLine:%d\n",
flashobj.SpicInitPara.Mode.BitMode, flashobj.SpicInitPara.BaudRate, flashobj.SpicInitPara.RdDummyCyle, flashobj.SpicInitPara.DelayLine);
DBG_SPIF_INFO("Flash Size: %d bytes\n", flash_get_size(obj));
#endif
}
void flash_turnon(void)
{
void flash_turnon(void) {
SPI_FLASH_PIN_FCTRL(ON);
SpicWaitBusyDoneRtl8195A();
}
@ -91,8 +105,7 @@ void flash_turnon(void)
* @param address: Specifies the starting address to be erased.
* @retval none
*/
void flash_erase_sector(flash_t *obj, uint32_t address)
{
void flash_erase_sector(flash_t *obj, uint32_t address) {
flash_turnon();
if (fspic_isinit == 0)
@ -102,8 +115,7 @@ void flash_erase_sector(flash_t *obj, uint32_t address)
SpicDisableRtl8195A();
}
void flash_erase_block(flash_t *obj, uint32_t address)
{
void flash_erase_block(flash_t *obj, uint32_t address) {
flash_turnon();
if (fspic_isinit == 0)
@ -113,7 +125,6 @@ void flash_erase_block(flash_t *obj, uint32_t address)
SpicDisableRtl8195A();
}
/**
* @brief Read a word from specified address
* @param obj: Specifies the parameter of flash object.
@ -121,8 +132,7 @@ void flash_erase_block(flash_t *obj, uint32_t address)
* @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)
{
int flash_read_word(flash_t *obj, uint32_t address, uint32_t * data) {
flash_turnon();
if (fspic_isinit == 0)
@ -143,15 +153,13 @@ int flash_read_word(flash_t *obj, uint32_t address, uint32_t * data)
* @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)
{
int flash_write_word(flash_t *obj, uint32_t address, uint32_t data) {
u8 flashtype = 0;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
flashtype = flashobj.SpicInitPara.flashtype;
//Write word
@ -163,15 +171,13 @@ int flash_write_word(flash_t *obj, uint32_t address, uint32_t data)
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
}
else
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
SpicDisableRtl8195A();
return 1;
}
/**
* @brief Read a stream of data from specified address
* @param obj: Specifies the parameter of flash object.
@ -180,8 +186,8 @@ int flash_write_word(flash_t *obj, uint32_t address, uint32_t data)
* @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)
{
int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len,
uint8_t * data) {
u32 offset_to_align;
u32 i;
u32 read_word;
@ -193,7 +199,6 @@ int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len, uint8_t * d
if (fspic_isinit == 0)
flash_init(&flashobj);
// Wait flash busy done (wip=0)
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
@ -227,8 +232,7 @@ int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len, uint8_t * d
address += 4;
len -= 4;
}
}
else {
} else {
while (len >= 4) {
*((u32 *) pbuf) = HAL_READ32(SPI_FLASH_BASE, address);
pbuf += 4;
@ -257,8 +261,8 @@ int flash_stream_read(flash_t *obj, uint32_t address, uint32_t len, uint8_t * d
* @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)
{
int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len,
uint8_t * data) {
u32 offset_to_align;
u32 align_addr;
u32 i;
@ -296,8 +300,7 @@ int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t *
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
}
else
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
}
@ -305,7 +308,8 @@ int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t *
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 = (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
@ -313,16 +317,14 @@ int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t *
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
}
else
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
pbuf += 4;
address += 4;
len -= 4;
}
}
else {
} else {
while (len >= 4) {
//Write word
HAL_WRITE32(SPI_FLASH_BASE, address, (u32)*((u32 *)pbuf));
@ -331,8 +333,7 @@ int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t *
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
}
else
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
pbuf += 4;
@ -355,8 +356,7 @@ int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t *
// Wait flash busy done (wip=0)
if (flashtype == FLASH_MICRON) {
SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara);
}
else
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
}
@ -365,7 +365,6 @@ int flash_stream_write(flash_t *obj, uint32_t address, uint32_t len, uint8_t *
return 1;
}
/*
Function Description:
This function performans the same functionality as the function flash_stream_write.
@ -381,8 +380,8 @@ Users can use either of functions depending on their needs.
*/
int flash_burst_write(flash_t *obj, uint32_t address ,uint32_t Length, uint8_t * data)
{
int flash_burst_write(flash_t *obj, uint32_t address, uint32_t Length,
uint8_t * data) {
u32 OccuSize;
u32 ProgramSize;
@ -407,31 +406,30 @@ int flash_burst_write(flash_t *obj, uint32_t address ,uint32_t Length, uint8_t *
flashobj.Length = Length;
while (Length > 0) {
if (OccuSize) {
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
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
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
address += ProgramSize;
data += ProgramSize;
Length -= ProgramSize;
OccuSize = 0;
}
else{
} else {
while ((flashobj.Length) >= PageSize) {
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
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
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
address += PageSize;
@ -440,14 +438,14 @@ int flash_burst_write(flash_t *obj, uint32_t address ,uint32_t Length, uint8_t *
}
flashobj.Length = Length;
if ((flashobj.Length) > 0) {
SpicUserProgramRtl8195A(data, flashobj.SpicInitPara, address, &(flashobj.Length));
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
} else
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
break;
@ -469,8 +467,8 @@ int flash_burst_write(flash_t *obj, uint32_t address ,uint32_t Length, uint8_t *
* @retval status: Success:1 or Failure: Others.
*/
int flash_burst_read(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) {
flash_turnon();
if (fspic_isinit == 0)
@ -478,13 +476,13 @@ int flash_burst_read(flash_t *obj, uint32_t address, uint32_t Length, uint8_t *
// Wait flash busy done (wip=0)
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
SpicUserReadRtl8195A(Length, address, data, SpicDualBitMode); // SpicOneBitMode);
SpicUserReadRtl8195A(Length, address, data,
flashobj.SpicInitPara.Mode.BitMode);
SpicDisableRtl8195A();
return 1;
}
int flash_get_status(flash_t *obj)
{
int flash_get_status(flash_t *obj) {
u8 Status = 0;
flash_turnon();
@ -509,8 +507,7 @@ The block protected area and the corresponding control bits are provided in the
ex: if users want to set the third bit, data = 0x8.
*/
int flash_set_status(flash_t *obj, uint32_t data)
{
int flash_set_status(flash_t *obj, uint32_t data) {
flash_turnon();
if (fspic_isinit == 0)
@ -518,7 +515,8 @@ int flash_set_status(flash_t *obj, uint32_t data)
SpicSetFlashStatusRefinedRtl8195A(data, flashobj.SpicInitPara);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
DBG_8195A("Status Register After Setting= %x\n", flash_get_status(&flashobj));
DBG_8195A("Status Register After Setting= %x\n",
flash_get_status(&flashobj));
SpicDisableRtl8195A();
return 1;
}
@ -527,8 +525,7 @@ int flash_set_status(flash_t *obj, uint32_t data)
Function Description:
This function aims to reset the status register, please make sure the operation is appropriate.
*/
void flash_reset_status(flash_t *obj)
{
void flash_reset_status(flash_t *obj) {
flash_turnon();
if (fspic_isinit == 0)
@ -544,8 +541,7 @@ This function is only for Micron 512Mbit flash to access beyond 128Mbit by switc
Please refer to flash datasheet for more information about memory mapping.
*/
int flash_set_extend_addr(flash_t *obj, uint32_t data)
{
int flash_set_extend_addr(flash_t *obj, uint32_t data) {
flash_turnon();
if (fspic_isinit == 0)
@ -553,13 +549,13 @@ int flash_set_extend_addr(flash_t *obj, uint32_t data)
SpicSetExtendAddrRtl8195A(data, flashobj.SpicInitPara);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
DBG_8195A("Extended Address Register After Setting = %x\n", flash_get_extend_addr(&flashobj));
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)
{
int flash_get_extend_addr(flash_t *obj) {
u8 Status = 0;
flash_turnon();
@ -572,4 +568,68 @@ int flash_get_extend_addr(flash_t *obj)
}
/*
* Return Flash size in bytes
* = 0 - unknown flash
*/
unsigned int flash_get_size(flash_t *obj) {
unsigned int flashchip_size = 0;
if (fspic_isinit == 0) {
flash_turnon();
flash_init(&flashobj);
SpicDisableRtl8195A();
if (fspic_isinit == 0)
return flashchip_size;
}
if (flashobj.SpicInitPara.id[2] > 0x11
&& flashobj.SpicInitPara.id[2] < 0x20) {
flashchip_size = 1 << (flashobj.SpicInitPara.id[2]); // Flash size in bytes
} else
flashchip_size = 1024 * 1024; // default 1 mbytes?
return flashchip_size;
}
/*
* Read Flash OTP data
*/
int flash_otp_read(flash_t *obj, uint32_t address, uint32_t Length,
uint8_t * data) {
int ret = 1;
flash_turnon();
if (fspic_isinit == 0)
flash_init(&flashobj);
SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara);
switch (flashobj.SpicInitPara.flashtype) {
case FLASH_MXIC_4IO:
case FLASH_MXIC: // Only 512 bits
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("MXIC: Only 512 bits!\n");
#endif
SpicTxCmdWithDataRtl8195A(FLASH_CMD_ENSO, 0, 0, flashobj.SpicInitPara); // enter secured OTP
SpicUserReadRtl8195A(Length, address, data,
flashobj.SpicInitPara.Mode.BitMode);
SpicTxCmdWithDataRtl8195A(FLASH_CMD_EXSO, 0, 0, flashobj.SpicInitPara); // exit secured OTP
break;
case FLASH_EON: // OTP sector is mapping to sector 1023
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("EON: OTP sector is mapping to sector 1023!\n");
#endif
SpicTxCmdWithDataRtl8195A(FLASH_CMD_EOTPM, 0, 0, flashobj.SpicInitPara); // enter secured OTP
SpicUserReadRtl8195A(Length, address, data,
flashobj.SpicInitPara.Mode.BitMode);
SpicTxCmdWithDataRtl8195A(FLASH_CMD_WRDI, 0, 0, flashobj.SpicInitPara); // exit secured OTP
break;
case FLASH_MICRON: // (4Bh) READ OTP ARRAY
#if CONFIG_DEBUG_LOG > 4
DBG_SPIF_INFO("MICRON: @TODO !\n");
#endif
// FLASH_CMD_ROTPA
ret = 0;
break;
default:
DBG_8195A("Flash type?");
ret = 0;
}
SpicDisableRtl8195A();
return ret;
}