/** * @file morse.c * @brief Implementation of Morse code LED blinking for MSP430. * * This module provides functions to initialize an LED pin and blink * Morse code patterns for alphanumeric characters (A–Z, 0–9). * * Timing follows standard Morse code rules: dot = 1 unit on, dash = 3 units on, * intra-character gap = 1 unit off (handled in blinkDot/blinkDash), * inter-character gap = 3 units off. * * Usage: * morseInit(); * blinkMorseChar('S'); // ... * * @date 2025-07-02 */ #include "morse.h" #include #include #include "constants.h" /** One time unit in CPU cycles (1 MHz SMCLK) */ #define MORSE_UNIT_CYCLES 200000U /** LED port definition */ #define LED_PORT GPIO_PORT_P1 /** LED pin definition */ #define LED_PIN GPIO_PIN0 /** * @brief Blink the LED for a dot: on 1 unit, off 1 unit. */ static void blinkDot(void) { GPIO_setOutputHighOnPin(LED_PORT, LED_PIN); __delay_cycles(MORSE_UNIT_CYCLES); GPIO_setOutputLowOnPin(LED_PORT, LED_PIN); __delay_cycles(MORSE_UNIT_CYCLES); } /** * @brief Blink the LED for a dash: on 3 units, off 1 unit. */ static void blinkDash(void) { GPIO_setOutputHighOnPin(LED_PORT, LED_PIN); __delay_cycles(3 * MORSE_UNIT_CYCLES); GPIO_setOutputLowOnPin(LED_PORT, LED_PIN); __delay_cycles(MORSE_UNIT_CYCLES); } /** * @brief Mapping of characters to Morse code patterns. */ typedef struct { char c; /**< Character (A–Z, 0–9) */ const char *pattern;/**< Morse code string (".", "-" sequences) */ } MorseMapEntry; /** Lookup table for supported characters */ static const MorseMapEntry morseTable[] = { {'A', ".-"}, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."}, {'E', "."}, {'F', "..-."}, {'G', "--."}, {'H', "...."}, {'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."}, {'M', "--"}, {'N', "-."}, {'O', "---"}, {'P', ".--."}, {'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"}, {'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"}, {'Y', "-.--"}, {'Z', "--.."}, {'0', "-----"},{'1', ".----"},{'2', "..---"},{'3', "...--"}, {'4', "....-"},{'5', "....."},{'6', "-...."},{'7', "--..."}, {'8', "---.."},{'9', "----."} }; /** * @brief Lookup Morse pattern for given character. * @param in Character to look up (case-insensitive) * @return Pointer to pattern string, or NULL if unsupported */ static const char *lookupMorse(char in) { unsigned int i; /* Convert lowercase to uppercase */ if (in >= 'a' && in <= 'z') { in -= ('a' - 'A'); } /* Search table */ for (i = 0; i < sizeof(morseTable) / sizeof(morseTable[0]); i++) { if (morseTable[i].c == in) { return morseTable[i].pattern; } } return NULL; } /** * @brief Initialize the LED pin for output. * * Unlocks FRAM I/O power-on default high-impedance lock, * then configures LED pin as output low. */ void morseInit(void) { PMM_unlockLPM5(); GPIO_setAsOutputPin(LED_PORT, LED_PIN); GPIO_setOutputLowOnPin(LED_PORT, LED_PIN); } /** * @brief Blink a single character in Morse code. * * Uses dot (.) and dash (-) patterns for timing, with * an inter-letter gap of 3 units (2 units additional after pattern). * Unsupported characters are ignored. * * @param c Character to blink (A–Z, a–z, 0–9) */ void blinkMorseChar(char c) { const char *pattern = lookupMorse(c); const char *p; if (!pattern) { return; } /* Blink each element in pattern */ for (p = pattern; *p; p++) { if (*p == '.') { blinkDot(); } else if (*p == '-') { blinkDash(); } } /* Inter-letter gap: total 3 units; dot/dash leaves 1 unit, so add 2 */ __delay_cycles(2 * MORSE_UNIT_CYCLES); }