kopia lustrzana https://github.com/mikaelnousiainen/RS41ng
Add support for morse code (CW)
rodzic
6d2416d307
commit
7af1ada130
|
@ -1,151 +0,0 @@
|
||||||
// Morse Code Playback Functions
|
|
||||||
// Mark Jessop 2018-04
|
|
||||||
// OK1TE 2018-11
|
|
||||||
//
|
|
||||||
// Based on code from https://github.com/Paradoxis/Arduino-morse-code-translator/blob/master/main.ino
|
|
||||||
//
|
|
||||||
#include "morse.h"
|
|
||||||
#include "config.h"
|
|
||||||
|
|
||||||
// All morse delays
|
|
||||||
#define MORSE_DELAY (1200 / MORSE_WPM)
|
|
||||||
#define MORSE_DELAY_DOT (MORSE_DELAY * 1)
|
|
||||||
#define MORSE_DELAY_DASH (MORSE_DELAY * 3)
|
|
||||||
#define MORSE_DELAY_SPACE (MORSE_DELAY * 7)
|
|
||||||
|
|
||||||
// All morse characters
|
|
||||||
const char MORSE_DOT = '.';
|
|
||||||
const char MORSE_DASH = '-';
|
|
||||||
|
|
||||||
// Letters
|
|
||||||
const char* const MORSE_LETTERS[] = {
|
|
||||||
".-", // A
|
|
||||||
"-...", // B
|
|
||||||
"-.-.", // C
|
|
||||||
"-..", // D
|
|
||||||
".", // E
|
|
||||||
"..-.", // F
|
|
||||||
"--.", // G
|
|
||||||
"....", // H
|
|
||||||
"..", // I
|
|
||||||
".---", // J
|
|
||||||
"-.-", // K
|
|
||||||
".-..", // L
|
|
||||||
"--", // M
|
|
||||||
"-.", // N
|
|
||||||
"---", // O
|
|
||||||
".--.", // P
|
|
||||||
"--.-", // Q
|
|
||||||
".-.", // R
|
|
||||||
"...", // S
|
|
||||||
"-", // T
|
|
||||||
"..-", // U
|
|
||||||
"...-", // V
|
|
||||||
".--", // W
|
|
||||||
"-..-", // X
|
|
||||||
"-.--", // Y
|
|
||||||
"--.." // Z
|
|
||||||
};
|
|
||||||
|
|
||||||
// Numerals.
|
|
||||||
const char* const MORSE_NUMBERS[] = {
|
|
||||||
"-----", // 0
|
|
||||||
".----", // 1
|
|
||||||
"..---", // 2
|
|
||||||
"...--", // 3
|
|
||||||
"....-", // 4
|
|
||||||
".....", // 5
|
|
||||||
"-....", // 6
|
|
||||||
"--...", // 7
|
|
||||||
"---..", // 8
|
|
||||||
"----." // 9
|
|
||||||
};
|
|
||||||
|
|
||||||
// Symbols
|
|
||||||
const char Morse_Slash[] = "-..-.";
|
|
||||||
const char Morse_Equal[] = "-...-";
|
|
||||||
const char Morse_FullStop[] = ".-.-.-";
|
|
||||||
const char Morse_Comma[] = "--..--";
|
|
||||||
const char Morse_QuestionMark[] = "..--..";
|
|
||||||
const char Morse_Plus[] = ".-.-.";
|
|
||||||
const char Morse_AtSign[] = ".--.-.";
|
|
||||||
|
|
||||||
// Send a single character
|
|
||||||
void sendDotOrDash (char unit) {
|
|
||||||
//radio_enable_tx();
|
|
||||||
|
|
||||||
// Unit is a dot (500 ms)
|
|
||||||
if (unit == MORSE_DOT) {
|
|
||||||
//_delay_ms(MORSE_DELAY_DOT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unit is a dash (1500 ms)
|
|
||||||
else if (unit == MORSE_DASH) {
|
|
||||||
//_delay_ms(MORSE_DELAY_DASH);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inter-element gap
|
|
||||||
//radio_inhibit_tx();
|
|
||||||
//_delay_ms(MORSE_DELAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendMorseSequence (const char* sequence) {
|
|
||||||
// Counter
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
// Loop through every character until an 'end-of-line' (null) character is found
|
|
||||||
while (sequence[i] != 0) {
|
|
||||||
sendDotOrDash(sequence[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay between every letter
|
|
||||||
//_delay_ms(MORSE_DELAY * 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sendMorse(const char* message){
|
|
||||||
int i = 0;
|
|
||||||
while (message[i] != 0){
|
|
||||||
const char current = message[i];
|
|
||||||
|
|
||||||
// Lower case letters
|
|
||||||
if (current >= 'a' && current <= 'z') {
|
|
||||||
sendMorseSequence(MORSE_LETTERS[current - 'a']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Capital case letters
|
|
||||||
else if (current >= 'A' && current <= 'Z') {
|
|
||||||
sendMorseSequence(MORSE_LETTERS[current - 'A']);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Numbers
|
|
||||||
else if (current >= '0' && current <= '9') {
|
|
||||||
sendMorseSequence(MORSE_NUMBERS[current - '0']);
|
|
||||||
}
|
|
||||||
|
|
||||||
else switch (current) {
|
|
||||||
case '/': sendMorseSequence(Morse_Slash);
|
|
||||||
break;
|
|
||||||
case '=': sendMorseSequence(Morse_Equal);
|
|
||||||
break;
|
|
||||||
case '.': sendMorseSequence(Morse_FullStop);
|
|
||||||
break;
|
|
||||||
case ',': sendMorseSequence(Morse_Comma);
|
|
||||||
break;
|
|
||||||
case '?': sendMorseSequence(Morse_QuestionMark);
|
|
||||||
break;
|
|
||||||
case '+': sendMorseSequence(Morse_Plus);
|
|
||||||
break;
|
|
||||||
case '@': sendMorseSequence(Morse_AtSign);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
// Treat all other characters as a space.
|
|
||||||
//_delay_ms(MORSE_DELAY_SPACE);
|
|
||||||
}
|
|
||||||
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
//radio_disable_tx();
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
//
|
|
||||||
// Morse Code Playback Functions
|
|
||||||
// Mark Jessop 2018-04
|
|
||||||
// OK1TE 2018-10
|
|
||||||
//
|
|
||||||
#ifndef __MORSE_H
|
|
||||||
#define __MORSE_H
|
|
||||||
|
|
||||||
void sendDotOrDash (char unit);
|
|
||||||
void sendMorseSequence (const char* sequence);
|
|
||||||
void sendMorse(const char* message);
|
|
||||||
|
|
||||||
#endif //__MORSE_H
|
|
|
@ -0,0 +1,265 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "morse.h"
|
||||||
|
|
||||||
|
// Morse code definitions adapted from code by Mark Jessop VK5QI and OK1TE, also based on
|
||||||
|
// https://github.com/Paradoxis/Arduino-morse-code-translator/blob/master/main.ino
|
||||||
|
|
||||||
|
#define MORSE_UNITS_DOT 1
|
||||||
|
#define MORSE_UNITS_DASH 3
|
||||||
|
#define MORSE_UNITS_GAP 3
|
||||||
|
#define MORSE_UNITS_SPACE 7
|
||||||
|
|
||||||
|
const char MORSE_DOT = '.';
|
||||||
|
const char MORSE_DASH = '-';
|
||||||
|
const char MORSE_SPACE = ' ';
|
||||||
|
|
||||||
|
const char *const morse_letters[] = {
|
||||||
|
".-", // A
|
||||||
|
"-...", // B
|
||||||
|
"-.-.", // C
|
||||||
|
"-..", // D
|
||||||
|
".", // E
|
||||||
|
"..-.", // F
|
||||||
|
"--.", // G
|
||||||
|
"....", // H
|
||||||
|
"..", // I
|
||||||
|
".---", // J
|
||||||
|
"-.-", // K
|
||||||
|
".-..", // L
|
||||||
|
"--", // M
|
||||||
|
"-.", // N
|
||||||
|
"---", // O
|
||||||
|
".--.", // P
|
||||||
|
"--.-", // Q
|
||||||
|
".-.", // R
|
||||||
|
"...", // S
|
||||||
|
"-", // T
|
||||||
|
"..-", // U
|
||||||
|
"...-", // V
|
||||||
|
".--", // W
|
||||||
|
"-..-", // X
|
||||||
|
"-.--", // Y
|
||||||
|
"--.." // Z
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *const morse_numbers[] = {
|
||||||
|
"-----", // 0
|
||||||
|
".----", // 1
|
||||||
|
"..---", // 2
|
||||||
|
"...--", // 3
|
||||||
|
"....-", // 4
|
||||||
|
".....", // 5
|
||||||
|
"-....", // 6
|
||||||
|
"--...", // 7
|
||||||
|
"---..", // 8
|
||||||
|
"----." // 9
|
||||||
|
};
|
||||||
|
|
||||||
|
const char morse_stroke[] = "-..-.";
|
||||||
|
const char morse_equal[] = "-...-";
|
||||||
|
const char morse_full_stop[] = ".-.-.-";
|
||||||
|
const char morse_comma[] = "--..--";
|
||||||
|
const char morse_question_mark[] = "..--..";
|
||||||
|
const char morse_plus[] = ".-.-.";
|
||||||
|
const char morse_at_sign[] = ".--.-.";
|
||||||
|
const char morse_space[] = " ";
|
||||||
|
|
||||||
|
static const char *morse_get_sequence(char c)
|
||||||
|
{
|
||||||
|
if (c >= 'A' && c <= 'Z') { // Uppercase letters
|
||||||
|
return morse_letters[c - 'A'];
|
||||||
|
} else if (c >= 'a' && c <= 'z') { // Lowercase letters
|
||||||
|
return morse_letters[c - 'a'];
|
||||||
|
} else if (c >= '0' && c <= '9') { // Numbers
|
||||||
|
return morse_numbers[c - '0'];
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '/':
|
||||||
|
return morse_stroke;
|
||||||
|
case '=':
|
||||||
|
return morse_equal;
|
||||||
|
case '.':
|
||||||
|
return morse_full_stop;
|
||||||
|
case ',':
|
||||||
|
return morse_comma;
|
||||||
|
case '?':
|
||||||
|
return morse_question_mark;
|
||||||
|
case '+':
|
||||||
|
return morse_plus;
|
||||||
|
case '@':
|
||||||
|
return morse_at_sign;
|
||||||
|
default:
|
||||||
|
// Treat all other characters as a space
|
||||||
|
return morse_space;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct _morse_encoder {
|
||||||
|
uint32_t symbol_rate;
|
||||||
|
|
||||||
|
uint16_t data_length;
|
||||||
|
uint8_t *data;
|
||||||
|
|
||||||
|
uint16_t current_byte_index;
|
||||||
|
|
||||||
|
const char *current_sequence;
|
||||||
|
uint8_t current_sequence_index;
|
||||||
|
|
||||||
|
bool tone_active;
|
||||||
|
uint8_t units_left;
|
||||||
|
|
||||||
|
bool start;
|
||||||
|
|
||||||
|
fsk_tone tones[2];
|
||||||
|
} morse_encoder;
|
||||||
|
|
||||||
|
void morse_encoder_new(fsk_encoder *encoder, uint32_t symbol_rate)
|
||||||
|
{
|
||||||
|
encoder->priv = malloc(sizeof(morse_encoder));
|
||||||
|
memset(encoder->priv, 0, sizeof(morse_encoder));
|
||||||
|
|
||||||
|
morse_encoder *morse = (morse_encoder *) encoder->priv;
|
||||||
|
morse->symbol_rate = symbol_rate;
|
||||||
|
|
||||||
|
for (int i = 0; i < 2; i++) {
|
||||||
|
morse->tones[i].index = (int8_t) i;
|
||||||
|
morse->tones[i].frequency_hz_100 = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void morse_encoder_destroy(fsk_encoder *encoder)
|
||||||
|
{
|
||||||
|
if (encoder->priv != NULL) {
|
||||||
|
free(encoder->priv);
|
||||||
|
encoder->priv = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void morse_encoder_set_data(fsk_encoder *encoder, uint16_t data_length, uint8_t *data)
|
||||||
|
{
|
||||||
|
morse_encoder *morse = (morse_encoder *) encoder->priv;
|
||||||
|
|
||||||
|
morse->data = data;
|
||||||
|
morse->data_length = data_length;
|
||||||
|
|
||||||
|
morse->current_byte_index = 0;
|
||||||
|
morse->current_sequence = morse_get_sequence((char) data[0]);
|
||||||
|
morse->current_sequence_index = 0;
|
||||||
|
morse->tone_active = false;
|
||||||
|
morse->units_left = 0;
|
||||||
|
morse->start = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void morse_encoder_get_tones(fsk_encoder *encoder, int8_t *tone_count, fsk_tone **tones)
|
||||||
|
{
|
||||||
|
morse_encoder *morse = (morse_encoder *) encoder->priv;
|
||||||
|
|
||||||
|
*tone_count = 2;
|
||||||
|
*tones = morse->tones;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t morse_encoder_get_tone_spacing(fsk_encoder *encoder)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t morse_encoder_get_symbol_rate(fsk_encoder *encoder)
|
||||||
|
{
|
||||||
|
morse_encoder *morse = (morse_encoder *) encoder->priv;
|
||||||
|
return morse->symbol_rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t morse_encoder_get_symbol_delay(fsk_encoder *encoder)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t morse_encoder_next_tone(fsk_encoder *encoder)
|
||||||
|
{
|
||||||
|
morse_encoder *morse = (morse_encoder *) encoder->priv;
|
||||||
|
|
||||||
|
if (morse->current_byte_index >= morse->data_length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!morse->start && morse->units_left == 0) {
|
||||||
|
char next_element = morse->current_sequence[morse->current_sequence_index + 1];
|
||||||
|
if (morse->tone_active) {
|
||||||
|
if (next_element == 0) {
|
||||||
|
bool char_gap = true;
|
||||||
|
|
||||||
|
if (morse->current_byte_index + 1 < morse->data_length) {
|
||||||
|
const char *next_byte_sequence = morse_get_sequence((char) morse->data[morse->current_byte_index + 1]);
|
||||||
|
if (next_byte_sequence[0] == MORSE_SPACE) {
|
||||||
|
char_gap = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
char_gap = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (char_gap) {
|
||||||
|
// Char gap
|
||||||
|
morse->tone_active = false;
|
||||||
|
morse->units_left = MORSE_UNITS_GAP - 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unit gap
|
||||||
|
morse->tone_active = false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
morse->current_sequence_index++;
|
||||||
|
|
||||||
|
if (next_element == 0) {
|
||||||
|
morse->current_byte_index++;
|
||||||
|
|
||||||
|
if (morse->current_byte_index >= morse->data_length) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
morse->current_sequence = morse_get_sequence((char) morse->data[morse->current_byte_index]);
|
||||||
|
morse->current_sequence_index = 0;
|
||||||
|
|
||||||
|
morse->tone_active = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
morse->start = false;
|
||||||
|
|
||||||
|
char element = morse->current_sequence[morse->current_sequence_index];
|
||||||
|
|
||||||
|
if (morse->units_left > 0) {
|
||||||
|
morse->units_left--;
|
||||||
|
return morse->tone_active ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element == MORSE_DOT) {
|
||||||
|
morse->units_left = MORSE_UNITS_DOT;
|
||||||
|
morse->tone_active = true;
|
||||||
|
} else if (element == MORSE_DASH) {
|
||||||
|
morse->units_left = MORSE_UNITS_DASH;
|
||||||
|
morse->tone_active = true;
|
||||||
|
} else {
|
||||||
|
morse->units_left = MORSE_UNITS_SPACE;
|
||||||
|
morse->tone_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
morse->units_left--;
|
||||||
|
|
||||||
|
return morse->tone_active ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fsk_encoder_api morse_fsk_encoder_api = {
|
||||||
|
.get_tones = morse_encoder_get_tones,
|
||||||
|
.get_tone_spacing = morse_encoder_get_tone_spacing,
|
||||||
|
.get_symbol_rate = morse_encoder_get_symbol_rate,
|
||||||
|
.get_symbol_delay = morse_encoder_get_symbol_delay,
|
||||||
|
.set_data = morse_encoder_set_data,
|
||||||
|
.next_tone = morse_encoder_next_tone,
|
||||||
|
};
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef __MORSE_H
|
||||||
|
#define __MORSE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "codecs/fsk/fsk.h"
|
||||||
|
|
||||||
|
void morse_encoder_new(fsk_encoder *encoder, uint32_t symbol_rate);
|
||||||
|
void morse_encoder_destroy(fsk_encoder *encoder);
|
||||||
|
void morse_encoder_set_data(fsk_encoder *encoder, uint16_t data_length, uint8_t *data);
|
||||||
|
void morse_encoder_get_tones(fsk_encoder *encoder, int8_t *tone_count, fsk_tone **tones);
|
||||||
|
uint32_t morse_encoder_get_symbol_rate(fsk_encoder *encoder);
|
||||||
|
uint32_t morse_encoder_get_symbol_delay(fsk_encoder *encoder);
|
||||||
|
int8_t morse_encoder_next_tone(fsk_encoder *encoder);
|
||||||
|
|
||||||
|
extern fsk_encoder_api morse_fsk_encoder_api;
|
||||||
|
|
||||||
|
#endif
|
24
src/config.c
24
src/config.c
|
@ -46,6 +46,16 @@ bool si5351_enabled = RADIO_SI5351_ENABLE;
|
||||||
|
|
||||||
volatile bool system_initialized = false;
|
volatile bool system_initialized = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CW mode messages.
|
||||||
|
* Maximum length: 64 characters.
|
||||||
|
*/
|
||||||
|
char *cw_message_templates[] = {
|
||||||
|
"$cs",
|
||||||
|
"$loc6",
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APRS mode comment messages.
|
* APRS mode comment messages.
|
||||||
* Maximum length: depends on the packet contents, but keeping this under 100 characters is usually safe.
|
* Maximum length: depends on the packet contents, but keeping this under 100 characters is usually safe.
|
||||||
|
@ -64,8 +74,8 @@ char *aprs_comment_templates[] = {
|
||||||
* Maximum length: 130 characters.
|
* Maximum length: 130 characters.
|
||||||
*/
|
*/
|
||||||
char *fsq_comment_templates[] = {
|
char *fsq_comment_templates[] = {
|
||||||
" $lat $lon, $alt m, $cl m/s, $gs km/h, $he deg - " FSQ_COMMENT,
|
// " $lat $lon, $alt m, $cl m/s, $gs km/h, $he deg - " FSQ_COMMENT,
|
||||||
" $loc12, $teC $hu% $prmb $hh:$mm:$ss @ $tow ms - " FSQ_COMMENT,
|
// " $loc12, $teC $hu% $prmb $hh:$mm:$ss @ $tow ms - " FSQ_COMMENT,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,10 +84,10 @@ char *fsq_comment_templates[] = {
|
||||||
* Maximum length: 13 characters allowed by the protocols.
|
* Maximum length: 13 characters allowed by the protocols.
|
||||||
*/
|
*/
|
||||||
char *ftjt_message_templates[] = {
|
char *ftjt_message_templates[] = {
|
||||||
"$cs $loc4",
|
// "$cs $loc4",
|
||||||
"$loc12",
|
// "$loc12",
|
||||||
"$altm $cl",
|
// "$altm $cl",
|
||||||
"$bvmV $tiC",
|
// "$bvmV $tiC",
|
||||||
"$hu% $prmb",
|
// "$hu% $prmb",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
16
src/config.h
16
src/config.h
|
@ -42,14 +42,12 @@
|
||||||
#define RADIO_SI4032_TX_POWER 7
|
#define RADIO_SI4032_TX_POWER 7
|
||||||
|
|
||||||
// Which modes to transmit using the built-in Si4032 transmitter chip
|
// Which modes to transmit using the built-in Si4032 transmitter chip
|
||||||
#define RADIO_SI4032_TX_CW false
|
#define RADIO_SI4032_TX_CW true
|
||||||
#define RADIO_SI4032_TX_RTTY false
|
|
||||||
#define RADIO_SI4032_TX_APRS true
|
#define RADIO_SI4032_TX_APRS true
|
||||||
#define RADIO_SI4032_TX_HORUS_V1 true
|
#define RADIO_SI4032_TX_HORUS_V1 true
|
||||||
|
|
||||||
// Transmit frequencies for the Si4032 transmitter modes
|
// Transmit frequencies for the Si4032 transmitter modes
|
||||||
#define RADIO_SI4032_TX_FREQUENCY_CW 432060000
|
#define RADIO_SI4032_TX_FREQUENCY_CW 432500000
|
||||||
#define RADIO_SI4032_TX_FREQUENCY_RTTY 432060000
|
|
||||||
#define RADIO_SI4032_TX_FREQUENCY_APRS_1200 432500000
|
#define RADIO_SI4032_TX_FREQUENCY_APRS_1200 432500000
|
||||||
// Use a frequency offset to place FSK tones slightly above the defined frequency for SSB reception
|
// Use a frequency offset to place FSK tones slightly above the defined frequency for SSB reception
|
||||||
#define RADIO_SI4032_TX_FREQUENCY_HORUS_V1 432501000
|
#define RADIO_SI4032_TX_FREQUENCY_HORUS_V1 432501000
|
||||||
|
@ -132,10 +130,16 @@
|
||||||
#define HORUS_V1_TIME_SYNC_OFFSET_SECONDS 0
|
#define HORUS_V1_TIME_SYNC_OFFSET_SECONDS 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: CW settings (once implemented)
|
* CW settings
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CW_LOCATOR_PAIR_COUNT 4 // max. 6 (12 characters WWL)
|
// CW speed in WPM, range 5 - 40
|
||||||
|
#define CW_SPEED_WPM 20
|
||||||
|
|
||||||
|
// Schedule transmission every N seconds, counting from beginning of an hour (based on GPS time). Set to zero to disable time sync.
|
||||||
|
#define CW_TIME_SYNC_SECONDS 1
|
||||||
|
// Delay transmission for an N second offset after the scheduled time.
|
||||||
|
#define CW_TIME_SYNC_OFFSET_SECONDS 0
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WSPR settings
|
* WSPR settings
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
#define RADIO_SYMBOL_DATA_MAX_LENGTH 512
|
#define RADIO_SYMBOL_DATA_MAX_LENGTH 512
|
||||||
#define RADIO_PAYLOAD_MESSAGE_MAX_LENGTH 128
|
#define RADIO_PAYLOAD_MESSAGE_MAX_LENGTH 128
|
||||||
|
|
||||||
|
// PARIS: 50 dot durations, 20 WPM -> 60ms per unit
|
||||||
|
#define MORSE_WPM_TO_SYMBOL_RATE(wpm) (1000 / (60 * 20 / wpm))
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
extern bool leds_enabled;
|
extern bool leds_enabled;
|
||||||
|
@ -13,6 +16,7 @@ extern bool si5351_enabled;
|
||||||
|
|
||||||
extern volatile bool system_initialized;
|
extern volatile bool system_initialized;
|
||||||
|
|
||||||
|
extern char *cw_message_templates[];
|
||||||
extern char *aprs_comment_templates[];
|
extern char *aprs_comment_templates[];
|
||||||
extern char *fsq_comment_templates[];
|
extern char *fsq_comment_templates[];
|
||||||
extern char *ftjt_message_templates[];
|
extern char *ftjt_message_templates[];
|
||||||
|
|
|
@ -7,22 +7,20 @@
|
||||||
|
|
||||||
#define SI4032_CLOCK 26.0f
|
#define SI4032_CLOCK 26.0f
|
||||||
|
|
||||||
#define GPIO_SI_4032_CS GPIOC
|
#define GPIO_SI4032_NSEL GPIOC
|
||||||
#define GPIO_PIN_SI4032_CS GPIO_Pin_13
|
#define GPIO_PIN_SI4032_NSEL GPIO_Pin_13
|
||||||
|
|
||||||
// TODO: For CW support:
|
#define GPIO_SI4032_SDI GPIOB
|
||||||
// TODO: static const uint16_t radioSDIpin = GPIO_Pin_15; // @ GPIOB!
|
#define GPIO_PIN_SI4032_SDI GPIO_Pin_15
|
||||||
// TODO: Add methods to init SDI pin GPIO and to set SDI pin state -> Verify it can be used for OOK (CW), NSEL (CS) must be high
|
|
||||||
// TODO: Call uninitialization of PWM timer after use so that SDI pin is free to use
|
|
||||||
|
|
||||||
static inline uint8_t si4032_write(uint8_t reg, uint8_t value)
|
static inline uint8_t si4032_write(uint8_t reg, uint8_t value)
|
||||||
{
|
{
|
||||||
return spi_send_and_receive(GPIO_SI_4032_CS, GPIO_PIN_SI4032_CS, ((reg | SPI_WRITE_FLAG) << 8U) | value);
|
return spi_send_and_receive(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL, ((reg | SPI_WRITE_FLAG) << 8U) | value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint8_t si4032_read(uint8_t reg)
|
static inline uint8_t si4032_read(uint8_t reg)
|
||||||
{
|
{
|
||||||
return spi_send_and_receive(GPIO_SI_4032_CS, GPIO_PIN_SI4032_CS, (reg << 8U) | 0xFFU);
|
return spi_send_and_receive(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL, (reg << 8U) | 0xFFU);
|
||||||
}
|
}
|
||||||
|
|
||||||
void si4032_soft_reset()
|
void si4032_soft_reset()
|
||||||
|
@ -50,9 +48,9 @@ void si4032_disable_tx()
|
||||||
void si4032_use_direct_mode(bool use)
|
void si4032_use_direct_mode(bool use)
|
||||||
{
|
{
|
||||||
if (use) {
|
if (use) {
|
||||||
GPIO_SetBits(GPIO_SI_4032_CS, GPIO_PIN_SI4032_CS);
|
GPIO_SetBits(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL);
|
||||||
} else {
|
} else {
|
||||||
GPIO_ResetBits(GPIO_SI_4032_CS, GPIO_PIN_SI4032_CS);
|
GPIO_ResetBits(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,15 +136,49 @@ int32_t si4032_read_temperature_celsius_100()
|
||||||
return temperature;
|
return temperature;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void si4032_set_nsel_pin(bool high)
|
||||||
|
{
|
||||||
|
if (high) {
|
||||||
|
GPIO_SetBits(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL);
|
||||||
|
} else {
|
||||||
|
GPIO_ResetBits(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void si4032_set_sdi_pin(bool high)
|
||||||
|
{
|
||||||
|
if (high) {
|
||||||
|
GPIO_SetBits(GPIO_SI4032_SDI, GPIO_PIN_SI4032_SDI);
|
||||||
|
} else {
|
||||||
|
GPIO_ResetBits(GPIO_SI4032_SDI, GPIO_PIN_SI4032_SDI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void si4032_use_sdi_pin(bool use)
|
||||||
|
{
|
||||||
|
GPIO_InitTypeDef gpio_init;
|
||||||
|
|
||||||
|
si4032_set_nsel_pin(true);
|
||||||
|
|
||||||
|
gpio_init.GPIO_Pin = GPIO_PIN_SI4032_SDI;
|
||||||
|
gpio_init.GPIO_Mode = use ? GPIO_Mode_Out_PP : GPIO_Mode_AF_PP;
|
||||||
|
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
|
GPIO_Init(GPIO_SI4032_SDI, &gpio_init);
|
||||||
|
|
||||||
|
si4032_set_sdi_pin(false);
|
||||||
|
}
|
||||||
|
|
||||||
void si4032_init()
|
void si4032_init()
|
||||||
{
|
{
|
||||||
GPIO_InitTypeDef gpio_init;
|
GPIO_InitTypeDef gpio_init;
|
||||||
|
|
||||||
// Si4032 chip select pin
|
// Si4032 chip select pin
|
||||||
gpio_init.GPIO_Pin = GPIO_PIN_SI4032_CS;
|
gpio_init.GPIO_Pin = GPIO_PIN_SI4032_NSEL;
|
||||||
gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
|
gpio_init.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||||
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
|
gpio_init.GPIO_Speed = GPIO_Speed_50MHz;
|
||||||
GPIO_Init(GPIO_SI_4032_CS, &gpio_init);
|
GPIO_Init(GPIO_SI4032_NSEL, &gpio_init);
|
||||||
|
|
||||||
|
si4032_set_nsel_pin(true);
|
||||||
|
|
||||||
si4032_soft_reset();
|
si4032_soft_reset();
|
||||||
si4032_set_tx_power(0);
|
si4032_set_tx_power(0);
|
||||||
|
|
|
@ -22,6 +22,8 @@ void si4032_set_frequency_offset_small(uint8_t offset);
|
||||||
void si4032_set_frequency_deviation(uint8_t deviation);
|
void si4032_set_frequency_deviation(uint8_t deviation);
|
||||||
void si4032_set_modulation_type(si4032_modulation_type type);
|
void si4032_set_modulation_type(si4032_modulation_type type);
|
||||||
int32_t si4032_read_temperature_celsius_100();
|
int32_t si4032_read_temperature_celsius_100();
|
||||||
|
void si4032_set_sdi_pin(bool high);
|
||||||
|
void si4032_use_sdi_pin(bool use);
|
||||||
void si4032_init();
|
void si4032_init();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
23
src/radio.c
23
src/radio.c
|
@ -6,6 +6,7 @@
|
||||||
#include "hal/system.h"
|
#include "hal/system.h"
|
||||||
#include "hal/delay.h"
|
#include "hal/delay.h"
|
||||||
#include "hal/usart_gps.h"
|
#include "hal/usart_gps.h"
|
||||||
|
#include "codecs/morse/morse.h"
|
||||||
#include "codecs/bell/bell.h"
|
#include "codecs/bell/bell.h"
|
||||||
#include "codecs/mfsk/mfsk.h"
|
#include "codecs/mfsk/mfsk.h"
|
||||||
#include "codecs/jtencode/jtencode.h"
|
#include "codecs/jtencode/jtencode.h"
|
||||||
|
@ -13,6 +14,7 @@
|
||||||
#include "radio_internal.h"
|
#include "radio_internal.h"
|
||||||
#include "radio_si4032.h"
|
#include "radio_si4032.h"
|
||||||
#include "radio_si5351.h"
|
#include "radio_si5351.h"
|
||||||
|
#include "radio_payload_cw.h"
|
||||||
#include "radio_payload_aprs.h"
|
#include "radio_payload_aprs.h"
|
||||||
#include "radio_payload_horus_v1.h"
|
#include "radio_payload_horus_v1.h"
|
||||||
#include "radio_payload_wspr.h"
|
#include "radio_payload_wspr.h"
|
||||||
|
@ -20,6 +22,18 @@
|
||||||
#include "radio_payload_fsq.h"
|
#include "radio_payload_fsq.h"
|
||||||
|
|
||||||
radio_transmit_entry radio_transmit_schedule[] = {
|
radio_transmit_entry radio_transmit_schedule[] = {
|
||||||
|
{
|
||||||
|
.enabled = RADIO_SI4032_TX_CW,
|
||||||
|
.radio_type = RADIO_TYPE_SI4032,
|
||||||
|
.data_mode = RADIO_DATA_MODE_CW,
|
||||||
|
.time_sync_seconds = CW_TIME_SYNC_SECONDS,
|
||||||
|
.time_sync_seconds_offset = CW_TIME_SYNC_OFFSET_SECONDS,
|
||||||
|
.frequency = RADIO_SI4032_TX_FREQUENCY_CW,
|
||||||
|
.tx_power = RADIO_SI4032_TX_POWER,
|
||||||
|
.symbol_rate = MORSE_WPM_TO_SYMBOL_RATE(CW_SPEED_WPM),
|
||||||
|
.payload_encoder = &radio_cw_payload_encoder,
|
||||||
|
.fsk_encoder_api = &morse_fsk_encoder_api,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.enabled = RADIO_SI4032_TX_APRS,
|
.enabled = RADIO_SI4032_TX_APRS,
|
||||||
.radio_type = RADIO_TYPE_SI4032,
|
.radio_type = RADIO_TYPE_SI4032,
|
||||||
|
@ -233,6 +247,11 @@ static bool radio_start_transmit(radio_transmit_entry *entry)
|
||||||
|
|
||||||
switch (entry->data_mode) {
|
switch (entry->data_mode) {
|
||||||
case RADIO_DATA_MODE_CW:
|
case RADIO_DATA_MODE_CW:
|
||||||
|
morse_encoder_new(&entry->fsk_encoder, entry->symbol_rate);
|
||||||
|
radio_shared_state.radio_current_symbol_rate = entry->fsk_encoder_api->get_symbol_rate(&entry->fsk_encoder);
|
||||||
|
entry->fsk_encoder_api->get_tones(&entry->fsk_encoder, &radio_shared_state.radio_current_fsk_tone_count,
|
||||||
|
&radio_shared_state.radio_current_fsk_tones);
|
||||||
|
entry->fsk_encoder_api->set_data(&entry->fsk_encoder, radio_current_payload_length, radio_current_payload);
|
||||||
break;
|
break;
|
||||||
case RADIO_DATA_MODE_RTTY:
|
case RADIO_DATA_MODE_RTTY:
|
||||||
break;
|
break;
|
||||||
|
@ -354,6 +373,7 @@ static bool radio_stop_transmit(radio_transmit_entry *entry)
|
||||||
|
|
||||||
switch (entry->data_mode) {
|
switch (entry->data_mode) {
|
||||||
case RADIO_DATA_MODE_CW:
|
case RADIO_DATA_MODE_CW:
|
||||||
|
morse_encoder_destroy(&entry->fsk_encoder);
|
||||||
break;
|
break;
|
||||||
case RADIO_DATA_MODE_RTTY:
|
case RADIO_DATA_MODE_RTTY:
|
||||||
break;
|
break;
|
||||||
|
@ -616,6 +636,9 @@ void radio_init()
|
||||||
for (uint8_t i = 0; i < radio_transmit_entry_count; i++) {
|
for (uint8_t i = 0; i < radio_transmit_entry_count; i++) {
|
||||||
radio_transmit_entry *entry = &radio_transmit_schedule[i];
|
radio_transmit_entry *entry = &radio_transmit_schedule[i];
|
||||||
switch (entry->data_mode) {
|
switch (entry->data_mode) {
|
||||||
|
case RADIO_DATA_MODE_CW:
|
||||||
|
entry->messages = cw_message_templates;
|
||||||
|
break;
|
||||||
case RADIO_DATA_MODE_APRS_1200:
|
case RADIO_DATA_MODE_APRS_1200:
|
||||||
entry->messages = aprs_comment_templates;
|
entry->messages = aprs_comment_templates;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "radio_payload_cw.h"
|
||||||
|
|
||||||
|
uint16_t radio_cw_encode(uint8_t *payload, uint16_t length, telemetry_data *telemetry_data, char *message)
|
||||||
|
{
|
||||||
|
return snprintf((char *) payload, length, "%s", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
payload_encoder radio_cw_payload_encoder = {
|
||||||
|
.encode = radio_cw_encode,
|
||||||
|
};
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef __RADIO_PAYLOAD_CW_H
|
||||||
|
#define __RADIO_PAYLOAD_CW_H
|
||||||
|
|
||||||
|
#include "payload.h"
|
||||||
|
|
||||||
|
extern payload_encoder radio_cw_payload_encoder;
|
||||||
|
|
||||||
|
#endif
|
|
@ -12,6 +12,8 @@
|
||||||
#include "radio_si4032.h"
|
#include "radio_si4032.h"
|
||||||
#include "codecs/mfsk/mfsk.h"
|
#include "codecs/mfsk/mfsk.h"
|
||||||
|
|
||||||
|
#define CW_SYMBOL_RATE_MULTIPLIER 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* I have attempted to implement Bell 202 frequency generation using hardware DMA and PWM, but have failed to generate
|
* I have attempted to implement Bell 202 frequency generation using hardware DMA and PWM, but have failed to generate
|
||||||
* correct symbol rate that other APRS equipment are able to decode. I have tried to decode the DMA-based modulation with
|
* correct symbol rate that other APRS equipment are able to decode. I have tried to decode the DMA-based modulation with
|
||||||
|
@ -46,6 +48,8 @@ bool radio_start_transmit_si4032(radio_transmit_entry *entry, radio_module_state
|
||||||
frequency_offset = 1;
|
frequency_offset = 1;
|
||||||
modulation_type = SI4032_MODULATION_TYPE_OOK;
|
modulation_type = SI4032_MODULATION_TYPE_OOK;
|
||||||
use_direct_mode = false;
|
use_direct_mode = false;
|
||||||
|
|
||||||
|
data_timer_init(entry->symbol_rate * CW_SYMBOL_RATE_MULTIPLIER);
|
||||||
break;
|
break;
|
||||||
case RADIO_DATA_MODE_RTTY:
|
case RADIO_DATA_MODE_RTTY:
|
||||||
frequency_offset = 0;
|
frequency_offset = 0;
|
||||||
|
@ -83,12 +87,19 @@ bool radio_start_transmit_si4032(radio_transmit_entry *entry, radio_module_state
|
||||||
|
|
||||||
if (use_direct_mode) {
|
if (use_direct_mode) {
|
||||||
spi_uninit();
|
spi_uninit();
|
||||||
|
pwm_timer_init(100 * 100); // TODO: Idle tone
|
||||||
pwm_timer_use(true);
|
pwm_timer_use(true);
|
||||||
pwm_timer_pwm_enable(true);
|
pwm_timer_pwm_enable(true);
|
||||||
si4032_use_direct_mode(true);
|
si4032_use_direct_mode(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (entry->data_mode) {
|
switch (entry->data_mode) {
|
||||||
|
case RADIO_DATA_MODE_CW:
|
||||||
|
spi_uninit();
|
||||||
|
system_disable_tick();
|
||||||
|
si4032_use_sdi_pin(true);
|
||||||
|
shared_state->radio_interrupt_transmit_active = true;
|
||||||
|
break;
|
||||||
case RADIO_DATA_MODE_APRS_1200:
|
case RADIO_DATA_MODE_APRS_1200:
|
||||||
if (si4032_use_dma) {
|
if (si4032_use_dma) {
|
||||||
shared_state->radio_dma_transfer_active = true;
|
shared_state->radio_dma_transfer_active = true;
|
||||||
|
@ -196,11 +207,40 @@ void radio_handle_main_loop_si4032(radio_transmit_entry *entry, radio_module_sta
|
||||||
|
|
||||||
inline void radio_handle_data_timer_si4032()
|
inline void radio_handle_data_timer_si4032()
|
||||||
{
|
{
|
||||||
|
static int cw_symbol_rate_multiplier = CW_SYMBOL_RATE_MULTIPLIER;
|
||||||
|
|
||||||
if (radio_current_transmit_entry->radio_type != RADIO_TYPE_SI4032 || !radio_shared_state.radio_interrupt_transmit_active) {
|
if (radio_current_transmit_entry->radio_type != RADIO_TYPE_SI4032 || !radio_shared_state.radio_interrupt_transmit_active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (radio_current_transmit_entry->data_mode) {
|
switch (radio_current_transmit_entry->data_mode) {
|
||||||
|
case RADIO_DATA_MODE_CW: {
|
||||||
|
cw_symbol_rate_multiplier--;
|
||||||
|
if (cw_symbol_rate_multiplier > 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cw_symbol_rate_multiplier = CW_SYMBOL_RATE_MULTIPLIER;
|
||||||
|
|
||||||
|
fsk_encoder_api *fsk_encoder_api = radio_current_transmit_entry->fsk_encoder_api;
|
||||||
|
fsk_encoder *fsk_enc = &radio_current_transmit_entry->fsk_encoder;
|
||||||
|
int8_t tone_index;
|
||||||
|
|
||||||
|
tone_index = fsk_encoder_api->next_tone(fsk_enc);
|
||||||
|
if (tone_index < 0) {
|
||||||
|
si4032_set_sdi_pin(false);
|
||||||
|
log_info("CW TX finished\n");
|
||||||
|
radio_shared_state.radio_interrupt_transmit_active = false;
|
||||||
|
radio_shared_state.radio_transmission_finished = true;
|
||||||
|
system_enable_tick();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
si4032_set_sdi_pin(tone_index == 0 ? false : true);
|
||||||
|
|
||||||
|
radio_shared_state.radio_symbol_count_interrupt++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case RADIO_DATA_MODE_HORUS_V1: {
|
case RADIO_DATA_MODE_HORUS_V1: {
|
||||||
fsk_encoder_api *fsk_encoder_api = radio_current_transmit_entry->fsk_encoder_api;
|
fsk_encoder_api *fsk_encoder_api = radio_current_transmit_entry->fsk_encoder_api;
|
||||||
fsk_encoder *fsk_enc = &radio_current_transmit_entry->fsk_encoder;
|
fsk_encoder *fsk_enc = &radio_current_transmit_entry->fsk_encoder;
|
||||||
|
@ -216,6 +256,7 @@ inline void radio_handle_data_timer_si4032()
|
||||||
}
|
}
|
||||||
|
|
||||||
si4032_set_frequency_offset_small(tone_index + HORUS_V1_FREQUENCY_OFFSET);
|
si4032_set_frequency_offset_small(tone_index + HORUS_V1_FREQUENCY_OFFSET);
|
||||||
|
|
||||||
radio_shared_state.radio_symbol_count_interrupt++;
|
radio_shared_state.radio_symbol_count_interrupt++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -230,9 +271,13 @@ bool radio_stop_transmit_si4032(radio_transmit_entry *entry, radio_module_state
|
||||||
|
|
||||||
switch (entry->data_mode) {
|
switch (entry->data_mode) {
|
||||||
case RADIO_DATA_MODE_CW:
|
case RADIO_DATA_MODE_CW:
|
||||||
|
si4032_use_sdi_pin(false);
|
||||||
|
data_timer_uninit();
|
||||||
|
spi_init();
|
||||||
|
break;
|
||||||
case RADIO_DATA_MODE_RTTY:
|
case RADIO_DATA_MODE_RTTY:
|
||||||
case RADIO_DATA_MODE_HORUS_V1:
|
case RADIO_DATA_MODE_HORUS_V1:
|
||||||
use_direct_mode = false;
|
data_timer_uninit();
|
||||||
break;
|
break;
|
||||||
case RADIO_DATA_MODE_APRS_1200:
|
case RADIO_DATA_MODE_APRS_1200:
|
||||||
use_direct_mode = true;
|
use_direct_mode = true;
|
||||||
|
@ -245,12 +290,16 @@ bool radio_stop_transmit_si4032(radio_transmit_entry *entry, radio_module_state
|
||||||
si4032_use_direct_mode(false);
|
si4032_use_direct_mode(false);
|
||||||
pwm_timer_pwm_enable(false);
|
pwm_timer_pwm_enable(false);
|
||||||
pwm_timer_use(false);
|
pwm_timer_use(false);
|
||||||
|
pwm_timer_uninit();
|
||||||
spi_init();
|
spi_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
si4032_inhibit_tx();
|
si4032_inhibit_tx();
|
||||||
|
|
||||||
switch (entry->data_mode) {
|
switch (entry->data_mode) {
|
||||||
|
case RADIO_DATA_MODE_CW:
|
||||||
|
system_enable_tick();
|
||||||
|
break;
|
||||||
case RADIO_DATA_MODE_APRS_1200:
|
case RADIO_DATA_MODE_APRS_1200:
|
||||||
if (si4032_use_dma) {
|
if (si4032_use_dma) {
|
||||||
pwm_data_timer_uninit();
|
pwm_data_timer_uninit();
|
||||||
|
@ -258,7 +307,6 @@ bool radio_stop_transmit_si4032(radio_transmit_entry *entry, radio_module_state
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case RADIO_DATA_MODE_HORUS_V1:
|
case RADIO_DATA_MODE_HORUS_V1:
|
||||||
data_timer_uninit();
|
|
||||||
system_enable_tick();
|
system_enable_tick();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -338,8 +386,6 @@ void radio_init_si4032()
|
||||||
pwm_handle_dma_transfer_half = radio_si4032_handle_pwm_transfer_half;
|
pwm_handle_dma_transfer_half = radio_si4032_handle_pwm_transfer_half;
|
||||||
pwm_handle_dma_transfer_full = radio_si4032_handle_pwm_transfer_full;
|
pwm_handle_dma_transfer_full = radio_si4032_handle_pwm_transfer_full;
|
||||||
|
|
||||||
pwm_timer_init(100 * 100);
|
|
||||||
|
|
||||||
if (si4032_use_dma) {
|
if (si4032_use_dma) {
|
||||||
pwm_data_timer_init();
|
pwm_data_timer_init();
|
||||||
pwm_dma_init();
|
pwm_dma_init();
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "codecs/morse/morse.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
fsk_encoder morse;
|
||||||
|
|
||||||
|
printf("%d\n", MORSE_WPM_TO_SYMBOL_RATE(20));
|
||||||
|
printf("%d\n", MORSE_WPM_TO_SYMBOL_RATE(15));
|
||||||
|
printf("%d\n", MORSE_WPM_TO_SYMBOL_RATE(10));
|
||||||
|
|
||||||
|
char *input = "TEST T";
|
||||||
|
|
||||||
|
morse_encoder_new(&morse, 25);
|
||||||
|
|
||||||
|
morse_encoder_set_data(&morse, strlen(input), (uint8_t *) input);
|
||||||
|
|
||||||
|
int8_t tone_index;
|
||||||
|
|
||||||
|
while ((tone_index = morse_encoder_next_tone(&morse)) >= 0) {
|
||||||
|
printf("CW: %d\n", tone_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
morse_encoder_destroy(&morse);
|
||||||
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
#include <bsd/string.h>
|
#include <bsd/string.h>
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
|
|
||||||
int main(void)
|
int main3(void)
|
||||||
{
|
{
|
||||||
char *source = "DE $cs: $bv $loc6, $hh:$mm:$ss, $tow, Ti$ti Te$te $hu $pr";
|
char *source = "DE $cs: $bv $loc6, $hh:$mm:$ss, $tow, Ti$ti Te$te $hu $pr";
|
||||||
char dest[512];
|
char dest[512];
|
||||||
|
|
Ładowanie…
Reference in New Issue