185 lines
4.1 KiB
C++
185 lines
4.1 KiB
C++
#include "morse.h"
|
|
|
|
struct MorseSign {
|
|
// Length of this sign. If Length is 0, Bits is the duration of a pause.
|
|
uint8_t Length;
|
|
uint8_t Bits;
|
|
};
|
|
|
|
const struct MorseSign GetMorseSign(char c) {
|
|
switch (c) {
|
|
case 3: // ETX - End of Text
|
|
return (struct MorseSign){8, 0b01010101};
|
|
case 4: // EOT - End of Transmission
|
|
return (struct MorseSign){0, MORSE_PAUSE_TRANSMISSION};
|
|
case ' ':
|
|
return (struct MorseSign){0, MORSE_PAUSE_WORD};
|
|
case '0':
|
|
return (struct MorseSign){5, 0b11111};
|
|
case '1':
|
|
return (struct MorseSign){5, 0b01111};
|
|
case '2':
|
|
return (struct MorseSign){5, 0b00111};
|
|
case '3':
|
|
return (struct MorseSign){5, 0b00011};
|
|
case '4':
|
|
return (struct MorseSign){5, 0b00001};
|
|
case 5:
|
|
return (struct MorseSign){5, 0b00000};
|
|
case 6:
|
|
return (struct MorseSign){5, 0b10000};
|
|
case 7:
|
|
return (struct MorseSign){5, 0b11000};
|
|
case 8:
|
|
return (struct MorseSign){5, 0b11100};
|
|
case 9:
|
|
return (struct MorseSign){5, 0b11110};
|
|
case 'a':
|
|
case 'A':
|
|
return (struct MorseSign){2, 0b01};
|
|
case 'b':
|
|
case 'B':
|
|
return (struct MorseSign){4, 0b1000};
|
|
case 'c':
|
|
case 'C':
|
|
return (struct MorseSign){4, 0b1010};
|
|
case 'd':
|
|
case 'D':
|
|
return (struct MorseSign){3, 0b100};
|
|
case 'e':
|
|
case 'E':
|
|
return (struct MorseSign){1, 0b0};
|
|
case 'f':
|
|
case 'F':
|
|
return (struct MorseSign){4, 0b0010};
|
|
case 'g':
|
|
case 'G':
|
|
return (struct MorseSign){3, 0b110};
|
|
case 'h':
|
|
case 'H':
|
|
return (struct MorseSign){4, 0b0000};
|
|
case 'i':
|
|
case 'I':
|
|
return (struct MorseSign){2, 0b00};
|
|
case 'j':
|
|
case 'J':
|
|
return (struct MorseSign){4, 0b0111};
|
|
case 'k':
|
|
case 'K':
|
|
return (struct MorseSign){3, 0b101};
|
|
case 'l':
|
|
case 'L':
|
|
return (struct MorseSign){4, 0b0100};
|
|
case 'm':
|
|
case 'M':
|
|
return (struct MorseSign){2, 0b11};
|
|
case 'n':
|
|
case 'N':
|
|
return (struct MorseSign){2, 0b10};
|
|
case 'o':
|
|
case 'O':
|
|
return (struct MorseSign){3, 0b111};
|
|
case 'p':
|
|
case 'P':
|
|
return (struct MorseSign){4, 0b0110};
|
|
case 'q':
|
|
case 'Q':
|
|
return (struct MorseSign){4, 0b1101};
|
|
case 'r':
|
|
case 'R':
|
|
return (struct MorseSign){3, 0b010};
|
|
case 's':
|
|
case 'S':
|
|
return (struct MorseSign){3, 0b000};
|
|
case 't':
|
|
case 'T':
|
|
return (struct MorseSign){1, 0b1};
|
|
case 'u':
|
|
case 'U':
|
|
return (struct MorseSign){3, 0b001};
|
|
case 'v':
|
|
case 'V':
|
|
return (struct MorseSign){4, 0b0001};
|
|
case 'w':
|
|
case 'W':
|
|
return (struct MorseSign){3, 0b011};
|
|
case 'x':
|
|
case 'X':
|
|
return (struct MorseSign){4, 0b1001};
|
|
case 'y':
|
|
case 'Y':
|
|
return (struct MorseSign){4, 0b1011};
|
|
case 'z':
|
|
case 'Z':
|
|
return (struct MorseSign){4, 0b1100};
|
|
default:
|
|
return (struct MorseSign){0, 0};
|
|
}
|
|
}
|
|
|
|
MorseEncoder::MorseEncoder() {
|
|
SetText("");
|
|
}
|
|
MorseEncoder::MorseEncoder(const char *s) {
|
|
SetText(s);
|
|
}
|
|
|
|
void MorseEncoder::SetText(const char *s) {
|
|
p = s;
|
|
bit = 0;
|
|
ticksLeft = 0;
|
|
Transmitting = false;
|
|
}
|
|
|
|
void MorseEncoder::Quiet(int ticks) {
|
|
Transmitting = false;
|
|
ticksLeft = ticks;
|
|
}
|
|
|
|
bool MorseEncoder::Tick() {
|
|
--ticksLeft;
|
|
if (ticksLeft > 0) {
|
|
return true;
|
|
}
|
|
|
|
// We're out of ticks
|
|
|
|
if (!p || !*p) {
|
|
return false;
|
|
}
|
|
|
|
// If we were just transmitting, we have to stop for at least one dit
|
|
if (Transmitting) {
|
|
Transmitting = false;
|
|
ticksLeft = MORSE_DIT;
|
|
return true;
|
|
}
|
|
|
|
const struct MorseSign sign = GetMorseSign(*p);
|
|
if (sign.Length == 0) {
|
|
// Pause
|
|
Transmitting = false;
|
|
ticksLeft = sign.Bits - (MORSE_PAUSE_LETTER - MORSE_DIT);
|
|
++p;
|
|
bit = 0;
|
|
} else if (bit == sign.Length) {
|
|
// All done with that sign!
|
|
Transmitting = false;
|
|
ticksLeft = MORSE_PAUSE_LETTER;
|
|
++p;
|
|
bit = 0;
|
|
} else {
|
|
// Sign
|
|
uint8_t bitMask = 1 << (sign.Length - bit - 1);
|
|
Transmitting = true;
|
|
if (sign.Bits & bitMask) {
|
|
ticksLeft = MORSE_DAH;
|
|
} else {
|
|
ticksLeft = MORSE_DIT;
|
|
}
|
|
++bit;
|
|
}
|
|
|
|
return true;
|
|
}
|