radio.c 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. //
  2. // Created by SQ5RWU on 2016-12-24.
  3. //
  4. #include "radio.h"
  5. uint8_t _spi_sendrecv(const uint16_t data_word)
  6. {
  7. GPIO_ResetBits(GPIOC, radioNSELpin);
  8. // wait for tx buffer
  9. while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET) continue;
  10. SPI_I2S_SendData(SPI2, data_word);
  11. // wait for data in rx buffer
  12. while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_RXNE) == RESET) continue;
  13. GPIO_SetBits(GPIOC, radioNSELpin);
  14. return (uint8_t) SPI_I2S_ReceiveData(SPI2);
  15. }
  16. inline uint8_t radio_rw_register (const uint8_t register_addr, uint8_t value, uint8_t write)
  17. {
  18. return _spi_sendrecv(((write ? register_addr | WR : register_addr) << 8) | value);
  19. }
  20. #if 0
  21. void radio_set_tx_frequency_int (long freq)
  22. {
  23. if ((freq < 240000000) || (freq >= 960000000))
  24. return;
  25. long hz = (30L*freq) / SI4032_CLOCK; /* off-spec 26MHz xtal in the RS */
  26. int hbsel, freqband, off, f;
  27. hbsel = (hz >= 480000000) ? 32 : 0;
  28. if (hbsel)
  29. { /* high band select 480-959.9 */
  30. freqband = (hz - 480000000) / 20000000;
  31. off = hz - (freqband * 20000000);
  32. f = (off * 32000) / 20000000;
  33. }
  34. else
  35. { /* low band 240-479.9 */
  36. int a = hz - 240000000;
  37. int b = a % 10000000;
  38. int c = a / 10000000;
  39. int d = (32000 * b) / 10000000;
  40. freqband = (hz - 240000000) / 10000000;
  41. off = hz - (freqband * 10000000);
  42. f = (off * 32000) / 10000000;
  43. }
  44. radio_rw_register(0x75, (uint8_t) (0b01000000 | (fb & 0b11111) | hbsel), 1);
  45. radio_rw_register(0x76, (uint8_t) (((uint16_t)fc >> 8) & 0xff), 1);
  46. radio_rw_register(0x77, (uint8_t) ((uint16_t)fc & 0xff), 1);
  47. }
  48. #endif
  49. void radio_set_tx_frequency (float freq_in_mhz)
  50. {
  51. uint8_t hbsel = (uint8_t) ((freq_in_mhz * (30.0f / SI4032_CLOCK)) >= 480.0f ? 1 : 0);
  52. uint8_t fb = (uint8_t) ((((uint8_t)((freq_in_mhz * (30.0f / SI4032_CLOCK)) / 10) - 24) - (24 * hbsel)) / (1 + hbsel));
  53. uint8_t gen_div = 3; // constant - not possible to change!
  54. uint16_t fc = (uint16_t) (((freq_in_mhz / ((SI4032_CLOCK / gen_div) * (hbsel + 1))) - fb - 24) * 64000);
  55. radio_rw_register(0x75, (uint8_t) (0b01000000 | (fb & 0b11111) | ((hbsel & 1) << 5)), 1);
  56. radio_rw_register(0x76, (uint8_t) (((uint16_t)fc >> 8) & 0xff), 1);
  57. radio_rw_register(0x77, (uint8_t) ((uint16_t)fc & 0xff), 1);
  58. }
  59. void radio_disable_tx (void)
  60. {
  61. radio_rw_register(0x07, 0x40, 1);
  62. }
  63. void radio_soft_reset (void)
  64. {
  65. radio_rw_register(0x07, 0x80, 1);
  66. }
  67. void radio_enable_tx (void)
  68. {
  69. radio_rw_register(0x07, 0x4B, 1); // was 0x48 ???
  70. }
  71. int8_t radio_read_temperature (void)
  72. {
  73. uint8_t temp;
  74. // Read ADC Value.
  75. // Temp (degC) = -64 + ADC Value * 0.5
  76. temp = radio_rw_register(0x11, 0xff, 0);
  77. int16_t temp_2 = -64 + ((int16_t)temp * 5) / 10; // Convert ADC value to signed temperature value.
  78. radio_rw_register(0x0f, 0x80, 1); // Trigger ADC to capture another measurement.
  79. return (int8_t)temp_2; // Cast temperature value to int8_t and return.
  80. }