/************************** Copyright (c) **********************************
|
** FUZHOU FUGUANG ELECTRONICS Co.,LTD.
|
** ¸£Öݸ£¹âµç×ÓÓÐÏÞ¹«Ë¾
|
** http://www.fuguang.com
|
**
|
**-------------- File Info -------------------------------------------------
|
** File name: SST25VF_Driver.c
|
** Last modified Date: 2008-11-16
|
** Last Version: 1.0
|
** Descriptions: SST25VF Drivers lib
|
**
|
**--------------------------------------------------------------------------
|
** Created by: mxpopstar
|
** Created date: 2008-11-16
|
** Version: 1.0
|
** Descriptions: The original version
|
**
|
**--------------------------------------------------------------------------
|
** Modified by: mxpopstar
|
** Modified date: 2008-11-20
|
** Version:
|
** Descriptions: SST25VF Drivers lib
|
**
|
***************************************************************************/
|
//
|
#include <avr/wdt.h>
|
#include "SST25VF_Driver.h"
|
#include "M64USART_Driver.h"
|
#include "USBModule_Driver.h"
|
#include "ProgressForm.h"
|
#include "TFT_Driver.h"
|
#include "CH376file_sys.h"
|
#include <string.h>
|
#include "STM32U.h"
|
#include "SAMD21U.h"
|
|
extern SYS_State GB_SYS_State;
|
|
|
void InitIO_SST25VF(void)
|
{
|
DDRG |= 1<<PG2;
|
DDRB |= 0x06; // SCK to AD7843
|
DDRB &= (~0x08); // MISO to AD7843
|
|
SST25VF_SPI_OFF; // Spi disable
|
SST25VF_SCK_0; // Spi clock line init high
|
_delay_ms(1);
|
}
|
//
|
|
|
//function SpiWrite();
|
/*******************************************************************************************/
|
void SpiWrite_SST25VF(const unsigned char byte)
|
{
|
unsigned char i;
|
for(i=0; i<8; i++) // Setup byte circulation bits
|
{
|
if(0x80 & (byte<<i)) // Put DATA_BUF.7 on data line
|
SST25VF_MOSI_1;
|
else
|
SST25VF_MOSI_0;
|
SST25VF_SCK_1; // Set clock line high
|
//_delay_us(20);
|
SST25VF_SCK_0; // Set clock line low
|
}
|
}
|
/*******************************************************************************************/
|
|
//function SpiRead();
|
/*******************************************************************************************/
|
unsigned char SpiRead_SST25VF(void)
|
{
|
unsigned char i;
|
unsigned char data = 0;
|
for(i=0; i<8; i++) // Setup byte circulation bits
|
{
|
SST25VF_SCK_1; // Set clock line high
|
//_delay_us(20);
|
if (SST25VF_MISO_1)
|
data += 1; // Read data
|
if(i<7)
|
data <<= 1;
|
SST25VF_SCK_0; // Set clock line low
|
}
|
return data; // Return function parameter
|
}
|
/*******************************************************************************************/
|
|
|
void Config_SST25VF(void)
|
{
|
WriteCMD_SST25VF(0x06); //Enable Write
|
WriteSR_SST25VF(0x40); //flash protect none
|
_delay_us(1);
|
}
|
//
|
|
void EraseChip_SST25VF(void)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x06);//EnableWrite
|
SST25VF_SPI_OFF;
|
|
_delay_us(1);
|
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x60);//CMD
|
SST25VF_SPI_OFF;
|
|
_delay_ms(60);//ÑÓʱ60ms,ʹÆä²Á³ýÕûƬִÐÐÍê±Ï
|
}
|
//
|
|
void Erase32K_SST25VF(const unsigned long addr)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x06);//EnableWrite
|
SST25VF_SPI_OFF;
|
|
_delay_us(1);
|
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x52);//CMD
|
SpiWrite_SST25VF((unsigned char)(addr>>16));
|
SpiWrite_SST25VF((unsigned char)(addr>>8));
|
SpiWrite_SST25VF((unsigned char)addr);
|
SST25VF_SPI_OFF;
|
|
_delay_ms(30);//ÑÓʱ30ms,ʹÆä²Á³ý32KÖ´ÐÐÍê±Ï
|
}
|
//
|
|
void Erase4K_SST25VF(const unsigned long addr)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x06);//EnableWrite
|
SST25VF_SPI_OFF;
|
|
_delay_us(1);
|
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x20);//CMD
|
SpiWrite_SST25VF((unsigned char)(addr>>16));
|
SpiWrite_SST25VF((unsigned char)(addr>>8));
|
SpiWrite_SST25VF((unsigned char)addr);
|
SST25VF_SPI_OFF;
|
|
_delay_ms(30);//ÑÓʱ30ms,ʹÆä²Á³ý4KÖ´ÐÐÍê±Ï
|
}
|
//
|
|
void WriteCMD_SST25VF(const unsigned char cmd)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(cmd);
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
}
|
//
|
|
void WriteSR_SST25VF(const unsigned char data)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x01);//cmd
|
SpiWrite_SST25VF(data);
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
}
|
//
|
|
unsigned char ReadSR_SST25VF(void)
|
{
|
unsigned char sr;
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x05);//CMD
|
sr = SpiRead_SST25VF();//data to read
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
return sr;
|
}
|
//
|
|
void ReadID_SST25VF(unsigned char *id)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x9f);//CMD
|
id[0] = SpiRead_SST25VF();
|
id[1] = SpiRead_SST25VF();
|
id[2] = SpiRead_SST25VF();
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
}
|
//
|
|
unsigned char ReadByte_SST25VF(const unsigned long addr)
|
{
|
unsigned char data;
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x03);//CMD
|
SpiWrite_SST25VF((unsigned char)(addr>>16));
|
SpiWrite_SST25VF((unsigned char)(addr>>8));//ADDR
|
SpiWrite_SST25VF((unsigned char)addr);
|
|
data = SpiRead_SST25VF();
|
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
return (data);
|
}
|
//
|
|
void ReadFileInf(const unsigned long addr, File_Inf *fileinf)
|
{
|
unsigned int len = sizeof(File_Inf);
|
char *pdata = (char *)fileinf;
|
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x03);//read CMD
|
SpiWrite_SST25VF((unsigned char)(addr>>16));
|
SpiWrite_SST25VF((unsigned char)(addr>>8));//ADDR
|
SpiWrite_SST25VF((unsigned char)addr);
|
|
while(len--)
|
{
|
*pdata++ = SpiRead_SST25VF();
|
}
|
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
}
|
//
|
//
|
unsigned char ReadBlock_SST25VF(const unsigned char tag, const unsigned char BlockSum, const unsigned char device)//Õû¸öº¯ÊýÓÉCH376°æ±¾Ìæ»»¶øÀ´¡£
|
{
|
unsigned long addr = 0;
|
unsigned long datalen = 0;
|
unsigned char deviceType;
|
|
//-------- ¹©½ø¶ÈÌõʹÓõıäÁ¿ --------------------
|
unsigned long ppos = 0;
|
unsigned long pposlen = 0;
|
unsigned char tmppos = 0,BlockSn=0;
|
|
|
//----- Êý¾ÝÎļþµÄ³¤¶È ---------------------------
|
datalen = SSTBlockSize*BlockSum;
|
pposlen = datalen;
|
|
//----- ÏÔʾ½ø¶ÈÌõ -------------------------------
|
if(device == usb_stm32U||device == usb_samd21U)
|
deviceType = 0;
|
else
|
deviceType = device;
|
DSPProgressBar(deviceType);
|
|
while((addr<SSTMemorySize) && (datalen>0))
|
{
|
unsigned char databuf[513] = {0};
|
|
unsigned char tmpdata = 0;
|
unsigned char fileseeken = 0;
|
// databuf[0] = 64; //дUÅÌÎļþµÄ×Ö½ÚÊý
|
|
//----------- ÈôÊÇ32k¿éµÄ¿ªÊ¼´¦ --------------
|
if((addr%SSTBlockSize) == 0) //ÕÒµ½32KµÄÊý¾Ý¿é
|
{
|
SST25VF_SCK_0;
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
tmpdata = ReadByte_SST25VF(addr);
|
|
if(tmpdata == tag)
|
{
|
ppos += 2; //½ø¶ÈÌõλÖÃÔö¼Ó
|
fileseeken = 1; //ÒÆ¶¯µØÖ·µÄ±êʶÖÃ1
|
}
|
else if(tmpdata != tag) //ûÕÒµ½32KµÄÊý¾Ý¿é
|
{
|
addr += SSTBlockSize; //ÉèÖõØÖ·Ö¸Õëµ½ÏÂÒ»¸ö32KÊý¾Ý¿é
|
fileseeken = 0; //ÒÆ¶¯µØÖ·µÄ±êʶÖÃ0
|
continue;
|
}
|
}
|
|
//----------- ÒÆ¶¯µØÖ·Ö¸Õëµ½ÕýÈ·µÄÊý¾Ý¿é ------------
|
if(fileseeken)
|
{
|
unsigned int dataCNT = 0;
|
|
datalen -= SSTBlockSize; //Òª¶ÁÈ¡µÄÊý¾ÝµÄ³¤¶È¼õ32768
|
|
fileseeken = 0; //ÒÆ¶¯µØÖ·µÄ±êʶÇåÁã
|
SST25VF_SCK_0;
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
_delay_us(1);
|
SpiWrite_SST25VF(0x03);//CMD_read
|
SpiWrite_SST25VF((unsigned char)((addr+2)>>16));
|
SpiWrite_SST25VF((unsigned char)((addr+2)>>8));//ADDR
|
SpiWrite_SST25VF((unsigned char)(addr+2));
|
addr += SSTBlockSize; //ÎļþÖ¸ÕëÏÈÒÆ¶¯µ½ÏÂÒ»¸ö¿é
|
|
//-------- ¶Á³öÒ»Õû¿éµÄÊý¾Ý(32768-2=32766×Ö½Ú) --------------
|
unsigned short OneBlockData = 0;
|
if(device == usb_stm32U||device == usb_samd21U)
|
OneBlockData = 512;
|
else
|
OneBlockData = 64;
|
|
while(dataCNT < (SSTBlockSize-2))//×ܹ²¶ÁÈ¡32766×Ö½Ú
|
{
|
unsigned short count = 0;
|
//---- ÿ´Î¶ÁÈ¡64×Ö½ÚµÄÊý¾Ý,·¢Ë͵½UÅÌ»òRS232 ----
|
while(count < OneBlockData)
|
{
|
if(dataCNT < (SSTBlockSize-2))
|
{
|
databuf[count] = SpiRead_SST25VF();//¶ÁÈ¡ÓÐЧÊý¾Ý
|
dataCNT++;
|
ppos++; //½ø¶ÈÌõλÖÃ
|
}
|
else
|
{
|
databuf[count] = 0xFF;
|
}
|
count++;
|
}
|
wdt_reset(); //ι¹·
|
//--------- ½«Êý¾Ý·¢Ë͵ĶÔÓ¦µÄÉ豸ÉÏ(UÅÌ»òRS232) ----------
|
if(device == comm_device)
|
SendSTR_M64USART0(databuf, 64);
|
else if(device == usb_device)
|
{
|
unsigned int DataCount = 0;
|
if(CH376ByteWrite(databuf, 64, &DataCount) != USB_INT_SUCCESS)
|
{
|
SST25VF_SPI_OFF;
|
return NO;
|
}
|
}
|
else if(device == usb_stm32U) //20160116
|
{ //20160116
|
|
if( pdFALSE == STM32U_writeFile(databuf, OneBlockData) )
|
{
|
SST25VF_SPI_OFF;
|
return NO;
|
}
|
|
}
|
else if(usb_samd21U == device)
|
{
|
if( pdFALSE == SAMD21U_writeFile(databuf, OneBlockData,BlockSn) )
|
{
|
SST25VF_SPI_OFF;
|
return NO;
|
}
|
BlockSn++;
|
}
|
//--------- ¸üнø¶ÈÌõλÖà -------------------------------
|
if((ppos)*16/pposlen > tmppos)
|
{
|
tmppos = ppos*16/pposlen;
|
UpdateProgessBar(tmppos);
|
}
|
}
|
}
|
}
|
|
SST25VF_SPI_OFF;
|
_delay_us(1);
|
return YES;
|
}
|
//-------------------------------------------------------------------
|
void WriteByte_SST25VF(const unsigned long addr, const unsigned char data)
|
{
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x06);//EnableWrite
|
SST25VF_SPI_OFF;
|
|
_delay_us(1);
|
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x02);//write CMD
|
SpiWrite_SST25VF((unsigned char)(addr>>16));
|
SpiWrite_SST25VF((unsigned char)(addr>>8));//ADDR
|
SpiWrite_SST25VF((unsigned char)addr);
|
SpiWrite_SST25VF(data);//data to write
|
SST25VF_SPI_OFF;
|
|
_delay_us(20);//ÑÓʱ20us,ʹÆä×Ö½ÚдִÐÐÍê±Ï;
|
|
}
|
//
|
|
//---------------- ¸ÃģʽÏÂÆðʼµØÖ·±ØÐëΪżÊý,·ñÔò½«³ö´í ---------------------
|
void WriteBlock_SST25VF(const unsigned long addr, volatile const void *data, const unsigned int count)
|
{
|
unsigned char *pdata = (unsigned char *)data;
|
unsigned int bytelen = count;
|
|
//---------------- EnableWrite ------------------
|
SST25VF_SPI_OFF;
|
SST25VF_SCK_0;
|
_delay_us(1);
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x06);
|
SST25VF_SPI_OFF;
|
|
_delay_us(1);
|
|
//--------------- first 2 bytes -----------------
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0xAD);//write AAI CMD
|
SpiWrite_SST25VF((unsigned char)(addr>>16));
|
SpiWrite_SST25VF((unsigned char)(addr>>8));
|
SpiWrite_SST25VF((unsigned char)addr);
|
SpiWrite_SST25VF(*pdata++);
|
SpiWrite_SST25VF(*pdata++);
|
bytelen -= 2;
|
SST25VF_SPI_OFF;
|
|
while(bytelen)
|
{
|
_delay_us(10);//ÑÓʱ10ÒÔ±£Ö¤Ð´²Ù×÷³É¹¦;
|
//----------------- other 2 bytes -----------
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0xAD);//write AAI CMD
|
SpiWrite_SST25VF(*pdata++);
|
bytelen--;
|
if(bytelen>0)
|
{
|
SpiWrite_SST25VF(*pdata++);
|
bytelen--;
|
}
|
SST25VF_SPI_OFF;
|
//-------------------------------------------
|
}
|
|
_delay_us(10);//ÑÓʱ10ÒÔ±£Ö¤Ð´²Ù×÷³É¹¦;
|
|
//-------------- exit AAIWrite mode -------------
|
SST25VF_SPI_ON;
|
SpiWrite_SST25VF(0x04);
|
SST25VF_SPI_OFF;
|
|
_delay_us(1);
|
}
|
//
|