📄 spistatus.c
字号:
/*
$Workfile: spiStatus.c $
$Revision: 1.4 $
$Date: Aug 23 2006 22:57:16 $
*/
//******************************************************************
//
// Copyright (C) 2004. GENESIS MICROCHIP INC.
// All rights reserved. No part of this program may be reproduced.
//
// Genesis Microchip Inc., 165 Commerce Valley Dr. West
// Thornhill, Ontario, Canada, L3T 7V8
// Genesis Microchip Corp., 2150 Gold Street
// Alviso, CA 95002 USA
//
//================================================================
//
// MODULE: spistatus.c
//
// USAGE : This module contains a function for AppsTest to read SPI flash
// register status, protect or unprotect SPI flash and status register.
// The code of ReadWriteFlashStatusRegister has to be run in RAM. For
// PMC and SST serial flash, the meaning of status register indicated as follow:
// Flash Status Register:
// BIT7: --- 1, enable hardware WP#; 0, disable WP#;
// BIT3, BIT2: --- BP1, BP0; 1, indicate memory block protected.
// when status register is 0x8C, flash and register is protected, NO data can be written to flash;
// when status register is 0x00, flash and register is NOT protected;
//******************************************************************
#include <embedded.h>
#include <mem.h>
#include "inc\all.h"
#include "system\Mcu186.h"
#if NVRAM_USE_FLASH
#define DEBUG_SPI 1
#define CODE_IN_DCOMPBUF 1
#if DEBUG_SPI && DEBUG_MSG
#define msg(a,b) gm_Print((const char far *)a,b)
#else
#define msg(a,b)
#endif
//read/write flash status register mode
#define REG_READ_MODE 0x00
#define REG_PROTECT_MODE 0x01
#define REG_UNPROTECT_MODE 0x02
//Following are only available for new PMC flash with 4-1K sectors in sector0
#define REG_CONFIG_READ_MODE 0x03
#define REG_CONFIG_PROTECT_MODE 0x04
#define REG_CONFIG_UNPROTECT_MODE 0x05
//flash type related macro
#define PM39F010 1 // PARALLEL FLASH
#define PM39F020 2 // PARALLEL FLASH
#define SPI_FLASH 3 // SPI FLASH
#define PROMJET_PARALLEL 4 // PROMJET PARALLEL FLASH
#define PROMJET_SPI 5 // PROMJET SPI FLASH
#define SST25VF010_ID 0x01
#define PM25LV010_ID 0x02
#define ST0000000_ID 0x04
#define AT45DB011_ID 0x08 // SPI FLASH ATMEL AT45DB011 or AT45DB041
#define SIZE_128K 0x10
#define SIZE_256K 0x20
#define SIZE_512K 0x40
//command related macro
#define FLASH_TIMEOUT 100 // 100ms.
#define CMD_ENABLE_WRITE_SR 0x50 // enable writing to the status register (command)
#define CMD_WRITE_TO_SR 0x01 // status register
#define CMD_READ_SR 0x05 // Read STATUS REGISTER command
#define CMD_CLEAR_BPX 0 // Clear BPx bit in status register
#define CMD_SET_BPX 0x8C // Set BPx bits (BP1, BP0 and BPL) in status register
//Following are only available for new PMC flash with 4-1K sectors in sector0
#define CMD_READ_RDCR 0xA1 //read configuration register
#define CMD_WRITE_WRCR 0xF1 //write to configuration register
#define CMD_Set_SCFG 0x01 //set SCFG bit
#define CMD_Clear_SCFG 0x00 //clear SCFG bit
#define CMD_Set_Spn(a) ((a)<<1) //set n-1K sector to be locked/protected
#define CMD_WRITE_ENABLE 0x06 // WREN command
#define CMD_AUTO_ADDR_INC 0xAF // AAI command
#define CMD_SECTOR_ERASE 0x20 // Sector Erase command
#define CMD_WRITE_DISABLE 0x04 // WRDI command
#define CHIP_STATUS_BUSY BIT0 // BUSY bit
#define CHIP_STATUS_WEL BIT1 // Device is memory Write enabled/disabled
#define CHIP_STATUS_BP0 BIT2 // Indicate current level of block write protection
#define CHIP_STATUS_BP1 BIT3 // Indicate current level of block write protection
#define CHIP_STATUS_RES1 BIT4 // Reserved
#define CHIP_STATUS_RES2 BIT5 // Reserved
#define CHIP_STATUS_AAI BIT6 // Auto Address Increment Programming status
#define CHIP_STATUs_BPL BIT7 // =1 - BP0, BP1 are read-only bits, =0 - BP0, BP1 are read/writable
#define CMD_WRITE_BLOCK 0x00
#define CMD_ERASE_BLOCK 0x01
#define ERROR_TIMEOUT 0x01
#define CODE_IN_RAM_ADDR 0x1800
extern BYTE DecompBuf[768];
extern BYTE B_FlashChipID;
void far SpiFlashReadWriteStatusRegister(BYTE mode, BYTE B_data);
BYTE far ReadWriteFlashStatusRegister(BYTE mode, BYTE B_data);
void DummyReadFlashStatusRegister();
//static functions
static __near void SPI_WriteByte(BYTE B_Value);
static __near BYTE SPI_ReadByte(void);
static __near BYTE ReadStatusReg(BYTE B_CtrlPBCS, BYTE B_CtrlPB);
static __near BYTE ReadConfigStatusReg(BYTE B_CtrlPBCS, BYTE B_CtrlPB);
static __near BYTE Wait_Busy(BYTE B_CtrlPBCS, BYTE B_CtrlPB);
static __near BYTE timeoutCheck(WORD *timeout);
#define SPI_BUSY BIT2
#define WAIT_EX_DONE() while((gm_ReadRegByte(SPI_STATUS ) & SPI_EXCH_ACTIVE) != 0)
#define ENABLE_INT() asm{ STI } // Enable all interrupts
//***************************************************************
// FUNCTION : void SpiFlashReadWriteStatusRegister(BYTE B_mode)
// USAGE :
// DESCRIPTION : This procedure outputs lash status register value
// INPUT : BYTE B_mode - byte for write to the register
// OUTPUT : current flash status register value
//***************************************************************
void far SpiFlashReadWriteStatusRegister(BYTE B_mode, BYTE B_data)
{
BYTE far (*func)(BYTE v, BYTE n);
BYTE status=0x55;
WORD Csize ;
WORD F1_OFF;
WORD F2_OFF;
BYTE regBypass, regGpioDir, regGPO;
//validate mode first
if(B_mode>REG_CONFIG_UNPROTECT_MODE || (B_mode>REG_UNPROTECT_MODE && B_FlashChipID!=PM25LV010_ID))
{
msg("Invalid mode!", 0);
return;
}
//intialize gpio setting
regBypass = gm_ReadRegByte(BYPASS);
regGpioDir = gm_ReadRegByte(GPIO_DIRCTRL1);
regGPO = gm_ReadRegByte(GPOUTPUT1);
#ifdef PHOENIX
#ifdef TCON_LB_BYPASS
//gm_WriteRegByte(BYPASS, (TCON_LB_BYPASS | TCON_SIGNALS_OFF));
gm_WriteRegByte(BYPASS, 0);//TL060725 modified
#else
//gm_WriteRegByte(BYPASS, TCON_SIGNALS_OFF);//TL060725 marked
gm_WriteRegByte(BYPASS, 0);//TL060725 modified
#endif
#endif
gm_WriteRegByte(GPIO_DIRCTRL1, GPIO6_IO);
// copy routine into RAM, use DecompBuf.
F1_OFF = FP_OFF(ReadWriteFlashStatusRegister) ;
F2_OFF = FP_OFF(DummyReadFlashStatusRegister) ;
Csize = F2_OFF - F1_OFF ;
#if CODE_IN_DCOMPBUF
_fmemcpy((void far *)&DecompBuf[0], (void far *)ReadWriteFlashStatusRegister, Csize);
func = ((BYTE far(*)(BYTE, BYTE)) &DecompBuf[0]);
#else
_fmemcpy((void far *)CODE_IN_RAM_ADDR, (void far *)ReadWriteFlashStatusRegister, Csize);
func = ((BYTE far(*)(BYTE, BYTE)) CODE_IN_RAM_ADDR);
#endif
gm_DisableInterrupts();
//to toggle gpio for testing
gm_SetRegBitsByte(GPOUTPUT1, GPIO6_IO);
status = func(B_mode, B_data);
gm_ClearRegBitsByte(GPOUTPUT1, GPIO6_IO);
ENABLE_INT();
//restore gpio setting
#ifdef PHOENIX
gm_WriteRegByte(BYPASS, regBypass);
#endif
gm_WriteRegByte(GPIO_DIRCTRL1, regGpioDir);
gm_WriteRegByte(GPOUTPUT1, regGPO);
//output
// msg("CodeSize: 0x%x", Csize);
msg("Flash status register: 0x%x", (WORD)status);
}
#pragma codeseg CUSTOM_CODE1
//***************************************************************
// FUNCTION : void ReadWriteFlashStatusRegister(BYTE B_mode, BYTE B_data)
// USAGE :
// DESCRIPTION : This procedure outputs a byte
// INPUT : BYTE B_mode - byte for write to the register
// OUTPUT : BYTE: value of flash status register
//***************************************************************
BYTE far ReadWriteFlashStatusRegister(BYTE B_mode, BYTE B_data)
{
BYTE v;
BYTE cmd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -