From 0de89c7712645b7e2c32d2059514cb3b64f81a68 Mon Sep 17 00:00:00 2001 From: Yuguo Zou Date: Thu, 15 Jun 2017 16:27:08 +0800 Subject: [PATCH 1/2] Add FlashIAP support for REALTEK_RTL8195AM --- .../TARGET_Realtek/TARGET_AMEBA/flash_api.c | 551 +----------------- .../TARGET_Realtek/TARGET_AMEBA/flash_api.h | 59 -- .../TARGET_Realtek/TARGET_AMEBA/flash_ext.c | 480 +++++++++++++++ .../TARGET_Realtek/TARGET_AMEBA/flash_ext.h | 53 ++ targets/targets.json | 2 +- 5 files changed, 563 insertions(+), 582 deletions(-) delete mode 100644 targets/TARGET_Realtek/TARGET_AMEBA/flash_api.h create mode 100644 targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c create mode 100644 targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.h diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c b/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c index 790b1c075f..985fc95fc8 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c @@ -13,555 +13,62 @@ * See the License for the specific language governing permissions and * 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" -#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) +int32_t flash_init(flash_t *obj) { - flash_turnon(); + //obj->flash_size = FLASH_SIZE; + //obj->sector_size = FLASH_SECTOR_SIZE; + //obj->page_size = FLASH_PAGE_SIZE; - if(isinit == 0) - flash_init(&flashobj); - SpicWriteProtectFlashRtl8195A(protect); - SpicDisableRtl8195A(); + __flash_ext_turnon(); + + return 0; } -/** - * @brief Init Flash - * @param obj: address of the flash object - * @retval none - */ -void flash_init(flash_t *obj) +int32_t flash_free(flash_t *obj) { - //SPIC_INIT_PARA spic_init_para; + __flash_ext_turnoff(); - // Init SPI Flash Controller -// 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(); + return 0; } -/** - * @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) +int32_t flash_erase_sector(flash_t *obj, uint32_t address) { - flash_turnon(); + __flash_ext_erase_sector(obj, FLASH_OFS(address)); - if(isinit == 0) - flash_init(&flashobj); - - SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address); - SpicDisableRtl8195A(); + return 0; } -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(); - - if(isinit == 0) - flash_init(&flashobj); - - SpicBlockEraseFlashRtl8195A(SPI_FLASH_BASE + address); - SpicDisableRtl8195A(); + return __flash_ext_stream_write(obj, FLASH_OFS(address), size, data); } - -/** - * @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) +uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) { - - flash_turnon(); - if(isinit == 0) - flash_init(&flashobj); - // Wait flash busy done (wip=0) - SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + if (address < FLASH_START || address >= FLASH_END) + return (uint32_t)-1; - * data = HAL_READ32(SPI_FLASH_BASE, address); - SpicDisableRtl8195A(); - - return 1; + return FLASH_SECTOR_SIZE; } -/** - * @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) +uint32_t flash_get_page_size(const flash_t *obj) { - u8 flashtype = 0; - - 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; + return FLASH_PAGE_SIZE; } - -/** - * @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) +uint32_t flash_get_start_address(const flash_t *obj) { - u32 offset_to_align; - 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> 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> 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= 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; -} - - diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.h b/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.h deleted file mode 100644 index e1223dee9d..0000000000 --- a/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.h +++ /dev/null @@ -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 diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c b/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c new file mode 100644 index 0000000000..965e1702ec --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c @@ -0,0 +1,480 @@ +/* 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)){ + + 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 { + 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); + DBG_8195A("Status Register After Setting= %x\n", flash_ext_get_status(&flashobj)); + + __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); + DBG_8195A("Extended Address Register After Setting= %x\n", flash_ext_get_extend_addr(&flashobj)); + + __flash_ext_turnoff(); + return 0; +} + + diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.h b/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.h new file mode 100644 index 0000000000..aed9f266b5 --- /dev/null +++ b/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.h @@ -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 diff --git a/targets/targets.json b/targets/targets.json index 40c57b5c26..b2d4fdc813 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -2938,7 +2938,7 @@ "extra_labels": ["Realtek", "AMEBA", "RTL8195A"], "macros": ["__RTL8195A__","CONFIG_PLATFORM_8195A","CONFIG_MBED_ENABLED","PLATFORM_CMSIS_RTOS"], "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"], "post_binary_hook": { "function": "RTL8195ACode.binary_hook", From f7b2edc88c5204e0a96562db64cf9a5657b53884 Mon Sep 17 00:00:00 2001 From: Yuguo Zou Date: Tue, 27 Jun 2017 11:33:46 +0800 Subject: [PATCH 2/2] Coding style fix --- .../TARGET_Realtek/TARGET_AMEBA/flash_api.c | 6 +-- .../TARGET_Realtek/TARGET_AMEBA/flash_ext.c | 41 +++++++------------ 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c b/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c index 985fc95fc8..851b7e2155 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/flash_api.c @@ -21,10 +21,6 @@ int32_t flash_init(flash_t *obj) { - //obj->flash_size = FLASH_SIZE; - //obj->sector_size = FLASH_SECTOR_SIZE; - //obj->page_size = FLASH_PAGE_SIZE; - __flash_ext_turnon(); return 0; @@ -52,7 +48,7 @@ int32_t flash_program_page(flash_t *obj, uint32_t address, const uint8_t *data, uint32_t flash_get_sector_size(const flash_t *obj, uint32_t address) { if (address < FLASH_START || address >= FLASH_END) - return (uint32_t)-1; + return 0; return FLASH_SECTOR_SIZE; } diff --git a/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c b/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c index 965e1702ec..598966ca7c 100644 --- a/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c +++ b/targets/TARGET_Realtek/TARGET_AMEBA/flash_ext.c @@ -28,8 +28,6 @@ static flash_t flashobj; static void flash_ext_init(void) { 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 { flash_inited = 1; @@ -106,8 +104,7 @@ int flash_ext_write_word(flash_t *obj, uint32_t address, uint32_t data) if(flashtype == FLASH_MICRON){ SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); - } else - { + } else { SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); } @@ -206,7 +203,7 @@ int __flash_ext_stream_write(flash_t *obj, uint32_t addr, uint32_t len, const ui for (i = 0; i < offset && len > 0; i++, len--) { *ptr = *pbuf; pbuf++; - ptr++; + ptr++; } HAL_WRITE32(SPI_FLASH_BASE, addr, word); SpicWaitBusyDoneRtl8195A(); @@ -285,11 +282,13 @@ int flash_ext_stream_write(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *d return status; } -int flash_stream_read(flash_t *obj, uint32_t addr, uint32_t len, uint8_t *data){ +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){ +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); } @@ -320,7 +319,6 @@ int flash_ext_burst_write(flash_t *obj, uint32_t address ,uint32_t length, uint8 __flash_ext_turnon(); flashtype = flashobj.SpicInitPara.flashtype; - OccuSize = address & 0xFF; if((length >= PageSize) ||((length + OccuSize) >= PageSize)){ ProgramSize = PageSize - OccuSize; @@ -337,11 +335,12 @@ int flash_ext_burst_write(flash_t *obj, uint32_t address ,uint32_t length, uint8 // Wait flash busy done (wip=0) if(flashtype == FLASH_MICRON){ SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); - } else + } else { SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + } address += ProgramSize; - data+= ProgramSize; + data += ProgramSize; length -= ProgramSize; OccuSize = 0; } else{ @@ -352,11 +351,12 @@ int flash_ext_burst_write(flash_t *obj, uint32_t address ,uint32_t length, uint8 // Wait flash busy done (wip=0) if(flashtype == FLASH_MICRON){ SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); - } else + } else { SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + } address += PageSize; - data+=PageSize; + data += PageSize; length -= PageSize; } flashobj.Length = length; @@ -367,16 +367,15 @@ int flash_ext_burst_write(flash_t *obj, uint32_t address ,uint32_t length, uint8 // Wait flash busy done (wip=0) if(flashtype == FLASH_MICRON){ SpicWaitOperationDoneRtl8195A(flashobj.SpicInitPara); - } else + } else { SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); + } break; } } flashobj.Length = length; } - - __flash_ext_turnoff(); return 0; @@ -393,10 +392,8 @@ int flash_ext_burst_write(flash_t *obj, uint32_t address ,uint32_t length, uint8 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; } @@ -406,9 +403,7 @@ int flash_ext_get_status(flash_t *obj) uint8_t status = 0; __flash_ext_turnon(); - status = SpicGetFlashStatusRefinedRtl8195A(flashobj.SpicInitPara); - __flash_ext_turnoff(); return status; } @@ -427,11 +422,8 @@ The block protected area and the corresponding control bits are provided in the int flash_ext_set_status(flash_t *obj, uint32_t data) { __flash_ext_turnon(); - SpicSetFlashStatusRefinedRtl8195A(data, flashobj.SpicInitPara); SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); - DBG_8195A("Status Register After Setting= %x\n", flash_ext_get_status(&flashobj)); - __flash_ext_turnoff(); return 0; } @@ -443,10 +435,8 @@ This function aims to reset the status register, please make sure the operation void flash_ext_reset_status(flash_t *obj) { __flash_ext_turnon(); - SpicSetFlashStatusRefinedRtl8195A(0, flashobj.SpicInitPara); SpicWaitWipDoneRefinedRtl8195A(flashobj.SpicInitPara); - __flash_ext_turnoff(); } @@ -468,11 +458,8 @@ 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); - DBG_8195A("Extended Address Register After Setting= %x\n", flash_ext_get_extend_addr(&flashobj)); - __flash_ext_turnoff(); return 0; }