It is currently Wed Jul 06, 2011 7:31 pm

All times are UTC - 8 hours




 Page 1 of 1 [ 2 posts ] 
Author Message
 Post subject: Morse code... code
PostPosted: Fri Apr 08, 2011 10:07 am 

Joined: Thu Apr 07, 2011 7:11 pm
Posts: 6
I didn't see any other mention of morsecode, but personally I find it a rather nifty way to interface with the watch. In the interest of seeing other's use it, or better yet, improve my code, here's the respective code.

Since I haven't built a local toolchain yet, I'm just catting all my .c files into one chunk and sending to compileandload that way. Thus no header :>

The idea is you add updates in your button up/ down/ main loop event loops and pass in the current millisecond time. The timing of dot vs dash is the MORSE_DOT define - my experiments found 250 best - 200 still got some false dashes.

I was only caring about RAM usage, not code size when writing this, so ways to crunch the code to be smaller would be appreciated.

//
// Defines the morse functions.
// Hook up, passing in current millisec
//    morse_buttondown(int ms)
//    morse_buttonup(int ms)
//    morse_mainloop(int ms)
//
// Read with, which return 0 if none on stack.
// u8 morse_getchar()
//
// RAM use: 11 bytes
//

//
// Prototypes
//
u8 morse_getchar();
void morse_mainloop(int ms);
void morse_buttonup(int ms);
void morse_buttondown(int ms);
void morse_reset();

//
// Implementation
//

#define         MORSE_DOT               250
#define         MORSE_ENDOFSYMBOL       400
#define         MORSE_SPACEPUSH         1100

u32 morse_downtime = 0;
u32 morse_uptime = 0;

u8      morse_seq;
u8      morse_symbols = 0;
u8      morse_char = 0;

void
morse_pushdot()
{
    // zero by default
    morse_symbols++;
}

void
morse_pushdash()
{
    morse_seq |= 1 << morse_symbols;
    morse_symbols++;
}

void
morse_pushchar(u8 c)
{
    morse_char = c;
}

void
morse_pushcode()
{
    if (morse_symbols == 0)
        return;

    if (morse_symbols < 5)
    {
        const char *lut =
            //
               " "
            //  oI
               "et"
            //  oIoI
            //  ooII
               "inam"
            //  oIoIoIoI
            //  ooIIooII
            //  ooooIIII
               "sdrgukwo"
            //  oIoIoIoIoIoIoIoI
            //  ooIIooIIooIIooII
            //  ooooIIIIooooIIII
            //  ooooooooIIIIIIII
               "hblzfcp-vx-q-yj-"
            ;
        int     off;
        off = 1 << morse_symbols;
        off--;
        off += morse_seq;
        morse_pushchar(lut[off]);
    }

    // Longer lengths take special codes.
    else if (morse_symbols == 5)
    {
        // NOTE: These are all backwards bit patterns!
        switch (morse_seq)
        {
            // Number patterns
            case 0b11110:
                morse_pushchar('1');
                break;
            case 0b11100:
                morse_pushchar('2');
                break;
            case 0b11000:
                morse_pushchar('3');
                break;
            case 0b10000:
                morse_pushchar('4');
                break;
            case 0b00000:
                morse_pushchar('5');
                break;
            case 0b00001:
                morse_pushchar('6');
                break;
            case 0b00011:
                morse_pushchar('7');
                break;
            case 0b00111:
                morse_pushchar('8');
                break;
            case 0b01111:
                morse_pushchar('9');
                break;
            case 0b11111:
                morse_pushchar('0');
                break;

            // Punctuation
            case 0b01001:
                morse_pushchar('/');
                break;
            case 0b01101:
                morse_pushchar('(');
                break;
            case 0b00010:
                morse_pushchar('&');
                break;
            case 0b10001:
                morse_pushchar('=');
                break;
            case 0b01010:
                morse_pushchar('+');
                break;
        }
    }
    else if (morse_symbols == 6)
    {
        // NOTE: These are all backwards bit patterns!
        switch (morse_seq)
        {
            case 0b000000:
                // All e's, error code.
                morse_pushchar('\b');
                break;
            case 0b101010:
                morse_pushchar('.');
                break;
            case 0b110011:
                morse_pushchar(',');
                break;
            case 0b001100:
                morse_pushchar('?');
                break;
            case 0b011110:
                morse_pushchar('\'');
                break;
            case 0b101011:
                morse_pushchar('!');
                break;
            case 0b101101:
                morse_pushchar(')');
                break;
            case 0b000111:
                morse_pushchar(':');
                break;
            case 0b010101:
                morse_pushchar(';');
                break;
            case 0b100001:
                morse_pushchar('-');
                break;
            case 0b101100:
                morse_pushchar('_');
                break;
            case 0b010010:
                morse_pushchar('"');
                break;

            // Recent addition from 2004.
            case 0b010110:
                morse_pushchar('@');
                break;

        }
    }

    else if (morse_symbols == 7)
    {
        switch (morse_seq)
        {
            case 0b0000000:
                // All e's, error code.
                morse_pushchar('\b');
                break;
            case 0b1001000:
                morse_pushchar('$');
                break;
        }
    }
    // 6 or more e's is considered error, ie, backspace, so
    // we detect
    else if (!morse_seq)
    {
        morse_pushchar('\b');
    }

    // Reset in any case.
    morse_symbols = 0;
    morse_seq = 0;
}

