1
0
mirror of https://github.com/peterantypas/maiana.git synced 2025-05-18 00:10:08 -07:00
maiana/src/DataTerminal.cpp
Peter Antypas 693874feef Cleanup
2016-05-30 16:50:44 -07:00

196 lines
5.6 KiB
C++

/*
* Terminal.cpp
*
* Created on: Apr 19, 2016
* Author: peter
*/
#include "DataTerminal.hpp"
#include "stm32f30x.h"
#include "printf2.h"
#include "MenuScreens.hpp"
#include "Events.hpp"
#include <stdio.h>
#ifdef ENABLE_TERMINAL
DataTerminal &DataTerminal::instance()
{
static DataTerminal __instance;
return __instance;
}
void DataTerminal::init()
{
GPIO_InitTypeDef GPIO_InitStruct;
NVIC_InitTypeDef NVIC_InitStruct;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); // For USART3
GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_7);
GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_7);
// Initialize pins as alternative function 7 (USART)
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_Level_1;
GPIO_Init(GPIOB, &GPIO_InitStruct);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
USART_InitTypeDef USART_InitStructure;
USART_StructInit(&USART_InitStructure);
USART_InitStructure.USART_BaudRate = 38400;
USART_Init(USART3, &USART_InitStructure);
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Cmd(USART3, ENABLE);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
NVIC_InitStruct.NVIC_IRQChannel = USART3_IRQn;
NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_Init(&NVIC_InitStruct);
}
DataTerminal::DataTerminal()
: mEscapes(0), mCurrentScreen(MAIN_SCREEN), mInteractive(false)
{
EventQueue::instance().addObserver(this, CLOCK_EVENT|KEYPRESS_EVENT);
}
void DataTerminal::processEvent(Event *e)
{
if ( e->type() == CLOCK_EVENT ) {
ClockEvent *c = static_cast<ClockEvent*>(e);
if ( c->mTime % 2 == 0 ) {
mEscapes = 0;
}
}
else if ( e->type() == KEYPRESS_EVENT ) {
KeyPressEvent *k = static_cast<KeyPressEvent*>(e);
processCharacter(k->key);
}
}
void DataTerminal::processCharacter(char c)
{
if ( !mInteractive ) {
if ( c == 27 )
++mEscapes;
if ( mEscapes == 3 ) {
mInteractive = true;
printf2("Entering interactive mode\r\n");
showScreen(MAIN_SCREEN);
}
}
else {
if ( c == 13 ) {
clearScreen();
printf2("Exiting interactive mode\r\n");
mInteractive = false;
}
}
}
void write_char(USART_TypeDef* USARTx, char c)
{
while (!(USARTx->ISR & 0x00000040))
;
USART_SendData(USARTx, c);
}
void DataTerminal::write(const char* s, bool interactive)
{
if ( mInteractive && !interactive )
return;
for ( int i = 0; s[i] != 0; ++i )
write_char(USART3, s[i]);
}
void DataTerminal::clearScreen()
{
_write("\033[2J");
_write("\033[H");
}
void DataTerminal::_write(const char *s)
{
write(s, true);
}
void DataTerminal::showScreen(MenuScreen screen)
{
char buff[100];
switch(screen) {
case MAIN_SCREEN: {
clearScreen();
//_write("****************************** Interactive Mode ******************************\r\n");
//_write("NOTICE: IT IS AGAINST USCG REGULATIONS FOR END USERS TO ALTER THEIR MMSI,\r\n");
//_write("STATION NAME AND CALL SIGN AFTER INITIAL INSTALLATION.\r\n");
//_write("IF YOUR UNIT HAS BEEN FACTORY PROGRAMMED, THIS TERMINAL WILL PROMPT YOU\r\n");
//_write("FOR A SPECIAL CODE BEFORE ALLOWING THIS OPERATION. YOU CAN ONLY OBTAIN THE\r\n");
//_write("CODE BY CONTACTING US AND PROVIDING THE UNIT'S SERIAL NUMBER AND CURRENT MMSI.\r\n\r\n");
sprintf(buff, "Model: %s\r\n", MODEL);
_write(buff);
sprintf(buff, "Software revision: %s\r\n", REVISION);
_write(buff);
#if 0
sprintf(buff, "MMSI: %d\r\n", STATION_MMSI);
_write(buff);
sprintf(buff, "Name: %s\r\n", STATION_NAME);
_write(buff);
sprintf(buff, "Call sign: %s\r\n", STATION_CALLSIGN);
_write(buff);
#endif
_write("\r\n");
_write("****************************** AIS Transponder Menu ******************************\r\n\r\n");
_write("\t\033[1mP\033[0m\tProgram MMSI, station name and call sign \r\n");
_write("\t\033[1mD\033[0m\tPerform diagnostics \r\n");
_write("\t\033[1m<Enter>\033[0m\tReturn to AIS data mode\r\n\r\n");
_write("**********************************************************************************\r\n\r\n");
//_write("Note: The device will automatically return to AIS data mode if rebooted.\r\n");
break;
}
case PROGRAMMING_SCREEN:
break;
}
mCurrentScreen = screen;
}
extern "C" {
void USART3_IRQHandler(void)
{
if ( USART_GetITStatus(USART3, USART_IT_RXNE) ) {
char c = (char) USART3->RDR; // This clears the interrupt right away
KeyPressEvent *e = static_cast<KeyPressEvent*>(EventPool::instance().newEvent(KEYPRESS_EVENT));
if ( e == NULL )
return;
e->key = c;
EventQueue::instance().push(e);
//DataTerminal::instance().processCharacter(c);
}
}
}
#endif