-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New project for SPI communication with the logibone
- Loading branch information
Showing
4 changed files
with
278 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
CC = gcc | ||
|
||
|
||
all: test_wishbone | ||
|
||
clean: | ||
rm -f *.a *.o test_wishbone | ||
|
||
wishbone_wrapper.o: wishbone_wrapper.c | ||
$(CC) -c wishbone_wrapper.c | ||
|
||
test_wishbone : test_wishbone.c wishbone_wrapper.o | ||
$(CC) -o $@ test_wishbone.c wishbone_wrapper.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <sys/mman.h> | ||
#include <string.h> | ||
#include <fcntl.h> | ||
#include <errno.h> | ||
#include <sys/ioctl.h> | ||
#include "wishbone_wrapper.h" | ||
|
||
|
||
#define NB_VAL 1024 | ||
|
||
int main(int argc, char ** argv){ | ||
int address ; | ||
unsigned short i ; | ||
unsigned short writeVals [NB_VAL/2], readVals [NB_VAL/2] ; | ||
struct timeval temp1,temp2; | ||
long elapsed_u_sec,elapsed_s_sec,elapsed_m_time,elapsed_u_time; | ||
|
||
wishbone_init(); | ||
if(argc > 1){ | ||
unsigned long int speed = 0 ; | ||
speed = atof(argv[1])*1000000L ; | ||
set_speed(speed); | ||
} | ||
|
||
for(i=0; i < NB_VAL/2; i ++){ | ||
writeVals[i] = ~i ; | ||
} | ||
|
||
while(1){ | ||
gettimeofday(&temp1,NULL); | ||
if((i = wishbone_write(writeVals, NB_VAL, 0x0800)) < NB_VAL){ | ||
printf("Write error !, returned %d \n", i); | ||
} | ||
gettimeofday(&temp2,NULL); | ||
elapsed_s_sec=temp2.tv_sec-temp1.tv_sec; | ||
elapsed_u_sec=temp2.tv_usec-temp1.tv_usec; | ||
elapsed_u_time=(elapsed_s_sec)*100000+elapsed_u_sec; | ||
printf("Time in Microsecond=%ld \n",elapsed_u_time); | ||
printf("W Speed=====%d KB/Sec \n",(NB_VAL*1000)/elapsed_u_time ); | ||
|
||
gettimeofday(&temp1,NULL); | ||
if((i = wishbone_read(readVals, NB_VAL, 0x0800)) < NB_VAL){ | ||
printf("Read error !, returned %d \n", i); | ||
} | ||
gettimeofday(&temp2,NULL); | ||
elapsed_s_sec=temp2.tv_sec-temp1.tv_sec; | ||
elapsed_u_sec=temp2.tv_usec-temp1.tv_usec; | ||
elapsed_u_time=(elapsed_s_sec)*100000+elapsed_u_sec; | ||
printf("Time in Microsecond=%ld \n",elapsed_u_time); | ||
printf("R Speed=====%d KB/Sec \n",(NB_VAL*1000)/elapsed_u_time ); | ||
|
||
for(i=0; i < NB_VAL/2; i ++){ | ||
if(readVals[i] != writeVals[i]){ | ||
printf("Transfer failed [%u] = %04x \n", i, readVals[i]); | ||
} | ||
} | ||
sleep(1); | ||
} | ||
return 0 ; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
#include <unistd.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <sys/mman.h> | ||
#include <string.h> | ||
#include <fcntl.h> | ||
#include <errno.h> | ||
#include <sys/ioctl.h> | ||
#include <linux/types.h> | ||
#include <linux/spi/spidev.h> | ||
|
||
|
||
#define WR0(a, i) ((a >> 6) & 0x0FF) | ||
#define WR1(a, i) (((a << 2) & 0xFC) | (i << 1)) | ||
|
||
#define RD0(a, i) ((a >> 6) & 0x0FF) | ||
#define RD1(a, i) (((a << 2) & 0xFC) | 0x01 | (i << 1)) | ||
|
||
|
||
|
||
int fd ; | ||
unsigned int fifo_size ; | ||
static const char * device = "/dev/spidev1.0"; | ||
static unsigned int mode = 0 ; | ||
static unsigned int bits = 8 ; | ||
//unsigned long speed = 32000000UL ; | ||
unsigned long speed = 16000000UL ; | ||
static unsigned int delay = 0; | ||
|
||
static unsigned char com_buffer [4096] ; | ||
|
||
|
||
void spi_close(void) ; | ||
int spi_init(void) ; | ||
int spi_transfer(unsigned char * send_buffer, unsigned char * receive_buffer, unsigned int size); | ||
int logipi_write(unsigned int add, unsigned char * data, unsigned int size, unsigned char inc); | ||
int logipi_read(unsigned int add, unsigned char * data, unsigned int size, unsigned char inc); | ||
|
||
|
||
int set_speed(unsigned long speed_arg){ | ||
|
||
int ret ; | ||
if(fd == 0){ | ||
spi_init(); | ||
} | ||
speed = speed_arg ; | ||
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); | ||
if (ret == -1){ | ||
printf("can't set max speed hz \n"); | ||
return -1 ; | ||
} | ||
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); | ||
if (ret == -1){ | ||
printf("can't get max speed hz \n"); | ||
return -1 ; | ||
} | ||
|
||
return 0 ; | ||
} | ||
|
||
int spi_init(void){ | ||
int ret ; | ||
fd = open(device, O_RDWR); | ||
if (fd < 0){ | ||
printf("can't open device\n"); | ||
return -1 ; | ||
} | ||
|
||
ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); | ||
if (ret == -1){ | ||
printf("can't set spi mode \n"); | ||
return -1 ; | ||
} | ||
|
||
ret = ioctl(fd, SPI_IOC_RD_MODE, &mode); | ||
if (ret == -1){ | ||
printf("can't get spi mode \n "); | ||
return -1 ; | ||
} | ||
|
||
/* | ||
* bits per word | ||
*/ | ||
ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits); | ||
if (ret == -1){ | ||
printf("can't set bits per word \n"); | ||
return -1 ; | ||
} | ||
|
||
ret = ioctl(fd, SPI_IOC_RD_BITS_PER_WORD, &bits); | ||
if (ret == -1){ | ||
printf("can't get bits per word \n"); | ||
return -1 ; | ||
} | ||
|
||
/* | ||
* max speed hz | ||
*/ | ||
ret = ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed); | ||
if (ret == -1){ | ||
printf("can't set max speed hz \n"); | ||
return -1 ; | ||
} | ||
|
||
ret = ioctl(fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed); | ||
if (ret == -1){ | ||
printf("can't get max speed hz \n"); | ||
return -1 ; | ||
} | ||
|
||
return 1; | ||
} | ||
|
||
|
||
int spi_transfer(unsigned char * send_buffer, unsigned char * receive_buffer, unsigned int size) | ||
{ | ||
int ret ; | ||
struct spi_ioc_transfer tr = { | ||
.tx_buf = (unsigned long)send_buffer, | ||
.rx_buf = (unsigned long)receive_buffer, | ||
.len = size, | ||
.delay_usecs = delay, | ||
.speed_hz = speed, | ||
.bits_per_word = bits, | ||
}; | ||
|
||
ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); | ||
if (ret < 1){ | ||
printf("can't send spi message \n"); | ||
return -1 ; | ||
} | ||
return 0; | ||
} | ||
|
||
int logipi_write(unsigned int add, unsigned char * data, unsigned int size, unsigned char inc){ | ||
com_buffer[0] = WR0(add, inc) ; | ||
com_buffer[1] = WR1(add, inc) ; | ||
memcpy(&com_buffer[2], data, size); | ||
return spi_transfer(com_buffer, com_buffer , (size + 2)); | ||
} | ||
|
||
|
||
int logipi_read(unsigned int add, unsigned char * data, unsigned int size, unsigned char inc){ | ||
int ret ; | ||
com_buffer[0] = RD0(add, inc) ; | ||
com_buffer[1] = RD1(add, inc) ; | ||
ret = spi_transfer(com_buffer, com_buffer , (size + 2)); | ||
memcpy(data, &com_buffer[2], size); | ||
return ret ; | ||
} | ||
|
||
|
||
void spi_close(void){ | ||
close(fd); | ||
} | ||
|
||
|
||
int wishbone_init(void){ | ||
if(fd == 0){ | ||
spi_init(); | ||
} | ||
return 0 ; | ||
} | ||
|
||
unsigned int wishbone_write(unsigned char * buffer, unsigned int length, unsigned int address){ | ||
unsigned int tr_size = 0, count = 0 ; | ||
if(fd == 0){ | ||
spi_init(); | ||
} | ||
while(count < length){ | ||
tr_size = (length-count) < 4094 ? (length-count) : 4094 ; | ||
if(logipi_write(((address+count)), &buffer[count], tr_size, 1) < 0) return 0; | ||
count = count + tr_size ; | ||
} | ||
|
||
return count ; | ||
} | ||
unsigned int wishbone_read(unsigned char * buffer, unsigned int length, unsigned int address){ | ||
unsigned int tr_size = 0, count = 0 ; | ||
if(fd == 0){ | ||
spi_init(); | ||
} | ||
while(count < length){ | ||
tr_size = (length-count) < 4094 ? (length-count) : 4094 ; | ||
if(logipi_read(((address+count)), &buffer[count], tr_size, 1) < 0) return 0 ; | ||
count = count + tr_size ; | ||
} | ||
return count ; | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
|
||
|
||
|
||
int wishbone_init(void); | ||
int set_speed(unsigned long speed_arg); | ||
unsigned int wishbone_write(unsigned char * buffer, unsigned int length, unsigned int address); | ||
unsigned int wishbone_read(unsigned char * buffer, unsigned int length, unsigned int address); |