Ein Roboter mit bürstenlosem Antrieb, differenzial und NRF24L01 Funk. Großflächig gebaut um ein großes Solarpanel aufzunehmen. https://gitlab.informatik.hs-fulda.de/fdai5253/roboter
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

168 lines
3.5 KiB

  1. /*
  2. * File: spi.cpp
  3. * Author: Purinda Gunasekara <purinda@gmail.com>
  4. *
  5. * Created on 24 June 2012, 11:00 AM
  6. *
  7. * Patched for exception handling and selectable SPI SPEED by ldiaz 2018.
  8. *
  9. * Inspired from spidev test in linux kernel documentation
  10. * www.kernel.org/doc/Documentation/spi/spidev_test.c
  11. */
  12. #include "spi.h"
  13. #include <fcntl.h>
  14. #include <linux/spi/spidev.h>
  15. #include <memory.h>
  16. #include <stdio.h>
  17. #include <stdlib.h>
  18. #include <sys/ioctl.h>
  19. #include <unistd.h>
  20. #define RF24_SPIDEV_BITS 8
  21. SPI::SPI():fd(-1), _spi_speed(RF24_SPIDEV_SPEED) {
  22. }
  23. bool spiIsInitialized = 0;
  24. void SPI::begin(int busNo,uint32_t spi_speed){
  25. if(spiIsInitialized){
  26. return;
  27. }
  28. /* set spidev accordingly to busNo like:
  29. * busNo = 23 -> /dev/spidev2.3
  30. *
  31. * a bit messy but simple
  32. * */
  33. char device[] = "/dev/spidev0.0";
  34. device[11] += (busNo / 10) % 10;
  35. device[13] += busNo % 10;
  36. if(this->fd >=0) // check whether spi is already open
  37. {
  38. close(this->fd);
  39. this->fd=-1;
  40. }
  41. this->fd = open(device, O_RDWR);
  42. if (this->fd < 0) throw SPIException("can't open device");
  43. /*
  44. {
  45. perror("can't open device");
  46. abort();
  47. }*/
  48. spiIsInitialized = true;
  49. init(spi_speed);
  50. }
  51. void SPI::init(uint32_t speed)
  52. {
  53. uint8_t bits = RF24_SPIDEV_BITS;
  54. uint8_t mode = 0;
  55. int ret;
  56. /*
  57. * spi mode
  58. */
  59. ret = ioctl(this->fd, SPI_IOC_WR_MODE, &mode);
  60. if (ret == -1) throw SPIException("cant set WR spi mode");
  61. /*{
  62. perror("can't set spi mode");
  63. abort();
  64. }*/
  65. ret = ioctl(this->fd, SPI_IOC_RD_MODE, &mode);
  66. if (ret == -1) throw SPIException("can't set RD spi mode");
  67. /*{
  68. perror("can't set spi mode");
  69. abort();
  70. }*/
  71. /*
  72. * bits per word
  73. */
  74. ret = ioctl(this->fd, SPI_IOC_WR_BITS_PER_WORD, &bits);
  75. if (ret == -1) throw SPIException("can't set WR bits per word");
  76. /*{
  77. perror("can't set bits per word");
  78. abort();
  79. }*/
  80. ret = ioctl(this->fd, SPI_IOC_RD_BITS_PER_WORD, &bits);
  81. if (ret == -1) throw SPIException("can't set RD bits per word");
  82. /*{
  83. perror("can't set bits per word");
  84. abort();
  85. }*/
  86. /*
  87. * max speed hz
  88. */
  89. ret = ioctl(this->fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed);
  90. if (ret == -1) throw SPIException("can't WR set max speed hz");
  91. /*{
  92. perror("can't set max speed hz");
  93. abort();
  94. }*/
  95. ret = ioctl(this->fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed);
  96. if (ret == -1) throw SPIException("can't RD set max speed hz");
  97. /*{
  98. perror("can't set max speed hz");
  99. abort();
  100. }*/
  101. _spi_speed=speed;
  102. }
  103. uint8_t SPI::transfer(uint8_t tx)
  104. {
  105. struct spi_ioc_transfer tr;
  106. memset(&tr, 0, sizeof(tr));
  107. tr.tx_buf = (unsigned long)&tx;
  108. uint8_t rx;
  109. tr.rx_buf = (unsigned long)&rx;
  110. tr.len = sizeof(tx);
  111. tr.speed_hz = _spi_speed; //RF24_SPIDEV_SPEED;
  112. tr.delay_usecs = 0;
  113. tr.bits_per_word = RF24_SPIDEV_BITS;
  114. tr.cs_change = 0;
  115. int ret;
  116. ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
  117. if (ret < 1) throw SPIException("can't send spi message");
  118. /*{
  119. perror("can't send spi message");
  120. abort();
  121. }*/
  122. return rx;
  123. }
  124. void SPI::transfernb(char* tbuf, char* rbuf, uint32_t len)
  125. {
  126. struct spi_ioc_transfer tr;
  127. memset(&tr, 0, sizeof(tr));
  128. tr.tx_buf = (unsigned long)tbuf;
  129. tr.rx_buf = (unsigned long)rbuf;
  130. tr.len = len;
  131. tr.speed_hz = _spi_speed; //RF24_SPIDEV_SPEED;
  132. tr.delay_usecs = 0;
  133. tr.bits_per_word = RF24_SPIDEV_BITS;
  134. tr.cs_change = 0;
  135. int ret;
  136. ret = ioctl(this->fd, SPI_IOC_MESSAGE(1), &tr);
  137. if (ret < 1) throw SPIException("can't send spi message");
  138. /*{
  139. perror("can't send spi message");
  140. abort();
  141. }*/
  142. }
  143. SPI::~SPI() {
  144. if (this->fd >= 0) close(this->fd);
  145. }