提交SMOD ATSC IMX APP版本 V122

This commit is contained in:
2026-07-16 14:35:59 +08:00
commit 7601c270d5
485 changed files with 255032 additions and 0 deletions
+407
View File
@@ -0,0 +1,407 @@
#include <string.h>
#include "type.h"
//#include "stm32f4xx_spi.h"
//#include "stm32f4xx_gpio.h"
//#include "stm32f4xx_hal.h"
#include "stm32f4xx_spi.h"
#include "stm32f4xx_gpio.h"
#include "config.h"
#include "os_task.h"
#include "delay.h"
#include "flash.h"
#include "sys_config.h"
#if USE_SPI_FLASH
#define SST25_SECTOR_PER_SIZE (4096) //一个扇区为4kB
#define SST25_TOTAL_SIZE (4*1024*1024*2/8) //总大小为4Mb 512*2KB 128个扇区
#define SST25_TOTAL_SECTOR_NUM (SST25_TOTAL_SIZE/SST25_SECTOR_PER_SIZE)
#define FLASH_SPI SPI1
#define SST25_SELECT() do{GPIO_ResetBits(GPIOA,GPIO_Pin_4);}while(0)
#define SST25_DESELECT() do{GPIO_SetBits(GPIOA,GPIO_Pin_4);}while(0)
#define SST25_READDATA 0x03
#define SST25_FASTREADDATA 0x0B
#define SST25_4KBYTE_BLOCKERASE 0x20
#define SST25_32KBYTE_BLOCKERASE 0x52
#define SST25_64KBYTE_BLOCKERASE 0xD8
#define SST25_CHIPERASE 0xC7
#define SST25_BYTEPORGRAM 0x02
#define SST25_AAI_WORDPROGRAM 0xAD
#define SST25_READSTATUSREG 0x05
#define SST25_ENABLEWRITESTATUSREG 0x50
#define SST25_WRITESTATUSREG 0x01
#define SST25_WRITEENABLE 0x06
#define SST25_WRITEDISABLE 0x04
#define SST25_DEVICEID 0x90
#define SST25_JEDECDEVICEID 0x9F
#define SST25_EBSY 0x70
#define SST25_DBSY 0x80
//extern SPI_HandleTypeDef hspi1;
static uint8 spi1_read_byte(void)
{
while (SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(FLASH_SPI,0xff);
while (SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
return (SPI_I2S_ReceiveData(FLASH_SPI));
}
static void spi1_write_byte(uint8 byte)
{
while (SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_TXE) == RESET);
SPI_I2S_SendData(FLASH_SPI, byte);
while (SPI_I2S_GetFlagStatus(FLASH_SPI, SPI_I2S_FLAG_RXNE) == RESET);
(void)SPI_I2S_ReceiveData(FLASH_SPI);
}
/******************************************
写一个命令
******************************************/
void sst25_write_cmd(uint8 cmd)
{
SST25_SELECT();
spi1_write_byte(cmd);
SST25_DESELECT();
}
/******************************************
写一个命令一个数据
******************************************/
void sst25_write_cmd_data(uint8 cmd,uint8 data)
{
SST25_SELECT();
spi1_write_byte(cmd);
spi1_write_byte(data);
SST25_DESELECT();
}
/******************************************
写一个命令三个数据
******************************************/
void sst25_write_cmd_data3(uint8 cmd, uint8* data)
{
SST25_SELECT();
spi1_write_byte(cmd);
spi1_write_byte(*data++);
spi1_write_byte(*data++);
spi1_write_byte(*data);
SST25_DESELECT();
}
/******************************************
写一个命令返回一个数据
******************************************/
uint8 sst25_read_data(uint8 cmd)
{
uint8 temp;
SST25_SELECT();
spi1_write_byte(cmd);
temp = spi1_read_byte();
SST25_DESELECT();
return temp;
}
/******************************************
写一个命令,三个地址 返回多个数据
******************************************/
void sst25_read_datas(uint8 cmd,uint8 *addr,uint8 *data,uint32 no)
{
uint16 i;
SST25_SELECT();
spi1_write_byte(cmd);
spi1_write_byte(*addr++);
spi1_write_byte(*addr++);
spi1_write_byte(*addr);
for(i=0;i<no;i++)
{
data[i] = spi1_read_byte();
}
SST25_DESELECT();
}
/******************************************
SST25读取状态寄存器
******************************************/
uint8 sst25_readsr(void)
{
uint8 sr;
sr = sst25_read_data(SST25_READSTATUSREG);
return sr;
}
/******************************************
SST25写状态寄存器
******************************************/
void sst25_writesr(uint8 cmd)
{
sst25_write_cmd(SST25_ENABLEWRITESTATUSREG);
sst25_write_cmd_data(SST25_WRITESTATUSREG,cmd);
}
/******************************************
SST25写使能
******************************************/
void sst25_wren(void)
{
sst25_write_cmd(SST25_WRITEENABLE);
}
/******************************************
SST25写失能
******************************************/
void sst25_wrdi(void)
{
sst25_write_cmd(SST25_WRITEDISABLE);
}
/******************************************
SST25忙检测
1 忙
******************************************/
void sst25_wait_busy(void)
{
while(sst25_readsr()&0x01);
}
/******************************************
SST25允许软件写保护
******************************************/
void sst25_wpen(void)
{
uint8 sta;
sta = sst25_read_data(SST25_READSTATUSREG)|0x1c;
sst25_write_cmd(SST25_ENABLEWRITESTATUSREG);
sst25_write_cmd_data(0x01,sta);
}
/******************************************
SST25先取消保护位,再允许写
******************************************/
void sst25_writeen(void)
{
uint8 sta;
sta = sst25_read_data(SST25_READSTATUSREG)&(~0x0c);
sst25_write_cmd(SST25_ENABLEWRITESTATUSREG);
sst25_write_cmd(0xff);
sst25_write_cmd_data(SST25_WRITESTATUSREG,sta);
sst25_write_cmd(SST25_WRITEENABLE);
}
/******************************************
SST25 读芯片ID
******************************************/
uint16 sst25_readid(void)
{
uint8 id[3]= {0,};
uint8 addr[3] = {0,0,0};
sst25_read_datas(SST25_DEVICEID,addr,id,2);
return ((id[0]<<8)+id[1]);
}
/******************************************
SST25 擦除整块flash
******************************************/
void sst25_chip_erase(void)
{
sst25_writesr(0x02);
sst25_wren();
sst25_write_cmd(SST25_CHIPERASE);
sst25_wait_busy();
}
/******************************************
SST25 擦除扇区
******************************************/
void sst25_sector_erase(uint32 addr)
{
uint8 ad[3]={0,};
ad[0] = ((addr>>16)&0xff);
ad[1] = ((addr>>8)&0xff);
ad[2] = (addr&0xff);
sst25_writesr(0x02);
sst25_wren();
SST25_SELECT();
spi1_write_byte(SST25_4KBYTE_BLOCKERASE);
spi1_write_byte(ad[0]);
spi1_write_byte(ad[1]);
spi1_write_byte(ad[2]);
SST25_DESELECT();
sst25_wait_busy();
}
/******************************************
SST25 写入一个字节
******************************************/
void sst25_byte_write(uint32 addr,uint8 byte)
{
sst25_writesr(0x02);
sst25_wren();
SST25_SELECT();
spi1_write_byte(SST25_BYTEPORGRAM);
spi1_write_byte((addr>>16)&0xff);
spi1_write_byte((addr>>8)&0xff);
spi1_write_byte(addr&0xff);
spi1_write_byte(byte);
SST25_DESELECT();
sst25_wait_busy();
}
/******************************************
SST25 写入多个字节
******************************************/
void sst25_datas_write(uint32 addr,uint8 *buf,uint32 no)
{
uint32 cnt;
if(no == 0)
return;
sst25_writesr(0x02);
sst25_wren();
if(no == 1)
{
sst25_byte_write(addr,*buf);
}
else
{
cnt = no;
SST25_SELECT();
spi1_write_byte(SST25_AAI_WORDPROGRAM);
spi1_write_byte((addr>>16)&0xff);
spi1_write_byte((addr>>8)&0xff);
spi1_write_byte(addr&0xff);
spi1_write_byte(*buf++);
spi1_write_byte(*buf++);
SST25_DESELECT();
cnt-=2;
sst25_wait_busy();
for(;cnt>1;cnt-=2)
{
SST25_SELECT();
spi1_write_byte(SST25_AAI_WORDPROGRAM);
spi1_write_byte(*buf++);
spi1_write_byte(*buf++);
SST25_DESELECT();
sst25_wait_busy();
}
sst25_wrdi();
if(cnt == 1)
{
sst25_wren();
sst25_byte_write(addr+no-1,*buf);
}
}
sst25_wpen();
}
/******************************************
SST25 高速读
******************************************/
void sst25_readh(uint32 addr,uint8 *buf,uint32 no)
{
uint16 i;
SST25_SELECT();
spi1_write_byte(SST25_FASTREADDATA);
spi1_write_byte((uint8)(addr>>16)&0xff);
spi1_write_byte((uint8)(addr>>8)&0xff);
spi1_write_byte((uint8)addr&0xff);
spi1_write_byte(0xff);
for(i=0;i<no;i++)
{
buf[i] = spi1_read_byte();
}
SST25_DESELECT();
}
/******************************************
SST25 低速读
******************************************/
void sst25_readl(uint32 addr,uint8 *buf,uint32 no)
{
uint8 ad[3];
ad[0] = (addr>>16)&0xff;
ad[1] = (addr>>8)&0xff;
ad[2] = addr&0xff;
sst25_read_datas(SST25_READDATA,ad,buf,no);
}
void flash_write_byte(uint8 byte,uint32 addr)
{
uint32 secpos;
secpos = addr/SST25_SECTOR_PER_SIZE;
if(secpos>=SST25_TOTAL_SECTOR_NUM)
return;
sst25_sector_erase(secpos);
sst25_byte_write(addr,byte);
}
void flash_write_buf(uint8 *buf,uint32 num,uint32 addr)
{
uint32 secpos;
secpos = addr/SST25_SECTOR_PER_SIZE;
if(secpos >= SST25_TOTAL_SECTOR_NUM)
return;
if(addr+num>SST25_TOTAL_SIZE)
num = SST25_TOTAL_SIZE - addr;
sst25_datas_write(addr, buf, num);
}
void flash_erase_sector(uint32 start_address,uint32 num)
{
uint32 secpos,secoff,secremain;
uint16 secnum=0;
int32 i = 0;
secpos = start_address/SST25_SECTOR_PER_SIZE;
if(secpos >= SST25_TOTAL_SECTOR_NUM)
return;
if(start_address+num>SST25_TOTAL_SIZE)
num = SST25_TOTAL_SIZE - start_address;
secoff = start_address%SST25_SECTOR_PER_SIZE;
secremain = SST25_SECTOR_PER_SIZE-secoff;
if(num < secremain)
{
secnum = 1;
}
else
{
secnum = 1;
i = num -secremain;
do
{
secnum++;
i = i - SST25_SECTOR_PER_SIZE;
}while(i>0);
}
for(i=0;i<secnum;i++)
{
sst25_sector_erase((secpos+i)*SST25_SECTOR_PER_SIZE);
}
}
void flash_read_buf(uint8 *buf,uint32 len,uint32 addr)
{
if(addr >= SST25_TOTAL_SIZE)
return;
sst25_readl(addr,buf,len);
}
#endif