2018.9.14 本篇是关于SPI 访问 FLASH的
SPI 访问 FLASH的代码写完了很久一直没有去写这篇笔记,今天简单记录一下以免以后忘记。
我这里用到了 SPI的控制器 来进行数据的通信 然后观看FLASH的数据手册发现SPI对FLASH进行访问大致分这样一些步骤:
在读FLASH的情况下
如图所示是读的操作 command这个数组中0x03是读数据指令,后边三个字节的数据是表示读数据的地址即24位地址
读之前要
1、判断这个FLASH忙不忙 如果忙的话则一直等待着不忙。
2、然后进行才能进行读指令的操作。
/***********************************************************************************************************************************************************************************************************************************/
值得注意的是 我所用到的函数接口中有偏移量这一说,而当我们进行读取数据的时候,需要将偏移量设定为指令的长度,本例子中设定的长度为4个字节。
如果不设置准确的偏移量的话,读取出来的数据是不对的。
/***********************************************************************************************************************************************************************************************************************************/
在写操作的时候:
在进行写操作的时候,需要的步骤为
1、写使能
2、擦除数据(可以是扇区,可以是整个芯片)
3、判断状态寄存器忙不忙(忙则阻塞等待不忙)
4、然后写入指令 0x02是写指令,后边跟三个字节的地址,(在写操作的时候函数接口不需要偏移量)
/***********************************************************************************************************************************************************************************************************************************/
接下来贴出来的是完整代码
#include "A60_Upgrade_FPGA.h"
#include <sys/types.h>
#include <sys/socket.h>
typedef struct SpiData{
uint32_t nID;
uint8_t *outBuffer;
uint32_t nOutCount;
uint8_t *inBuffer;
uint32_t nInOffset;
uint32_t nInCount;
}SPI;
static int compare_flag = 0;
static pthread_mutex_t lock;
int Spi_Write_Flash(int fd,int Start_Addr,int End_Addr,int count,int SelectMode );
void Save_Upgreda_File(int sock_fd,int fd);
void Spi_Init_And_RDWR(struct SpiData *spi)
{
if(true != Pic32IoSpiWriteRead(spi->nID,spi->outBuffer,spi->nOutCount,spi->inBuffer,spi->nInOffset,spi->nInCount)){
printf("RDWR ERROR !!!\n");
}
}
/*********************************
功能:写使能
**********************************/
void Spi_Write_Enable()
{
SPI spi;
spi.nID = 0;
spi.nInOffset = 0;
uint8_t write_command[1] = {0x06};//写使能
spi.outBuffer = write_command;
spi.nOutCount = 1;
spi.inBuffer = NULL;
spi.nInCount = 0;
Spi_Init_And_RDWR(&spi);
}
/********************************
功能:擦除整个芯片数据
*********************************/
void Spi_Chip_Erase()
{
SPI spi;
spi.nID = 0;
spi.nInOffset = 0;
uint8_t buffer5[1] = {0x60};//擦除整个芯片
spi.outBuffer = buffer5;
spi.nOutCount = 1;
spi.inBuffer = NULL;
spi.nInCount = 0;
Spi_Init_And_RDWR(&spi);
}
/*******************************
功能:读取并设置状态寄存器2的QE位
用于使能四路输出
********************************/
void Spi_RDWR_Reg2()
{
SPI spi;
spi.nID = 0;
uint8_t read_reqister2[2] = {0x35};
spi.outBuffer = read_reqister2;
spi.nOutCount = 1;
spi.nInOffset = 1;
spi.inBuffer = &read_reqister2[1];
spi.nInCount = 1;
Spi_Init_And_RDWR(&spi);
uint8_t write_reqister2[2] = {0x31};
write_reqister2[1] = read_reqister2[1]|0x02;
spi.outBuffer = write_reqister2;
spi.nOutCount = 2;
spi.nInOffset = 0;
spi.inBuffer = NULL;
spi.nInCount = 0;
Spi_Init_And_RDWR(&spi);
}
/*******************************************
功能:读取状态寄存器1的S0位和S1位
参数:read_register1 发送读取指令
********************************************/
void Spi_RD_Reg1(uint8_t *read_register1)
{
SPI spi;
spi.nID = 0;
spi.outBuffer = read_register1;
spi.nOutCount = 1;
spi.nInOffset = 1;
spi.inBuffer = &read_register1[1];
spi.nInCount = 1;
Spi_Init_And_RDWR(&spi);
// printf("read reqister :%x\n",read_register1[1]);
}
/*******************************************
功能:写状态寄存器1
参数:read_register1 发送写入指令
*******************************************/
void Spi_Write_Reg1(uint8_t *read_register1)
{
SPI spi;
spi.nID = 0;
read_register1[0] = 0x01;
spi.outBuffer = read_register1;
spi.nOutCount = 2;
spi.nInOffset = 0;
// spi.outBuffer = &read_register1[1];
spi.inBuffer = NULL;
spi.nInCount = 0;
Spi_Init_And_RDWR(&spi);
// printf("read reqister :%x\n",read_register1[1]);
}
/***************************************
功能:用于设置读取和写入的偏移地址
参数:
buff 发送指令和接收读取缓存
addr 地址偏移
****************************************/
void Spi_Set_Addr(uint8_t *buff,int *addr)
{
buff[1] = ((*addr) >> 16)&0xff;
buff[2] = ((*addr) >> 8)&0xff;
buff[3] = (*addr)&0xff;
}
/*****************************************
功能:擦除一个扇区
参数:
Erase_Addr 擦除扇区地址
*******************************************/
void Spi_Sector_Erase(int Erase_Addr)
{
SPI spi;
spi.nID = 0;
spi.nInOffset = 0;
uint8_t buffer5[4] = {0x20};//擦除整个芯片
Spi_Set_Addr(buffer5,&Erase_Addr);
spi.outBuffer = buffer5;
spi.nOutCount = 4;
spi.inBuffer = NULL;
spi.nInCount = 0;
printf("buffer5 0x%x 0x%x 0x%x \n",buffer5[1],buffer5[2],buffer5[3]);
Spi_Init_And_RDWR(&spi);
}
/*************************************
功能:读取Flash中数据存入文件当中
参数:
fd 存储数据的文件
Start_Addr 开始读地址
End_Addr 结束读地址
read_flag 准许读标志位
**********************