-
-
Save davide99/8d34656c01cb7a43126b7e93deccc9d5 to your computer and use it in GitHub Desktop.
Generate PSK with an Arduino and Si5351
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <si5351.h> | |
#include "Wire.h" | |
Si5351 si5351; | |
uint16_t varicode[] = | |
{ | |
0b1010101011000000, // 0 NUL | |
0b1011011011000000, // 1 SOH | |
0b1011101101000000, // 2 STX | |
0b1101110111000000, // 3 ETX | |
0b1011101011000000, // 4 EOT | |
0b1101011111000000, // 5 ENQ | |
0b1011101111000000, // 6 ACK | |
0b1011111101000000, // 7 BEL | |
0b1011111111000000, // 8 BS | |
0b1110111100000000, // 9 HT | |
0b1110100000000000, // 10 LF | |
0b1101101111000000, // 11 VT | |
0b1011011101000000, // 12 FF | |
0b1111100000000000, // 13 CR | |
0b1101110101000000, // 14 SO | |
0b1110101011000000, // 15 SI | |
0b1011110111000000, // 16 DLE | |
0b1011110101000000, // 17 DC1 | |
0b1110101101000000, // 18 DC2 | |
0b1110101111000000, // 19 DC3 | |
0b1101011011000000, // 20 DC4 | |
0b1101101011000000, // 21 NAK | |
0b1101101101000000, // 22 SYN | |
0b1101010111000000, // 23 ETB | |
0b1101111011000000, // 24 CAN | |
0b1101111101000000, // 25 EM | |
0b1110110111000000, // 26 SUB | |
0b1101010101000000, // 27 ESC | |
0b1101011101000000, // 28 FS | |
0b1110111011000000, // 29 GS | |
0b1011111011000000, // 30 RS | |
0b1101111111000000, // 31 US | |
0b1000000000000000, // 32 SP | |
0b1111111110000000, // 33 ! | |
0b1010111110000000, // 34 " | |
0b1111101010000000, // 35 # | |
0b1110110110000000, // 36 $ | |
0b1011010101000000, // 37 % | |
0b1010111011000000, // 38 & | |
0b1011111110000000, // 39 ' | |
0b1111101100000000, // 40 ( | |
0b1111011100000000, // 41 ) | |
0b1011011110000000, // 42 * | |
0b1110111110000000, // 43 + | |
0b1110101000000000, // 44 , | |
0b1101010000000000, // 45 - | |
0b1010111000000000, // 46 . | |
0b1101011110000000, // 47 / | |
0b1011011100000000, // 48 0 | |
0b1011110100000000, // 49 1 | |
0b1110110100000000, // 50 2 | |
0b1111111100000000, // 51 3 | |
0b1011101110000000, // 52 4 | |
0b1010110110000000, // 53 5 | |
0b1011010110000000, // 54 6 | |
0b1101011010000000, // 55 7 | |
0b1101010110000000, // 56 8 | |
0b1101101110000000, // 57 9 | |
0b1111010100000000, // 58 : | |
0b1101111010000000, // 59 ; | |
0b1111011010000000, // 60 < | |
0b1010101000000000, // 61 = | |
0b1110101110000000, // 62 > | |
0b1010101111000000, // 63 ? | |
0b1010111101000000, // 64 @ | |
0b1111101000000000, // 65 A | |
0b1110101100000000, // 66 B | |
0b1010110100000000, // 67 C | |
0b1011010100000000, // 68 D | |
0b1110111000000000, // 69 E | |
0b1101101100000000, // 70 F | |
0b1111110100000000, // 71 G | |
0b1010101010000000, // 72 H | |
0b1111111000000000, // 73 I | |
0b1111111010000000, // 74 J | |
0b1011111010000000, // 75 K | |
0b1101011100000000, // 76 L | |
0b1011101100000000, // 77 M | |
0b1101110100000000, // 78 N | |
0b1010101100000000, // 79 O | |
0b1101010100000000, // 80 P | |
0b1110111010000000, // 81 Q | |
0b1010111100000000, // 82 R | |
0b1101111000000000, // 83 S | |
0b1101101000000000, // 84 T | |
0b1010101110000000, // 85 U | |
0b1101101010000000, // 86 V | |
0b1010111010000000, // 87 W | |
0b1011101010000000, // 88 X | |
0b1011110110000000, // 89 Y | |
0b1010101101000000, // 90 Z | |
0b1111101110000000, // 91 [ | |
0b1111011110000000, // 92 backslash | |
0b1111110110000000, // 93 ] | |
0b1010111111000000, // 94 ^ | |
0b1011011010000000, // 95 _ | |
0b1011011111000000, // 96 ` | |
0b1011000000000000, // 97 a | |
0b1011111000000000, // 98 b | |
0b1011110000000000, // 99 c | |
0b1011010000000000, // 100 d | |
0b1100000000000000, // 101 e | |
0b1111010000000000, // 102 f | |
0b1011011000000000, // 103 g | |
0b1010110000000000, // 104 h | |
0b1101000000000000, // 105 i | |
0b1111010110000000, // 106 j | |
0b1011111100000000, // 107 k | |
0b1101100000000000, // 108 l | |
0b1110110000000000, // 109 m | |
0b1111000000000000, // 110 n | |
0b1110000000000000, // 111 o | |
0b1111110000000000, // 112 p | |
0b1101111110000000, // 113 q | |
0b1010100000000000, // 114 r | |
0b1011100000000000, // 115 s | |
0b1010000000000000, // 116 t | |
0b1101110000000000, // 117 u | |
0b1111011000000000, // 118 v | |
0b1101011000000000, // 119 w | |
0b1101111100000000, // 120 x | |
0b1011101000000000, // 121 y | |
0b1110101010000000, // 122 z | |
0b1010110111000000, // 123 { | |
0b1101110110000000, // 124 | | |
0b1010110101000000, // 125 } | |
0b1011010111000000, // 126 ~ | |
0b1110110101000000 // 127 (del) | |
}; | |
volatile int index = 0; | |
volatile uint16_t symbol; | |
volatile int psk_bit = 0; | |
volatile int zero_count = 0; | |
volatile int set_vfo = 0; | |
const uint16_t baud_rate = 3125; | |
//const uint16_t baud_rate = 6250; | |
const uint16_t clock_mult = 1000; | |
uint32_t freq = 14100000UL; | |
uint32_t clock_freq = baud_rate * clock_mult; | |
String mystring = "DE NT7S CN85NM\n"; | |
int psk_bit_prev = 0; | |
const unsigned long long pll_freq = 87000000000ULL; | |
int led = 13; | |
int external_clock_pin = 2; | |
void setup() | |
{ | |
Serial.begin(57600); | |
// Setup external interrupt for clock input | |
pinMode(external_clock_pin, INPUT); | |
attachInterrupt(0, ext_clock, RISING); | |
// Initialize the Si5351A | |
si5351.init(SI5351_CRYSTAL_LOAD_8PF, 0); | |
delay(10); | |
uint8_t temp = si5351.si5351_read(16); | |
Serial.println(temp, HEX); | |
temp = si5351.si5351_read(17); | |
Serial.println(temp, HEX); | |
si5351.set_correction(-67); | |
//si5351.si5351_write(187, 0x92); | |
si5351.set_pll(pll_freq, SI5351_PLLA); | |
//si5351.set_pll(pll_freq, SI5351_PLLB); | |
si5351.si5351_write(16, 0x80); | |
si5351.si5351_write(17, 0x80); | |
//si5351.si5351_write(18, 0x80); | |
si5351.set_ms_source(SI5351_CLK0, SI5351_PLLA); | |
si5351.set_ms_source(SI5351_CLK1, SI5351_PLLA); | |
si5351.set_ms_source(SI5351_CLK2, SI5351_PLLA); | |
si5351.set_freq((freq * 100ULL), pll_freq, SI5351_CLK0); | |
si5351.set_freq((freq * 100ULL), pll_freq, SI5351_CLK1); | |
si5351.set_freq((3138100ULL), pll_freq, SI5351_CLK2); | |
si5351.set_phase(SI5351_CLK0, 0); | |
si5351.set_phase(SI5351_CLK1, 0); | |
si5351.set_phase(SI5351_CLK2, 0); | |
si5351.si5351_write(16, 0x0c); | |
si5351.si5351_write(17, 0x0c); | |
si5351.si5351_write(18, 0x0c); | |
si5351.pll_reset(SI5351_PLLA); | |
// Load the first varicode symbol from the message | |
symbol = varicode[mystring.charAt(index)]; | |
// We'll flash the LED in sync with the PSK modulation | |
pinMode(led, OUTPUT); | |
/* | |
// Set up Timer1 for interrupts at 31.25 Hz | |
cli(); //stop interrupts | |
TCCR1A = 0;// set entire TCCR1A register to 0 | |
TCNT1 = 0;//initialize counter value to 0 | |
// set compare match register | |
if(baud_rate == 3125) | |
{ | |
OCR1A = 7969d;// = (16*10^6) / (1*1024) - 1 (must be <65536) | |
//OCR1A = 499;// = (16*10^6) / (1*1024) - 1 (must be <65536) | |
} | |
else if(baud_rate == 6250) | |
{ | |
OCR1A = 250; | |
} | |
// turn on CTC mode, set CS12 and CS10 bits for 1024 prescaler | |
//TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10); | |
// 64 | |
TCCR1B = (1 << WGM12) | (1 << CS11) | (1 << CS10); | |
// enable timer compare interrupt | |
TIMSK1 = (1 << OCIE1A); | |
sei(); //allow interrupts*/ | |
} | |
/* | |
ISR(TIMER1_COMPA_vect) | |
{ | |
if(symbol == 0) | |
{ | |
if(zero_count) | |
{ | |
psk_bit = 0; | |
zero_count--; | |
} | |
else | |
{ | |
index++; | |
// Reset message pointer to beginning of string if at end | |
if(index >= mystring.length()) | |
{ | |
index = 0; | |
} | |
symbol = varicode[mystring.charAt(index)]; | |
} | |
} | |
else | |
{ | |
if(symbol & 0x8000) // 1 in the MSB position | |
{ | |
psk_bit = 1; | |
} | |
else // 0 in the MSB position | |
{ | |
psk_bit = 0; | |
} | |
symbol <<= 1; | |
if(symbol == 0) | |
{ | |
zero_count = 2; | |
} | |
else | |
{ | |
zero_count = 0; | |
} | |
} | |
set_vfo = 1; | |
} | |
*/ | |
void loop() | |
{ | |
if(set_vfo) | |
{ | |
if(psk_bit) | |
{ | |
psk_one(); | |
} | |
else | |
{ | |
psk_zero(); | |
} | |
if(symbol == 0) | |
{ | |
if(zero_count) | |
{ | |
psk_bit = 0; | |
zero_count--; | |
} | |
else | |
{ | |
index++; | |
// Reset message pointer to beginning of string if at end | |
if(index >= mystring.length()) | |
{ | |
index = 0; | |
} | |
symbol = varicode[mystring.charAt(index)]; | |
} | |
} | |
else | |
{ | |
if(symbol & 0x8000) // 1 in the MSB position | |
{ | |
psk_bit = 1; | |
} | |
else // 0 in the MSB position | |
{ | |
psk_bit = 0; | |
} | |
symbol <<= 1; | |
if(symbol == 0) | |
{ | |
zero_count = 2; | |
} | |
else | |
{ | |
zero_count = 0; | |
} | |
} | |
set_vfo = 0; | |
} | |
} | |
void psk_zero() | |
{ | |
//si5351.si5351_write(165, 0); | |
//si5351.si5351_write(166, 0); | |
//si5351.pll_reset(SI5351_PLLA); | |
//si5351.set_clock_source(SI5351_CLK0, SI5351_CLK_SRC_CLKIN); | |
//si5351.set_clock_source(SI5351_CLK1, SI5351_CLK_SRC_MS); | |
//si5351.set_clock_source(SI5351_CLK2, SI5351_CLK_SRC_MS); | |
si5351.set_freq((freq * 100ULL) + (baud_rate / 2), pll_freq, SI5351_CLK0); | |
si5351.set_freq((freq * 100ULL) - (baud_rate / 2), pll_freq, SI5351_CLK1); | |
digitalWrite(led, LOW); | |
//si5351.set_phase(SI5351_CLK1, 0); | |
//si5351.set_phase(SI5351_CLK2, 0); | |
//si5351.si5351_write(16, 0x0c); | |
//si5351.si5351_write(17, 0x0c); | |
} | |
void psk_one() | |
{ | |
//si5351.set_clock_source(SI5351_CLK0, SI5351_CLK_SRC_CLKIN); | |
//si5351.set_clock_source(SI5351_CLK1, SI5351_CLK_SRC_MS0); | |
//si5351.set_clock_source(SI5351_CLK2, SI5351_CLK_SRC_MS0); | |
//si5351.set_phase(SI5351_CLK1, 0); | |
//si5351.set_phase(SI5351_CLK2, 0); | |
si5351.set_freq((freq * 100ULL), pll_freq, SI5351_CLK0); | |
si5351.set_freq((freq * 100ULL), pll_freq, SI5351_CLK1); | |
digitalWrite(led, HIGH); | |
//si5351.set_phase(SI5351_CLK1, 0); | |
//si5351.set_phase(SI5351_CLK2, 0); | |
//si5351.si5351_write(16, 0x0c); | |
//si5351.si5351_write(17, 0x0c); | |
} | |
void ext_clock() | |
{ | |
static uint32_t ext_ticks = 0; | |
ext_ticks++; | |
if(ext_ticks >= clock_mult) | |
{ | |
set_vfo = 1; | |
ext_ticks = 0; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment