feat: Crude State Machine
This commit is contained in:
parent
34a965f03a
commit
aac5c5a44c
@ -27,7 +27,7 @@
|
|||||||
</option>
|
</option>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1502413104" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="21.6.1.LTS" valueType="string"/>
|
<option id="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION.1502413104" superClass="com.ti.ccstudio.buildDefinitions.core.OPT_CODEGEN_VERSION" value="21.6.1.LTS" valueType="string"/>
|
||||||
<targetPlatform id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.targetPlatformDebug.1741833122" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.targetPlatformDebug"/>
|
<targetPlatform id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.targetPlatformDebug.1741833122" name="Platform" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.targetPlatformDebug"/>
|
||||||
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.builderDebug.235413854" name="GNU Make.Debug" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.builderDebug"/>
|
<builder buildPath="${BuildDirectory}" id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.builderDebug.235413854" keepEnvironmentInBuildfile="false" name="GNU Make" parallelBuildOn="true" parallelizationNumber="optimal" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.builderDebug"/>
|
||||||
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.compilerDebug.281898955" name="MSP430 Compiler" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.compilerDebug">
|
<tool id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.compilerDebug.281898955" name="MSP430 Compiler" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.exe.compilerDebug">
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEFINE.925722857" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEFINE" valueType="definedSymbols">
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEFINE.925722857" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEFINE" valueType="definedSymbols">
|
||||||
<listOptionValue value="__MSP430FR2355__"/>
|
<listOptionValue value="__MSP430FR2355__"/>
|
||||||
@ -40,7 +40,7 @@
|
|||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU22.253852873" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU22" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU22.253852873" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU22" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU40.916653631" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU40" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU40.916653631" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_ERRATA.CPU40" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_VERSION.973894696" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_VERSION.mspx" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_VERSION.973894696" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_VERSION" value="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.SILICON_VERSION.mspx" valueType="enumerated"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.PRINTF_SUPPORT.1310228180" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.PRINTF_SUPPORT" value="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.PRINTF_SUPPORT.minimal" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.PRINTF_SUPPORT.1310228180" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.PRINTF_SUPPORT" value="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.PRINTF_SUPPORT.full" valueType="enumerated"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEBUGGING_MODEL.1031813406" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEBUGGING_MODEL.1031813406" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEBUGGING_MODEL" value="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DEBUGGING_MODEL.SYMDEBUG__DWARF" valueType="enumerated"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DISPLAY_ERROR_NUMBER.482096263" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DISPLAY_ERROR_NUMBER.482096263" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DISPLAY_ERROR_NUMBER" value="true" valueType="boolean"/>
|
||||||
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DIAG_WARNING.1891170450" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DIAG_WARNING" valueType="stringList">
|
<option id="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DIAG_WARNING.1891170450" superClass="com.ti.ccstudio.buildDefinitions.MSP430_21.6.compilerID.DIAG_WARNING" valueType="stringList">
|
||||||
|
|||||||
@ -148,5 +148,15 @@
|
|||||||
"directory" : "/home/frederik/workspace_ccstheia/ESR-11/Debug",
|
"directory" : "/home/frederik/workspace_ccstheia/ESR-11/Debug",
|
||||||
"command" : "clang++ -I\"/home/frederik/.ti/ccs2010/ccs/ccs_base/msp430/include\" -I\"/home/frederik/workspace_ccstheia/ESR-11\" -I\"/home/frederik/workspace_ccstheia/ESR-11/jsmn\" -I\"/home/frederik/workspace_ccstheia/ESR-11/driverlib/MSP430FR2xx_4xx\" -I\"/home/frederik/.ti/ccs2010/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/include\" -D__MSP430FR2355__ -D_FRWP_ENABLE -D_INFO_FRWP_ENABLE -xc",
|
"command" : "clang++ -I\"/home/frederik/.ti/ccs2010/ccs/ccs_base/msp430/include\" -I\"/home/frederik/workspace_ccstheia/ESR-11\" -I\"/home/frederik/workspace_ccstheia/ESR-11/jsmn\" -I\"/home/frederik/workspace_ccstheia/ESR-11/driverlib/MSP430FR2xx_4xx\" -I\"/home/frederik/.ti/ccs2010/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/include\" -D__MSP430FR2355__ -D_FRWP_ENABLE -D_INFO_FRWP_ENABLE -xc",
|
||||||
"file" : "/home/frederik/workspace_ccstheia/ESR-11/src/state_machine.c"
|
"file" : "/home/frederik/workspace_ccstheia/ESR-11/src/state_machine.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory" : "/home/frederik/workspace_ccstheia/ESR-11/Debug",
|
||||||
|
"command" : "clang++ -I\"/home/frederik/.ti/ccs2010/ccs/ccs_base/msp430/include\" -I\"/home/frederik/workspace_ccstheia/ESR-11\" -I\"/home/frederik/workspace_ccstheia/ESR-11/jsmn\" -I\"/home/frederik/workspace_ccstheia/ESR-11/driverlib/MSP430FR2xx_4xx\" -I\"/home/frederik/.ti/ccs2010/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/include\" -D__MSP430FR2355__ -D_FRWP_ENABLE -D_INFO_FRWP_ENABLE -xc",
|
||||||
|
"file" : "/home/frederik/workspace_ccstheia/ESR-11/src/timer.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory" : "/home/frederik/workspace_ccstheia/ESR-11/Debug",
|
||||||
|
"command" : "clang++ -I\"/home/frederik/.ti/ccs2010/ccs/ccs_base/msp430/include\" -I\"/home/frederik/workspace_ccstheia/ESR-11\" -I\"/home/frederik/workspace_ccstheia/ESR-11/jsmn\" -I\"/home/frederik/workspace_ccstheia/ESR-11/driverlib/MSP430FR2xx_4xx\" -I\"/home/frederik/.ti/ccs2010/ccs/tools/compiler/ti-cgt-msp430_21.6.1.LTS/include\" -D__MSP430FR2355__ -D_FRWP_ENABLE -D_INFO_FRWP_ENABLE -xc",
|
||||||
|
"file" : "/home/frederik/workspace_ccstheia/ESR-11/src/door_sensor.c"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
111
main.c
111
main.c
@ -18,72 +18,13 @@
|
|||||||
#include "src/i2c.h"
|
#include "src/i2c.h"
|
||||||
#include "src/lcd.h"
|
#include "src/lcd.h"
|
||||||
#include "src/Board.h"
|
#include "src/Board.h"
|
||||||
|
#include "src/timer.h"
|
||||||
|
#include "src/state_machine.h"
|
||||||
|
|
||||||
/** On-board LED port and pin (used by Morse module) */
|
/** On-board LED port and pin (used by Morse module) */
|
||||||
#define LED_PORT GPIO_PORT_P1 /**< On-board LED port */
|
#define LED_PORT GPIO_PORT_P1 /**< On-board LED port */
|
||||||
#define LED_PIN GPIO_PIN0 /**< On-board LED pin */
|
#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, ¶m);
|
|
||||||
}
|
|
||||||
|
|
||||||
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, ¶m);
|
|
||||||
|
|
||||||
//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.
|
* @brief Main application entry point.
|
||||||
*
|
*
|
||||||
@ -102,48 +43,10 @@ int main(void)
|
|||||||
GPIO_setAsOutputPin(LED_PORT, LED_PIN);
|
GPIO_setAsOutputPin(LED_PORT, LED_PIN);
|
||||||
GPIO_setOutputLowOnPin(LED_PORT, LED_PIN);
|
GPIO_setOutputLowOnPin(LED_PORT, LED_PIN);
|
||||||
|
|
||||||
/* Initialize keypad interrupt driver */
|
|
||||||
initKeypadInterrupts(myKeyHandler);
|
|
||||||
|
|
||||||
init_timer();
|
init_timer();
|
||||||
|
i2c_init();
|
||||||
|
lcd_init();
|
||||||
|
|
||||||
I2C_init(); /* I²C-Master initialisieren */
|
sm_init();
|
||||||
lcd_init(); /* LCD initialisieren */
|
sm_loop();
|
||||||
|
}
|
||||||
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);
|
|
||||||
}
|
|
||||||
55
src/door_sensor.c
Normal file
55
src/door_sensor.c
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <msp430.h>
|
||||||
|
#include <driverlib.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "door_sensor.h"
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
|
#define SENSOR_PORT GPIO_PORT_P2
|
||||||
|
#define SENSOR_PIN GPIO_PIN0
|
||||||
|
#define SENSOR_VECTOR PORT2_VECTOR
|
||||||
|
|
||||||
|
/** User callback invoked on confirmed key press */
|
||||||
|
static DoorOpenedCallback_t doorOpenedCallback = NULL;
|
||||||
|
static DoorClosedCallback_t doorClosedCallback = NULL;
|
||||||
|
|
||||||
|
void door_init(DoorOpenedCallback_t ocb, DoorClosedCallback_t ccb) {
|
||||||
|
doorOpenedCallback = ocb;
|
||||||
|
doorClosedCallback = ccb;
|
||||||
|
|
||||||
|
/* Configure port as pull up with interrupt */
|
||||||
|
GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2, GPIO_PIN0);
|
||||||
|
GPIO_clearInterrupt(GPIO_PORT_P2, GPIO_PIN0);
|
||||||
|
GPIO_selectInterruptEdge(GPIO_PORT_P2, GPIO_PIN0, GPIO_LOW_TO_HIGH_TRANSITION);
|
||||||
|
GPIO_enableInterrupt(GPIO_PORT_P2, GPIO_PIN0);
|
||||||
|
|
||||||
|
/* Enable global interrupts */
|
||||||
|
__enable_interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile bool door_last_open = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Interrupt Service Routine for PORT2
|
||||||
|
*/
|
||||||
|
#pragma vector=SENSOR_VECTOR
|
||||||
|
__interrupt void SENSOR_ISR(void)
|
||||||
|
{
|
||||||
|
uint16_t status = GPIO_getInterruptStatus(SENSOR_PORT, SENSOR_PIN);
|
||||||
|
|
||||||
|
if (status) {
|
||||||
|
if (door_last_open) {
|
||||||
|
if (doorClosedCallback)
|
||||||
|
doorClosedCallback();
|
||||||
|
GPIO_selectInterruptEdge(GPIO_PORT_P2, GPIO_PIN0, GPIO_LOW_TO_HIGH_TRANSITION);
|
||||||
|
} else {
|
||||||
|
if (doorOpenedCallback)
|
||||||
|
doorOpenedCallback();
|
||||||
|
GPIO_selectInterruptEdge(GPIO_PORT_P2, GPIO_PIN0, GPIO_HIGH_TO_LOW_TRANSITION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GPIO_clearInterrupt(SENSOR_PORT, SENSOR_PIN);
|
||||||
|
|
||||||
|
door_last_open = !door_last_open;
|
||||||
|
}
|
||||||
13
src/door_sensor.h
Normal file
13
src/door_sensor.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ifndef DOOR_H
|
||||||
|
#define DOOR_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Callback invoked on a confirmed key press.
|
||||||
|
* @param key ASCII character of the pressed key.
|
||||||
|
*/
|
||||||
|
typedef void (*DoorOpenedCallback_t)(void);
|
||||||
|
typedef void (*DoorClosedCallback_t)(void);
|
||||||
|
|
||||||
|
void door_init(DoorOpenedCallback_t ocb, DoorClosedCallback_t ccb);
|
||||||
|
|
||||||
|
#endif // DOOR_H
|
||||||
@ -28,7 +28,7 @@ static char dataIn;
|
|||||||
|
|
||||||
static volatile bool i2cDone = false;
|
static volatile bool i2cDone = false;
|
||||||
|
|
||||||
void I2C_init(void)
|
void i2c_init(void)
|
||||||
{
|
{
|
||||||
// USCI in Reset setzen um Konfiguration zu ermöglichen
|
// USCI in Reset setzen um Konfiguration zu ermöglichen
|
||||||
UCB0CTLW0 |= UCSWRST;
|
UCB0CTLW0 |= UCSWRST;
|
||||||
@ -56,7 +56,7 @@ void I2C_init(void)
|
|||||||
__enable_interrupt();
|
__enable_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void I2C_write(uint8_t slaveAddress, char data[], uint8_t length)
|
void i2c_write(uint8_t slaveAddress, char data[], uint8_t length)
|
||||||
{
|
{
|
||||||
UCB0I2CSA = slaveAddress;
|
UCB0I2CSA = slaveAddress;
|
||||||
packet = data;
|
packet = data;
|
||||||
@ -77,11 +77,11 @@ void I2C_write(uint8_t slaveAddress, char data[], uint8_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char I2C_read_reg(uint8_t slaveAddress, uint8_t registerAddress)
|
char i2c_read_reg(uint8_t slaveAddress, uint8_t registerAddress)
|
||||||
{
|
{
|
||||||
// Registeradresse zuerst senden
|
// Registeradresse zuerst senden
|
||||||
char addressBuffer[1] = {registerAddress};
|
char addressBuffer[1] = {registerAddress};
|
||||||
I2C_write(slaveAddress, addressBuffer, 1);
|
i2c_write(slaveAddress, addressBuffer, 1);
|
||||||
|
|
||||||
// In Empfangsmodus wechseln und 1 Byte anfordern
|
// In Empfangsmodus wechseln und 1 Byte anfordern
|
||||||
UCB0CTLW0 &= ~UCTR;
|
UCB0CTLW0 &= ~UCTR;
|
||||||
|
|||||||
@ -21,7 +21,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Initialize the I2C module as master (SMCLK/20 → 50 kHz SCL).
|
* @brief Initialize the I2C module as master (SMCLK/20 → 50 kHz SCL).
|
||||||
*/
|
*/
|
||||||
void I2C_init(void);
|
void i2c_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Send a data packet to an I2C slave.
|
* @brief Send a data packet to an I2C slave.
|
||||||
@ -29,7 +29,7 @@ void I2C_init(void);
|
|||||||
* @param data Pointer to the data buffer to send.
|
* @param data Pointer to the data buffer to send.
|
||||||
* @param length Number of bytes to send.
|
* @param length Number of bytes to send.
|
||||||
*/
|
*/
|
||||||
void I2C_write(uint8_t slaveAddress, char data[], uint8_t length);
|
void i2c_write(uint8_t slaveAddress, char data[], uint8_t length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read a single byte from a specific register of an I2C slave.
|
* @brief Read a single byte from a specific register of an I2C slave.
|
||||||
@ -37,6 +37,6 @@ void I2C_write(uint8_t slaveAddress, char data[], uint8_t length);
|
|||||||
* @param registerAddress Register address to read.
|
* @param registerAddress Register address to read.
|
||||||
* @return The byte read from the device.
|
* @return The byte read from the device.
|
||||||
*/
|
*/
|
||||||
char I2C_read_reg(uint8_t slaveAddress, uint8_t registerAddress);
|
char i2c_read_reg(uint8_t slaveAddress, uint8_t registerAddress);
|
||||||
|
|
||||||
#endif /* I2C_H */
|
#endif /* I2C_H */
|
||||||
|
|||||||
16
src/keypad.c
16
src/keypad.c
@ -54,7 +54,7 @@ static KeypadCallback_t keyCallback = NULL;
|
|||||||
* @param colIdx Index of column (0–3) that triggered interrupt
|
* @param colIdx Index of column (0–3) that triggered interrupt
|
||||||
* @return ASCII character of pressed key, or 0 if none detected
|
* @return ASCII character of pressed key, or 0 if none detected
|
||||||
*/
|
*/
|
||||||
static char scanRowForColumn(uint8_t colIdx)
|
static char scan_row_for_column(uint8_t colIdx)
|
||||||
{
|
{
|
||||||
char result = 0;
|
char result = 0;
|
||||||
unsigned int r;
|
unsigned int r;
|
||||||
@ -85,7 +85,7 @@ static char scanRowForColumn(uint8_t colIdx)
|
|||||||
* wait for release, then re-arm interrupts.
|
* wait for release, then re-arm interrupts.
|
||||||
* @param colIdx Index of column that triggered the interrupt
|
* @param colIdx Index of column that triggered the interrupt
|
||||||
*/
|
*/
|
||||||
static void handleColumnInterrupt(uint8_t colIdx)
|
static void handle_column_interrupt(uint8_t colIdx)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ static void handleColumnInterrupt(uint8_t colIdx)
|
|||||||
|
|
||||||
/* Identify pressed key and invoke callback if set */
|
/* Identify pressed key and invoke callback if set */
|
||||||
{
|
{
|
||||||
char key = scanRowForColumn(colIdx);
|
char key = scan_row_for_column(colIdx);
|
||||||
if (key && keyCallback) {
|
if (key && keyCallback) {
|
||||||
keyCallback(key);
|
keyCallback(key);
|
||||||
}
|
}
|
||||||
@ -137,12 +137,12 @@ __interrupt void PORT1_ISR(void)
|
|||||||
uint16_t status = GPIO_getInterruptStatus(GPIO_PORT_P1, mask);
|
uint16_t status = GPIO_getInterruptStatus(GPIO_PORT_P1, mask);
|
||||||
|
|
||||||
if (status & colPin[COL1]) {
|
if (status & colPin[COL1]) {
|
||||||
handleColumnInterrupt(COL1);
|
handle_column_interrupt(COL1);
|
||||||
__bic_SR_register_on_exit(LPM0_bits);
|
__bic_SR_register_on_exit(LPM0_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & colPin[COL3]) {
|
if (status & colPin[COL3]) {
|
||||||
handleColumnInterrupt(COL3);
|
handle_column_interrupt(COL3);
|
||||||
__bic_SR_register_on_exit(LPM0_bits);
|
__bic_SR_register_on_exit(LPM0_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,12 +159,12 @@ __interrupt void PORT3_ISR(void)
|
|||||||
uint16_t status = GPIO_getInterruptStatus(GPIO_PORT_P3, mask);
|
uint16_t status = GPIO_getInterruptStatus(GPIO_PORT_P3, mask);
|
||||||
|
|
||||||
if (status & colPin[COL0]) {
|
if (status & colPin[COL0]) {
|
||||||
handleColumnInterrupt(COL0);
|
handle_column_interrupt(COL0);
|
||||||
__bic_SR_register_on_exit(LPM0_bits);
|
__bic_SR_register_on_exit(LPM0_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status & colPin[COL2]) {
|
if (status & colPin[COL2]) {
|
||||||
handleColumnInterrupt(COL2);
|
handle_column_interrupt(COL2);
|
||||||
__bic_SR_register_on_exit(LPM0_bits);
|
__bic_SR_register_on_exit(LPM0_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +179,7 @@ __interrupt void PORT3_ISR(void)
|
|||||||
* @brief Initialize keypad GPIOs and interrupts.
|
* @brief Initialize keypad GPIOs and interrupts.
|
||||||
* @param cb Callback invoked with ASCII key on press
|
* @param cb Callback invoked with ASCII key on press
|
||||||
*/
|
*/
|
||||||
void initKeypadInterrupts(KeypadCallback_t cb)
|
void keypad_init(KeypadCallback_t cb)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
keyCallback = cb;
|
keyCallback = cb;
|
||||||
|
|||||||
@ -27,6 +27,6 @@ typedef void (*KeypadCallback_t)(char key);
|
|||||||
* @brief Initialize the keypad pins and interrupts.
|
* @brief Initialize the keypad pins and interrupts.
|
||||||
* @param cb User callback for key events.
|
* @param cb User callback for key events.
|
||||||
*/
|
*/
|
||||||
void initKeypadInterrupts(KeypadCallback_t cb);
|
void keypad_init(KeypadCallback_t cb);
|
||||||
|
|
||||||
#endif /* KEYPAD_H */
|
#endif /* KEYPAD_H */
|
||||||
|
|||||||
@ -11,13 +11,13 @@ static void lcd_write_nibble(uint8_t nibble, uint8_t control)
|
|||||||
/* High-Nibble in die oberen 4 Bits */
|
/* High-Nibble in die oberen 4 Bits */
|
||||||
buf[0] = (nibble << 4) | control | LCD_BACKLIGHT;
|
buf[0] = (nibble << 4) | control | LCD_BACKLIGHT;
|
||||||
/* EN=1 */
|
/* EN=1 */
|
||||||
I2C_write(LCD_I2C_ADDR, buf, 1);
|
i2c_write(LCD_I2C_ADDR, buf, 1);
|
||||||
buf[0] |= LCD_ENABLE;
|
buf[0] |= LCD_ENABLE;
|
||||||
I2C_write(LCD_I2C_ADDR, buf, 1);
|
i2c_write(LCD_I2C_ADDR, buf, 1);
|
||||||
__delay_cycles(500); /* ca. 50 µs @ 1 MHz */
|
__delay_cycles(500); /* ca. 50 µs @ 1 MHz */
|
||||||
/* EN=0 */
|
/* EN=0 */
|
||||||
buf[0] &= ~LCD_ENABLE;
|
buf[0] &= ~LCD_ENABLE;
|
||||||
I2C_write(LCD_I2C_ADDR, buf, 1);
|
i2c_write(LCD_I2C_ADDR, buf, 1);
|
||||||
__delay_cycles(500);
|
__delay_cycles(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
src/morse.c
12
src/morse.c
@ -32,7 +32,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Blink the LED for a dot: on 1 unit, off 1 unit.
|
* @brief Blink the LED for a dot: on 1 unit, off 1 unit.
|
||||||
*/
|
*/
|
||||||
static void blinkDot(void)
|
static void blink_dot(void)
|
||||||
{
|
{
|
||||||
GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);
|
GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);
|
||||||
__delay_cycles(MORSE_UNIT_CYCLES);
|
__delay_cycles(MORSE_UNIT_CYCLES);
|
||||||
@ -43,7 +43,7 @@ static void blinkDot(void)
|
|||||||
/**
|
/**
|
||||||
* @brief Blink the LED for a dash: on 3 units, off 1 unit.
|
* @brief Blink the LED for a dash: on 3 units, off 1 unit.
|
||||||
*/
|
*/
|
||||||
static void blinkDash(void)
|
static void blink_dash(void)
|
||||||
{
|
{
|
||||||
GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);
|
GPIO_setOutputHighOnPin(LED_PORT, LED_PIN);
|
||||||
__delay_cycles(3 * MORSE_UNIT_CYCLES);
|
__delay_cycles(3 * MORSE_UNIT_CYCLES);
|
||||||
@ -102,7 +102,7 @@ static const char *lookupMorse(char in)
|
|||||||
* Unlocks FRAM I/O power-on default high-impedance lock,
|
* Unlocks FRAM I/O power-on default high-impedance lock,
|
||||||
* then configures LED pin as output low.
|
* then configures LED pin as output low.
|
||||||
*/
|
*/
|
||||||
void morseInit(void)
|
void morse_init(void)
|
||||||
{
|
{
|
||||||
PMM_unlockLPM5();
|
PMM_unlockLPM5();
|
||||||
GPIO_setAsOutputPin(LED_PORT, LED_PIN);
|
GPIO_setAsOutputPin(LED_PORT, LED_PIN);
|
||||||
@ -118,7 +118,7 @@ void morseInit(void)
|
|||||||
*
|
*
|
||||||
* @param c Character to blink (A–Z, a–z, 0–9)
|
* @param c Character to blink (A–Z, a–z, 0–9)
|
||||||
*/
|
*/
|
||||||
void blinkMorseChar(char c)
|
void blink_morse_char(char c)
|
||||||
{
|
{
|
||||||
const char *pattern = lookupMorse(c);
|
const char *pattern = lookupMorse(c);
|
||||||
const char *p;
|
const char *p;
|
||||||
@ -130,9 +130,9 @@ void blinkMorseChar(char c)
|
|||||||
/* Blink each element in pattern */
|
/* Blink each element in pattern */
|
||||||
for (p = pattern; *p; p++) {
|
for (p = pattern; *p; p++) {
|
||||||
if (*p == '.') {
|
if (*p == '.') {
|
||||||
blinkDot();
|
blink_dot();
|
||||||
} else if (*p == '-') {
|
} else if (*p == '-') {
|
||||||
blinkDash();
|
blink_dash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
/**
|
/**
|
||||||
* @brief Initialize LED output pin (P1.0) for Morse blinking.
|
* @brief Initialize LED output pin (P1.0) for Morse blinking.
|
||||||
*/
|
*/
|
||||||
void morseInit(void);
|
void morse_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Blink an alphanumeric character in Morse code.
|
* @brief Blink an alphanumeric character in Morse code.
|
||||||
@ -18,6 +18,6 @@ void morseInit(void);
|
|||||||
* Supports A–Z (case-insensitive) and 0–9. Others are ignored.
|
* Supports A–Z (case-insensitive) and 0–9. Others are ignored.
|
||||||
* @param c Character to blink
|
* @param c Character to blink
|
||||||
*/
|
*/
|
||||||
void blinkMorseChar(char c);
|
void blink_morse_char(char c);
|
||||||
|
|
||||||
#endif // MORSE_H
|
#endif // MORSE_H
|
||||||
|
|||||||
@ -12,4 +12,365 @@
|
|||||||
* @date 2025-07-02
|
* @date 2025-07-02
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <msp430.h>
|
||||||
|
#include <driverlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "keypad.h"
|
||||||
|
#include "lcd.h"
|
||||||
|
#include "morse.h"
|
||||||
|
#include "door_sensor.h"
|
||||||
|
#include "state_machine.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
volatile char keypad_last_key = '\0';
|
||||||
|
volatile bool keypad_flag_chg = false;
|
||||||
|
|
||||||
|
volatile bool allow_open = false;
|
||||||
|
|
||||||
|
/* Function Declarations */
|
||||||
|
void handle_interrupt(void);
|
||||||
|
void buzz_invalid_input(void);
|
||||||
|
void sound_alarm(void);
|
||||||
|
void reset_alarm(void);
|
||||||
|
void transition(State_t state);
|
||||||
|
void ui_draw_idle(void);
|
||||||
|
void ui_draw_sel_count(void);
|
||||||
|
void ui_draw_confirmed(void);
|
||||||
|
void ui_draw_error(void);
|
||||||
|
void ui_draw_open(void);
|
||||||
|
void ui_draw_none_selected(void);
|
||||||
|
void ui_draw_reset(void);
|
||||||
|
void reset_amount();
|
||||||
|
void reset_amounts();
|
||||||
|
bool any_selected(void);
|
||||||
|
|
||||||
|
volatile State_t current_state = STATE_IDLE;
|
||||||
|
volatile bool state_chg = false;
|
||||||
|
|
||||||
|
volatile uint8_t count_a = 0;
|
||||||
|
volatile uint8_t count_b = 0;
|
||||||
|
volatile uint8_t count_c = 0;
|
||||||
|
volatile uint8_t count_d = 0;
|
||||||
|
volatile SelectedBev_t selected_bev = BEV_A;
|
||||||
|
|
||||||
|
volatile bool door_open = false;
|
||||||
|
|
||||||
|
void handle_input_idle(unsigned char key) {
|
||||||
|
switch (key) {
|
||||||
|
case 'A':
|
||||||
|
selected_bev = BEV_A;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
selected_bev = BEV_B;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
selected_bev = BEV_C;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
selected_bev = BEV_D;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buzz_invalid_input();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_input_confirmed(unsigned char key) {
|
||||||
|
switch (key) {
|
||||||
|
case 'A':
|
||||||
|
selected_bev = BEV_A;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case 'B':
|
||||||
|
selected_bev = BEV_B;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case 'C':
|
||||||
|
selected_bev = BEV_C;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case 'D':
|
||||||
|
selected_bev = BEV_D;
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
reset_amounts();
|
||||||
|
transition(STATE_RESET);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buzz_invalid_input();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void update_amount(uint8_t new_digit) {
|
||||||
|
switch (selected_bev) {
|
||||||
|
case BEV_A:
|
||||||
|
if (count_a * 10 + new_digit < 255)
|
||||||
|
count_a = count_a * 10 + new_digit;
|
||||||
|
break;
|
||||||
|
case BEV_B:
|
||||||
|
if (count_b * 10 + new_digit < 255)
|
||||||
|
count_b = count_b * 10 + new_digit;
|
||||||
|
break;
|
||||||
|
case BEV_C:
|
||||||
|
if (count_c * 10 + new_digit < 255)
|
||||||
|
count_c = count_c * 10 + new_digit;
|
||||||
|
break;
|
||||||
|
case BEV_D:
|
||||||
|
if (count_d * 10 + new_digit < 255)
|
||||||
|
count_d = count_d * 10 + new_digit;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_amount() {
|
||||||
|
switch (selected_bev) {
|
||||||
|
case BEV_A:
|
||||||
|
count_a = 0;
|
||||||
|
break;
|
||||||
|
case BEV_B:
|
||||||
|
count_b = 0;
|
||||||
|
break;
|
||||||
|
case BEV_C:
|
||||||
|
count_c = 0;
|
||||||
|
break;
|
||||||
|
case BEV_D:
|
||||||
|
count_d = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_amounts() {
|
||||||
|
count_a = 0;
|
||||||
|
count_b = 0;
|
||||||
|
count_c = 0;
|
||||||
|
count_d = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_input_sel_count(unsigned char key) {
|
||||||
|
// Check if input is number
|
||||||
|
if (key >= '0' && key <= '9') {
|
||||||
|
update_amount((uint8_t) key - '0');
|
||||||
|
transition(current_state);
|
||||||
|
} else if (key == '#') {
|
||||||
|
if (door_open) {
|
||||||
|
transition(STATE_OPEN);
|
||||||
|
} else {
|
||||||
|
if (!any_selected()) {
|
||||||
|
transition(STATE_NONE_SELECTED);
|
||||||
|
} else {
|
||||||
|
transition(STATE_CONFIRMED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (key == '*') {
|
||||||
|
reset_amount();
|
||||||
|
transition(current_state);
|
||||||
|
} else {
|
||||||
|
handle_input_idle(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 keypad_handler(char key)
|
||||||
|
{
|
||||||
|
keypad_last_key = key;
|
||||||
|
keypad_flag_chg = true;
|
||||||
|
|
||||||
|
switch (current_state) {
|
||||||
|
case STATE_IDLE:
|
||||||
|
handle_input_idle(key);
|
||||||
|
break;
|
||||||
|
case STATE_SEL_COUNT:
|
||||||
|
handle_input_sel_count(key);
|
||||||
|
break;
|
||||||
|
case STATE_CONFIRMED:
|
||||||
|
handle_input_confirmed(key);
|
||||||
|
break;
|
||||||
|
case STATE_OPEN:
|
||||||
|
handle_input_confirmed(key);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
buzz_invalid_input();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool any_selected(void) {
|
||||||
|
return count_a + count_b + count_c + count_d > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void door_opened_handler(void) {
|
||||||
|
if (current_state != STATE_CONFIRMED && current_state != STATE_UNLOCKED) {
|
||||||
|
transition(STATE_UNAUTHORIZED);
|
||||||
|
} else {
|
||||||
|
transition(STATE_OPEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
door_open = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void door_closed_handler(void) {
|
||||||
|
reset_amounts();
|
||||||
|
transition(STATE_IDLE);
|
||||||
|
|
||||||
|
door_open = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void buzz_invalid_input(void) {
|
||||||
|
// FIXME: Implement this later
|
||||||
|
}
|
||||||
|
|
||||||
|
void sound_alarm(void) {
|
||||||
|
// FIXME: Implement this later
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_alarm(void) {
|
||||||
|
// FIXME: Implement this later
|
||||||
|
}
|
||||||
|
|
||||||
|
void transition(State_t state) {
|
||||||
|
state_chg = true;
|
||||||
|
current_state = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm_init(void) {
|
||||||
|
keypad_init(keypad_handler);
|
||||||
|
door_init(door_opened_handler, door_closed_handler);
|
||||||
|
|
||||||
|
ui_draw_idle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sm_loop(void) {
|
||||||
|
for (;;) {
|
||||||
|
__bis_SR_register(LPM0_bits | GIE); /* Enter LPM0 with interrupts enabled */
|
||||||
|
__no_operation();
|
||||||
|
|
||||||
|
handle_general_interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_general_interrupt(void) {
|
||||||
|
if (state_chg) {
|
||||||
|
switch (current_state) {
|
||||||
|
case STATE_IDLE:
|
||||||
|
ui_draw_idle();
|
||||||
|
break;
|
||||||
|
case STATE_SEL_COUNT:
|
||||||
|
ui_draw_sel_count();
|
||||||
|
break;
|
||||||
|
case STATE_CONFIRMED:
|
||||||
|
ui_draw_confirmed();
|
||||||
|
break;
|
||||||
|
case STATE_UNAUTHORIZED:
|
||||||
|
ui_draw_error();
|
||||||
|
break;
|
||||||
|
case STATE_OPEN:
|
||||||
|
ui_draw_open();
|
||||||
|
break;
|
||||||
|
case STATE_NONE_SELECTED:
|
||||||
|
ui_draw_none_selected();
|
||||||
|
break;
|
||||||
|
case STATE_RESET:
|
||||||
|
ui_draw_reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
state_chg = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char buffer_ab[16];
|
||||||
|
char buffer_cd[16];
|
||||||
|
|
||||||
|
void ui_draw_idle(void) {
|
||||||
|
lcd_clear();
|
||||||
|
lcd_set_cursor(0, 5);
|
||||||
|
lcd_print("Ready!");
|
||||||
|
lcd_set_cursor(1, 1);
|
||||||
|
lcd_print("Press A/B/C/D");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_draw_sel_count(void) {
|
||||||
|
snprintf(buffer_ab, 17, "A:%c%4d B:%c%4d ",
|
||||||
|
selected_bev == BEV_A ? '*' : ' ',
|
||||||
|
count_a,
|
||||||
|
selected_bev == BEV_B ? '*' : ' ',
|
||||||
|
count_b
|
||||||
|
);
|
||||||
|
snprintf(buffer_cd, 17, "C:%c%4d D:%c%4d ",
|
||||||
|
selected_bev == BEV_C ? '*' : ' ',
|
||||||
|
count_c,
|
||||||
|
selected_bev == BEV_D ? '*' : ' ',
|
||||||
|
count_d
|
||||||
|
);
|
||||||
|
|
||||||
|
lcd_set_cursor(0, 0);
|
||||||
|
lcd_print(buffer_ab);
|
||||||
|
lcd_set_cursor(1, 0);
|
||||||
|
lcd_print(buffer_cd);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_draw_confirmed(void) {
|
||||||
|
lcd_clear();
|
||||||
|
lcd_set_cursor(0, 3);
|
||||||
|
lcd_print("Confirmed!");
|
||||||
|
lcd_set_cursor(1, 1);
|
||||||
|
lcd_print("OPEN/[A-D]/[*]");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_draw_error(void) {
|
||||||
|
lcd_clear();
|
||||||
|
lcd_set_cursor(0, 2);
|
||||||
|
lcd_print("UNAUTHORIZED");
|
||||||
|
lcd_set_cursor(1, 1);
|
||||||
|
lcd_print("CLOSE DOOR NOW");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_draw_open(void) {
|
||||||
|
lcd_clear();
|
||||||
|
lcd_set_cursor(0, 2);
|
||||||
|
lcd_print("DOOR IS OPEN");
|
||||||
|
lcd_set_cursor(1, 0);
|
||||||
|
lcd_print("CLOSE /[A-D]/[*]");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_draw_none_selected(void) {
|
||||||
|
lcd_clear();
|
||||||
|
lcd_set_cursor(0, 5);
|
||||||
|
lcd_print("SELECT");
|
||||||
|
lcd_set_cursor(1, 1);
|
||||||
|
lcd_print("ANY BEVERAGES!");
|
||||||
|
|
||||||
|
sleep(1000);
|
||||||
|
|
||||||
|
transition(STATE_SEL_COUNT);
|
||||||
|
ui_draw_sel_count();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui_draw_reset(void) {
|
||||||
|
lcd_clear();
|
||||||
|
lcd_set_cursor(0, 2);
|
||||||
|
lcd_print("AMOUNTS HAVE");
|
||||||
|
lcd_set_cursor(1, 3);
|
||||||
|
lcd_print("BEEN RESET");
|
||||||
|
|
||||||
|
sleep(1000);
|
||||||
|
|
||||||
|
if (door_open) {
|
||||||
|
transition(STATE_OPEN);
|
||||||
|
ui_draw_open();
|
||||||
|
} else {
|
||||||
|
transition(STATE_IDLE);
|
||||||
|
ui_draw_idle();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,4 +12,33 @@
|
|||||||
* @date 2025-07-02
|
* @date 2025-07-02
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void keypad_handler(char key);
|
#ifndef STATE_MACHINE_H
|
||||||
|
#define STATE_MACHINE_H
|
||||||
|
|
||||||
|
static void keypad_handler(char key);
|
||||||
|
|
||||||
|
void sm_init(void);
|
||||||
|
|
||||||
|
void sm_loop(void);
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STATE_IDLE,
|
||||||
|
STATE_SEL_COUNT,
|
||||||
|
STATE_CONFIRMED,
|
||||||
|
STATE_OPEN,
|
||||||
|
STATE_SECRET_INPUT,
|
||||||
|
STATE_UNLOCKED,
|
||||||
|
STATE_UNAUTHORIZED,
|
||||||
|
STATE_NONE_SELECTED,
|
||||||
|
STATE_RESET
|
||||||
|
} State_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BEV_A,
|
||||||
|
BEV_B,
|
||||||
|
BEV_C,
|
||||||
|
BEV_D
|
||||||
|
} SelectedBev_t;
|
||||||
|
|
||||||
|
#endif // STATE_MACHINE_H
|
||||||
41
src/timer.c
Normal file
41
src/timer.c
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <msp430.h>
|
||||||
|
#include <driverlib.h>
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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, ¶m);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TimerB0 Interrupt Vector (TBxIV) handler
|
||||||
|
#pragma vector=TIMER0_B0_VECTOR
|
||||||
|
__interrupt void TIMER0_B0_ISR(void)
|
||||||
|
{
|
||||||
|
__bic_SR_register_on_exit(LPM0_bits);
|
||||||
|
}
|
||||||
7
src/timer.h
Normal file
7
src/timer.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#ifndef TIMER_H
|
||||||
|
#define TIMER_H
|
||||||
|
|
||||||
|
void sleep(uint16_t ms);
|
||||||
|
void init_timer(void);
|
||||||
|
|
||||||
|
#endif // TIMER_H
|
||||||
Loading…
Reference in New Issue
Block a user