void
morse_process(bool signal, int lenms)
{
    if (signal)
    {
        if (lenms < MORSE_DOT)
            morse_pushdot();
        else
            morse_pushdash();
    }
    else
    {
        if (lenms > MORSE_ENDOFSYMBOL)
        {
            morse_pushcode();
        }
        if (lenms > MORSE_SPACEPUSH)
        {
            morse_uptime = 0;
            morse_pushchar(' ');
        }
    }
}

void
morse_buttondown(int ms)
{
    morse_uptime = 0;
    morse_downtime = ms;
}

void
morse_buttonup(int ms)
{
    morse_uptime = ms;
    morse_process(true, morse_uptime - morse_downtime);
    morse_downtime = 0;
}

void
morse_mainloop(int ms)
{
    if (morse_uptime)
    {
        morse_process(false, ms - morse_uptime);
    }
}

u8
morse_getchar()
{
    u8          c;
    c = morse_char;
    morse_char = 0;
    return c;
}

void
morse_reset()
{
    morse_char = 0;
    morse_seq = 0;
    morse_uptime = 0;
}


Offline
 Profile  
 
 Post subject: Re: Morse code... code
PostPosted: Mon Apr 11, 2011 6:13 pm 

Joined: Thu Apr 07, 2011 7:11 pm
Posts: 6
I've since found that inlinining the hook functions cuts a lot of code. Likewise, the 5 bit length codes can also be dumped into the LUT, while it is only half full, it saves more bytes of code than is wasted.

Here's the latest:
//
// Defines the morse functions.
// Hook up, passing in current millisec
//    morse_buttondown(int ms)
//    morse_buttonup(int ms)
//    morse_mainloop(int ms)
//
// Read with, which return 0 if none on stack.
// u8 morse_getchar()
//
// RAM use: 11 bytes
//

//
// Prototypes
// Commented out inline methods
//
u8 morse_getchar();
//void morse_mainloop(int ms);
//void morse_buttonup(int ms);
//void morse_buttondown(int ms);
void morse_reset();

//
// Implementation
//

#define      MORSE_DOT      250
#define      MORSE_ENDOFSYMBOL   400
#define      MORSE_SPACEPUSH      1100

u32 morse_downtime = 0;
u32 morse_uptime = 0;

u8   morse_seq;
u8   morse_symbols = 0;
u8   morse_char = 0;

inline void
morse_pushdot()
{
    // zero by default
    morse_symbols++;
}

inline void
morse_pushdash()
{
    morse_seq |= 1 << morse_symbols;
    morse_symbols++;
}

inline void
morse_pushchar(u8 c)
{
    morse_char = c;
}

