diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile index 6eacfff..c094514 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/Makefile @@ -14,6 +14,7 @@ startup_stm32f10x_cl.o \ \ Display.o \ FreeRTOSFixes.o \ +hwValidationMenu.o \ \ heap_2.o\ list.o \ diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h index f37d953..4a0d465 100644 --- a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/inc/hwValidationMenu.h @@ -44,27 +44,22 @@ // ----------------------------------------------------------------------------- +#define ANSI_TERMINAL_RESET "\x1b[2J" +#define ANSI_TERMINAL_HOME "\x1b[H" + +#define CON_INF_MAX_MENU_ITEMS (15) + // ----------------------------------------------------------------------------- // Type definitions. // ----------------------------------------------------------------------------- - -struct HwValidationMenu -{ - struct IODevice* displayDevice; - TaskHandle_t taskHandle; - int TaskPriority; - uint16_t stackSize; - bool runTask; -}; - - struct HwValidationMenuItems { struct DisplayDevice* display; // DisplayDevice to talk to struct Adc* internalADC; // Internal ADC with channel array struct MAX5715* externalDAC; // External DAC with channel array + struct Gpio* power6v5Enable; struct Gpio* interlock1; struct Gpio* interlock2; struct Gpio* solenoid; @@ -72,12 +67,24 @@ struct HwValidationMenuItems struct Gpio* mcp1Relay; struct Gpio* mcp2Relay; struct Gpio* cat0Relay; - struct Gpio* cat0Relay; - struct Gpio* cat0Relay; + struct Gpio* cat1Relay; + struct Gpio* cat2Relay; struct Pcba* pcba; // struct Eeprom* eeprom; // Not implemented yet - }; + +struct HwValidationMenu +{ + TaskHandle_t taskHandle; + int TaskPriority; + uint16_t stackSize; + bool runTask; + struct HwValidationMenuItems* testItems; + int menuItemSelected; + struct IODevice* ioDevice; +}; + + // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- diff --git a/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/hwValidationMenu.c b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/hwValidationMenu.c new file mode 100644 index 0000000..a60b44f --- /dev/null +++ b/S - Software/0 - HSB MRTS Kathode-MCP/3 - Implementation/0 - Code/hsb-mrts/src/hwValidationMenu.c @@ -0,0 +1,1240 @@ +// ----------------------------------------------------------------------------- +/// @file hwValidationMenu.c +/// @brief Description +// ----------------------------------------------------------------------------- +// Micro-Key bv +// Industrieweg 28, 9804 TG Noordhorn +// Postbus 92, 9800 AB Zuidhorn +// The Netherlands +// Tel: +31 594 503020 +// Fax: +31 594 505825 +// Email: support@microkey.nl +// Web: www.microkey.nl +// ----------------------------------------------------------------------------- +/// $Revision: 235 $ +/// $Author: swo $ +/// $Date: 2017-10-05 09:49:28 +0200 (do, 05 okt 2017) $ +// (c) 2017 Micro-Key bv +// ----------------------------------------------------------------------------- + +/// @file hwValidationMenu.c +/// @ingroup {group_name} + + +// ----------------------------------------------------------------------------- +// Include files +// ----------------------------------------------------------------------------- + +#include "hwValidationMenu.h" + +#include "DisplayDevice.h" +#include "gpio.h" +#include "adc.h" + +#include "Logger.h" + +// ----------------------------------------------------------------------------- +// Constant and macro definitions +// ----------------------------------------------------------------------------- + +#define MENU_DRAW_SELECTED(index) if( index == self->menuItemSelected ) { menuItems[index] = '*'; } else { menuItems[index] = ' '; } + +#define CMD_BUFFER_SIZE (10) + +// ----------------------------------------------------------------------------- +// Type definitions +// ----------------------------------------------------------------------------- + +typedef enum +{ + CONSOLE_MAIN_MENU, + CONSOLE_TEST_POWER, + CONSOLE_TEST_DISPLAY, + CONSOLE_TEST_KEYPAD, + CONSOLE_TEST_ADC, + CONSOLE_TEST_DAC, + CONSOLE_TEST_INTERLOCK, + CONSOLE_TEST_SOLENOID, + CONSOLE_TEST_RELAY, + CONSOLE_TEST_PCB_VARIANT, + CONSOLE_TEST_EEPROM, + CONSOLE_IDLE +}Menu_States_t; + +typedef enum +{ + DISPLAY_MENU_MAIN, + DISPLAY_MENU_POWER, + DISPLAY_MENU_DISPLAY, + DISPLAY_MENU_KEYPAD, + DISPLAY_MENU_ADC, + DISPLAY_MENU_DAC, + DISPLAY_MENU_INTERLOCK, + DISPLAY_MENU_SOLENOID, + DISPLAY_MENU_RELAY, + DISPLAY_MENU_PCB_VARIANT, + DISPLAY_MENU_EEPROM +}Display_States_t; + +typedef enum +{ + BUTTON_ENTER, + BUTTON_UP, + BUTTON_DOWN, + BUTTON_RIGHT, + BUTTON_LEFT, + BUTTON_PASSPHRASE +}Button_Pressed_t; + + +// ----------------------------------------------------------------------------- +// File-scope variables +// ----------------------------------------------------------------------------- + + +static const char conInfHeader[] = + "*******************************************************************************\r\n" + "** Photonis - something **\r\n" + "** **\r\n" + "*******************************************************************************\r\n" + " \r\n"; + +static const char conInfMainMenu[] = + " MAIN MENU \r\n" + " Select one of the options: \r\n" + " [%c] Test Power \r\n" + " [%c] Test Display \r\n" + " [%c] Test Keypad \r\n" + " [%c] Test ADCs \r\n" + " [%c] Test DACs \r\n" + " [%c] Test Interlocks \r\n" + " [%c] Test Solenoids \r\n" + " [%c] Test relays \r\n" + " [%c] Test PCB variant \r\n" + " [%c] Test EEPROM \r\n" + " \r\n"; + +enum +{ + MENU_MAIN_POWER, + MENU_MAIN_DISPLAY, + MENU_MAIN_KEYPAD, + MENU_MAIN_ADC, + MENU_MAIN_DAC, + MENU_MAIN_INTERLOCK, + MENU_MAIN_SOLENOID, + MENU_MAIN_RELAY, + MENU_MAIN_PCB_VARIANT, + MENU_MAIN_EEPROM, + MENU_MAIN_LAST +}; + + +static const char conTestPower[] = + " TEST POWER \r\n" + " \r\n" + " Control the 6V5 power supply \r\n" + " \r\n" + " [%c] Power on 6V5 \r\n" + " [%c] Power off 6V5 \r\n" + " [%c] Back \r\n" + " \r\n"; + +enum +{ + MENU_TEST_POWER_ON, + MENU_TEST_POWER_OFF, + MENU_TEST_POWER_BACK, + MENU_TEST_POWER_LAST +}; + + +static const char conTestDisplay[] = + " TEST Display \r\n" + " \r\n" + " Test the display and backlight \r\n" + " \r\n" + " [%c] Set backlight to 10%% \r\n" + " [%c] Set backlight to 50%% \r\n" + " [%c] Set backlight to 100%% \r\n" + " [%c] Show text on display \r\n" + " [%c] Clear display content \r\n" + " [%c] Back \r\n" + " \r\n"; + +enum +{ + MENU_TEST_DISPLAY_BL_10, + MENU_TEST_DISPLAY_BL_50, + MENU_TEST_DISPLAY_BL_100, + MENU_TEST_DISPLAY_SHOW_TEXT, + MENU_TEST_DISPLAY_CLEAR_DISPLAY, + MENU_TEST_DISPLAY_BACK, + MENU_TEST_DISPLAY_LAST +}; + + +static const char conTestADC[] = + " TEST ADC[0-2] \r\n" + " \r\n" + " Test the ADC channel 0-2 \r\n" + " \r\n" + " [%c] Read channel 0 \r\n" + " [%c] Read channel 1 \r\n" + " [%c] Read channel 2 \r\n" + " [%c] Back \r\n" + " \r\n"; + +enum +{ + MENU_TEST_ADC_CH_0, + MENU_TEST_ADC_CH_1, + MENU_TEST_ADC_CH_2, + MENU_TEST_ADC_BACK, + MENU_TEST_ADC_LAST +}; + +static const char conTestDAC[] = + " TEST DAC[0-2] \r\n" + " \r\n" + " Test the DAC channel 0-2 \r\n" + " \r\n" + " [%c] Set DAC CH0 to 0V \r\n" + " [%c] Set DAC CH0 to 1.25V \r\n" + " [%c] Set DAC CH0 to 2.5V \r\n" + " [%c] Set DAC CH0 to 5.0V \r\n" + " [%c] Set DAC CH1 to 0V \r\n" + " [%c] Set DAC CH1 to 1.25V \r\n" + " [%c] Set DAC CH1 to 2.5V \r\n" + " [%c] Set DAC CH1 to 5.0V \r\n" + " [%c] Set DAC CH2 to 0V \r\n" + " [%c] Set DAC CH2 to 1.25V \r\n" + " [%c] Set DAC CH2 to 2.5V \r\n" + " [%c] Set DAC CH2 to 5.0V \r\n" + " [%c] Back \r\n" + " \r\n"; +enum +{ + MENU_TEST_DAC_CH_0_0V0, + MENU_TEST_DAC_CH_0_1V25, + MENU_TEST_DAC_CH_0_2V5, + MENU_TEST_DAC_CH_0_5V0, + MENU_TEST_DAC_CH_1_0V0, + MENU_TEST_DAC_CH_1_1V25, + MENU_TEST_DAC_CH_1_2V5, + MENU_TEST_DAC_CH_1_5V0, + MENU_TEST_DAC_CH_2_0V0, + MENU_TEST_DAC_CH_2_1V25, + MENU_TEST_DAC_CH_2_2V5, + MENU_TEST_DAC_CH_2_5V0, + MENU_TEST_DAC_BACK, + MENU_TEST_DAC_LAST +}; + +static const char conTestInterlock[] = + " TEST Interlock \r\n" + " \r\n" + " Test the interlock [1-2] \r\n" + " \r\n" + " [%c] Read Interlock 1 \r\n" + " [%c] Read Interlock 2 \r\n" + " [%c] Back \r\n" + " \r\n"; + +enum +{ + MENU_TEST_INTERLOCK_1, + MENU_TEST_INTERLOCK_2, + MENU_TEST_INTERLOCK_BACK, + MENU_TEST_INTERLOCK_LAST +}; + +static const char conTestSolenoid[] = + " TEST Solenoid \r\n" + " \r\n" + " Test the interlock [1-2] \r\n" + " \r\n" + " [%c] Toggle Solenoid \r\n" + " [%c] Back \r\n" + " \r\n"; +enum +{ + MENU_TEST_SOLENOID_TOGGLE, + MENU_TEST_SOLENOID_BACK, + MENU_TEST_SOLENOID_LAST +}; + + +static const char conTestRelays[] = + " TEST Relays \r\n" + " \r\n" + " Test the relays [1-6] \r\n" + " \r\n" + " [%c] Toggle Relay 1 \r\n" + " [%c] Toggle Relay 2 \r\n" + " [%c] Toggle Relay 3 \r\n" + " [%c] Toggle Relay 4 \r\n" + " [%c] Toggle Relay 5 \r\n" + " [%c] Toggle Relay 6 \r\n" + " [%c] Clear all relays \r\n" + " [%c] Back \r\n" + " \r\n"; + +enum +{ + MENU_TEST_RELAYS_TOGGLE_1, + MENU_TEST_RELAYS_TOGGLE_2, + MENU_TEST_RELAYS_TOGGLE_3, + MENU_TEST_RELAYS_TOGGLE_4, + MENU_TEST_RELAYS_TOGGLE_5, + MENU_TEST_RELAYS_TOGGLE_6, + MENU_TEST_RELAYS_CLEAR_ALL, + MENU_TEST_RELAYS_BACK, + MENU_TEST_RELAYS_LAST +}; + + + + + +// ----------------------------------------------------------------------------- +// Function declarations +// ----------------------------------------------------------------------------- + +static void hwValidationMenuTask(void *parameters); + +static void hwValidationMenuSM(struct HwValidationMenu* self, Button_Pressed_t button ); +static void hwValidationMenuUpdate( struct HwValidationMenu* self ); +static void hwValidationMenuDisplay(struct HwValidationMenu* self, Display_States_t display ); + +static ErrorStatus hwValidationMenuReceiveMessage(struct HwValidationMenu* self, uint8_t * pData, uint16_t numBytes ); + +// ----------------------------------------------------------------------------- +// Function definitions +// ----------------------------------------------------------------------------- + + +ErrorStatus HwValidationMenu_construct(struct HwValidationMenu* self, struct IODevice* ioDevice, struct HwValidationMenuItems testItems) +{ + + ErrorStatus returnValue = SUCCESS; + + self->ioDevice = ioDevice; + + self->TaskPriority = 0; + self->stackSize = 1024; + + self->menuItemSelected = 0; + + if (xTaskCreate(hwValidationMenuTask, (const char*)"HwValidationMenu", self->stackSize, self, self->TaskPriority, self->taskHandle) != pdTRUE) + { + returnValue = ERROR; + LOGGER_ERROR(mainLog, "Starting hw validation menu task failed"); + } + else + { + LOGGER_INFO(mainLog, "hw validation menu task started"); + } + + return returnValue; +} + +static void hwValidationMenuTask(void *parameters) +{ + struct HwValidationMenu* self = (struct HwValidationMenu*)parameters; + + while(1) + { + hwValidationMenuUpdate(self); + vTaskDelay(1); + } +} + + +// catch keyboard input, relay to hwValidationMenuSM() +void hwValidationMenuUpdate( struct HwValidationMenu* self ) +{ + uint8_t cmdBuff[CMD_BUFFER_SIZE] = {0}; + ErrorStatus returnValue = SUCCESS; + + // Wait for the first character of an incoming command + returnValue = hwValidationMenuReceiveMessage(self, &cmdBuff[0], 1 ); + if( returnValue != SUCCESS ) + return; + + // Capture ENTER + if( (cmdBuff[0] == '\n') || (cmdBuff[0] == '\r') ) + { + hwValidationMenuSM(self, BUTTON_ENTER ); + } + + // Capture directional keys + else if( cmdBuff[0] == '\e' ) + { + // wait for 2 more characters + returnValue = hwValidationMenuReceiveMessage(self, &cmdBuff[1], 2 ); + if( returnValue != SUCCESS ) + return; + + if( cmdBuff[1] != '[' ) + return; + + if( cmdBuff[2] == 'A') // 'e' '[' 'A' + { + hwValidationMenuSM(self, BUTTON_UP ); + } + else if( cmdBuff[2] == 'B' ) // 'e' '[' 'B' + { + hwValidationMenuSM(self, BUTTON_DOWN ); + } + else if( cmdBuff[2] == 'C' ) // 'e' '[' 'C' + { + hwValidationMenuSM(self, BUTTON_RIGHT ); + } + else if( cmdBuff[2] == 'D' ) // 'e' '[' 'D' + { + hwValidationMenuSM(self, BUTTON_LEFT ); + } + } + + // Flush other characters + else + { + ; // do nothing, essentially flush UART buffer + } +} + + +// traverse menu based on buttons pressed, update console with +// selected menu item using hwValidationMenuDisplay() +static void hwValidationMenuSM(struct HwValidationMenu* self, Button_Pressed_t button ) +{ + static Menu_States_t menuState = CONSOLE_IDLE; + char outputBuffer[128]; + int outputBufferLength = 0; + + switch( menuState ) + { + case CONSOLE_IDLE : + if( button == BUTTON_ENTER ) + { + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + break; + + case CONSOLE_MAIN_MENU : + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_MAIN_LAST - 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_MAIN_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + else if( button == BUTTON_ENTER ) + { + // Go to selected menu + if( self->menuItemSelected == MENU_MAIN_POWER ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_POWER ); + } + else if( self->menuItemSelected == MENU_MAIN_POWER ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_DISPLAY ); + } + else if( self->menuItemSelected == MENU_MAIN_DISPLAY ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, MENU_MAIN_KEYPAD ); + } + else if( self->menuItemSelected == MENU_MAIN_KEYPAD ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, MENU_MAIN_ADC ); + } + else if( self->menuItemSelected == MENU_MAIN_ADC) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_DAC ); + } + else if( self->menuItemSelected == MENU_MAIN_DAC ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_INTERLOCK ); + } + else if( self->menuItemSelected == MENU_MAIN_INTERLOCK ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_SOLENOID ); + } + else if( self->menuItemSelected == MENU_MAIN_SOLENOID ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_RELAY ); + } + else if( self->menuItemSelected == MENU_MAIN_RELAY ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_PCB_VARIANT ); + } + else if( self->menuItemSelected == MENU_MAIN_EEPROM ) + { + self->menuItemSelected = 0; + menuState = CONSOLE_TEST_DISPLAY; + hwValidationMenuDisplay(self, DISPLAY_MENU_EEPROM ); + } + + } + break; + + + case CONSOLE_TEST_POWER: + + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_POWER_LAST - 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_POWER ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_POWER_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_POWER ); + } + else if( button == BUTTON_ENTER ) + { + if( self->menuItemSelected == MENU_TEST_POWER_ON ) + { + // Turn on 6V5 power ( enable active low ) + if(GPIO_setValue(self->testItems->power6v5Enable, false) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Power: Off\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Power: Failure\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_POWER_OFF ) + { + //Turn on 6V5 power ( enable active low ) + if( GPIO_setValue(self->testItems->power6v5Enable, true) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Power: Off\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Power: Failure\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_POWER_BACK ) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + + break; + + case CONSOLE_TEST_DISPLAY: + + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_DISPLAY_LAST - 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_DISPLAY ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_DISPLAY_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_DISPLAY ); + } + else if( button == BUTTON_ENTER ) + { + if( self->menuItemSelected == MENU_TEST_DISPLAY_BL_10) + { + // Set display backlight to 10% + if( DisplayDevice_setBrightness(self->testItems->display, 10) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Display: bl set to 10%%\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Display: failed to set bl\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_DISPLAY_BL_50 ) + { + // Set display backlight to 50% + if( DisplayDevice_setBrightness(self->testItems->display, 50) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Display: bl set to 50%%\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Display: failed to set bl\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_DISPLAY_BL_100 ) + { + // Set display backlight to 100% + if( DisplayDevice_setBrightness(self->testItems->display, 100) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Display: bl set to 100%%\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Display: failed to set bl\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_DISPLAY_SHOW_TEXT ) + { + const char buffer[] = "Display Test Text"; + if( DisplayDevice_write(self->testItems->display, buffer, sizeof(buffer), 2, 2) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Display: text written\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Display: write failed\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_DISPLAY_CLEAR_DISPLAY ) + { + // Clear display + if( DisplayDevice_clear(self->testItems->display) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Display: cleared\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Display: Clear failed\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_DISPLAY_BACK ) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + + break; + + case CONSOLE_TEST_KEYPAD: + // No sub items + // TODO: Implement test + break; + + case CONSOLE_TEST_ADC: + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_ADC_LAST - 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_ADC ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_ADC_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_ADC ); + } + else if( button == BUTTON_ENTER ) + { + uint16_t adcValue = 0; + if( self->menuItemSelected == MENU_TEST_ADC_CH_0) + { + if(ADCChannel_read(&self->testItems->internalADC->channel[0], &adcValue) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "ADC0 value:%d\r\n", adcValue); + } + else + { + outputBufferLength = sprintf(outputBuffer, "ADC0: failed to read\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_ADC_CH_1 ) + { + if(ADCChannel_read(&self->testItems->internalADC->channel[0], &adcValue) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "ADC1 value:%d\r\n", adcValue); + } + else + { + outputBufferLength = sprintf(outputBuffer, "ADC1: failed to read\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_ADC_CH_2 ) + { + if(ADCChannel_read(&self->testItems->internalADC->channel[2], &adcValue) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "ADC2 value:%d\r\n", adcValue); + } + else + { + outputBufferLength = sprintf(outputBuffer, "ADC2: failed to read\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_ADC_BACK ) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + break; + + case CONSOLE_TEST_DAC: + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_ADC_LAST - 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_ADC ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_ADC_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_ADC ); + } + else if( button == BUTTON_ENTER ) + { + // DAC 0 + if( self->menuItemSelected == MENU_TEST_DAC_CH_0_0V0) + { + + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_0_1V25 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_0_2V5 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_0_5V0 ) + { + //TODO: Implement test + } + // DAC 1 + else if( self->menuItemSelected == MENU_TEST_DAC_CH_1_0V0) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_1_1V25 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_1_2V5 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_1_5V0 ) + { + //TODO: Implement test + } + // DAC 2 + else if( self->menuItemSelected == MENU_TEST_DAC_CH_2_0V0) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_2_1V25 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_2_2V5 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_CH_2_5V0 ) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_DAC_BACK) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + break; + + case CONSOLE_TEST_INTERLOCK: + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_INTERLOCK_LAST- 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_INTERLOCK ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_INTERLOCK_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_INTERLOCK ); + } + else if( button == BUTTON_ENTER ) + { + bool value = false; + if( self->menuItemSelected == MENU_TEST_INTERLOCK_1) + { + if( GPIO_getValue(self->testItems->interlock1, &value) == SUCCESS ){ + outputBufferLength = sprintf(outputBuffer, "Interlock: %d\r\n", value); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Interlock: Failure\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_INTERLOCK_2 ) + { + if( GPIO_getValue(self->testItems->interlock2, &value) == SUCCESS ){ + outputBufferLength = sprintf(outputBuffer, "Interlock: %d\r\n", value); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Interlock: Failure\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_INTERLOCK_BACK ) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + break; + + case CONSOLE_TEST_SOLENOID: + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_SOLENOID_LAST- 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_SOLENOID ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_SOLENOID_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_SOLENOID ); + } + else if( button == BUTTON_ENTER ) + { + bool value = false; + if( self->menuItemSelected == MENU_TEST_SOLENOID_TOGGLE) + { + if( GPIO_getValue(self->testItems->interlock1, &value) == SUCCESS) + { + // Invert current value + value = !value; + if( GPIO_setValue(self->testItems->interlock1, value) == SUCCESS) + { + outputBufferLength = sprintf(outputBuffer, "Solenoid: Toggled\r\n"); + } + else + { + outputBufferLength = sprintf(outputBuffer, "Solenoid: Failed to set value\r\n"); + } + } + else + { + outputBufferLength = sprintf(outputBuffer, "Solenoid: Failed to get value\r\n"); + } + IODevice_write(self->ioDevice, outputBuffer, outputBufferLength); + } + else if (self->menuItemSelected == MENU_TEST_SOLENOID_BACK ) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + break; + + case CONSOLE_TEST_RELAY: + if( button == BUTTON_UP ) + { + if( self->menuItemSelected == 0 ) + self->menuItemSelected = (MENU_TEST_RELAYS_LAST- 1); + else + self->menuItemSelected--; + + hwValidationMenuDisplay(self, DISPLAY_MENU_RELAY ); + } + else if( button == BUTTON_DOWN ) + { + if( self->menuItemSelected == (MENU_TEST_RELAYS_LAST - 1) ) + self->menuItemSelected = 0; + else + self->menuItemSelected++; + + hwValidationMenuDisplay(self, DISPLAY_MENU_RELAY ); + } + else if( button == BUTTON_ENTER ) + { + + struct Gpio* relay = NULL; + if( (self->menuItemSelected >= MENU_TEST_RELAYS_TOGGLE_1) && (self->menuItemSelected <= MENU_TEST_RELAYS_TOGGLE_6) ) + { + switch(self->menuItemSelected) + { + case MENU_TEST_RELAYS_TOGGLE_1: + break; + + case MENU_TEST_RELAYS_TOGGLE_2: + break; + + case MENU_TEST_RELAYS_TOGGLE_3: + break; + + case MENU_TEST_RELAYS_TOGGLE_4: + break; + + case MENU_TEST_RELAYS_TOGGLE_5: + break; + + case MENU_TEST_RELAYS_TOGGLE_6: + break; + } + } + + else if( self->menuItemSelected == MENU_TEST_RELAYS_CLEAR_ALL) + { + //TODO: Implement test + } + else if (self->menuItemSelected == MENU_TEST_RELAYS_BACK ) + { + // Back to main menu + self->menuItemSelected = 0; + menuState = CONSOLE_MAIN_MENU; + hwValidationMenuDisplay(self, DISPLAY_MENU_MAIN ); + } + } + break; + + case CONSOLE_TEST_PCB_VARIANT: + // No sub test + //TODO: implement test + break; + + case CONSOLE_TEST_EEPROM: + // No sub test + //TODO: implement test + break; + + default: + // Do not so much + break; + } + +} + + +// render current menu items +static void hwValidationMenuDisplay(struct HwValidationMenu* self, Display_States_t display ) +{ + uint8_t menuIndex; + char menuItems[ CON_INF_MAX_MENU_ITEMS ]; + int menu_length = 0; + + + switch( display ) + { + case DISPLAY_MENU_MAIN : + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_MAIN_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char menuBuffer[ sizeof( conInfMainMenu ) ]; + menu_length = sprintf( menuBuffer, conInfMainMenu, + menuItems[MENU_MAIN_POWER], + menuItems[MENU_MAIN_DISPLAY], + menuItems[MENU_MAIN_KEYPAD], + menuItems[MENU_MAIN_ADC], + menuItems[MENU_MAIN_DAC], + menuItems[MENU_MAIN_INTERLOCK], + menuItems[MENU_MAIN_SOLENOID], + menuItems[MENU_MAIN_RELAY], + menuItems[MENU_MAIN_PCB_VARIANT], + menuItems[MENU_MAIN_EEPROM] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, menuBuffer, menu_length); + break; + + case DISPLAY_MENU_POWER: + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_POWER_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char powerMenuBuffer[ sizeof( conTestPower ) ]; + menu_length = sprintf( powerMenuBuffer, conTestPower, + menuItems[MENU_TEST_POWER_ON], + menuItems[MENU_TEST_POWER_OFF], + menuItems[MENU_TEST_POWER_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, powerMenuBuffer, menu_length); + + break; + + case DISPLAY_MENU_DISPLAY: + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_DISPLAY_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char displayMenuBuffer[ sizeof( conTestDisplay ) ]; + menu_length = sprintf( displayMenuBuffer, conTestDisplay, + menuItems[MENU_TEST_DISPLAY_BL_10], + menuItems[MENU_TEST_DISPLAY_BL_50], + menuItems[MENU_TEST_DISPLAY_BL_100], + menuItems[MENU_TEST_DISPLAY_SHOW_TEXT], + menuItems[MENU_TEST_DISPLAY_CLEAR_DISPLAY], + menuItems[MENU_TEST_DISPLAY_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, displayMenuBuffer, menu_length); + + break; + + //case DISPLAY_MENU_KEYPAD: + //break; + + case DISPLAY_MENU_ADC: + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_ADC_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char adcMenuBuffer[ sizeof( conTestADC ) ]; + menu_length = sprintf( adcMenuBuffer, conTestADC, + menuItems[MENU_TEST_ADC_CH_0], + menuItems[MENU_TEST_ADC_CH_1], + menuItems[MENU_TEST_ADC_CH_2], + menuItems[MENU_TEST_ADC_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, adcMenuBuffer, menu_length); + break; + + case DISPLAY_MENU_DAC: + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_DAC_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char dacMenuBuffer[ sizeof( conTestDAC ) ]; + menu_length = sprintf( dacMenuBuffer, conTestDAC, + menuItems[MENU_TEST_DAC_CH_0_0V0], + menuItems[MENU_TEST_DAC_CH_0_1V25], + menuItems[MENU_TEST_DAC_CH_0_2V5], + menuItems[MENU_TEST_DAC_CH_0_5V0], + menuItems[MENU_TEST_DAC_CH_1_0V0], + menuItems[MENU_TEST_DAC_CH_1_1V25], + menuItems[MENU_TEST_DAC_CH_1_2V5], + menuItems[MENU_TEST_DAC_CH_1_5V0], + menuItems[MENU_TEST_DAC_CH_2_0V0], + menuItems[MENU_TEST_DAC_CH_2_1V25], + menuItems[MENU_TEST_DAC_CH_2_2V5], + menuItems[MENU_TEST_DAC_CH_2_5V0], + menuItems[MENU_TEST_DAC_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, dacMenuBuffer, menu_length); + break; + + case DISPLAY_MENU_INTERLOCK: + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_INTERLOCK_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char interlockMenuBuffer[ sizeof( conTestInterlock ) ]; + menu_length = sprintf( interlockMenuBuffer, conTestInterlock, + menuItems[MENU_TEST_INTERLOCK_1], + menuItems[MENU_TEST_INTERLOCK_2], + menuItems[MENU_TEST_INTERLOCK_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, interlockMenuBuffer, menu_length); + break; + + case DISPLAY_MENU_SOLENOID: + + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_SOLENOID_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char solenoidMenuBuffer[ sizeof( conTestSolenoid ) ]; + menu_length = sprintf( solenoidMenuBuffer, conTestSolenoid, + menuItems[MENU_TEST_SOLENOID_TOGGLE], + menuItems[MENU_TEST_SOLENOID_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, solenoidMenuBuffer, menu_length); + break; + + case DISPLAY_MENU_RELAY: + + // Put an asterisk (*) at the selected item in the menu + for( menuIndex = 0; menuIndex < MENU_TEST_RELAYS_LAST; menuIndex++ ) + { + MENU_DRAW_SELECTED(menuIndex); + } + + // Fill buffer with menu items + char relayMenuBuffer[ sizeof( conTestRelays ) ]; + menu_length = sprintf( relayMenuBuffer, conTestRelays, + menuItems[MENU_TEST_RELAYS_TOGGLE_1], + menuItems[MENU_TEST_RELAYS_TOGGLE_2], + menuItems[MENU_TEST_RELAYS_TOGGLE_3], + menuItems[MENU_TEST_RELAYS_TOGGLE_4], + menuItems[MENU_TEST_RELAYS_TOGGLE_5], + menuItems[MENU_TEST_RELAYS_TOGGLE_6], + menuItems[MENU_TEST_RELAYS_CLEAR_ALL], + menuItems[MENU_TEST_RELAYS_BACK] + ); + + // Write message to debout interface + IODevice_write(self->ioDevice, relayMenuBuffer, menu_length); + break; + + //case DISPLAY_MENU_PCB_VARIANT: + //break; + + //case DISPLAY_MENU_EEPROM: + //break; + + default: + //Do nothing + break; + + } +} + + +static ErrorStatus hwValidationMenuReceiveMessage(struct HwValidationMenu* self, uint8_t * pData, uint16_t numBytes ) +{ + + size_t actual_length = 0; + ErrorStatus returnValue = SUCCESS; + + while(numBytes > 0) + { + if(IODevice_read(self->ioDevice, (char *)pData, numBytes, &actual_length) == SUCCESS) + { + numBytes -= actual_length; + pData += actual_length; + } + else + { + returnValue = ERROR; + break; + } + } + + return returnValue; +} \ No newline at end of file