sx125x_spi.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. / _____) _ | |
  3. ( (____ _____ ____ _| |_ _____ ____| |__
  4. \____ \| ___ | (_ _) ___ |/ ___) _ \
  5. _____) ) ____| | | || |_| ____( (___| | | |
  6. (______/|_____)_|_|_| \__)_____)\____)_| |_|
  7. (C)2019 Semtech
  8. Description:
  9. Functions used to handle LoRa concentrator SX1255/SX1257 radios.
  10. License: Revised BSD License, see LICENSE.TXT file include in the project
  11. */
  12. /* -------------------------------------------------------------------------- */
  13. /* --- DEPENDANCIES --------------------------------------------------------- */
  14. #include <stdint.h> /* C99 types */
  15. #include <stdbool.h> /* bool type */
  16. #include <stdio.h> /* printf fprintf */
  17. #include <string.h> /* memset */
  18. #include <sys/ioctl.h>
  19. #include <linux/spi/spidev.h>
  20. #include "sx125x_spi.h"
  21. #include "loragw_spi.h"
  22. /* -------------------------------------------------------------------------- */
  23. /* --- PRIVATE MACROS ------------------------------------------------------- */
  24. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  25. #if DEBUG_RAD == 1
  26. #define DEBUG_MSG(str) fprintf(stdout, str)
  27. #define DEBUG_PRINTF(fmt, args...) fprintf(stdout,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
  28. #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_SPI_ERROR;}
  29. #else
  30. #define DEBUG_MSG(str)
  31. #define DEBUG_PRINTF(fmt, args...)
  32. #define CHECK_NULL(a) if(a==NULL){return LGW_SPI_ERROR;}
  33. #endif
  34. /* -------------------------------------------------------------------------- */
  35. /* --- PRIVATE TYPES -------------------------------------------------------- */
  36. /* -------------------------------------------------------------------------- */
  37. /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
  38. #define READ_ACCESS 0x00
  39. #define WRITE_ACCESS 0x80
  40. /* -------------------------------------------------------------------------- */
  41. /* --- PRIVATE VARIABLES ---------------------------------------------------- */
  42. /* -------------------------------------------------------------------------- */
  43. /* --- PRIVATE FUNCTIONS ---------------------------------------------------- */
  44. /* -------------------------------------------------------------------------- */
  45. /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
  46. /* Simple read */
  47. int sx125x_spi_r(void *com_target, uint8_t spi_mux_target, uint8_t address, uint8_t *data) {
  48. int com_device;
  49. uint8_t out_buf[3];
  50. uint8_t command_size;
  51. uint8_t in_buf[ARRAY_SIZE(out_buf)];
  52. struct spi_ioc_transfer k;
  53. int a;
  54. /* check input variables */
  55. CHECK_NULL(com_target);
  56. CHECK_NULL(data);
  57. com_device = *(int *)com_target;
  58. /* prepare frame to be sent */
  59. out_buf[0] = spi_mux_target;
  60. out_buf[1] = READ_ACCESS | (address & 0x7F);
  61. out_buf[2] = 0x00;
  62. command_size = 3;
  63. /* I/O transaction */
  64. memset(&k, 0, sizeof(k)); /* clear k */
  65. k.tx_buf = (unsigned long) out_buf;
  66. k.rx_buf = (unsigned long) in_buf;
  67. k.len = command_size;
  68. k.cs_change = 0;
  69. a = ioctl(com_device, SPI_IOC_MESSAGE(1), &k);
  70. /* determine return code */
  71. if (a != (int)k.len) {
  72. DEBUG_MSG("ERROR: SPI READ FAILURE\n");
  73. return LGW_SPI_ERROR;
  74. } else {
  75. //DEBUG_MSG("Note: SPI read success\n");
  76. *data = in_buf[command_size - 1];
  77. return LGW_SPI_SUCCESS;
  78. }
  79. }
  80. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  81. int sx125x_spi_w(void *spi_target, uint8_t spi_mux_target, uint8_t address, uint8_t data) {
  82. int spi_device;
  83. uint8_t out_buf[3];
  84. uint8_t command_size;
  85. struct spi_ioc_transfer k;
  86. int a;
  87. /* check input variables */
  88. CHECK_NULL(spi_target);
  89. spi_device = *(int *)spi_target; /* must check that spi_target is not null beforehand */
  90. /* prepare frame to be sent */
  91. out_buf[0] = spi_mux_target;
  92. out_buf[1] = WRITE_ACCESS | (address & 0x7F);
  93. out_buf[2] = data;
  94. command_size = 3;
  95. /* I/O transaction */
  96. memset(&k, 0, sizeof(k)); /* clear k */
  97. k.tx_buf = (unsigned long) out_buf;
  98. k.len = command_size;
  99. k.speed_hz = SPI_SPEED;
  100. k.cs_change = 0;
  101. k.bits_per_word = 8;
  102. a = ioctl(spi_device, SPI_IOC_MESSAGE(1), &k);
  103. /* determine return code */
  104. if (a != (int)k.len) {
  105. DEBUG_MSG("ERROR: SPI WRITE FAILURE\n");
  106. return LGW_SPI_ERROR;
  107. } else {
  108. //DEBUG_MSG("Note: SPI write success\n");
  109. return LGW_SPI_SUCCESS;
  110. }
  111. }
  112. /* --- EOF ------------------------------------------------------------------ */