spi.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /* @brief This is a simple application for testing SPI communication on a RedPitaya
  2. * @Author Luka Golinar <luka.golinar@redpitaya.com>
  3. *
  4. * (c) Red Pitaya http://www.redpitaya.com
  5. *
  6. * This part of code is written in C programming language.
  7. * Please visit http://en.wikipedia.org/wiki/C_(programming_language)
  8. * for more details on the language used herein.
  9. */
  10. #include <stdio.h>
  11. #include <stdint.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <fcntl.h>
  15. #include <sys/ioctl.h>
  16. #include <errno.h>
  17. #include <string.h>
  18. #include <linux/spi/spidev.h>
  19. #include <linux/types.h>
  20. /* Inline functions definition */
  21. static int init_spi();
  22. static int release_spi();
  23. static int read_flash_id(int fd);
  24. static int write_spi(char *write_data, int size);
  25. /* Constants definition */
  26. int spi_fd = -1;
  27. int main(void){
  28. /* Sample data */
  29. char *data = "REDPITAYA SPI TEST";
  30. /* Init the spi resources */
  31. if(init_spi() < 0){
  32. printf("Initialization of SPI failed. Error: %s\n", strerror(errno));
  33. return -1;
  34. }
  35. /* Write some sample data */
  36. if(write_spi(data, strlen(data)) < 0){
  37. printf("Write to SPI failed. Error: %s\n", strerror(errno));
  38. return -1;
  39. }
  40. /* Read flash ID and some sample loopback data */
  41. if(read_flash_id(spi_fd) < 0){
  42. printf("Error reading from SPI bus : %s\n", strerror(errno));
  43. return -1;
  44. }
  45. /* Release resources */
  46. if(release_spi() < 0){
  47. printf("Relase of SPI resources failed, Error: %s\n", strerror(errno));
  48. return -1;
  49. }
  50. return 0;
  51. }
  52. static int init_spi(){
  53. /* MODES: mode |= SPI_LOOP;
  54. * mode |= SPI_CPHA;
  55. * mode |= SPI_CPOL;
  56. * mode |= SPI_LSB_FIRST;
  57. * mode |= SPI_CS_HIGH;
  58. * mode |= SPI_3WIRE;
  59. * mode |= SPI_NO_CS;
  60. * mode |= SPI_READY;
  61. *
  62. * multiple possibilities possible using | */
  63. int mode = 0;
  64. /* Opening file stream */
  65. spi_fd = open("/dev/spidev1.0", O_RDWR | O_NOCTTY);
  66. if(spi_fd < 0){
  67. printf("Error opening spidev0.1. Error: %s\n", strerror(errno));
  68. return -1;
  69. }
  70. /* Setting mode (CPHA, CPOL) */
  71. if(ioctl(spi_fd, SPI_IOC_WR_MODE, &mode) < 0){
  72. printf("Error setting SPI_IOC_RD_MODE. Error: %s\n", strerror(errno));
  73. return -1;
  74. }
  75. /* Setting SPI bus speed */
  76. int spi_speed = 1000000;
  77. if(ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed) < 0){
  78. printf("Error setting SPI_IOC_WR_MAX_SPEED_HZ. Error: %s\n", strerror(errno));
  79. return -1;
  80. }
  81. return 0;
  82. }
  83. static int release_spi(){
  84. /* Release the spi resources */
  85. close(spi_fd);
  86. return 0;
  87. }
  88. /* Read data from the SPI bus */
  89. static int read_flash_id(int fd){
  90. int size = 2;
  91. /*struct spi_ioc_transfer {
  92. __u64 tx_buf;
  93. __u64 rx_buf;
  94. __u32 len;
  95. __u32 speed_hz;
  96. __u16 delay_usecs;
  97. __u8 bits_per_word;
  98. __u8 cs_change;
  99. __u32 pad;
  100. }*/
  101. /* If the contents of 'struct spi_ioc_transfer' ever change
  102. * incompatibly, then the ioctl number (currently 0) must change;
  103. * ioctls with constant size fields get a bit more in the way of
  104. * error checking than ones (like this) where that field varies.
  105. *
  106. * NOTE: struct layout is the same in 64bit and 32bit userspace.*/
  107. struct spi_ioc_transfer xfer[size];
  108. unsigned char buf0[1];
  109. unsigned char buf1[3];
  110. int status;
  111. memset(xfer, 0, sizeof xfer);
  112. /* RDID command */
  113. buf0[0] = 0x9f;
  114. /* Some sample data */
  115. buf1[0] = 0x01;
  116. buf1[1] = 0x23;
  117. buf1[2] = 0x45;
  118. /* RDID buffer */
  119. xfer[0].tx_buf = (__u64)((__u32)buf0);
  120. xfer[0].rx_buf = (__u64)((__u32)buf0);
  121. xfer[0].len = 1;
  122. /* Sample loopback buffer */
  123. xfer[1].tx_buf = (__u64)((__u32)buf1);
  124. xfer[1].rx_buf = (__u64)((__u32)buf1);
  125. xfer[1].len = 3;
  126. /* ioctl function arguments
  127. * arg[0] - file descriptor
  128. * arg[1] - message number
  129. * arg[2] - spi_ioc_transfer structure
  130. */
  131. status = ioctl(fd, SPI_IOC_MESSAGE(2), xfer);
  132. if (status < 0) {
  133. perror("SPI_IOC_MESSAGE");
  134. return -1;
  135. }
  136. /* Print read buffer */
  137. for(int i = 0; i < 3; i++){
  138. printf("Buffer: %d\n", buf1[i]);
  139. }
  140. return 0;
  141. }
  142. /* Write data to the SPI bus */
  143. static int write_spi(char *write_buffer, int size){
  144. int write_spi = write(spi_fd, write_buffer, strlen(write_buffer));
  145. if(write_spi < 0){
  146. printf("Failed to write to SPI. Error: %s\n", strerror(errno));
  147. return -1;
  148. }
  149. return 0;
  150. }