// ----------------------------------------------------------------------------- /// @file main.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$ /// $Author$ /// $Date$ // (c) 2017 Micro-Key bv // ----------------------------------------------------------------------------- /// @file main.c /// @ingroup {group_name} // ----------------------------------------------------------------------------- // Include files // ----------------------------------------------------------------------------- #include #include #include // FreeRTOS includes #include "FreeRTOS.h" #include "task.h" #include "stm32f10x.h" #include "misc.h" #include "ADConverters.h" #include "DAConverters.h" #include "DeviceParameters.h" #include "Displays.h" #include "Error.h" #include "hsb-mrts.h" #include "hwValidationMenu.h" #include "PowerLossDetector.h" #include "repairMenu.h" #include "repairMenus.h" #include "repairProcesses.h" #include "Warning.h" #include "CathodeMCP.h" #include "CoverSolenoid.h" #include "Interlock.h" #include "Leds.h" #include "Logger.h" #include "nhd0420.h" #include "TeslaGunSafety.h" #include "PCBA.h" #include "uart.h" // ----------------------------------------------------------------------------- // Constant and macro definitions // ----------------------------------------------------------------------------- /* The time between cycles of the 'check' functionality (defined within the tick hook. */ #define mainCHECK_DELAY ( ( TickType_t ) 5000 / portTICK_PERIOD_MS ) #define INIT_START_SCREEN_DELAY (5000) // ----------------------------------------------------------------------------- // Type definitions // ----------------------------------------------------------------------------- struct LedTaskArguments { Led led; int frequency; }; // ----------------------------------------------------------------------------- // File-scope variables // ----------------------------------------------------------------------------- /* Variable that counts at 20KHz to provide the time base for the run time stats. */ unsigned long ulRunTimeStatsClock = 0UL; static struct LedTaskArguments ledTaskArguments; static xTaskHandle initTaskHandle; static xTaskHandle ledTaskHandle; static xTaskHandle sysTaskHandle; #ifdef ENABLE_HW_VALIDATION static struct HwValidationMenu _hwValidation = {.initialized = false}; static struct HwValidationMenuItems hwTestItems; struct HwValidationMenu* hwValidation = &_hwValidation; #endif static struct CachedStorage cs = {.initialized = false}; static struct CachedStorage deviceParameters = {.initialized = false}; //static char taskList[600]; // ----------------------------------------------------------------------------- // Function declarations // ----------------------------------------------------------------------------- static ErrorStatus systeminfoCommandHandler(void); static void initTask(void* parameters); static void ledBlinkTask(void* parameters); // ----------------------------------------------------------------------------- // Function definitions // ----------------------------------------------------------------------------- int main (void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4); // Create TaskHandles ledTaskArguments.led = LED_ONBOARD_ORANGE; ledTaskArguments.frequency = 1; xTaskCreate(initTask, (const char* const)"initTask", 1024, NULL, 5, &initTaskHandle); /* Start the scheduler. */ vTaskStartScheduler(); /* Will only get here if there was insufficient memory to create the idle task. The idle task is created within vTaskStartScheduler(). */ for( ;; ); return -1; } void vApplicationTickHook () { } static void printSystemInfoTask(void* parameters) { while (1) { LOGGER_INFO(mainLog, "---------------------------------------"); systeminfoCommandHandler(); vTaskDelay(10000); } } static ErrorStatus systeminfoCommandHandler(void) { ErrorStatus errorStatus = SUCCESS; size_t freeMemory; char text[128]; freeMemory = xPortGetFreeHeapSize(); snprintf(text, sizeof(text), "Free heap memory: %d bytes", (int)freeMemory); LOGGER_INFO(mainLog, text); UBaseType_t numberOfTasks; numberOfTasks = uxTaskGetNumberOfTasks(); snprintf(text, sizeof(text), "Number of managed tasks: %d", (int)numberOfTasks); LOGGER_INFO(mainLog, text); // vTaskList(taskList); // IODevice_write((struct IODevice*)uart1, taskList, strlen(taskList)); // IODevice_write((struct IODevice*)uart1, "\n\r\n\r", 5); vTaskDelay(50); OS_logTaskInfo(initTaskHandle); vTaskDelay(50); OS_logTaskInfo(errorTaskHandle); vTaskDelay(50); OS_logTaskInfo(warningTaskHandle); vTaskDelay(50); OS_logTaskInfo(interlock->taskHandle); vTaskDelay(50); OS_logTaskInfo(mainLog->taskHandle); vTaskDelay(50); OS_logTaskInfo(keypad->taskHandle); vTaskDelay(50); OS_logTaskInfo(mainBuzzer->taskHandle); vTaskDelay(50); OS_logTaskInfo(mainDisplay->taskHandle); #ifdef ENABLE_HW_VALIDATION vTaskDelay(50); OS_logTaskInfo(hwValidation->taskHandle); #endif vTaskDelay(50); OS_logTaskInfo(sysTaskHandle); vTaskDelay(50); OS_logTaskInfo(ledTaskHandle); vTaskDelay(50); OS_logTaskInfo(mainMenu->menuCore->taskHandle); vTaskDelay(50); OS_logTaskInfo(rp->taskHandle); return errorStatus; } static void initTask(void* parameters) { ErrorStatus returnValue = SUCCESS; if (returnValue == SUCCESS) { // Create the error handler returnValue = Error_construct(); } if (returnValue == SUCCESS) { // Create the warning handler returnValue = Warning_construct(); } if (returnValue == SUCCESS) { // Initialize the platform first // All IO is initialized here // Also, all periphery and platform-specifics are initialized here // IRQs are defined here returnValue = initPlatform(); } if (returnValue == SUCCESS) { // Construct the displays returnValue = Displays_construct(); } if (returnValue == SUCCESS) { // Construct the powerloss detector returnValue = PowerLossDetector_construct(&iFlash->memoryDevice, APP_FLASH_POWERLOSS_PAGE, APP_FLASH_STORAGE_POWERLOSS, APP_FLASH_POWERLOSS_PAGESIZE); } if (returnValue == SUCCESS) { // Construct the AD Converters returnValue = ADConverters_construct(); } if (returnValue == SUCCESS) { // Construct the DA Converters returnValue = DAConverters_construct(); } if (returnValue == SUCCESS) { returnValue = hsb_generateStartScreen(mainDisplay); // Let start screen stay for 5 seconds vTaskDelay(INIT_START_SCREEN_DELAY); } if (returnValue == SUCCESS) { // Construct/Load the device parameters returnValue = DeviceParameters_construct(&deviceParameters, &iFlash->memoryDevice); } if (returnValue == SUCCESS) { // Construct the repair presets returnValue = RepairPresets_construct(&cs, &iFlash->memoryDevice); } #ifdef ENABLE_HW_VALIDATION if (returnValue == SUCCESS) { hwTestItems.display = &nhd0420->displayDevice; hwTestItems.internalADC = adc1; hwTestItems.externalDAC = max5715; hwTestItems.interlockNO = interlock->NO.io; hwTestItems.interlockNC = interlock->NC.io; hwTestItems.TeslaSecurity = teslaRelay; hwTestItems.solenoid = solenoid; hwTestItems.mcp0Relay = mcp0Relay; hwTestItems.mcp1Relay = mcp1Relay; hwTestItems.mcp2Relay = mcp2Relay; hwTestItems.cat0Relay = cat0Relay; hwTestItems.cat1Relay = cat1Relay; hwTestItems.cat2Relay = cat2Relay; hwTestItems.buzzer = mainBuzzer; hwTestItems.bicolourRed = ledBicolourRed; hwTestItems.bicolourGreen = ledBicolourGreen; hwTestItems.hv0 = hv0Present; hwTestItems.hv1 = hv1Present; hwTestItems.hv2 = hv2Present; hwTestItems.pcba = PCBA_getInstance(); hwTestItems.keypad = keypad; // EEPROM TO BE DONE HwValidationMenu_construct(hwValidation, &uart3->device, &hwTestItems, 3, 1024); } #endif if (returnValue == SUCCESS) { // Create task that repeats to print out TASK information on the logger xTaskCreate(printSystemInfoTask, (const char* const)"SysInfoTask", 512, NULL, 4, &sysTaskHandle); // Create a small task that only blinks a LED and flashes the identification letter on the display xTaskCreate(ledBlinkTask, (const char* const)"ledTask", 100, &ledTaskArguments, 4, &ledTaskHandle); } if (returnValue == SUCCESS) { // Construct the repair menu returnValue = repairMenus_construct(); } if (PowerLossDetection_isFlagSet()) { LOGGER_ERROR(mainLog, "Powerloss detection triggered"); Error_postError(ERROR_POWER_LOSS); returnValue = ERROR; // Flag may be restored now PowerLossDetector_clearBusyFlag(); } // Delete this init task vTaskDelete(NULL); } static void ledBlinkTask (void* parameters) { char indicator[2]; indicator[0] = ' '; indicator[1] = '\0'; struct LedTaskArguments* arguments = (struct LedTaskArguments*) parameters; int frequency = arguments->frequency; while (1) { // Led_on(arguments->led); if (PCBA_getInstance()->pcba == PCBA_CathodeMCP) { indicator[0] = CathodeMCP_getInstance()->name[0]; Display_write(mainDisplay, indicator, 1, 20); } else { indicator[0] = PCBA_getInstance()->name[0]; Display_write(mainDisplay, indicator, 1, 20); } vTaskDelay(configTICK_RATE_HZ / (frequency * 2)); // Led_off(arguments->led); indicator[0] = ' '; // Display_write(mainDisplay, indicator, 1, 20); vTaskDelay(configTICK_RATE_HZ / (frequency * 2)); } }