morse.cpp 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /****************************************************************************
  2. * Copyright: (C) 2005 - 2017 by Dipl.-Ing. Stefan Heesch
  3. * callsign: HB9TWS
  4. * email: radio@heesch.net
  5. ****************************************************************************/
  6. #include "morse.h"
  7. static int DurationPoint;
  8. static char RawBuffer[PATTERN_SIZE + 1];
  9. static char FailedBuffer[PATTERN_SIZE + 1];
  10. const morse(MorseCode[]) PROGMEM =
  11. {
  12. { 'A',".-" }, { 'B',"-..." }, { 'C',"-.-." }, { 'D',"-.." },
  13. { 'E',"." }, { 'F',"..-." }, { 'G',"--." }, { 'H',"...." },
  14. { 'I',".." }, { 'J',".---" }, { 'K',"-.-" }, { 'L',".-.." },
  15. { 'M',"--" }, { 'N',"-." }, { 'O',"---" }, { 'P',".--." },
  16. { 'Q',"--.-" }, { 'R',".-." }, { 'S',"..." }, { 'T',"-" },
  17. { 'U',"..-" }, { 'V',"...-" }, { 'W',".--" }, { 'X',"-..-" },
  18. { 'Y',"-.--" }, { 'Z',"--.." },
  19. { '1',".----" }, { '2',"..---" }, { '3',"...--" }, { '4',"....-" },
  20. { '5',"....." }, { '6',"-...." }, { '7',"--..." }, { '8',"---.." },
  21. { '9',"----." }, { '0',"-----" },
  22. { ',',"--..--" }, { '.',".-.-.-" }, { '?',"..--.." }, { '/',"-..-." },
  23. { '=',"-...-" }, { '-',"-....-" }, { ':',"---..." }, { ';',"-.-.-." },
  24. { '(',"-.--." }, { ')',"-.--.-" }, { '\'',".----." },
  25. { '\"',".-..-." }, { '@',".--.-." }, { '#',"........" },
  26. { 'k',"-.-.-" }, // KA
  27. { 'a',".-.-." }, // AR
  28. { 's',"...-.-" }, // SK
  29. { '\0',"\0" }
  30. };
  31. /* ----------------------------------------------------------------------
  32. * Function Name: pgm_read_morse( morse* in, morse* out )
  33. * Description: Read cw pattern from program memore
  34. * Parameters: morse* in, morse* out
  35. * Return: void
  36. * ---------------------------------------------------------------------- */
  37. void pgm_read_morse(morse* in, morse* out)
  38. {
  39. out->letter = pgm_read_byte((PGM_P)in);
  40. for (int i = 0; i<PATTERN_SIZE; i++)
  41. out->pattern[i] = pgm_read_byte((PGM_P)in + i + 1);
  42. }
  43. /* ----------------------------------------------------------------------
  44. * Function Name: decode_letter( void )
  45. * Description: Decode cw pattern in variable RawBuffer and return a char
  46. * Parameters: void
  47. * Return: char; =0
  48. * ---------------------------------------------------------------------- */
  49. char decode_letter(void)
  50. {
  51. if (RawBuffer[0] == 0) return 0;
  52. char result = DECODING_ERROR;
  53. morse code;
  54. int i = 0;
  55. do
  56. {
  57. pgm_read_morse(const_cast<morse*>(&MorseCode[i]), &code);
  58. if (strcmp(RawBuffer, code.pattern) == 0)
  59. {
  60. result = code.letter;
  61. break;
  62. }
  63. i++;
  64. } while (code.letter);
  65. if (result == DECODING_ERROR)
  66. memcpy(FailedBuffer, RawBuffer, PATTERN_SIZE);
  67. return result;
  68. }
  69. /****************************************************************************
  70. *
  71. * Function Name: decode_tone( int duration )
  72. *
  73. * Description: Decode cw tone ( key pressed )
  74. *
  75. * Parameters: int duration
  76. *
  77. * Return: void
  78. *
  79. ***************************************************************************/
  80. void decode_tone(int duration)
  81. {
  82. char s = '.';
  83. if (duration > 2 * DurationPoint)
  84. {
  85. s = '-';
  86. }
  87. int i;
  88. for (i = 0; i < PATTERN_SIZE; ++i)
  89. {
  90. if (RawBuffer[i] == 0)
  91. {
  92. RawBuffer[i] = s;
  93. break;
  94. }
  95. }
  96. } /* decode_tone */
  97. /* ----------------------------------------------------------------------
  98. * Function Name: decode_pause( int duration )
  99. * Description: Decode cw pause ( key not pressed )
  100. * Parameters: int duration
  101. * Return: char
  102. * ---------------------------------------------------------------------- */
  103. char decode_pause(int duration)
  104. {
  105. char result = 0;
  106. if (duration > 2 * DurationPoint)
  107. {
  108. /* letter is complete, decode it and initialise buffer */
  109. result = decode_letter();
  110. memset(RawBuffer, 0, PATTERN_SIZE);
  111. }
  112. return result;
  113. }
  114. /* ----------------------------------------------------------------------
  115. * Function Name: morse_decode( cw input )
  116. * Description: Decode cw input
  117. * Parameters: cw input
  118. * Return: char
  119. * ---------------------------------------------------------------------- */
  120. char morse_decode(cw input)
  121. {
  122. char result = 0;
  123. if (input.level == 0)
  124. result = decode_pause(input.duration);
  125. else
  126. decode_tone(input.duration);
  127. return result;
  128. }
  129. /****************************************************************************
  130. *
  131. * Function Name: morse_speed( void )
  132. *
  133. * Description: speed in letters per minute
  134. *
  135. * Parameters: void
  136. *
  137. * Return: int
  138. *
  139. ***************************************************************************/
  140. int morse_speed(void)
  141. {
  142. return 6000 / DurationPoint;
  143. } /* morse_speed */
  144. /****************************************************************************
  145. *
  146. * Function Name: morse_timeout( void )
  147. *
  148. * Description: return timeout value for decoding
  149. *
  150. * Parameters: void
  151. *
  152. * Return: int
  153. *
  154. ***************************************************************************/
  155. int morse_timeout(void)
  156. {
  157. return 8 * DurationPoint;
  158. } /* morse_timeout */
  159. /****************************************************************************
  160. *
  161. * Function Name: morse_init( int speed )
  162. *
  163. * Description: Initialize morse decoder
  164. *
  165. * Parameters: int speed
  166. *
  167. * Return: void
  168. *
  169. ***************************************************************************/
  170. void morse_init(int speed)
  171. {
  172. memset(RawBuffer, 0, PATTERN_SIZE + 1);
  173. memset(FailedBuffer, 0, PATTERN_SIZE + 1);
  174. if (speed > 0 && speed < 120)
  175. {
  176. DurationPoint = 6000 / speed;
  177. }
  178. else
  179. {
  180. DurationPoint = 6000 / 50;
  181. }
  182. } /* morse_init */
  183. /****************************************************************************
  184. *
  185. * Function Name: morse_check( cw input )
  186. *
  187. * Description: Check for speed and new word (spacing)
  188. *
  189. * Parameters: cw input
  190. *
  191. * Return: char
  192. *
  193. ***************************************************************************/
  194. char morse_check(cw input)
  195. {
  196. char result = 0;
  197. if (input.level == 0)
  198. {
  199. if (input.duration > 6 * DurationPoint)
  200. {
  201. /* start a new block or word
  202. */
  203. result = ' ';
  204. }
  205. }
  206. else
  207. {
  208. /* Adopt speed
  209. */
  210. if (input.duration > 3 * DurationPoint + 15)
  211. {
  212. DurationPoint += 5;
  213. }
  214. else if (input.duration < DurationPoint - 10)
  215. {
  216. DurationPoint -= 5;
  217. }
  218. if (DurationPoint < MIN_DURATION)
  219. {
  220. DurationPoint = MIN_DURATION;
  221. }
  222. }
  223. return result;
  224. } /* morse_check */
  225. /****************************************************************************
  226. *
  227. * Function Name: morse_failed( void )
  228. *
  229. * Description: Return pattern that couldn't be decoded
  230. *
  231. * Parameters: void
  232. *
  233. * Return: char*
  234. *
  235. ***************************************************************************/
  236. char* morse_failed(void)
  237. {
  238. return FailedBuffer;
  239. } /* morse_failed */