cc1101.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. #include "cc1101.h"
  2. #include <cmsis_os2.h>
  3. #include <api-hal-delay.h>
  4. #include <assert.h>
  5. #include <string.h>
  6. CC1101Status cc1101_strobe(const ApiHalSpiDevice* device, uint8_t strobe) {
  7. uint8_t tx[1] = { strobe };
  8. CC1101Status rx[1] = { 0 };
  9. hal_gpio_write(device->chip_select, false);
  10. while(hal_gpio_read(device->bus->miso));
  11. api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 1, CC1101_TIMEOUT);
  12. hal_gpio_write(device->chip_select, true);
  13. assert(rx[0].CHIP_RDYn == 0);
  14. return rx[0];
  15. }
  16. CC1101Status cc1101_write_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t data) {
  17. uint8_t tx[2] = { reg, data };
  18. CC1101Status rx[2] = { 0 };
  19. hal_gpio_write(device->chip_select, false);
  20. while(hal_gpio_read(device->bus->miso));
  21. api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT);
  22. hal_gpio_write(device->chip_select, true);
  23. assert((rx[0].CHIP_RDYn|rx[1].CHIP_RDYn) == 0);
  24. return rx[1];
  25. }
  26. CC1101Status cc1101_read_reg(const ApiHalSpiDevice* device, uint8_t reg, uint8_t* data) {
  27. assert(sizeof(CC1101Status) == 1);
  28. uint8_t tx[2] = { reg|CC1101_READ, 0};
  29. CC1101Status rx[2] = { 0 };
  30. hal_gpio_write(device->chip_select, false);
  31. while(hal_gpio_read(device->bus->miso));
  32. api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT);
  33. hal_gpio_write(device->chip_select, true);
  34. assert((rx[0].CHIP_RDYn) == 0);
  35. *data = *(uint8_t*)&rx[1];
  36. return rx[0];
  37. }
  38. uint8_t cc1101_get_partnumber(const ApiHalSpiDevice* device) {
  39. uint8_t partnumber=0;
  40. cc1101_read_reg(device, CC1101_STATUS_PARTNUM|CC1101_BURST, &partnumber);
  41. return partnumber;
  42. }
  43. uint8_t cc1101_get_version(const ApiHalSpiDevice* device) {
  44. uint8_t version=0;
  45. cc1101_read_reg(device, CC1101_STATUS_VERSION|CC1101_BURST, &version);
  46. return version;
  47. }
  48. uint8_t cc1101_get_rssi(const ApiHalSpiDevice* device) {
  49. uint8_t rssi=0;
  50. cc1101_read_reg(device, CC1101_STATUS_RSSI|CC1101_BURST, &rssi);
  51. return rssi;
  52. }
  53. void cc1101_reset(const ApiHalSpiDevice* device) {
  54. hal_gpio_write(device->chip_select, false);
  55. delay_us(1000);
  56. hal_gpio_write(device->chip_select, true);
  57. delay_us(1000);
  58. cc1101_strobe(device, CC1101_STROBE_SRES);
  59. }
  60. void cc1101_shutdown(const ApiHalSpiDevice* device) {
  61. cc1101_strobe(device, CC1101_STROBE_SPWD);
  62. }
  63. void cc1101_calibrate(const ApiHalSpiDevice* device) {
  64. cc1101_strobe(device, CC1101_STROBE_SCAL);
  65. }
  66. void cc1101_switch_to_idle(const ApiHalSpiDevice* device) {
  67. cc1101_strobe(device, CC1101_STROBE_SIDLE);
  68. }
  69. void cc1101_switch_to_rx(const ApiHalSpiDevice* device) {
  70. cc1101_strobe(device, CC1101_STROBE_SRX);
  71. }
  72. void cc1101_switch_to_tx(const ApiHalSpiDevice* device) {
  73. cc1101_strobe(device, CC1101_STROBE_STX);
  74. }
  75. void cc1101_flush_rx(const ApiHalSpiDevice* device) {
  76. cc1101_strobe(device, CC1101_STROBE_SFRX);
  77. }
  78. void cc1101_flush_tx(const ApiHalSpiDevice* device) {
  79. cc1101_strobe(device, CC1101_STROBE_SFTX);
  80. }
  81. uint32_t cc1101_set_frequency(const ApiHalSpiDevice* device, uint32_t value) {
  82. uint64_t real_value = (uint64_t)value * 0xFFFF / CC1101_QUARTZ;
  83. // Sanity check
  84. assert((real_value & 0xFFFFFF) == real_value);
  85. cc1101_write_reg(device, CC1101_FREQ2, (real_value >> 16) & 0xFF);
  86. cc1101_write_reg(device, CC1101_FREQ1, (real_value >> 8 ) & 0xFF);
  87. cc1101_write_reg(device, CC1101_FREQ0, (real_value >> 0 ) & 0xFF);
  88. uint64_t real_frequency = real_value * CC1101_QUARTZ / 0xFFFF;
  89. return (uint32_t)real_frequency;
  90. }
  91. uint32_t cc1101_get_frequency_step(const ApiHalSpiDevice* device) {
  92. return CC1101_QUARTZ / 0xFFFF;
  93. }
  94. uint32_t cc1101_set_frequency_offset(const ApiHalSpiDevice* device, uint32_t value) {
  95. uint64_t real_value = value * 0x4000 / CC1101_QUARTZ;
  96. assert((real_value & 0xFF) == real_value);
  97. cc1101_write_reg(device, CC1101_FSCTRL0, (real_value >> 0 ) & 0xFF);
  98. uint64_t real_frequency = real_value * CC1101_QUARTZ / 0x4000;
  99. return (uint32_t)real_frequency;
  100. }
  101. uint32_t cc1101_get_frequency_offset_step(const ApiHalSpiDevice* device) {
  102. return CC1101_QUARTZ / 0x4000;
  103. }
  104. void cc1101_set_pa_table(const ApiHalSpiDevice* device, const uint8_t value[8]) {
  105. uint8_t tx[9] = { CC1101_PATABLE | CC1101_BURST };
  106. CC1101Status rx[9] = { 0 };
  107. memcpy(&tx[1], &value[0], 8);
  108. hal_gpio_write(device->chip_select, false);
  109. while(hal_gpio_read(device->bus->miso));
  110. api_hal_spi_bus_trx(device->bus, tx, (uint8_t*)rx, 2, CC1101_TIMEOUT);
  111. hal_gpio_write(device->chip_select, true);
  112. assert((rx[0].CHIP_RDYn|rx[8].CHIP_RDYn) == 0);
  113. }
  114. uint8_t cc1101_write_fifo(const ApiHalSpiDevice* device, const uint8_t* data, uint8_t size) {
  115. uint8_t tx = CC1101_FIFO | CC1101_BURST;
  116. CC1101Status rx = { 0 };
  117. // Start transaction
  118. hal_gpio_write(device->chip_select, false);
  119. // Wait IC to become ready
  120. while(hal_gpio_read(device->bus->miso));
  121. // Tell IC what we want
  122. api_hal_spi_bus_trx(device->bus, &tx, (uint8_t*)&rx, 1, CC1101_TIMEOUT);
  123. assert((rx.CHIP_RDYn) == 0);
  124. // Transmit data
  125. api_hal_spi_bus_tx(device->bus, (uint8_t*)data, size, CC1101_TIMEOUT);
  126. // Finish transaction
  127. hal_gpio_write(device->chip_select, true);
  128. return size;
  129. }
  130. uint8_t cc1101_read_fifo(const ApiHalSpiDevice* device, uint8_t* data, uint8_t size) {
  131. return size;
  132. }