spidriver.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. #include <stdio.h>
  2. #include <assert.h>
  3. #include <memory.h>
  4. #include <fcntl.h>
  5. #include <termios.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8. #define __STDC_FORMAT_MACROS
  9. #include <inttypes.h>
  10. #include "spidriver.h"
  11. // **************************** Serial port ********************************
  12. int openSerialPort(const char *portname)
  13. {
  14. int fd = open(portname, O_RDWR | O_NOCTTY);
  15. if (fd == -1)
  16. perror(portname);
  17. struct termios Settings;
  18. tcgetattr(fd, &Settings);
  19. cfsetispeed(&Settings, B460800);
  20. cfsetospeed(&Settings, B460800);
  21. Settings.c_cflag &= ~PARENB;
  22. Settings.c_cflag &= ~CSTOPB;
  23. Settings.c_cflag &= ~CSIZE;
  24. Settings.c_cflag &= ~CRTSCTS;
  25. Settings.c_cflag |= CS8;
  26. Settings.c_cflag |= CREAD | CLOCAL;
  27. Settings.c_iflag &= ~(IXON | IXOFF | IXANY);
  28. Settings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
  29. Settings.c_oflag &= ~OPOST;
  30. Settings.c_cc[VMIN] = 1;
  31. if (tcsetattr(fd, TCSANOW, &Settings) != 0)
  32. perror("Serial settings");
  33. return fd;
  34. }
  35. size_t readFromSerialPort(int fd, char *b, size_t s)
  36. {
  37. size_t n, t;
  38. t = 0;
  39. while (t < s) {
  40. n = read(fd, b + t, s);
  41. t += n;
  42. }
  43. #ifdef VERBOSE
  44. printf(" READ %d %d: ", (int)s, int(n));
  45. for (int i = 0; i < s; i++)
  46. printf("%02x ", 0xff & b[i]);
  47. printf("\n");
  48. #endif
  49. return s;
  50. }
  51. void writeToSerialPort(int fd, const char *b, size_t s)
  52. {
  53. write(fd, b, s);
  54. #ifdef VERBOSE
  55. printf("WRITE %u: ", (int)s);
  56. for (int i = 0; i < s; i++)
  57. printf("%02x ", 0xff & b[i]);
  58. printf("\n");
  59. #endif
  60. }
  61. // ****************************** SPIDriver *********************************
  62. void spi_connect(SPIDriver *sd, const char* portname)
  63. {
  64. sd->port = openSerialPort(portname);
  65. writeToSerialPort(sd->port, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", 64);
  66. for (int i = 0; i < 256; i++) {
  67. char tx[2] = {'e', (char)i};
  68. writeToSerialPort(sd->port, tx, 2);
  69. char rx[1];
  70. readFromSerialPort(sd->port, rx, 1);
  71. if ((rx[0] & 0xff) != i)
  72. assert(0);
  73. }
  74. printf("\n");
  75. spi_getstatus(sd);
  76. }
  77. void spi_getstatus(SPIDriver *sd)
  78. {
  79. char readbuffer[100];
  80. int bytesRead;
  81. writeToSerialPort(sd->port, "?", 1);
  82. bytesRead = readFromSerialPort(sd->port, readbuffer, 80);
  83. readbuffer[bytesRead] = 0;
  84. // printf("%d Bytes were read: %.*s\n", bytesRead, bytesRead, readbuffer);
  85. sscanf(readbuffer, "[%15s %8s %" SCNu64 " %f %f %f %d %d %d %x ]",
  86. sd->model,
  87. sd->serial,
  88. &sd->uptime,
  89. &sd->voltage_v,
  90. &sd->current_ma,
  91. &sd->temp_celsius,
  92. &sd->a,
  93. &sd->b,
  94. &sd->cs,
  95. &sd->debug
  96. );
  97. }
  98. void spi_sel(SPIDriver *sd)
  99. {
  100. writeToSerialPort(sd->port, "s", 1);
  101. sd->cs = 0;
  102. }
  103. void spi_unsel(SPIDriver *sd)
  104. {
  105. writeToSerialPort(sd->port, "u", 1);
  106. sd->cs = 1;
  107. }
  108. void spi_seta(SPIDriver *sd, char v)
  109. {
  110. char cmd[2] = {'a', v};
  111. writeToSerialPort(sd->port, cmd, 2);
  112. sd->a = v;
  113. }
  114. void spi_setb(SPIDriver *sd, char v)
  115. {
  116. char cmd[2] = {'b', v};
  117. writeToSerialPort(sd->port, cmd, 2);
  118. sd->b = v;
  119. }
  120. void spi_write(SPIDriver *sd, const char bytes[], size_t nn)
  121. {
  122. for (size_t i = 0; i < nn; i += 64) {
  123. size_t len = ((nn - i) < 64) ? (nn - i) : 64;
  124. char cmd[65] = {(char)(0xc0 + len - 1)};
  125. memcpy(cmd + 1, bytes + i, len);
  126. writeToSerialPort(sd->port, cmd, 1 + len);
  127. }
  128. }
  129. void spi_read(SPIDriver *sd, char bytes[], size_t nn)
  130. {
  131. for (size_t i = 0; i < nn; i += 64) {
  132. size_t len = ((nn - i) < 64) ? (nn - i) : 64;
  133. char cmd[65] = {(char)(0x80 + len - 1), 0};
  134. writeToSerialPort(sd->port, cmd, 1 + len);
  135. readFromSerialPort(sd->port, bytes + i, len);
  136. }
  137. }
  138. void spi_writeread(SPIDriver *sd, char bytes[], size_t nn)
  139. {
  140. for (size_t i = 0; i < nn; i += 64) {
  141. size_t len = ((nn - i) < 64) ? (nn - i) : 64;
  142. char cmd[65] = {(char)(0x80 + len - 1)};
  143. memcpy(cmd + 1, bytes + i, len);
  144. writeToSerialPort(sd->port, cmd, 1 + len);
  145. readFromSerialPort(sd->port, bytes + i, len);
  146. }
  147. }