i2c.c 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /* @brief This is a simple application for testing IIC 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 <fcntl.h>
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <linux/ioctl.h>
  14. #include <sys/ioctl.h>
  15. #include <linux/i2c-dev.h>
  16. #include <string.h>
  17. #include <unistd.h>
  18. #include <errno.h>
  19. #include <stdint.h>
  20. #define I2C_SLAVE_FORCE 0x0706
  21. #define I2C_SLAVE 0x0703 /* Change slave address */
  22. #define I2C_FUNCS 0x0705 /* Get the adapter functionality */
  23. #define I2C_RDWR 0x0707 /* Combined R/W transfer (one stop only)*/
  24. #define EEPROM_ADDR 0x50
  25. /*
  26. * Page size of the EEPROM. This depends on the type of the EEPROM available
  27. * on board.
  28. */
  29. #define PAGESIZE 32
  30. /* eeprom size on a redpitaya */
  31. #define EEPROMSIZE 64*1024/8
  32. /* Inline functions definition */
  33. static int iic_read(char *buffer, int offset, int size);
  34. static int iic_write(char *data, int offset, int size);
  35. /*
  36. * File descriptors
  37. */
  38. int fd;
  39. int main(int argc, char *argv[])
  40. {
  41. int status;
  42. /* Read buffer to hold the data */
  43. char *buffer = (char *)malloc(EEPROMSIZE * sizeof(char));
  44. char data[] = "THIS IS A TEST MESSAGE FOR THE I2C PROTOCOL COMMUNICATION WITH A EEPROM. IT WAS WRITTEN FOR A REDPITAYA MEASURMENT TOOL.";
  45. size_t size = strlen(data);
  46. /* Sample offset inside an eeprom */
  47. int offset = 0x100;
  48. /*
  49. * Open the device.
  50. */
  51. fd = open("/dev/i2c-0", O_RDWR);
  52. if(fd < 0)
  53. {
  54. printf("Cannot open the IIC device\n");
  55. return 1;
  56. }
  57. status = ioctl(fd, I2C_SLAVE_FORCE, EEPROM_ADDR);
  58. if(status < 0)
  59. {
  60. printf("Unable to set the EEPROM address\n");
  61. return -1;
  62. }
  63. /* Write to redpitaya eeprom */
  64. status = iic_write((char *)data, offset, size);
  65. if(status){
  66. fprintf(stderr, "Cannot Write to EEPROM\n");
  67. close(fd);
  68. return -1;
  69. }
  70. /* Read from redpitaya eeprom */
  71. status = iic_read(buffer, EEPROM_ADDR, EEPROMSIZE);
  72. if (status)
  73. {
  74. printf("Cannot Read from EEPROM \n");
  75. close(fd);
  76. return 1;
  77. }
  78. printf("eerprom test successfull.\n");
  79. /* Release allocations */
  80. close(fd);
  81. free(buffer);
  82. return 0;
  83. }
  84. /* Read the data from the EEPROM.
  85. *
  86. * @param read buffer -- input buffer for data storage
  87. * @param off set -- eeprom memory space offset
  88. * @param size -- size of read data
  89. * @return iicRead status
  90. *
  91. * @note None. */
  92. static int iic_read(char *buffer, int offset, int size)
  93. {
  94. ssize_t bytes_written;
  95. ssize_t bytes_read;
  96. uint8_t write_buffer[2];
  97. /*
  98. * Load the offset address inside EEPROM where data need to be written.
  99. * Supported for BigEndian and LittleEndian CPU's
  100. */
  101. write_buffer[0] = (uint8_t)(offset >> 8);
  102. write_buffer[1] = (uint8_t)(offset);
  103. /* Write the bytes onto the bus */
  104. bytes_written = write(fd, write_buffer, 2);
  105. if(bytes_written < 0){
  106. fprintf(stderr, "EEPROM write address error.\n");
  107. return -1;
  108. }
  109. /*
  110. * Read the bytes.
  111. */
  112. printf ("Performing Read operation.\n");
  113. /* Read bytes from the bus */
  114. bytes_read = read(fd, buffer, size);
  115. if(bytes_read < 0){
  116. fprintf(stderr, "EEPROM read error.\n");
  117. return -1;
  118. }
  119. printf("Read EEPROM Succesful\n");
  120. return 0;
  121. }
  122. static int iic_write(char *data, int offset, int size){
  123. /* variable declaration */
  124. int bytes_written;
  125. int write_bytes;
  126. int index;
  127. /* Check for limits */
  128. if(size > PAGESIZE){
  129. write_bytes = PAGESIZE;
  130. }else{
  131. write_bytes = size;
  132. }
  133. /* Number of needed loops to send all the data.
  134. * Limit data size per transmission is PAGESIZE */
  135. int loop = 0;
  136. while(size > 0){
  137. /* buffer size is PAGESIZE per transmission */
  138. uint8_t write_buffer[32 + 2];
  139. /*
  140. * Load the offset address inside EEPROM where data need to be written.
  141. * Supported for BigEndian and LittleEndian CPU's
  142. */
  143. write_buffer[0] = (uint8_t)(offset >> 8);
  144. write_buffer[1] = (uint8_t)(offset);
  145. for(index = 0; index < PAGESIZE; index++){
  146. write_buffer[index + 2] = data[index + (PAGESIZE * loop)];
  147. }
  148. /* Write the bytes onto the bus */
  149. bytes_written = write(fd, write_buffer, write_bytes + 2);
  150. /* Wait till the EEPROM internally completes the write cycle */
  151. sleep(2);
  152. if(bytes_written != write_bytes+2){
  153. fprintf(stderr, "Failed to write to EEPROM\n");
  154. return -1;
  155. }
  156. /* written bytes minus the offset addres of two */
  157. size -= bytes_written - 2;
  158. /* Increment offset */
  159. offset += PAGESIZE;
  160. /* Check for limits for the new message */
  161. if(size > PAGESIZE){
  162. write_bytes = PAGESIZE;
  163. }else{
  164. write_bytes = size;
  165. }
  166. loop++;
  167. }
  168. printf("\nWrite EEPROM Succesful\n");
  169. return 0;
  170. }