inline void
morse_pushcode()
{
    if (morse_symbols == 0)
   return;

    if (morse_symbols < 6)
    {
   const char *lut =
       //
          " "
       //  oI
          "et"
       //  oIoI
       //  ooII
          "inam"
       //  oIoIoIoI
       //  ooIIooII
       //  ooooIIII
          "sdrgukwo"
       //  oIoIoIoIoIoIoIoI
       //  ooIIooIIooIIooII
       //  ooooIIIIooooIIII
       //  ooooooooIIIIIIII
          "hblzfcp-vx-q-yj-"
       //  oIoIoIoIoIoIoIoI   oIoIoIoIoIoIoIoI
       //  ooIIooIIooIIooII   ooIIooIIooIIooII
       //  ooooIIIIooooIIII   ooooIIIIooooIIII
       //  ooooooooIIIIIIII   ooooooooIIIIIIII
       //  oooooooooooooooo   IIIIIIIIIIIIIIII
          "56 7   8 /+  ( 9" "4=      3   2&10"
       ;
   int   off;
   off = 1 << morse_symbols;
   off--;
   off += morse_seq;
   morse_pushchar(lut[off]);
    }

    // Longer lengths take special codes.
    else if (morse_symbols == 6)
    {
   // NOTE: These are all backwards bit patterns!
   switch (morse_seq)
   {
       case 0b000000:
      // All e's, error code.
      morse_pushchar('\b');
      break;
       case 0b101010:
      morse_pushchar('.');
      break;
       case 0b110011:
      morse_pushchar(',');
      break;
       case 0b001100:
      morse_pushchar('?');
      break;
       case 0b011110:
      morse_pushchar('\'');
      break;
       case 0b101011:
      morse_pushchar('!');
      break;
       case 0b101101:
      morse_pushchar(')');
      break;
       case 0b000111:
      morse_pushchar(':');
      break;
       case 0b010101:
      morse_pushchar(';');
      break;
       case 0b100001:
      morse_pushchar('-');
      break;
       case 0b101100:
      morse_pushchar('_');
      break;
       case 0b010010:
      morse_pushchar('"');
      break;

       // Recent addition from 2004.
       case 0b010110:
      morse_pushchar('@');
      break;

   }
    }
    else if (morse_symbols == 7)
    {
   switch (morse_seq)
   {
       case 0b0000000:
      // All e's, error code.
      morse_pushchar('\b');
      break;
       case 0b1001000:
      morse_pushchar('$');
      break;
   }
    }
    // 6 or more e's is considered error, ie, backspace, so
    // we detect
    else if (!morse_seq)
    {
   morse_pushchar('\b');
    }

    // Reset in any case.
    morse_symbols = 0;
    morse_seq = 0;
}

void
morse_process(bool signal, int lenms)
{
    if (signal)
    {
   if (lenms < MORSE_DOT)
       morse_pushdot();
   else
       morse_pushdash();
    }
    else
    {
   if (lenms > MORSE_ENDOFSYMBOL)
   {
       morse_pushcode();
   }
   if (lenms > MORSE_SPACEPUSH)
   {
       morse_uptime = 0;
       morse_pushchar(' ');
   }
    }
}

inline void
morse_buttondown(int ms)
{
    morse_uptime = 0;
    morse_downtime = ms;
}

inline void
morse_buttonup(int ms)
{
    morse_uptime = ms;
    morse_process(true, morse_uptime - morse_downtime);
    morse_downtime = 0;
}

inline void
morse_mainloop(int ms)
{
    if (morse_uptime)
    {
   morse_process(false, ms - morse_uptime);
    }
}

u8
morse_getchar()
{
    u8      c;
    c = morse_char;
    morse_char = 0;
    return c;
}

void
morse_reset()
{
    morse_char = 0;
    morse_seq = 0;
    morse_uptime = 0;
}


Offline
 Profile  
 
Display posts from previous:  Sort by  
 Page 1 of 1 [ 2 posts ] 

All times are UTC - 8 hours


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: