Add support for morse code (CW)

pull/11/head
Mikael Nousiainen 2021-08-13 00:42:50 +03:00
rodzic 6d2416d307
commit 7af1ada130
15 zmienionych plików z 482 dodań i 194 usunięć

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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

Wyświetl plik

@ -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,
};

Wyświetl plik

@ -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

Wyświetl plik

@ -46,6 +46,16 @@ bool si5351_enabled = RADIO_SI5351_ENABLE;
volatile bool system_initialized = false;
/**
* CW mode messages.
* Maximum length: 64 characters.
*/
char *cw_message_templates[] = {
"$cs",
"$loc6",
NULL
};
/**
* APRS mode comment messages.
* 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.
*/
char *fsq_comment_templates[] = {
" $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,
// " $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,
NULL
};
@ -74,10 +84,10 @@ char *fsq_comment_templates[] = {
* Maximum length: 13 characters allowed by the protocols.
*/
char *ftjt_message_templates[] = {
"$cs $loc4",
"$loc12",
"$altm $cl",
"$bvmV $tiC",
"$hu% $prmb",
// "$cs $loc4",
// "$loc12",
// "$altm $cl",
// "$bvmV $tiC",
// "$hu% $prmb",
NULL
};

Wyświetl plik

@ -42,14 +42,12 @@
#define RADIO_SI4032_TX_POWER 7
// Which modes to transmit using the built-in Si4032 transmitter chip
#define RADIO_SI4032_TX_CW false
#define RADIO_SI4032_TX_RTTY false
#define RADIO_SI4032_TX_CW true
#define RADIO_SI4032_TX_APRS true
#define RADIO_SI4032_TX_HORUS_V1 true
// Transmit frequencies for the Si4032 transmitter modes
#define RADIO_SI4032_TX_FREQUENCY_CW 432060000
#define RADIO_SI4032_TX_FREQUENCY_RTTY 432060000
#define RADIO_SI4032_TX_FREQUENCY_CW 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
#define RADIO_SI4032_TX_FREQUENCY_HORUS_V1 432501000
@ -132,10 +130,16 @@
#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

Wyświetl plik

@ -5,6 +5,9 @@
#define RADIO_SYMBOL_DATA_MAX_LENGTH 512
#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>
extern bool leds_enabled;
@ -13,6 +16,7 @@ extern bool si5351_enabled;
extern volatile bool system_initialized;
extern char *cw_message_templates[];
extern char *aprs_comment_templates[];
extern char *fsq_comment_templates[];
extern char *ftjt_message_templates[];

Wyświetl plik

@ -7,22 +7,20 @@
#define SI4032_CLOCK 26.0f
#define GPIO_SI_4032_CS GPIOC
#define GPIO_PIN_SI4032_CS GPIO_Pin_13
#define GPIO_SI4032_NSEL GPIOC
#define GPIO_PIN_SI4032_NSEL GPIO_Pin_13
// TODO: For CW support:
// TODO: static const uint16_t radioSDIpin = GPIO_Pin_15; // @ GPIOB!
// 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
#define GPIO_SI4032_SDI GPIOB
#define GPIO_PIN_SI4032_SDI GPIO_Pin_15
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)
{
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()
@ -50,9 +48,9 @@ void si4032_disable_tx()
void si4032_use_direct_mode(bool use)
{
if (use) {
GPIO_SetBits(GPIO_SI_4032_CS, GPIO_PIN_SI4032_CS);
GPIO_SetBits(GPIO_SI4032_NSEL, GPIO_PIN_SI4032_NSEL);
} 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;
}
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()
{
GPIO_InitTypeDef gpio_init;
// 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_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_set_tx_power(0);

Wyświetl plik

@ -22,6 +22,8 @@ void si4032_set_frequency_offset_small(uint8_t offset);
void si4032_set_frequency_deviation(uint8_t deviation);
void si4032_set_modulation_type(si4032_modulation_type type);
int32_t si4032_read_temperature_celsius_100();
void si4032_set_sdi_pin(bool high);
void si4032_use_sdi_pin(bool use);
void si4032_init();
#endif

Wyświetl plik

@ -6,6 +6,7 @@
#include "hal/system.h"
#include "hal/delay.h"
#include "hal/usart_gps.h"
#include "codecs/morse/morse.h"
#include "codecs/bell/bell.h"
#include "codecs/mfsk/mfsk.h"
#include "codecs/jtencode/jtencode.h"
@ -13,6 +14,7 @@
#include "radio_internal.h"
#include "radio_si4032.h"
#include "radio_si5351.h"
#include "radio_payload_cw.h"
#include "radio_payload_aprs.h"
#include "radio_payload_horus_v1.h"
#include "radio_payload_wspr.h"
@ -20,6 +22,18 @@
#include "radio_payload_fsq.h"
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,
.radio_type = RADIO_TYPE_SI4032,
@ -233,6 +247,11 @@ static bool radio_start_transmit(radio_transmit_entry *entry)
switch (entry->data_mode) {
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;
case RADIO_DATA_MODE_RTTY:
break;
@ -354,6 +373,7 @@ static bool radio_stop_transmit(radio_transmit_entry *entry)
switch (entry->data_mode) {
case RADIO_DATA_MODE_CW:
morse_encoder_destroy(&entry->fsk_encoder);
break;
case RADIO_DATA_MODE_RTTY:
break;
@ -616,6 +636,9 @@ void radio_init()
for (uint8_t i = 0; i < radio_transmit_entry_count; i++) {
radio_transmit_entry *entry = &radio_transmit_schedule[i];
switch (entry->data_mode) {
case RADIO_DATA_MODE_CW:
entry->messages = cw_message_templates;
break;
case RADIO_DATA_MODE_APRS_1200:
entry->messages = aprs_comment_templates;
break;

Wyświetl plik

@ -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,
};

Wyświetl plik

@ -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

Wyświetl plik

@ -12,6 +12,8 @@
#include "radio_si4032.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
* 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;
modulation_type = SI4032_MODULATION_TYPE_OOK;
use_direct_mode = false;
data_timer_init(entry->symbol_rate * CW_SYMBOL_RATE_MULTIPLIER);
break;
case RADIO_DATA_MODE_RTTY:
frequency_offset = 0;
@ -83,12 +87,19 @@ bool radio_start_transmit_si4032(radio_transmit_entry *entry, radio_module_state
if (use_direct_mode) {
spi_uninit();
pwm_timer_init(100 * 100); // TODO: Idle tone
pwm_timer_use(true);
pwm_timer_pwm_enable(true);
si4032_use_direct_mode(true);
}
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:
if (si4032_use_dma) {
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()
{
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) {
return;
}
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: {
fsk_encoder_api *fsk_encoder_api = radio_current_transmit_entry->fsk_encoder_api;
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);
radio_shared_state.radio_symbol_count_interrupt++;
break;
}
@ -230,9 +271,13 @@ bool radio_stop_transmit_si4032(radio_transmit_entry *entry, radio_module_state
switch (entry->data_mode) {
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_HORUS_V1:
use_direct_mode = false;
data_timer_uninit();
break;
case RADIO_DATA_MODE_APRS_1200:
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);
pwm_timer_pwm_enable(false);
pwm_timer_use(false);
pwm_timer_uninit();
spi_init();
}
si4032_inhibit_tx();
switch (entry->data_mode) {
case RADIO_DATA_MODE_CW:
system_enable_tick();
break;
case RADIO_DATA_MODE_APRS_1200:
if (si4032_use_dma) {
pwm_data_timer_uninit();
@ -258,7 +307,6 @@ bool radio_stop_transmit_si4032(radio_transmit_entry *entry, radio_module_state
}
break;
case RADIO_DATA_MODE_HORUS_V1:
data_timer_uninit();
system_enable_tick();
break;
default:
@ -338,8 +386,6 @@ void radio_init_si4032()
pwm_handle_dma_transfer_half = radio_si4032_handle_pwm_transfer_half;
pwm_handle_dma_transfer_full = radio_si4032_handle_pwm_transfer_full;
pwm_timer_init(100 * 100);
if (si4032_use_dma) {
pwm_data_timer_init();
pwm_dma_init();

28
tests/morse_test.c 100644
Wyświetl plik

@ -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);
}

Wyświetl plik

@ -3,7 +3,7 @@
#include <bsd/string.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 dest[512];