EmbeddedSystems/EmbeddedSystemsTHM/CLI.c

402 lines
15 KiB
C

//================================================================================================================================
// Includes
//================================================================================================================================
#include <avr/pgmspace.h>
#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include "CLI.h"
#include "Taster.h"
#include "Timer.h"
#include "Led.h"
#include "adc.h"
#include "rotaryEncoder.h"
//================================================================================================================================
// defines
//================================================================================================================================
#define COUNT_COMMANDS ( sizeof(command) / sizeof(command[0]) )
#define CHAR_DEL 0x7F
#define CHAR_BACKSPACE 0x08
#define CHAR_CR 0x0D
#define CHAR_LF 0x0A
#define CHAR_ESC 0x1B
#define NEXT_LINE (char*)"\r\n"
#define CURSOR (char*)">> "
//================================================================================================================================
// Lokale Variablen
//================================================================================================================================
uint16_t g_startMS;
static char data[200]; // Zwischenspeicher für die Befehlsdecodierung
static char rs232_buffer[50];
static uint8_t pointer=0; // Zeiger zu obiger Variable
static void (*callback_function)(char _data) = NULL; // Funktionszeiger auf eine Funktion, welche die Daten entgegen nimmt,
// und auf der Ausgabeschnittstelle ausgibt.
//================================================================================================================================
// Lokale Functionen
//================================================================================================================================
static void run_cmd(char *_data);
static char* get_next(char *_data);
static char to_uppercase (char _data);
static void print_char (char _data);
static void print_string (char* _data);
// Funktionen für Befehlsdecoder
static void cmd_help(const char* _data);
static void cmd_taster(const char* _data);
static void cmd_led_on(const char* _data);
static void cmd_led_off(const char* _data);
static void cmd_alert(const char* _data);
static void cmd_adc(const char* _data);
static void cmd_rotary(const char* _data);
//================================================================================================================================
// command-Tabelle
//================================================================================================================================
const struct {
const char cmd[20];
void (*funktion)(const char* _data);
const char info[40];
} command[] PROGMEM = {
{"HELP", &cmd_help, "Display this Help Menu"},
{"BUTTON", &cmd_taster, "Current State of the Buttons"},
{"LED_ON", &cmd_led_on, "Turn on the LED on position $LED"},
{"LED_OFF", &cmd_led_off, "Turn off the LED on position $LED"},
{"ADC", &cmd_adc, "Read the ADC output"},
{"ROTARY", &cmd_rotary, "Read the rotary encoder"},
{"ALERT", &cmd_alert, "RING THE ALTER!!!"},
};
//================================================================================================================================
// Funktion: line_interpreter_init
// Initialisierung des Line-Interpreters.
// Parameter: _ptr: Zeiger auf die Funktion, welche die einzelne Zeichen auf der Konsole ausgeben kann.
// Rückgabewert: keine
//================================================================================================================================
void line_interpreter_init(void (*_ptr)(char _data)){
callback_function = _ptr;
}
//================================================================================================================================
// Funktion: line_interpreter_get_data
// Dieser Funktion werden die Daten von der RS232 Schnittstelle übergeben. In dieser Funktion werden die Empfangen
// Zeichen zu einer Zeichenkette zusammengefügt, und wenn die ein Carryage-Return empfangen wurde, wird die
// Zeichenkette an den Decoder übergeben.
// Parameter: _char: Empfangenes Zeichen
// Rückgabewert: keine
//================================================================================================================================
void line_interpreter_get_data(char _char){
switch (_char){
case CHAR_BACKSPACE:
case CHAR_DEL:
if (pointer > 0){
pointer--; // Zeichen aus Zeichenkette entfernen
print_char (CHAR_BACKSPACE);
print_char (' ');
print_char (CHAR_BACKSPACE);
}
break;
case CHAR_CR: // Enter wurde gedrückt,
data[pointer] = 0; // Terminate String;
print_string(NEXT_LINE);
if (pointer>0){ // Wenn mindestens ein Zeichen empfangen wurde dann
run_cmd (data); // Empfangene Zeichenkette Ausweten
pointer = 0;
}
print_string (CURSOR);
break;
default: // Normales Zeichen empfangen.
_char = to_uppercase(_char); // Kleinbuchstaben zu Großbuchstaben wandeln
print_char(_char); // Empfangenes Zeichen Ausgeben
data[pointer++] = _char; // Empfangenes Zeichen in Zwischenspeicher speichern.
break;
}//end switch
}
//================================================================================================================================
// Funktion: Ausfuehren
// Diese Funktion überprüft das erste Wort in der Zeichenkette mit der Command-Tabelle und wenn es eine Über-
// einstimmung gibt, wird die entsprechende Funktion aufgerufen.
// Parameter: _string: Auszuwertende Zeichenkette
// Rückgabewert: keine
//================================================================================================================================
static void run_cmd (char *_string){
char *temp = 0;
uint8_t i;
void (*temp_func)(char* const _string);
temp = get_next(data);
for (i=0; i<COUNT_COMMANDS; i++){
if (strcmp_P(_string, command[i].cmd)==0){
memcpy_P(&temp_func, &command[i].funktion, sizeof (temp_func));
temp_func(temp);
break;
}
}
if (i==COUNT_COMMANDS){
sprintf_P (rs232_buffer, PSTR("COMMAND ERROR\r\n\r\n"));
print_string(rs232_buffer);
}
}
//================================================================================================================================
// Funktion: get_next
// Diese Funktion separiert den übergebenen String.
// Parameter: _data: Auszuwertende Zeichenkette
// Rückgabewert: keine
//================================================================================================================================
static char* get_next(char *_data){
char *temp = _data;
while (*temp != 0){
if (*temp==' '){
*temp = 0;
temp++;
break;
} else{
temp++;
}
}
return temp;
}
//================================================================================================================================
// Funktion: Grossbuchstaben
// Diese Funktion wandelt Kleinbuchstaben in Großbuchstaben.
// Parameter: _char: Auszuwertendes Zeichen
// Rückgabewert: Das eingegebene Zeichen als Großbuchstabe.
//================================================================================================================================
static char to_uppercase (char _char){
if ( (_char>='a') && (_char<='z') ){
_char -= 'a' - 'A';
}
return _char;
}
//================================================================================================================================
// Funktion: print_char
// Ausgabe eines Zeichens auf der Konsole.
// Parameter: _data: Zeichen, welches an die Callbackfunktion übergeben werden soll.
// Rückgabewert: keine
//================================================================================================================================
static void print_char (char _data){
if (callback_function != NULL){
callback_function(_data);
}
}
//================================================================================================================================
// Funktion: print_string
// Ausgabe eines Strings auf der Konsole.
// Parameter: _data: Zeichenkette
// Rückgabewert: keine
//================================================================================================================================
static void print_string (char* _data){
for(uint8_t i=0; i<200; i++) {
if(_data[i] == 0){
break;
}
print_char(_data[i]);
}
}
//================================================================================================================================
// Funktion: cmd_temp
// Hilfe Funktion. Gibt die Hilfe Tabelle aus.
// Parameter: _data: Zeichenkette mit Parametern des Befehls
// Rückgabewert: keine
//================================================================================================================================
static void cmd_help(const char* _data){
for (uint8_t i=0; i<COUNT_COMMANDS; i++){
strcpy_P(rs232_buffer, command[i].cmd);
print_string(rs232_buffer);
print_string((char*)" ");
strcpy_P(rs232_buffer, command[i].info);
print_string(rs232_buffer);
print_string(NEXT_LINE);
}
}
//================================================================================================================================
// Funktion: cmd_taster
// Kann verwendet werden, um den aktuellen Status der Taster abzufragen
// Parameter: _data: Zeichenkette mit Parametern des Befehls
// Rückgabewert: keine
//================================================================================================================================
static void cmd_taster(const char* _data){
print_string("Taster 1: ");
print_string(Taster1_get() ? "1" : "0");
print_string(NEXT_LINE);
print_string("Taster 2: ");
print_string(Taster2_get() ? "1" : "0");
print_string(NEXT_LINE);
print_string("Taster 3: ");
print_string(Taster3_get() ? "1" : "0");
print_string(NEXT_LINE);
print_string("Taster 4: ");
print_string(Taster4_get() ? "1" : "0");
print_string(NEXT_LINE);
}
//================================================================================================================================
// Funktion: cmd_led_on
// Kann verwendet werden, um eine LED einzuschalten
// Parameter: _data: Zeichenkette mit Parametern des Befehls.
// Hier: Die ID der LED, welche eingeschaltet werden soll
// Rückgabewert: keine
//================================================================================================================================
static void cmd_led_on(const char* _data){
switch(_data[0]){
case '1': Led1_On(); break;
case '2': Led2_On(); break;
case '3': Led3_On(); break;
case '4': Led4_On(); break;
case '5': Led5_On(); break;
case '6': Led6_On(); break;
case '7': Led7_On(); break;
case '8': Led8_On(); break;
default:
print_string("Led could not be found.");
print_string(NEXT_LINE);
}
}
//================================================================================================================================
// Funktion: cmd_led_off
// Kann verwendet werden, um eine LED auszuschalten
// Parameter: _data: Zeichenkette mit Parametern des Befehls.
// Hier: Die ID der LED, welche ausgeschaltet werden soll
// Rückgabewert: keine
//================================================================================================================================
static void cmd_led_off(const char* _data){
switch(_data[0]){
case '1': Led1_Off(); break;
case '2': Led2_Off(); break;
case '3': Led3_Off(); break;
case '4': Led4_Off(); break;
case '5': Led5_Off(); break;
case '6': Led6_Off(); break;
case '7': Led7_Off(); break;
case '8': Led8_Off(); break;
default:
print_string("LED could not be found.");
print_string(NEXT_LINE);
}
}
//================================================================================================================================
// Funktion: cmd_alert
// Lässt die Roten LEDs blinken und gibt einen Alarm text aus.
// Parameter: _data: Zeichenkette mit Parametern des Befehls.
// Rückgabewert: keine
//================================================================================================================================
static void cmd_alert(const char* _data){
uint8_t isOn = 0;
while (1)
{
if(Timer_getTick() - g_startMS >= 250){
g_startMS = Timer_getTick();
print_string("ALERT!!!");
if(!isOn){
isOn = 1;
Led6_On();
Led7_On();
Led8_On();
} else {
isOn = 0;
Led6_Off();
Led7_Off();
Led8_Off();
}
}
}
}
//================================================================================================================================
// Funktion: cmd_adc
// Wird verwendet um die Daten von Poti und LM35 zu lesen
// Parameter: _data: Zeichenkette mit Parametern des Befehls.
//
// Rückgabewert: keine
//================================================================================================================================
static void cmd_adc(const char* _data){
char potiData[50];
char lm35Data[50];
int loopInterval = 500;
int lm35;
do
{
if(Timer_getTick() - g_startMS >= loopInterval){
g_startMS=Timer_getTick();
/* Print Potentiometer info */
sprintf(potiData, "Poti: %d", adc_get_poti());
//sprintf(potiData, "Poti: %f", (adc_get_poti() / 1023.0)); // uses floats - disabled for performance reasons.
print_string(potiData);
print_string(NEXT_LINE);
/* Print LM35 temperature */
/* calculate the temperature from the ADC reading */
lm35 = (int)(adc_get_LM35() * 5000.0 / 1024 / 10);
sprintf(lm35Data, "LM35: %d\xC2\xB0 C", lm35);
//sprintf(lm35Data, "LM35: %f\xC2\xB0 C", (adc_get_LM35() * (5000 / 1024.0) / 10)); // uses floats - disabled for performance reasons.
print_string(lm35Data);
print_string(NEXT_LINE);
print_string("----------");
print_string(NEXT_LINE);
}
} while (strcmp(_data, "R") == 0 ? 1 : 0); /* Check if repeat flag is set*/
}
//================================================================================================================================
// Funktion: cmd_rotary
// Wird verwendet um die Bewegung von Dregeber zu lesen
// Parameter: _data: Zeichenkette mit Parametern des Befehls.
//
// Rückgabewert: keine
//================================================================================================================================
static void cmd_rotary(const char* _data){
char encoderText[50];
int16_t tmp=-32768, cnt=0;
do
{
cnt = drehgeber_get();
if(cnt != tmp)
{
sprintf(encoderText, "Rotary Encoder: %d", drehgeber_get());
print_string(encoderText);
print_string(NEXT_LINE);
tmp = cnt;
}
} while (strcmp(_data, "R") == 0 ? 1 : 0); /* Check if repeat flag is set*/
}