sx1250_spi.c 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. / _____) _ | |
  3. ( (____ _____ ____ _| |_ _____ ____| |__
  4. \____ \| ___ | (_ _) ___ |/ ___) _ \
  5. _____) ) ____| | | || |_| ____( (___| | | |
  6. (______/|_____)_|_|_| \__)_____)\____)_| |_|
  7. (C)2019 Semtech
  8. Description:
  9. Functions used to handle LoRa concentrator SX1250 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 <stdio.h> /* printf fprintf */
  16. #include <unistd.h> /* lseek, close */
  17. #include <fcntl.h> /* open */
  18. #include <string.h> /* memset */
  19. #include <sys/ioctl.h>
  20. #include <linux/spi/spidev.h>
  21. #include "loragw_spi.h"
  22. #include "loragw_aux.h"
  23. #include "sx1250_spi.h"
  24. /* -------------------------------------------------------------------------- */
  25. /* --- PRIVATE MACROS ------------------------------------------------------- */
  26. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  27. #if DEBUG_RAD == 1
  28. #define DEBUG_MSG(str) fprintf(stdout, str)
  29. #define DEBUG_PRINTF(fmt, args...) fprintf(stdout,"%s:%d: "fmt, __FUNCTION__, __LINE__, args)
  30. #define CHECK_NULL(a) if(a==NULL){fprintf(stderr,"%s:%d: ERROR: NULL POINTER AS ARGUMENT\n", __FUNCTION__, __LINE__);return LGW_SPI_ERROR;}
  31. #else
  32. #define DEBUG_MSG(str)
  33. #define DEBUG_PRINTF(fmt, args...)
  34. #define CHECK_NULL(a) if(a==NULL){return LGW_SPI_ERROR;}
  35. #endif
  36. /* -------------------------------------------------------------------------- */
  37. /* --- PRIVATE CONSTANTS ---------------------------------------------------- */
  38. #define WAIT_BUSY_SX1250_MS 1
  39. /* -------------------------------------------------------------------------- */
  40. /* --- PUBLIC FUNCTIONS DEFINITION ------------------------------------------ */
  41. int sx1250_spi_w(void *com_target, uint8_t spi_mux_target, sx1250_op_code_t op_code, uint8_t *data, uint16_t size) {
  42. int com_device;
  43. int cmd_size = 2; /* header + op_code */
  44. uint8_t out_buf[cmd_size + size];
  45. uint8_t command_size;
  46. struct spi_ioc_transfer k;
  47. int a, i;
  48. /* wait BUSY */
  49. wait_ms(WAIT_BUSY_SX1250_MS);
  50. /* check input variables */
  51. CHECK_NULL(com_target);
  52. CHECK_NULL(data);
  53. com_device = *(int *)com_target;
  54. /* prepare frame to be sent */
  55. out_buf[0] = spi_mux_target;
  56. out_buf[1] = (uint8_t)op_code;
  57. for(i = 0; i < (int)size; i++) {
  58. out_buf[cmd_size + i] = data[i];
  59. }
  60. command_size = cmd_size + size;
  61. /* I/O transaction */
  62. memset(&k, 0, sizeof(k)); /* clear k */
  63. k.tx_buf = (unsigned long) out_buf;
  64. k.len = command_size;
  65. k.speed_hz = SPI_SPEED;
  66. k.cs_change = 0;
  67. k.bits_per_word = 8;
  68. a = ioctl(com_device, SPI_IOC_MESSAGE(1), &k);
  69. /* determine return code */
  70. if (a != (int)k.len) {
  71. DEBUG_MSG("ERROR: SPI WRITE FAILURE\n");
  72. return LGW_SPI_ERROR;
  73. } else {
  74. DEBUG_MSG("Note: SPI write success\n");
  75. return LGW_SPI_SUCCESS;
  76. }
  77. }
  78. /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
  79. int sx1250_spi_r(void *com_target, uint8_t spi_mux_target, sx1250_op_code_t op_code, uint8_t *data, uint16_t size) {
  80. int com_device;
  81. int cmd_size = 2; /* header + op_code + NOP */
  82. uint8_t out_buf[cmd_size + size];
  83. uint8_t command_size;
  84. uint8_t in_buf[ARRAY_SIZE(out_buf)];
  85. struct spi_ioc_transfer k;
  86. int a, i;
  87. /* wait BUSY */
  88. wait_ms(WAIT_BUSY_SX1250_MS);
  89. /* check input variables */
  90. CHECK_NULL(com_target);
  91. CHECK_NULL(data);
  92. com_device = *(int *)com_target;
  93. /* prepare frame to be sent */
  94. out_buf[0] = spi_mux_target;
  95. out_buf[1] = (uint8_t)op_code;
  96. for(i = 0; i < (int)size; i++) {
  97. out_buf[cmd_size + i] = data[i];
  98. }
  99. command_size = cmd_size + size;
  100. /* I/O transaction */
  101. memset(&k, 0, sizeof(k)); /* clear k */
  102. k.tx_buf = (unsigned long) out_buf;
  103. k.rx_buf = (unsigned long) in_buf;
  104. k.len = command_size;
  105. k.cs_change = 0;
  106. a = ioctl(com_device, SPI_IOC_MESSAGE(1), &k);
  107. /* determine return code */
  108. if (a != (int)k.len) {
  109. DEBUG_MSG("ERROR: SPI READ FAILURE\n");
  110. return LGW_SPI_ERROR;
  111. } else {
  112. DEBUG_MSG("Note: SPI read success\n");
  113. //*data = in_buf[command_size - 1];
  114. memcpy(data, in_buf + cmd_size, size);
  115. return LGW_SPI_SUCCESS;
  116. }
  117. }
  118. /* --- EOF ------------------------------------------------------------------ */