// This program generates a FT8 audio signal using a Raspberry Pi Pico using PWM

#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/time.h"
#include "hardware/irq.h"  // interrupts
#include "hardware/pwm.h"  // pwm
#include "hardware/sync.h" // wait for interrupt

int symbolCount = 79;
#define FT8_TONE_SPACING 625  // ~6.25 Hz
#define FT8_SYMBOL_COUNT 79

char message[] = "VU3CER VU3FOE MK68";

uint8_t tones[FT8_SYMBOL_COUNT] = {3, 1, 4, 0, 6, 5, 2, 7, 0, 7, 4, 2, 6, 4, 5, 3, 6, 4, 1, 7, 5, 4, 4, 4, 7, 1, 1, 2, 0, 5, 2, 0, 3, 5, 2, 2, 3, 1, 4, 0, 6, 5, 2, 1, 3, 0, 0, 6, 4, 2, 6, 0, 4, 5, 6, 7, 6, 2, 7, 4, 0, 0, 4, 4, 3, 5, 5, 6, 6, 4, 1, 4, 3, 1, 4, 0, 6, 5, 2};
int toneDelay = 159;

// Audio PIN is to match some of the design guide shields.
#define AUDIO_PIN 28  // you can change this to whatever you like

/*
  $ ./pwm_calculator_wow
  Freq = 1000.000000   Top = 62499   Div = 0x04.0   Out = 1000.000000	Err = 0.000000%
  Freq = 1006.250000   Top = 19390   Div = 0x0C.D   Out = 1006.250122	Err = 0.000012%
  Freq = 1012.500000   Top = 24537   Div = 0x0A.1   Out = 1012.499817	Err = -0.000018%
  Freq = 1018.750000   Top = 16707   Div = 0x0E.B   Out = 1018.750061	Err = 0.000006%
*/

int tone_value = 0;

void tx()
{
  uint16_t wrap;
  uint8_t integer;
  uint8_t fract;

  gpio_set_function(AUDIO_PIN, GPIO_FUNC_PWM);
  int slice_num = pwm_gpio_to_slice_num(AUDIO_PIN);

  for (;;) {
    switch (tone_value) {
      case 0:
        wrap = 62499;
        integer = 0x04;
        fract = 0x0;
        break;
      case 1:
        wrap = 19390;
        integer = 0x0C;
        fract = 0xD;
        break;
      case 2:
        wrap = 24537;
        integer = 0xA;
        fract = 0x1;
        break;
      case 3:
        wrap = 16707;
        integer = 0x0E;
        fract = 0xB;
        break;
    }

    tone_value = (tone_value + 1) % 4;

    // Set period of 4 cycles (0 to 3 inclusive)
    pwm_set_wrap(slice_num, wrap);
    pwm_set_clkdiv_int_frac(slice_num, integer, fract);
    pwm_set_chan_level(slice_num, PWM_CHAN_A, wrap / 2);
    // Set initial B output high for three cycles before dropping
    pwm_set_chan_level(slice_num, PWM_CHAN_B, wrap / 2);
    pwm_set_enabled(slice_num, true);
    sleep_ms(10000); // 10 seconds each
  }
}

void setup() {
  int ret = 0;
  printf("Hello! ;-)\n");
}

void loop() {
  tx(tones);
}

int main() {
  set_sys_clock_khz(250000, true);

  stdio_init_all();

  setup();
  while (1) loop();
}
BOOTSELLED1239USBRaspberryPiPico©2020RP2-8020/21P64M15.00TTT