mirror of
https://github.com/ghsecuritylab/ameba_ws2812b.git
synced 2025-02-19 18:45:19 +00:00
321 lines
8.3 KiB
C
321 lines
8.3 KiB
C
/* mbed Microcontroller Library
|
|
*******************************************************************************
|
|
* Copyright (c) 2014, Realtek Semiconductor Corp.
|
|
* All rights reserved.
|
|
*
|
|
* This module is a confidential and proprietary property of RealTek and
|
|
* possession or use of this module requires written permission of RealTek.
|
|
*******************************************************************************
|
|
*/
|
|
|
|
|
|
#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;
|
|
|
|
/**
|
|
* global data structure
|
|
*/
|
|
flash_t flash;
|
|
|
|
static void flash_init(flash_t *obj);
|
|
|
|
/**
|
|
* @brief lock flash access
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void flash_lock()
|
|
{
|
|
|
|
HAL_WRITE32(0xE000ED00, 0x9C, 0x9807E012);
|
|
HAL_WRITE32(0xE000ED00, 0xA0, 0x06000017);
|
|
}
|
|
|
|
/**
|
|
* @brief unlock flash access
|
|
* @param none
|
|
* @retval none
|
|
*/
|
|
void flash_unlock()
|
|
{
|
|
HAL_WRITE32(0xE000ED00, 0x9C, 0x9807E012);
|
|
HAL_WRITE32(0xE000ED00, 0xA0, 0x03000017);
|
|
}
|
|
|
|
/**
|
|
* @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_init(obj);
|
|
SpicWriteProtectFlashRtl8195A(protect);
|
|
SpicDisableRtl8195A();
|
|
}
|
|
|
|
/**
|
|
* @brief Init Flash
|
|
* @param obj: address of the flash object
|
|
* @retval none
|
|
*/
|
|
static 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(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 {
|
|
// DBG_8195A("SPI Init SUCCESS\n");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @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_init(obj);
|
|
SpicSectorEraseFlashRtl8195A(SPI_FLASH_BASE + address);
|
|
SpicDisableRtl8195A();
|
|
}
|
|
|
|
/**
|
|
* @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)
|
|
{
|
|
|
|
// Check address
|
|
|
|
// Read Word
|
|
flash_init(obj);
|
|
|
|
// Wait flash busy done (wip=0)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->SpicInitPara);
|
|
|
|
* data = HAL_READ32(SPI_FLASH_BASE, address);
|
|
SpicDisableRtl8195A();
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* @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)
|
|
{
|
|
// Disable write protection
|
|
// flash_unlock();
|
|
flash_init(obj);
|
|
|
|
//Write word
|
|
HAL_WRITE32(SPI_FLASH_BASE, address, data);
|
|
|
|
// Wait spic busy done
|
|
SpicWaitBusyDoneRtl8195A();
|
|
|
|
// Wait flash busy done (wip=0)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->SpicInitPara);
|
|
|
|
SpicDisableRtl8195A();
|
|
// Enable write protection
|
|
// flash_lock();
|
|
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_stream_read(flash_t *obj, uint32_t address, uint32_t len, uint8_t * data)
|
|
{
|
|
u32 offset_to_align;
|
|
u32 i;
|
|
u32 read_word;
|
|
uint8_t *ptr;
|
|
uint8_t *pbuf;
|
|
|
|
flash_init(obj);
|
|
|
|
// Wait flash busy done (wip=0)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->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;
|
|
}
|
|
|
|
/**
|
|
* @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;
|
|
u32 align_addr;
|
|
u32 i;
|
|
u32 write_word;
|
|
uint8_t *ptr;
|
|
uint8_t *pbuf;
|
|
|
|
flash_init(obj);
|
|
|
|
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)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->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)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->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)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->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)
|
|
SpicWaitWipDoneRefinedRtl8195A(obj->SpicInitPara);
|
|
}
|
|
|
|
SpicDisableRtl8195A();
|
|
return 1;
|
|
}
|
|
|