141 lines
3.8 KiB
C
141 lines
3.8 KiB
C
/**
|
||
* @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 <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 (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);
|
||
} |