ESR-2025/main.c

150 lines
4.4 KiB
C
Executable File
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 main.c
* @brief UART console, interrupt-driven 4×4 keypad input, and Morse LED blink on MSP430FR2355.
*
* Initializes peripheral modules and enters low-power mode, waking on keypress
* interrupts to blink Morse code on LED and echo keys over UART.
*
* @date 2025-07-02
*/
#include <msp430.h>
#include <driverlib.h>
#include <stdint.h>
#include <stdio.h>
#include <stdbool.h>
#include "src/keypad.h"
#include "src/morse.h"
#include "src/i2c.h"
#include "src/lcd.h"
#include "src/Board.h"
/** On-board LED port and pin (used by Morse module) */
#define LED_PORT GPIO_PORT_P1 /**< On-board LED port */
#define LED_PIN GPIO_PIN0 /**< On-board LED pin */
volatile char last_key_pressed = '\0';
volatile bool key_changed = false;
/**
* @brief Keypad callback invoked on key press interrupt.
* @param key ASCII character of pressed key
*
* Stores key, sets ready flag, and blinks Morse code on LED.
*/
static void myKeyHandler(char key)
{
last_key_pressed = key;
key_changed = true;
}
void init_timer(void) {
static Timer_B_initUpModeParam param = {0};
param.clockSource = TIMER_B_CLOCKSOURCE_SMCLK;
param.clockSourceDivider = TIMER_B_CLOCKSOURCE_DIVIDER_1;
param.timerPeriod = 999; // wenn 1000 Taktimpulse gezählt
// wurden, erfolgt ein Interrupt
// Periodendauer somit 1ms
param.timerInterruptEnable_TBIE =
TIMER_B_TBIE_INTERRUPT_DISABLE; // no interrupt on 0x0000
param.captureCompareInterruptEnable_CCR0_CCIE =
TIMER_B_CAPTURECOMPARE_INTERRUPT_ENABLE; // interrupt on TRmax
param.timerClear = TIMER_B_DO_CLEAR;
param.startTimer = true;
// start Timer:
Timer_B_initUpMode(TB0_BASE, &param);
}
void init_i2c(void) {
EUSCI_B_I2C_initMasterParam param = {0};
// Configure Pins for I2C
/*
* Select Port 1
* Set Pin 2, 3 to input with function, (UCB0SIMO/UCB0SDA, UCB0SOMI/UCB0SCL).
*/
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SCL, GPIO_PIN_UCB0SCL, GPIO_FUNCTION_UCB0SCL);
GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_UCB0SDA, GPIO_PIN_UCB0SDA, GPIO_FUNCTION_UCB0SDA);
param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK;
param.i2cClk = CS_getSMCLK();
param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS;
param.byteCounterThreshold = 1;
param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP;
EUSCI_B_I2C_initMaster(EUSCI_B0_BASE, &param);
//Specify slave address
EUSCI_B_I2C_setSlaveAddress(EUSCI_B0_BASE, 0x27);
//Set in transmit mode
EUSCI_B_I2C_setMode(EUSCI_B0_BASE, EUSCI_B_I2C_TRANSMIT_MODE);
//Enable I2C Module to start operations
EUSCI_B_I2C_enable(EUSCI_B0_BASE);
}
/**
* @brief Main application entry point.
*
* Sets up GPIO, UART, keypad interrupts, and enters low-power loop.
* On keypress, echoes key over UART.
*
* @return Never returns
*/
int main(void)
{
/* Stop watchdog and unlock GPIO pins */
WDT_A_hold(WDT_A_BASE);
PMM_unlockLPM5();
/* Initialize on-board LED (used by Morse blinking) */
GPIO_setAsOutputPin(LED_PORT, LED_PIN);
GPIO_setOutputLowOnPin(LED_PORT, LED_PIN);
/* Initialize keypad interrupt driver */
initKeypadInterrupts(myKeyHandler);
init_timer();
I2C_init(); /* I²C-Master initialisieren */
lcd_init(); /* LCD initialisieren */
lcd_set_cursor(0, 0);
lcd_print("Press any Key!");
/* Enter low-power mode and wait for key interrupts */
for (;;) {
__bis_SR_register(LPM0_bits | GIE); /* Enter LPM0 with interrupts enabled */
__no_operation();
if (key_changed) {
lcd_set_cursor(1, 0);
char output[20] = "Key pressed: ";
output[13] = last_key_pressed;
lcd_print(output);
key_changed = false;
}
}
}
/**
* @brief Führt eine blockierende Wartezeit aus.
* @param ms Zeit in Millisekunden
*/
void sleep(uint16_t ms) {
while (ms--) {
__bis_SR_register(LPM0_bits + GIE);
__no_operation();
}
}
// TimerB0 Interrupt Vector (TBxIV) handler
#pragma vector=TIMER0_B0_VECTOR
__interrupt void TIMER0_B0_ISR(void)
{
__bic_SR_register_on_exit(LPM0_bits);
}