我在Beaglebone Black上写了一个C程序来读写25LC256(EEPROM)。我可以编译它而没有任何错误或警告gcc SPI.c -o SPI
,但是当我尝试运行它./SPI
时,我的整个Beaglebone都停止工作,我必须重新启动它。事实上,该程序甚至不输出任何东西。我打印出代码"开始"在乞讨,但这甚至不起作用。
有人能看到我可能出错的地方吗?
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/spi/spidev.h>
#include <stdint.h>
//You need to correctly identify the SPI device bus and number
int write64NVM(int fd, unsigned char data[], int length, unsigned int add);
int read64NVM(int fd, unsigned char to[], int length, unsigned int add);
static const char *device = "/dev/spidev1.0";
int main(){
uint8_t mode=0, bits=8;
uint32_t speed=500000;
int file;
printf("Starting");
if ((file = open(device, O_RDWR))<0){
perror("SPI: Can't open device.");
return -1;
}
if (ioctl(file, SPI_IOC_WR_MODE, &mode)==-1){
perror("SPI: Can't set SPI mode.");
return -1;
}
if (ioctl(file, SPI_IOC_RD_MODE, &mode)==-1){
perror("SPI: Can't get SPI mode.");
return -1;
}
if (ioctl(file, SPI_IOC_WR_BITS_PER_WORD, &bits)==-1){
perror("SPI: Can't set bits per word.");
return -1;
}
if (ioctl(file, SPI_IOC_RD_BITS_PER_WORD, &bits)==-1){
perror("SPI: Can't get bits per word.");
return -1;
}
if(ioctl(file, SPI_IOC_WR_MAX_SPEED_HZ, &speed)==-1){
perror("SPI: Can't set max speed HZ");
return -1;
}
if (ioctl(file, SPI_IOC_RD_MAX_SPEED_HZ, &speed)==-1){
perror("SPI: Can't get max speed HZ.");
return -1;
}
printf("spi mode: 0x%xn", mode);
printf("bits per word: %dn", bits);
printf("max speed: %d Hz (%d KHz)n", speed, speed/1000);
// sending one byte on the MOSI line and receiving the data on MISO
write64NVM(file, "hello", 6, 0);
close(file);
return 0;
}
int write64NVM(int fd, unsigned char data[], int length, unsigned int add)
{
unsigned char InstructionBuffer[1], AddressBuffer[3];
int status;
//DataBuffer = (char *) malloc(length);
struct spi_ioc_transfer xfer[3];
InstructionBuffer[0] = 6; //Set the write enable latch (enable write operations)
AddressBuffer[0] = 2; //Write data to memory array beginning at selected address
AddressBuffer[1] = (add >> 8);
AddressBuffer[2] = (add & 0b11111111);
//DataBuffer = data;
//First Transaction
xfer[0].tx_buf = (unsigned long)InstructionBuffer;
xfer[0].rx_buf = (unsigned long)NULL;
xfer[0].len = 1;
xfer[0].cs_change = 1;
//Second transaction
xfer[1].tx_buf = (unsigned long)AddressBuffer;
xfer[1].rx_buf = (unsigned long)NULL;
xfer[1].len = 3;
xfer[1].cs_change = 0;
//Third transaction
xfer[2].tx_buf = (unsigned long)data;
xfer[2].rx_buf = (unsigned long)NULL;
xfer[2].len = length;
xfer[2].cs_change = 1;
status = ioctl(fd, SPI_IOC_MESSAGE(3), &xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE error");
return;
}
return status;
}
int read64NVM(int fd, unsigned char to[], int length, unsigned int add){
//Read Sequence :
//Pull ~CS low
//The 8-bit instruction is transmited to EEPROM followed
//by 16-bit address, with first MSB of the address being a 'dont care'
//bit.
//According to Page 7 Figure 2-1 of the 25LC256.pdf, to read an address from
//EEPROM, the BBB must only send out 2 transactions. The instruction and the address.
//In this case, the instruction is read, so the value of transaction is 3.
//~CS apears to be kept low throughout the entire transaction until data
//has completely been shifted out of EEPROM.
//Like in write64NVM, there are 3 buffers
//unsigned char InstructionBuffer, AddressBuffer[3], DataBuffer[8],
//but the latter will be used to store the Data recieved.
unsigned char InstructionBuffer, AddressBuffer[2], *DataBuffer;
int status;
//DataBuffer = (char *) malloc(length);
struct spi_ioc_transfer xfer[3];
InstructionBuffer = 3; //Read intruction value
//AddressBuffer[0] = 2;
AddressBuffer[0] = add >> 8;
AddressBuffer[1] = add & 0b11111111;
DataBuffer = 0;
//First Transaction
xfer[0].tx_buf = (unsigned long)&InstructionBuffer;
xfer[0].rx_buf = (unsigned long)NULL;
xfer[0].len = 1;
xfer[0].cs_change = 1;
//Second transaction
xfer[1].tx_buf = (unsigned long)AddressBuffer;
xfer[1].rx_buf = (unsigned long)NULL;
xfer[1].len = 2;
xfer[1].cs_change = 0;
//Third transaction
xfer[2].tx_buf = (unsigned long)NULL;
xfer[2].rx_buf = (unsigned long)to;
xfer[2].len = length;
xfer[2].cs_change = 1;
status = ioctl(fd, SPI_IOC_MESSAGE(3), &xfer);
if (status < 0)
{
perror("SPI_IOC_MESSAGE error");
return;
}
return status;
}
请原谅我糟糕的编码,我还是个初学者。