ESR-2025/morse.c

141 lines
3.8 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @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 (AZ, 09).
*
* 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 <msp430.h>
#include <driverlib.h>
#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 (AZ, 09) */
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 (AZ, az, 09)
*/
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);
}