/* Copyright 2022, Savanni D'Gerinel This file is part of Savanni's AVR library. Lumeto is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Lumeto is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Lumeto. If not, see . */ #include #include #include "morse.h" /* TODO: all of this is a candidate for living in an EEPROM */ typedef struct morse_codepoint { size_t length; uint8_t values[5]; } morse_codepoint_t; const struct morse_codepoint MORSE[] = { /* 0 */ { .length = 5, .values = { DASH, DASH, DASH, DASH, DASH } }, /* 1 */ { .length = 5, .values = { DOT, DASH, DASH, DASH, DASH } }, /* 2 */ { .length = 5, .values = { DOT, DOT, DASH, DASH, DASH } }, /* 3 */ { .length = 5, .values = { DOT, DOT, DOT, DASH, DASH } }, /* 4 */ { .length = 5, .values = { DOT, DOT, DOT, DOT, DASH } }, /* 5 */ { .length = 5, .values = { DOT, DOT, DOT, DOT, DOT } }, /* 6 */ { .length = 5, .values = { DASH, DOT, DOT, DOT, DOT } }, /* 7 */ { .length = 5, .values = { DASH, DASH, DOT, DOT, DOT } }, /* 8 */ { .length = 5, .values = { DASH, DASH, DASH, DOT, DOT } }, /* 9 */ { .length = 5, .values = { DASH, DASH, DASH, DASH, DOT } }, /* a */ { .length = 2, .values = { DOT, DASH } }, /* b */ { .length = 4, .values = { DASH, DOT, DOT, DOT } }, /* c */ { .length = 4, .values = { DASH, DOT, DASH, DOT } }, /* d */ { .length = 3, .values = { DASH, DOT, DOT } }, /* e */ { .length = 1, .values = { DOT } }, /* f */ { .length = 4, .values = { DOT, DOT, DASH, DOT } }, /* g */ { .length = 3, .values = { DASH, DASH, DOT } }, /* h */ { .length = 4, .values = { DOT, DOT, DOT, DOT } }, /* i */ { .length = 2, .values = { DOT, DOT } }, /* j */ { .length = 4, .values = { DOT, DASH, DASH, DASH } }, /* k */ { .length = 3, .values = { DASH, DOT, DASH } }, /* l */ { .length = 4, .values = { DOT, DASH, DOT, DOT } }, /* m */ { .length = 2, .values = { DASH, DASH } }, /* n */ { .length = 2, .values = { DASH, DOT } }, /* o */ { .length = 3, .values = { DASH, DASH, DASH } }, /* p */ { .length = 4, .values = { DOT, DASH, DASH, DOT } }, /* q */ { .length = 4, .values = { DASH, DASH, DOT, DASH } }, /* r */ { .length = 3, .values = { DOT, DASH, DOT } }, /* s */ { .length = 3, .values = { DOT, DOT, DOT } }, /* t */ { .length = 1, .values = { DASH } }, /* u */ { .length = 3, .values = { DOT, DOT, DASH } }, /* v */ { .length = 4, .values = { DOT, DOT, DOT, DASH } }, /* w */ { .length = 3, .values = { DOT, DASH, DASH } }, /* x */ { .length = 4, .values = { DASH, DOT, DOT, DASH } }, /* y */ { .length = 4, .values = { DASH, DOT, DASH, DASH } }, /* z */ { .length = 4, .values = { DASH, DASH, DOT, DOT } }, }; const struct morse_codepoint * morse_lookup(char val) { size_t idx = -1; if (val >= '0' && val <= '9') { idx = val - '0'; } else if (val >= 'a' && val <= 'z') { idx = (val - 'a') + 10; } else if (val >= 'A' && val <= 'Z') { idx = (val - 'A') + 10; } if (idx < 0) return NULL; return &MORSE[idx]; } void send_codepoint(dio_t *dio, const struct morse_codepoint *codepoint) { const uint8_t one = 1 << dio->addr; for (size_t i = 0; i < codepoint->length; i++) { *dio->port = *(dio->port) | one; if (codepoint->values[i] == DOT) { _delay_ms(DOT * SCALE); } else { _delay_ms(DASH * SCALE); } *dio->port = *(dio->port) & ~one; _delay_ms(DIVIDER * SCALE); } _delay_ms(INTERCHAR * SCALE); } void send_morse(dio_t *dio, char *message) { for (size_t i = 0; i < strlen(message); i++) { if (message[i] == ' ') { _delay_ms(INTERWORD * SCALE); } const struct morse_codepoint *codepoint = morse_lookup(message[i]); if (codepoint != NULL) { send_codepoint(dio, codepoint); } } }