|
发表于 2017-6-20 11:32:37
只看该作者
6#
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
/*
* write a file to spi_flash
*/
#define W25_WRITE_ENABLE 0x06
#define W25_WRITE_DISABLE 0x04
#define W25_READ_STATUS_1 0x05
#define W25_READ_STATUS_2 0x35
#define W25_WRITE_STATUS 0x01
#define W25_READ_DATA 0x03
#define W25_ERASE_SECTOR 0x20
#define W25_ERASE_BLOCK 0xD8
#define W25_PAGE_PROGRAM 0x02
#define W25_CHIP_ID 0x9F
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static const char* spi_device = "/dev/spidev2.2";
static unsigned char mode;
static unsigned char bits = 8;
static unsigned int speed = 1000000;
/*
* 打印出buf的内容
* @parm info 前面的提示信息
*/
static void dis_array(const char* info , const unsigned char* buf, unsigned int len){
int i = 0;
printf("%s :",info);
for(i = 0; i< len ; i++){
printf("%02x " , buf[i]);
}
printf("\n");
}
/*
* write and read
*/
static int w25_write_read(int fd , const char* wbuf,unsigned int wlen,
const char* rbuf , unsigned int rlen){
int ret = 0;
struct spi_ioc_transfer tr[2] = {
{
.tx_buf = (unsigned long)wbuf,
.rx_buf = 0,
.len = wlen,
.speed_hz = speed,
},
{
.tx_buf = 0,
.rx_buf = (unsigned long)rbuf,
.len = rlen,
.speed_hz = speed,
},
};
ret = ioctl(fd , SPI_IOC_MESSAGE(2) , tr);
return ret;
}
/*
* write no read
*/
static int w25_write(int fd , const char* wbuf,unsigned int wlen){
int ret = 0;
struct spi_ioc_transfer tr[1] = {
{
.tx_buf = (unsigned long)wbuf,
.rx_buf = 0,
.len = wlen,
.speed_hz = speed,
}
};
ret = ioctl(fd , SPI_IOC_MESSAGE(1) , tr);
return ret;
}
int main(int argc , char* argv[]){
int ret = 0;
int fd;
unsigned char tempcmd = 0;
unsigned char cmd[8] = {0};
unsigned char buf[8] = {0};
fd = open(spi_device , O_RDWR);
if (fd < 0){
printf("open /dev/spidev error\n ");
}
/*
* spi mode
*/
ret = ioctl(fd , SPI_IOC_WR_MODE , &mode);
if (ret == -1){
printf("set spi mode error\n");
}
ret = ioctl(fd , SPI_IOC_RD_MODE , &mode);
if (ret == -1){
printf("get spi mode error\n");
}
/*
* bits per word
*/
ret = ioctl(fd , SPI_IOC_WR_BITS_PER_WORD , &bits);
if (ret == -1){
printf("set bits per word error\n");
}
ret = ioctl(fd , SPI_IOC_RD_BITS_PER_WORD , &bits);
if (ret == -1){
printf("get bits per word error\n");
}
/*
* max speed hz
*/
ret = ioctl(fd , SPI_IOC_WR_MAX_SPEED_HZ , &speed);
if (ret == -1){
printf("set max speed error\n");
}
ret = ioctl(fd , SPI_IOC_RD_MAX_SPEED_HZ , &speed);
if (ret == -1){
printf("get max speed error\n");
}
/*
* print useful info
*/
printf("spi mode: %d\n",mode);
printf("spi bits per words : %d \n" , bits);
printf("spi max speed : %dhz (%dkHz)\n",speed , speed/1000);
//get chip id
tempcmd = W25_CHIP_ID;
ret = w25_write_read(fd, &tempcmd , sizeof(tempcmd ), buf , 3 );
printf("w25_flash chip ID : %x , %x , %x\n" , buf[0] , buf[1] , buf[2] );
//erase first sector
tempcmd = W25_WRITE_ENABLE;
w25_write( fd, &tempcmd , 1 );
cmd[0] = W25_ERASE_SECTOR;
cmd[1] = 0;
cmd[2] = 0;
cmd[3] = 0;
ret = w25_write(fd, cmd , 4);
printf("frist sector erase done ..\n");
//read data
cmd[0] = W25_READ_DATA;
cmd[1] = 0;
cmd[2] = 0;
cmd[3] = 0;
ret = w25_write_read(fd, cmd , 4 , buf , sizeof(buf));
dis_array("before write: ", buf , sizeof(buf));
//write
w25_write( fd, &tempcmd , 1 );
cmd[0] = W25_PAGE_PROGRAM;
cmd[1] = 0;
cmd[2] = 0;
cmd[3] = 0;
cmd[4] = 0x88;
ret = w25_write( fd, cmd , 5);
printf("0x88 write ok \n");
//read data
cmd[0] = W25_READ_DATA;
cmd[1] = 0;
cmd[2] = 0;
cmd[3] = 0;
ret = w25_write_read(fd, cmd , 4 , buf , sizeof(buf));
dis_array("after write: ", buf , sizeof(buf));
close(fd);
return ret;
}
|
|