Program to transmit strings as Morse code using the CC1200. Useful for amateur radio projects!

Dependencies:   CC1200 SerialStream

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CC1200Morse.cpp Source File

CC1200Morse.cpp

00001 //
00002 // Created by jamie on 8/24/2020.
00003 //
00004 
00005 #include "CC1200Morse.h"
00006 
00007 #include <cinttypes>
00008 
00009 // Morse code tables.
00010 // Covers ASCII ranges 0x41-0x5A and 0x61-0x7A
00011 char const * const alphaMorse[] = {".-","-...","-.-.","-..",".","..-.","--.","....","..",".---",
00012                     "-.-",".-..","--","-.","---",".--.","--.-",".-.","...","-","..-",
00013                     "...-",".--","-..-","-.--","--.."};
00014 
00015 // Covers ASCII range 0x30-0x39
00016 char const * const numMorse[] = {"-----",".----","..---","...--","....-",".....","-....","--...","---..","----."};
00017 
00018 // covers ASCII range 0x21-0x2F
00019 char const * const punctuation1Morse[] = {"-.-.--", ".-..-.", nullptr, "...-..-", nullptr, ".-...", ".----.", "-.--.",
00020                                           "-.--.-", nullptr, ".-.-.", "--..--", nullptr, ".-.-.-", "-..-."};
00021 
00022 // covers ASCII range 0x3A-0x40
00023 char const * const punctuation2Morse[] = {"---...", "-.-.-.", nullptr, "-...-", nullptr, "..--..", ".--.-."};
00024 
00025 void CC1200Morse::configure(CC1200::Band band, float radioFrequency, float morseTimePeriod, float transmitPower)
00026 {
00027     radio.setPacketMode(CC1200::PacketMode::FIXED_LENGTH);
00028     radio.setCRCEnabled(false);
00029 
00030     // set frequency
00031     radio.setSymbolRate(1/morseTimePeriod);
00032     radio.setRadioFrequency(band, radioFrequency);
00033 
00034     // disable anything getting sent before the data
00035     radio.configureSyncWord(0x0, CC1200::SyncMode::SYNC_NONE, 8);
00036     radio.configurePreamble(0, 0);
00037 
00038     // configure OOK modulation
00039     radio.setModulationFormat(CC1200::ModFormat::ASK);
00040     radio.disablePARamping();
00041     radio.setASKPowers(transmitPower, CC1200::ASK_MIN_POWER_OFF);
00042 }
00043 
00044 // helper function for convertToMorse
00045 static bool appendBits(uint8_t *outputBuffer, size_t bufferLen, uint8_t & nextBit, size_t & currByte, uint8_t toAppend, size_t count)
00046 {
00047     //printf("appendBits(%" PRIu8 ", %zu)\n", toAppend, count);
00048     for(size_t counter = 0; counter < count; ++counter)
00049     {
00050         outputBuffer[currByte] |= toAppend << nextBit;
00051 
00052         if(nextBit == 0)
00053         {
00054             nextBit = 7;
00055             currByte += 1;
00056             if(currByte >= bufferLen)
00057             {
00058                 // out of space
00059                 return false;
00060             }
00061         }
00062         else
00063         {
00064             nextBit--;
00065         }
00066     }
00067 
00068     return true;
00069 }
00070 
00071 
00072 CC1200Morse::EncodedMorse CC1200Morse::convertToMorse(const char *string, uint8_t *outputBuffer, size_t bufferLen)
00073 {
00074     memset(outputBuffer, 0, bufferLen);
00075 
00076     // place in the output buffer where next items will be written
00077     uint8_t nextBit = 7;
00078     size_t currByte = 0;
00079 
00080     EncodedMorse encoded;
00081     encoded.buffer = outputBuffer;
00082     encoded.valid = false;
00083 
00084     if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, spaceBefore))
00085     {
00086         return encoded;
00087     }
00088 
00089     size_t stringLength = strlen(string);
00090     for(size_t charIndex = 0; charIndex < stringLength; ++charIndex)
00091     {
00092         char currChar = string[charIndex];
00093         char const * morseToAppend = nullptr;
00094         if((currChar >= 'A' && currChar <= 'Z'))
00095         {
00096             morseToAppend = alphaMorse[currChar - 'A'];
00097         }
00098         else if(currChar >= 'a' && currChar <= 'z')
00099         {
00100             morseToAppend = alphaMorse[currChar - 'a'];
00101         }
00102         else if(currChar >= '0' && currChar <= '9')
00103         {
00104             morseToAppend = numMorse[currChar - '0'];
00105         }
00106         else if(currChar >= '!' && currChar <= '/')
00107         {
00108             morseToAppend = punctuation1Morse[currChar - '!'];
00109         }
00110         else if(currChar >= ':' && currChar <= '@')
00111         {
00112             morseToAppend = punctuation2Morse[currChar - ':'];
00113         }
00114         else if(currChar == '_') // underscore is off by itself in the ASCII chart
00115         {
00116             morseToAppend = "..--.-";
00117         }
00118 
00119         // append bit timings
00120         //printf("currChar = '%c'\n", currChar);
00121         if(currChar == ' ')
00122         {
00123             // space between words is 7 time units
00124             if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, 7))
00125             {
00126                 return encoded;
00127             }
00128         }
00129         else if(morseToAppend != nullptr)
00130         {
00131             size_t morseLength = strlen(morseToAppend);
00132             for(size_t morseIndex = 0; morseIndex < morseLength; ++morseIndex)
00133             {
00134                 // dot is 1 time unit, dash is 3 time units
00135                 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 1, morseToAppend[morseIndex] == '-' ? 3 : 1))
00136                 {
00137                     return encoded;
00138                 }
00139 
00140                 // space between symbols is 1 time unit
00141                 if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, 1))
00142                 {
00143                     return encoded;
00144                 }
00145             }
00146 
00147             // extra space between letters is 2 time units
00148             if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, 2))
00149             {
00150                 return encoded;
00151             }
00152         }
00153     }
00154 
00155     if(!appendBits(outputBuffer, bufferLen, nextBit, currByte, 0, spaceAfter))
00156     {
00157         return encoded;
00158     }
00159 
00160     encoded.valid = true;
00161     encoded.byteLen = currByte;
00162     encoded.bitLen = 7 - nextBit;
00163     encoded.totalLength = currByte + (encoded.bitLen > 0 ? 1 : 0);
00164 
00165     return encoded;
00166 }
00167 
00168 void CC1200Morse::transmit(const CC1200Morse::EncodedMorse &morse)
00169 {
00170     if(morse.totalLength > 128)
00171     {
00172         // too large to send in one packet
00173         return;
00174     }
00175     radio.setPacketLength(morse.byteLen, morse.bitLen);
00176     radio.enqueuePacket(reinterpret_cast<const char *>(morse.buffer), morse.totalLength);
00177 }