afsk_modulator.c 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. /*
  2. * afsk_modulator.c
  3. *
  4. * Created on: Oct 10, 2019
  5. * Author: curiousmuch
  6. */
  7. #include <stdio.h>
  8. #include <stdint.h>
  9. #include <math.h>
  10. #include "esp_log.h"
  11. #include "freertos/FreeRTOS.h"
  12. #include "sdkconfig.h"
  13. /* LUT Defines */
  14. #define LUT_SIZE 256 // was 7 bits, but increase to 8 for more phase resolution...
  15. #define DAC_MAX 64 // cc1200 DAC is only 7 bits (+/- 64)
  16. /* Public Variables */
  17. float delta_phi_1, delta_phi_2; // phase deltas for two tones used in AFSK modulation
  18. float phase = 0; // current phase as AFSK modulator must be phase continous
  19. int32_t phase_i = 0; // integer of phase which is used by LUT
  20. DRAM_ATTR int8_t LUT[LUT_SIZE]; // look up table used for tone generation
  21. /* Private Functions */
  22. // Returns the phase for the LUT based on the current symbol being
  23. // sent
  24. static int32_t IRAM_ATTR afsk_get_phase(uint8_t tone)
  25. {
  26. if ( tone )
  27. delta_phi = delta_phi_1;
  28. else
  29. delta_phi = delta_phi_2;
  30. phase_i = (int32_t)phase; // get integer part of our phase
  31. phase += delta_phi; // increment phase
  32. if (phase >= (float)LUT_SIZE) // handle wraparound
  33. phase -= (float)LUT_SIZE;
  34. return phase_i;
  35. }
  36. /* Public Functions */
  37. // This function calculates the phase increment based on the sample rate for
  38. // the two freqs used for AFSK. In addition, the function setups a LUT for
  39. // tone generation
  40. void afsk_mod_init(uint32_t sample_rate, uint32_t freq0, uint32_t freq1)
  41. {
  42. // calculate phase deltas for 1200 and 2200 frequencies
  43. delta_phi_1 = (float) freq0 / sample_rate * LUT_SIZE;
  44. delta_phi_2 = (float) freq1 / sample_rate * LUT_SIZE;
  45. // calculate LUT
  46. uint32_t i=0;
  47. for (i=0; i<LUT_SIZE; ++i)
  48. {
  49. LUT[i] = (int8_t)roundf(DAC_MAX * sinf(2.0f * M_PI * (float)i / LUT_SIZE));
  50. }
  51. }
  52. // returns the amplitude for the current tone, but must be called
  53. // based on the sample frequency
  54. int8_t IRAM_ATTR afsk_get_amplitude(uint8_t tone)
  55. {
  56. return LUT[afsk_get_phase(tone)];
  57. }