/*
* (C) Copyright 2012 - 2014
*
* Written by: henry.he <shell428@google.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include "type_def.h"
#include "timer.h"
#include "hsfi_drv_phy.h"
#include "hsf_drv_common.h"
#include "hsf_dev_config.h"
#include "hsf_drv_interface.h"
#ifdef __cplusplus
extern "C"
{
#endif
static void HSF_SoftReset(void);
static bool_t HSF_PgmErs_Suspend(HSF_DEVICE_INFO_T *hsf_dev_ptr);
static bool_t HSF_PgmErs_Resume(HSF_DEVICE_INFO_T *hsf_dev_ptr);
static HSF_WIP_STATUS_E HSF_WIP_Get(HSF_DEVICE_INFO_T *hsf_dev_ptr);
extern void disable_global_interrupt(void);
extern void enable_global_interrupt(void);
extern bool_t soc_int_status_get(void);
#define HSF_DISABLE_INT disable_global_interrupt()
#define HSF_ENABLE_INT enable_global_interrupt()
#define HSF_DELAY_US(x) device_us_delay(x)
#define HSF_INT_DETECT soc_int_status_get()
#define HSF_SendCmd_Trig(cmd) HSFI_SendCmd_Prepare(cmd); \
HSFI_Trig_and_Wait()
void HSFI_Trig_and_Wait(void)
{
HSFI_SoftTrig();
if (HSFI_BusyWaiting() == FALSE)
{
HSF_SoftReset();
DRV_PASSERT(0, ("%s time out, line: %d", __func__, __LINE__));
}
}
void HSF_WIP_Waiting(HSF_DEVICE_INFO_T *hsf_dev_ptr, u32 max_us_delay, bool_t int_respond_enable)
{
bool_t ret;
u32 res2sus_delay;
u32 already_us_delay = 0;
u32 min_us_delay = 1;
u8 pgm_ers_resume_flag = 0;
HSF_DEVICE_INFO_T *sf = hsf_dev_ptr;
res2sus_delay = sf->hsf_timing->tRES2SUS;
while(HSF_WIP_Get(sf) == HSF_BUSY_STATUS)
{
HSF_DELAY_US(min_us_delay);
already_us_delay += min_us_delay;
if (already_us_delay >= max_us_delay)
{
HSF_ReadMode_Resume(sf);
DRV_PASSERT(0, ("%s time out, line: %d", __func__, __LINE__));
}
if(int_respond_enable)
{
if (HSF_INT_DETECT)
{
if (pgm_ers_resume_flag == 1)
{
HSF_DELAY_US(sf->hsf_timing->tRES2SUS);
already_us_delay += res2sus_delay;
if (already_us_delay >= max_us_delay)
{
HSF_ReadMode_Resume(sf);
DRV_PASSERT(0, ("%s time out, line: %d", __func__, __LINE__));
}
}
HSF_PgmErs_Suspend(sf);
HSF_ENABLE_INT;
{
int i;
for(i = 0; i < 10; i++);
}
HSF_DISABLE_INT;
HSF_PgmErs_Resume(sf);
pgm_ers_resume_flag = 1;
}
}
}
}
static void HSF_SoftReset(void)
{
u8 cmd;
cmd = HSF_CMD_RSTEN;
HSFI_SendCmd_Prepare(cmd);
HSFI_SoftTrig();
if (HSFI_BusyWaiting() == FALSE)
{
DRV_PASSERT(0, ("%s time out, line: %d", __func__, __LINE__));
}
cmd = HSF_CMD_RST;
HSFI_SendCmd_Prepare(cmd);
HSFI_SoftTrig();
if (HSFI_BusyWaiting() == FALSE)
{
DRV_PASSERT(0, ("%s time out, line: %d", __func__, __LINE__));
}
HSF_DELAY_US(50);
return;
}
void HSF_Module_Reset(void)
{
HSFI_SoftReset();
HSF_SoftReset();
}
void HSF_FlashReg_Read(u8 cmd, u8 *reg_rd, u32 reg_len)
{
HSFI_SF_RegRead_Prepare(cmd, reg_len);
HSFI_Trig_and_Wait();
HSFI_ReceiveData(reg_rd, reg_len);
return;
}
u32 HSF_StatusReg_Read(HSF_DEVICE_INFO_T *hsf_dev_ptr)
{
u8 sts_reg_l = 0;
u8 sts_reg_h = 0;
u16 sts_reg = 0;
u8 cmd = hsf_dev_ptr->hsf_cmd.cmd_sts_reg_rd;
HSF_FlashReg_Read(cmd, &sts_reg_l, sizeof(sts_reg_l));
hsf_dev_ptr->hsf_sts_reg.sts_reg_val[0] = sts_reg_l;
cmd = hsf_dev_ptr->hsf_cmd.cmd_sts_reg_2_rd;
if (cmd != HSF_INVALIDE_CMD)
{
HSF_FlashReg_Read(cmd, &sts_reg_h, sizeof(sts_reg_h));
hsf_dev_ptr->hsf_sts_reg.sts_reg_val[1] = sts_reg_h;
}
sts_reg = (sts_reg_h << 8) | sts_reg_l;
return (u32)sts_reg;
}
bool_t HSF_StatusReg_Write(HSF_DEVICE_INFO_T *hsf_dev_ptr, u32 reg_val)
{
bool_t ret = TRUE;
u8 cmd;
u16 sts_reg;
u32 reg_rd;
u32 max_us_delay;
HSF_DEVICE_INFO_T *sf = hsf_dev_ptr;
u32 WEL_bit = sf->hsf_sts_reg.WEL;
cmd = sf->hsf_cmd.cmd_sts_reg_wr;
max_us_delay = sf->hsf_timing->tW;
ret = HSF_WriteEnable(sf, NULL);
if(!ret)
{
HSF_DEBUG_LOG("ERR! write enable failed! %s %d", __func__, __LINE__);
return ret;
}
sts_reg = (u16)(WEL_bit | reg_val);
HSFI_SF_RegWrite_Prepare(cmd, &sts_reg, sizeof(sts_reg));
HSFI_Trig_and_Wait();
HSF_WIP_Waiting(sf, max_us_delay, FALSE);
reg_rd = HSF_StatusReg_Read(sf);
ret = (reg_rd == reg_val) ? TRUE : FALSE;
return ret;
}
u8 HSF_StatusRegByte1_Read(HSF_DEVICE_INFO_T *hsf_dev_ptr)
{
u8 sts_reg = 0;
u8 cmd = hsf_dev_ptr->hsf_cmd.cmd_sts_reg_rd;
HSF_FlashReg_Read(cmd, &sts_reg, sizeof(sts_reg));
hsf_dev_ptr->hsf_sts_reg.sts_reg_val[0] = sts_reg;
return (u32)sts_reg;
}
u8 HSF_StatusRegByte2_Read(HSF_DEVICE_INFO_T *hsf_dev_ptr)
{
u8 sts_reg = 0;
u8 cmd = hsf_dev_ptr->hsf_cmd.cmd_sts_reg_2_rd;
HSF_FlashReg_Read(cmd, &sts_reg, sizeof(sts_reg));
hsf_dev_ptr->hsf_sts_reg.sts_reg_val[1] = sts_reg;
return (u32)sts_reg;
}
static HSF_WIP_STATUS_E HSF_WIP_Get(HSF_DEVICE_INFO_T *hsf_dev_ptr)
{
u32 reg_rd;
HSF_WIP_STATUS_E hsf_wip_sts;
HSF_DEVICE_INFO_T *sf = hsf_dev_ptr;
u32 WIP_bit = sf->hsf_sts_reg.WIP;
reg_rd = HSF_StatusReg_Read(sf);
if ((reg_rd & WIP_bit) == 0)
hsf_wip_sts = HSF_IDLE_STATUS;
else
hsf_wip_sts = HSF_BUSY_STATUS;
return hsf_wip_sts;
}
bool_t HSF_WriteEnable(HSF_DEVICE_INFO_T *hsf_dev_ptr, u32 *sr_reg_get)
{
bool_t ret = FALSE;
u8 cmd;
u32 reg_rd = 0;
HSF_DEVICE_INFO_T *sf = hsf_dev_ptr;
u32 min_us_delay = 10;
u32 max_us_delay = 2000;
u32 already_us_delay = 0;
u32 WEL_bit = sf->hsf_sts_reg.WEL;
cmd = sf->hsf_cmd.cmd_wr_enable;
do{
HSF_SendCmd_Trig(cmd);
reg_rd = HSF_StatusReg_Read(sf);
if (sr_reg_get != NULL)
{
*sr_reg_get = reg_rd;
}
HSF_DELAY_US(min_us_delay);
already_us_delay += min_us_delay;
if (already_us_delay >= max_us_delay)
{
HSF_SoftReset();
ret= FALSE;
break;
}
ret = TRUE;
}while((WEL_bit & reg_rd) == 0);
return ret;
}
static bool_t HSF_WriteDisable(HSF_DEVICE_INFO_T *hsf_dev_ptr)
{
bool_t ret = FALSE;
u8 cmd;
u32 reg_rd;
HSF_DEVICE_INFO_T *sf = hsf_dev_ptr;
u32 WEL_bit = sf->hsf_sts_reg.WEL;
cmd = sf->hsf_cmd.cmd_wr_disable;
reg_rd = HSF_StatusReg_Read(sf);
if ((WEL_bit & reg_rd) == 0)
return TRUE;
HSF_SendCmd
spiflash 驱动代码
3星 · 超过75%的资源 需积分: 19 72 浏览量
2013-06-16
14:54:47
上传
评论 1
收藏 40KB ZIP 举报
东方传说科创教培
- 粉丝: 3
- 资源: 8
最新资源
- 基于Matlab人脸肤色定理的教师人数统计+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab霍夫曼变换的表盘读数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab火灾烟雾检测源码带GUI界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的恶劣天气交通标志识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的霍夫曼变换的表盘示数识别+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab的车道线识别系统 +源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的教室人数统计系统带Gui界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB的教室人数统计系统带Gui界面+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于MATLAB 的霍夫曼变换答题卡识别源码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
- 基于Matlab+bp神经网络的神经网络汉字识别系统+源代码+全部数据+文档说明+详细注释+使用说明+截图(高分课程设计)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