Clean version of the Morse binary format/table and lookup functions.

This commit is contained in:
Stephen Olesen 2015-06-30 15:13:55 -06:00
parent 8fb40c3716
commit 7dff74d780
1 changed files with 115 additions and 23 deletions

View File

@ -23,10 +23,82 @@ uint32_t MURS[] = {0,151820,151880,151940,154570,154600};
uint32_t WX[] = {0,162550,162400,162475,162425,162450,162500,162525};
/* morse code lookup table */
const char *ascii = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,?'!/()&:;=+-_\"$@",
*itu[] = { ".-","-...","-.-.","-..",".","..-.","--.","....","..",".---","-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--..","-----",".----","..---","...--","....-",".....","-....","--...","---..","----.",".-.-.-","--..--","..--..",".----.","-.-.--","-..-.","-.--.","-.--.-",".-...","---...","-.-.-.","-...-",".-.-.","-....-","..--.-",".-..-.","...-..-",".--.-."
};
// This is the Morse table in reverse binary format.
// It will occupy 108 bytes of memory (or program memory if defined)
#define MORSE_TABLE_LENGTH 54
#define MORSE_TABLE_PROGMEM
#ifndef MORSE_TABLE_PROGMEM
const struct asciiMorse {
char ascii;
uint8_t itu;
} asciiMorse[MORSE_TABLE_LENGTH] = {
{ 'E', 0b00000010 }, // .
{ 'T', 0b00000011 }, // -
{ 'I', 0b00000100 }, // ..
{ 'N', 0b00000101 }, // -.
{ 'A', 0b00000110 }, // .-
{ 'M', 0b00000111 }, // --
{ 'S', 0b00001000 }, // ...
{ 'D', 0b00001001 }, // -..
{ 'R', 0b00001010 }, // .-.
{ 'G', 0b00001011 }, // --.
{ 'U', 0b00001100 }, // ..-
{ 'K', 0b00001101 }, // -.-
{ 'W', 0b00001110 }, // .--
{ 'O', 0b00001111 }, // ---
{ 'H', 0b00010000 }, // ....
{ 'B', 0b00010001 }, // -...
{ 'L', 0b00010010 }, // .-..
{ 'Z', 0b00010011 }, // --..
{ 'F', 0b00010100 }, // ..-.
{ 'C', 0b00010101 }, // -.-.
{ 'P', 0b00010110 }, // .--.
{ 'V', 0b00011000 }, // ...-
{ 'X', 0b00011001 }, // -..-
{ 'Q', 0b00011011 }, // --.-
{ 'Y', 0b00011101 }, // -.--
{ 'J', 0b00011110 }, // .---
{ '5', 0b00100000 }, // .....
{ '6', 0b00100001 }, // -....
{ '&', 0b00100010 }, // .-...
{ '7', 0b00100011 }, // --...
{ '8', 0b00100111 }, // ---..
{ '/', 0b00101001 }, // -..-.
{ '+', 0b00101010 }, // .-.-.
{ '(', 0b00101101 }, // -.--.
{ '9', 0b00101111 }, // ----.
{ '4', 0b00110000 }, // ....-
{ '=', 0b00110001 }, // -...-
{ '3', 0b00111000 }, // ...--
{ '2', 0b00111100 }, // ..---
{ '1', 0b00111110 }, // .----
{ '0', 0b00111111 }, // -----
{ ':', 0b01000111 }, // ---...
{ '?', 0b01001100 }, // ..--..
{ '"', 0b01010010 }, // .-..-.
{ ';', 0b01010101 }, // -.-.-.
{ '@', 0b01010110 }, // .--.-.
{ '\047', 0b01011110 }, // (') .----.
{ '-', 0b01100001 }, // -....-
{ '.', 0b01101010 }, // .-.-.-
{ '_', 0b01101100 }, // ..--.-
{ ')', 0b01101101 }, // -.--.-
{ ',', 0b01110011 }, // --..--
{ '!', 0b01110101 }, // -.-.--
{ '$', 0b11001000 } // ...-..-
};
#else
#include <avr/pgmspace.h>
// This is a program memory variant, using 16 bit words for storage instead.
const uint16_t asciiMorseProgmem[] PROGMEM = {
0x4502, 0x5403, 0x4904, 0x4E05, 0x4106, 0x4D07, 0x5308, 0x4409, 0x520A,
0x470B, 0x550C, 0x4B0D, 0x570E, 0x4F0F, 0x4810, 0x4211, 0x4C12, 0x5A13,
0x4614, 0x4315, 0x5016, 0x5618, 0x5819, 0x511B, 0x591D, 0x4A1E, 0x3520,
0x3621, 0x2622, 0x3723, 0x3827, 0x2F29, 0x2B2A, 0x282D, 0x392F, 0x3430,
0x3D31, 0x3338, 0x323C, 0x313E, 0x303F, 0x3A47, 0x3F4C, 0x2252, 0x3B55,
0x4056, 0x275E, 0x2D61, 0x2E6A, 0x5F6C, 0x296D, 0x2C73, 0x2175, 0x24C8
};
#endif // MORSE_TABLE_PROGMEM
/* 2200 Hz */
@ -1196,30 +1268,50 @@ bool HamShield::waitForChannel(long timeout = 0, long breakwindow = 0, int setRS
/* Morse code out, blocking */
void HamShield::morseOut(char buffer[HAMSHIELD_MORSE_BUFFER_SIZE]) {
for(int x = 0; x < strlen(buffer); x++) {
char output = morseLookup(buffer[x]);
if(buffer[x] != ' ') {
for(int m = 0; m < strlen(itu[output]); m++) {
if(itu[output][m] == '-') { tone(HAMSHIELD_PWM_PIN,1000,HAMSHIELD_MORSE_DOT*3); delay(HAMSHIELD_MORSE_DOT*3); }
else { tone(HAMSHIELD_PWM_PIN,1000,HAMSHIELD_MORSE_DOT); delay(HAMSHIELD_MORSE_DOT); }
delay(HAMSHIELD_MORSE_DOT);
}
delay(HAMSHIELD_MORSE_DOT*3);
} else { delay(HAMSHIELD_MORSE_DOT*7); }
}
return;
int i = 0;
char prev = 0;
while(buffer[i] != '\0' && i < HAMSHIELD_MORSE_BUFFER_SIZE) {
// On a space, delay 7 dots
if(buffer[i] == ' ') {
// We delay by 4 here, if we previously sent a symbol. Otherwise 7.
if(prev == 0 || prev == ' ')
delay(HAMSHIELD_MORSE_DOT*7);
else
delay(HAMSHIELD_MORSE_DOT*4);
continue;
}
// Otherwise, lookup our character symbol
uint8_t bits = morseLookup(buffer[i]);
if(bits) { // If it is a valid character...
do {
tone(HAMSHIELD_PWM_PIN, 600, HAMSHIELD_MORSE_DOT * (bits & 1 ? 3 : 1));
delay(HAMSHIELD_MORSE_DOT);
bits >>= 1; // Shift into the next symbol
} while(bits != 1); // Wait for 1 termination to be all we have left
}
// End of character
delay(HAMSHIELD_MORSE_DOT * 3);
prev = buffer[i];
i++;
}
return;
}
/* Morse code lookup table */
char HamShield::morseLookup(char letter) {
for(int x = 0; x < 54; x++) {
if(letter == ascii[x]) {
return x;
// return itu[x];
}
}
uint8_t i;
for(i = 0; i < MORSE_TABLE_LENGTH; i++) {
#ifndef MORSE_TABLE_PROGMEM
if(asciiMorse[i].ascii == letter)
return asciiMorse[i].itu;
#else
uint16_t w = pgm_read_word_near(asciiMorseProgmem + i);
if( (char)((w>>8) & 0xff) == letter )
return (uint8_t)(w & 0xff);
#endif // MORSE_TABLE_PROGMEM
}
return 0;
}
/*