#include "gui.h" #include "hw/glcd_s6b0108.h" #include "keys.h" #include "font.h" #include "obrazki.h" #include "eeprom.h" #include "gfxlib.h" #include "main.h" #include #include #include #include #include #include "error.h" #include "amanero.h" //---------------------------stałe-------------------------------// #define LCD_BUF_SIZE LCD_WIDTH*LCD_HEIGHT/8 #define MAX_NAME_LENGTH 16 #define MAX_CHILDREN 7 #define MAX_TEXTS 6 #define MAX_OPTIONAL_TEXTS 1 #define MAX_TEXT_LENGTH 16 #define MAX_IMAGES 2 #define MAX_BOXES 1 #define MENU_TIMEOUT_2SEC 20000 #define MENU_TIMEOUT_5SEC 50000 #define MENU_TIMEOUT_30SEC 300000 #define MENU_DEFAULT_TIMEOUT MENU_TIMEOUT_30SEC #define VERSION_STRING "Nova+ 0.3" #define COMPILATION_DATE_STRING __DATE__ #define UI_MTXT_X 37 #define UI_MTXT_Y1 4 #define UI_MTXT_Y2 23 #define UI_MTXT_Y3 42 #define UI_MTXT_H 18 #define UI_ATXT_X 178 //dostęp do zegara systemowego #ifdef USE_RTOS #include "FreeRTOS.h" #include "task.h" #define TICK xTaskGetTickCount() #else extern uint32_t tick; #define TICK tick #endif //---------------------------typy---------------------------------// //ekran GUI typedef struct { uint8_t name[MAX_NAME_LENGTH]; void *child[MAX_CHILDREN]; void *parent; uint8_t child_keycode[MAX_CHILDREN]; uint32_t timeout; //czas nieaktywności void (*callback)(uint8_t keycode); //funkcja do wykonania //SIBLINGS void *left, *right; uint8_t default_sibling; //TEXTS uint8_t *texts[MAX_TEXTS]; uint8_t *texts_font[MAX_TEXTS]; uint8_t texts_invert[MAX_TEXTS]; int32_t texts_x[MAX_TEXTS], texts_y[MAX_TEXTS]; int8_t texts_show[MAX_TEXTS]; //IMAGES uint8_t *images[MAX_IMAGES]; int32_t images_x[MAX_IMAGES], images_y[MAX_IMAGES]; //BOXES uint8_t boxes[MAX_BOXES]; int32_t boxes_x1[MAX_BOXES], boxes_y1[MAX_BOXES]; int32_t boxes_x2[MAX_BOXES], boxes_y2[MAX_BOXES]; //DATA uint32_t data; }screen_t; //--------------------------Zmienne globalne------------------------// static uint8_t keycode; static uint8_t frame_buffer[LCD_BUF_SIZE]; static screen_t *menu_root; static screen_t *current_screen, *main_screen; static screen_t *filter1_screen, *autoselect_1st_screen; static screen_t *previous_screen; static uint32_t timestamp; static uint8_t current_input_text[MAX_TEXT_LENGTH]; static uint8_t sampling_rate_text[MAX_TEXT_LENGTH]; static uint8_t bit_rate_text[MAX_TEXT_LENGTH]; static uint8_t headphones_volume_text[MAX_TEXT_LENGTH]; static uint8_t autoselect_amanero_text[2]; static uint8_t autoselect_ext_pcm_text[2]; static uint8_t autoselect_ext_dsd_text[2]; static uint8_t autoselect_spdif_text[2]; static uint8_t autoselect_toslink_text[2]; static uint8_t autoselect_aes_ebu_text[2]; static uint8_t autoselect_bt_text[2]; static uint8_t global_invert; //------------------deklaracje funkcji prywatnych-------------------// void displaySamplingFrequency (status_t *status); void displayCurrentInput(status_t *status); void displayHeadphonesVolume(status_t *status); void displayCurrentFilter(status_t *status); void displayAutoselectStatus(status_t *status); screen_t *createMenu(void); screen_t *createRoot(uint8_t *name); screen_t *addNodeSibling(screen_t *screen, uint8_t *name); screen_t *addNodeChild(screen_t *screen, uint8_t keycode, uint8_t *name); screen_t *addNodeLink(screen_t *screen, uint8_t keycode, screen_t *ptr); screen_t *initializeScreenStructure(screen_t *screen, uint8_t *name); void setNodeTimeout(screen_t *screen, uint32_t timeout); void addNodeText(screen_t *screen, int32_t x, int32_t y, uint8_t invert, void *font, uint8_t *text); void addNodeImage(screen_t *screen, int32_t x, int32_t y, const void *image); void addNodeBox(screen_t *screen, int32_t x1, int32_t y1, int32_t x2, int32_t y2); void setNodeCallback(screen_t *screen, void (*callback)( uint8_t )); void setNodeData(screen_t *screen, uint32_t data); void setSiblingAsDefault(screen_t *screen); screen_t *changeScreen(uint8_t keycode); void inputSelectorCallback(uint8_t keycode); void headphonesVolumeCallback (uint8_t keycode); void filterSelectionCallback (uint8_t keycode); void autoselectCallback (uint8_t keycode); void restoreSettingsCallback (uint8_t keycode); void invertDisplayCallback (uint8_t keycode); //-----------------------------Funkcje------------------------------// /* * \opis Konfiguracja wstępna */ int8_t gui_Initialize(void) { int8_t k; keycode=KEYCODE_IDLE; menu_root=createMenu(); if (menu_root == NULL) return MALLOC_FAILURE; current_screen = menu_root; global_invert = 1; k=LCD_initialize(); return k; } void gui_KeyPressed(uint8_t keycode) { if(keycode || (current_screen->timeout && TICK - timestamp >= current_screen->timeout) ) { timestamp = TICK; previous_screen = current_screen; current_screen = changeScreen(keycode); if (current_screen->callback != NULL ) current_screen->callback(keycode); } } void gui_UpdateStatus(status_t *status) { displayCurrentInput (status); displaySamplingFrequency(status); displayHeadphonesVolume(status); displayCurrentFilter(status); displayAutoselectStatus(status); //HACK!!!! if(status->input == INPUT_AMANERO) { if(status->dsd) main_screen->images[0]=(void*)dsd_icon; else main_screen->images[0]=(void*)amanero_icon; } else if (status->input == INPUT_BT) main_screen->images[0]=(void*)blutut_icon; else main_screen->images[0]=(void*)all_icon; } /* GUI_RefreshScreen * \opis Funkcja ma za zadanie aktualizować menu. */ void gui_RefreshScreen(void) { uint8_t i; gfx_clear(frame_buffer, global_invert); for(i = 0; i < MAX_BOXES; i++) if(current_screen->boxes[i] != NULL) gfx_box_filled( current_screen->boxes_x1[i], current_screen->boxes_y1[i], current_screen->boxes_x2[i], current_screen->boxes_y2[i], global_invert, frame_buffer); for(i = 0; i < MAX_TEXTS; i++) if(current_screen->texts[i] != NULL) gfx_put_text( current_screen->texts_x[i], current_screen->texts_y[i], current_screen->texts[i], (uint8_t **)current_screen->texts_font[i], global_invert^current_screen->texts_invert[i], frame_buffer); for(i = 0; i < MAX_IMAGES; i++) if(current_screen->images[i] != NULL) gfx_put_graphic( current_screen->images_x[i], current_screen->images_y[i], *(current_screen->images[i]), *(current_screen->images[i]+1), current_screen->images[i]+2, global_invert, frame_buffer); LCD_write_buffer(frame_buffer,LCD_BUF_SIZE); } screen_t *createMenu(void) { screen_t *root, *ptr; root = createRoot("Main Screen"); main_screen = root; setNodeTimeout(root, 0); addNodeText(root, 48, 3, 0, wiekszepw2, current_input_text); addNodeText(root, 48, 40, 0, mniejsze_16ptpw, sampling_rate_text); addNodeText(root, 144, 40, 0, mniejsze_16ptpw, bit_rate_text); addNodeImage(root, 0, 0, all_icon); addNodeBox(root, 36, 31, 191, 32); setNodeCallback(root, inputSelectorCallback); ptr = addNodeChild(root, KEYCODE_ENC2L, "Volume"); addNodeLink(root, KEYCODE_ENC2R, ptr); setNodeTimeout(ptr, MENU_TIMEOUT_5SEC); addNodeText(ptr, 28, 3, 0, wiekszepw2, "MONITOR"); addNodeText(ptr, 48, 40, 0, mniejsze_16ptpw, headphones_volume_text); addNodeImage(ptr, 156, 0, sluchawki); addNodeBox(ptr, 0, 31, 155, 32); setNodeCallback(ptr, headphonesVolumeCallback); ptr = addNodeChild(root, KEYCODE_KEY2_LONG, "Filter 1"); filter1_screen = ptr; setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "Sharp Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "S.D. Sharp Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Slow roll-off"); addNodeImage(ptr, 0, 0, filter_po_lewej); setNodeCallback(ptr, filterSelectionCallback); setNodeData(ptr, SHARP_ROLLOFF); ptr = addNodeSibling(ptr, "Filter 2"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Sharp Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "S.D. Sharp Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Slow roll-off"); addNodeImage(ptr, 0, 0, filter_po_lewej); setNodeCallback(ptr, filterSelectionCallback); setNodeData(ptr, SHORT_DELAY_SHARP_ROLLOFF); ptr = addNodeSibling(ptr, "Filter 3"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Sharp Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "S.D. Sharp Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "Slow roll-off"); addNodeImage(ptr, 0, 0, filter_po_lewej); setNodeCallback(ptr, filterSelectionCallback); setNodeData(ptr, SLOW_ROLLOFF); ptr = addNodeSibling(ptr, "Filter 4"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "S.D. Slow Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Super Slow Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Exit"); addNodeImage(ptr, 0, 0, filter_po_lewej); setNodeCallback(ptr, filterSelectionCallback); setNodeData(ptr, SHORT_DELAY_SLOW_ROLLOFF); ptr = addNodeSibling(ptr, "Filter 5"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "S.D. Slow Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "Super Slow Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Exit"); addNodeImage(ptr, 0, 0, filter_po_lewej); setNodeCallback(ptr, filterSelectionCallback); setNodeData(ptr, SUPER_SLOW_ROLLOFF); ptr = addNodeSibling(ptr, "Filters Exit"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "S.D. Slow Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Super Slow Roll-off"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "Exit"); addNodeImage(ptr, 0, 0, filter_po_lewej); addNodeLink(ptr, KEYCODE_KEY2_SHORT, ptr->parent); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); //Menu pod lewym enkoderem //Autoselect ptr = addNodeChild(root, KEYCODE_KEY1_LONG, "Autoselect Menu"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "Autoselect Menu"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Service Menu"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Exit"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeChild(ptr, KEYCODE_KEY1_SHORT, "Auto Amanero"); autoselect_1st_screen = ptr; setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "Nova+ USB"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "S/PDIF"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "TOSLINK"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, autoselect_amanero_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, autoselect_spdif_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, autoselect_toslink_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_AMANERO); ptr = addNodeSibling(ptr, "Auto PCM"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Nova+ USB"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "S/PDIF"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "TOSLINK"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, autoselect_amanero_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, autoselect_spdif_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, autoselect_toslink_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_SPDIF); ptr = addNodeSibling(ptr, "Auto DSD"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Nova+ USB"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "S/PDIF"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "TOSLINK"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, autoselect_amanero_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, autoselect_spdif_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, autoselect_toslink_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_TOSLINK); ptr = addNodeSibling(ptr, "Auto SPDIF"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "EXT DSD"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "EXT PCM"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "AES/EBU"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, autoselect_ext_dsd_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, autoselect_ext_pcm_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, autoselect_aes_ebu_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_EXT_DSD); ptr = addNodeSibling(ptr, "Auto TOSLINK"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "EXT DSD"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "EXT PCM"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "AES/EBU"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, autoselect_ext_dsd_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, autoselect_ext_pcm_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, autoselect_aes_ebu_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_EXT_PCM); ptr = addNodeSibling(ptr, "Auto AES/EBU"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "EXT DSD"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "EXT PCM"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "AES/EBU"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, autoselect_ext_dsd_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, autoselect_ext_pcm_text); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, autoselect_aes_ebu_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_AES_EBU); ptr = addNodeSibling(ptr, "Auto BT"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "Bluetooth"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Back"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, autoselect_bt_text); addNodeImage(ptr, 0, 0, autoselect_icon); setNodeCallback(ptr, autoselectCallback); setNodeData(ptr, AUTOSELECT_BT); ptr = addNodeSibling(ptr, "Autoselect Back"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Bluetooth"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "Back"); addNodeText(ptr, UI_ATXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, autoselect_bt_text); addNodeImage(ptr, 0, 0, autoselect_icon); addNodeLink(ptr, KEYCODE_KEY1_SHORT, ptr->parent); ptr = ptr->parent; //menu serwisowe ptr = addNodeSibling(ptr, "Service Menu"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Autoselect Menu"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "Service Menu"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Exit"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeChild(ptr, KEYCODE_KEY1_SHORT, "Software Version menu"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "Software ver."); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Factory restore"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Invert Display"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeChild(ptr, KEYCODE_KEY1_SHORT, "Software Version"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, VERSION_STRING ); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, COMPILATION_DATE_STRING); addNodeLink(ptr, KEYCODE_KEY1_SHORT, ptr->parent); addNodeImage(ptr, 0, 0, n_ikonka); ptr = ptr->parent; ptr = addNodeSibling(ptr, "Factory Restore menu"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Software ver."); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "Factory restore"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Invert Display"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeChild(ptr, KEYCODE_KEY1_SHORT, " Factory Restore 1"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y2, 191, UI_MTXT_Y2 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Are you sure?"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 1, mniejsze_16ptpw, "No"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 0, mniejsze_16ptpw, "Yes"); addNodeLink(ptr, KEYCODE_KEY1_SHORT, ptr->parent); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeSibling(ptr, " Factory Restore 2"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Are you sure?"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "No"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "Yes"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeChild(ptr, KEYCODE_KEY1_SHORT, " Factory Restore 3"); setNodeTimeout(ptr, MENU_TIMEOUT_2SEC); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Settings Restored"); addNodeLink(ptr, KEYCODE_KEY1_SHORT, main_screen); addNodeImage(ptr, 0, 0, n_ikonka); setNodeCallback(ptr, restoreSettingsCallback); ptr = ptr->parent; ptr = ptr->parent; ptr = addNodeSibling(ptr, "Invert Display menu"); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Software ver."); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Factory restore"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "Invert Display"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = addNodeChild(ptr, KEYCODE_KEY1_SHORT, "Invert Display "); addNodeLink(ptr, KEYCODE_KEY1_SHORT, ptr->parent); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Display Inverted"); addNodeImage(ptr, 0, 0, n_ikonka); setNodeCallback(ptr, invertDisplayCallback); ptr = ptr->parent; ptr = addNodeSibling(ptr, "Service Menu Back"); addNodeLink(ptr, KEYCODE_KEY1_SHORT, ptr->parent); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y1, 191, UI_MTXT_Y1 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 1, mniejsze_16ptpw, "Back"); addNodeImage(ptr, 0, 0, n_ikonka); ptr = ptr->parent; ptr = addNodeSibling(ptr, "Menu Exit"); addNodeLink(ptr, KEYCODE_KEY1_SHORT, ptr->parent); setNodeTimeout(ptr, MENU_DEFAULT_TIMEOUT); addNodeBox(ptr, UI_MTXT_X - 1, UI_MTXT_Y3, 191, UI_MTXT_Y3 + UI_MTXT_H); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y1, 0, mniejsze_16ptpw, "Autoselect Menu"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y2, 0, mniejsze_16ptpw, "Service Menu"); addNodeText(ptr, UI_MTXT_X, UI_MTXT_Y3, 1, mniejsze_16ptpw, "Exit"); addNodeImage(ptr, 0, 0, n_ikonka); //Menu serwisowe return root; } screen_t *createRoot(uint8_t *name) { screen_t *screen; screen = malloc(sizeof(screen_t)); if (screen == NULL) return NULL; initializeScreenStructure(screen, name); return screen; } screen_t *addNodeSibling(screen_t *screen, uint8_t *name) { screen_t *sibling, *tmp; uint32_t i; sibling = malloc(sizeof(screen_t)); if (sibling == NULL) return NULL; initializeScreenStructure(sibling, name); sibling->parent = screen->parent; tmp = screen->right; screen->right = sibling; sibling->left = screen; sibling->right=tmp; tmp->left = sibling; return sibling; } screen_t *addNodeChild(screen_t *screen, uint8_t keycode, uint8_t *name) { screen_t *child; uint32_t i; i = 0; while(screen->child[i] != NULL) { i++; if(i == MAX_CHILDREN) { return NULL; } } child = malloc(sizeof(screen_t)); if (child == NULL) return NULL; initializeScreenStructure(child, name); child->parent = screen; screen->child[i] = child; screen->child_keycode[i] = keycode; return child; } screen_t *addNodeLink(screen_t *screen, uint8_t keycode, screen_t *ptr) { uint32_t i; if(screen == NULL) return NULL; i = 0; while(screen->child[i] != NULL) { i++; if(i == MAX_CHILDREN) return NULL; } screen->child[i] = ptr; screen->child_keycode[i] = keycode; return ptr; } screen_t *initializeScreenStructure(screen_t *screen, uint8_t *name) { uint8_t *ptr; uint32_t i; if(screen == NULL) return NULL; ptr = (uint8_t *) screen; for(i = 0; i < sizeof(screen_t); i++ ) *ptr++ = 0; strncpy(screen->name, name, MAX_NAME_LENGTH); screen->name[MAX_NAME_LENGTH-1] = 0; screen->left = screen; screen->right = screen; } void setNodeTimeout(screen_t *screen, uint32_t timeout) { if(screen == NULL) return; screen->timeout = timeout; } void addNodeText(screen_t *screen, int32_t x, int32_t y, uint8_t invert, void *font, uint8_t *text) { uint32_t i; if(screen == NULL) return; i = 0; while(screen->texts[i] != NULL) { i++; if(i == MAX_TEXTS) return; } screen->texts[i] = text; screen->texts_font[i] = font; screen->texts_x[i] = x; screen->texts_y[i] = y; screen->texts_invert[i] = invert; } void addNodeImage(screen_t *screen, int32_t x, int32_t y, const void *image) { uint32_t i; if(screen == NULL) return; i = 0; while(screen->images[i] != NULL) { i++; if(i == MAX_IMAGES) return; } screen->images[i] = image; screen->images_x[i] = x; screen->images_y[i] = y; } void addNodeBox(screen_t *screen, int32_t x1, int32_t y1, int32_t x2, int32_t y2) { uint32_t i; if(screen == NULL) return; i = 0; while(screen->boxes[i] != NULL) { i++; if(i == MAX_BOXES) return; } screen->boxes[i] = 1; screen->boxes_x1[i] = x1; screen->boxes_y1[i] = y1; screen->boxes_x2[i] = x2; screen->boxes_y2[i] = y2; } void setNodeCallback(screen_t *screen, void (*callback)( uint8_t )) { if(screen == NULL) return; screen->callback = callback; } void setNodeData(screen_t *screen, uint32_t data) { if(screen == NULL) return; screen->data = data; } void setSiblingAsDefault(screen_t *screen) { screen_t *ptr; ptr = screen; do { ptr -> default_sibling = 0; ptr = ptr->right; } while(ptr != screen); screen->default_sibling = 1; } screen_t *changeScreen(uint8_t keycode) { uint32_t i; screen_t *ptr; if (keycode == KEYCODE_IDLE) return menu_root; for( i = 0; i < MAX_CHILDREN; i++) if(current_screen->child_keycode[i] == keycode && current_screen->child[i] != NULL ) { ptr = current_screen->child[i]; do { if ( ptr->default_sibling) break; else ptr = ptr->right; }while (ptr != current_screen->child[i]); return ptr; } if (keycode == KEYCODE_ENC1L || keycode == KEYCODE_ENC2L) return current_screen->left; if (keycode == KEYCODE_ENC1R || keycode == KEYCODE_ENC2R) return current_screen->right; return current_screen; } void displayCurrentInput (status_t *status) { uint32_t length; switch(status->input) { case INPUT_OFF: snprintf (current_input_text, MAX_TEXT_LENGTH, "NO INPUT"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; case INPUT_AMANERO: switch(status->dsd) { case AMANERO_DSD_128X: snprintf (current_input_text, MAX_TEXT_LENGTH,"DSD128"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; case AMANERO_DSD_256X: snprintf (current_input_text, MAX_TEXT_LENGTH,"DSD256"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; case AMANERO_DSD_64X: snprintf (current_input_text, MAX_TEXT_LENGTH,"DSD64"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; case AMANERO_PCM: snprintf (current_input_text, MAX_TEXT_LENGTH, "Nova+ USB"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, "32bit"); break; default: snprintf (current_input_text, MAX_TEXT_LENGTH, "NO INPUT"); break; } break; case INPUT_PCM: snprintf (current_input_text, MAX_TEXT_LENGTH, "EXT PCM"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; case INPUT_DSD: snprintf (current_input_text, MAX_TEXT_LENGTH, "EXT DSD"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; case INPUT_SPDIF: snprintf (current_input_text, MAX_TEXT_LENGTH, "S/PDIF"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, "24bit"); break; case INPUT_TOSLINK: snprintf (current_input_text, MAX_TEXT_LENGTH, "TOSLINK"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, "24bit"); break; case INPUT_AES_EBU: snprintf (current_input_text, MAX_TEXT_LENGTH, "AES/EBU"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, "24bit"); break; case INPUT_BT: snprintf (current_input_text, MAX_TEXT_LENGTH, "BLUETOOTH"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, "24bit"); break; default: length = snprintf (current_input_text, MAX_TEXT_LENGTH, "NO INPUT"); snprintf (bit_rate_text, MAX_TEXT_LENGTH, ""); break; } } void displaySamplingFrequency (status_t *status) { uint8_t buffer[32]; uint32_t length; if (status->sample_rate > 1E6 ) snprintf (sampling_rate_text, MAX_TEXT_LENGTH, "%.1f MHz",status->sample_rate / 1E6); else if ( status->sample_rate > 1E3 ) snprintf (sampling_rate_text, MAX_TEXT_LENGTH, "%.1f kHz",status->sample_rate / 1E3); else snprintf(sampling_rate_text, MAX_TEXT_LENGTH, ""); } void displayHeadphonesVolume (status_t *status) { uint8_t buffer[32]; uint32_t length; float volume_dB; volume_dB = (status->volume-31); length = snprintf (headphones_volume_text, MAX_TEXT_LENGTH, "%.1f dB",volume_dB); } void displayCurrentFilter (status_t *status) { int i; screen_t *ptr; ptr = filter1_screen; do { if(ptr->data == status->filter) { setSiblingAsDefault(ptr); break; } ptr = ptr->right; }while(ptr != filter1_screen); } void displayAutoselectStatus (status_t *status) { int i; if(status->autoselect & AUTOSELECT_AMANERO) sprintf(autoselect_amanero_text,"A"); else sprintf(autoselect_amanero_text,""); if(status->autoselect & AUTOSELECT_SPDIF) sprintf(autoselect_spdif_text,"A"); else sprintf(autoselect_spdif_text,""); if(status->autoselect & AUTOSELECT_TOSLINK) sprintf(autoselect_toslink_text,"A"); else sprintf(autoselect_toslink_text,""); if(status->autoselect & AUTOSELECT_EXT_DSD) sprintf(autoselect_ext_dsd_text,"A"); else sprintf(autoselect_ext_dsd_text,""); if(status->autoselect & AUTOSELECT_EXT_PCM) sprintf(autoselect_ext_pcm_text,"A"); else sprintf(autoselect_ext_pcm_text,""); if(status->autoselect & AUTOSELECT_AES_EBU) sprintf(autoselect_aes_ebu_text,"A"); else sprintf(autoselect_aes_ebu_text,""); if(status->autoselect & AUTOSELECT_BT) sprintf(autoselect_bt_text,"A"); else sprintf(autoselect_bt_text,""); } //--------------------------CALLBACKS-------------------------// void inputSelectorCallback(uint8_t keycode) { switch(keycode) { case KEYCODE_ENC1R: main_ChangeInput(NEXT); break; case KEYCODE_ENC1L: main_ChangeInput(PREV); break; default: break; } } void headphonesVolumeCallback (uint8_t keycode) { switch(keycode) { case KEYCODE_ENC2R: main_ChangeVolume(VOLUME_UP); break; case KEYCODE_ENC2L: main_ChangeVolume(VOLUME_DOWN); break; default: break; } } void filterSelectionCallback (uint8_t keycode) { if( keycode == KEYCODE_KEY2_SHORT && current_screen == previous_screen) { main_ChangeFilter(current_screen->data); current_screen = current_screen->parent; } } void autoselectCallback (uint8_t keycode) { if( keycode == KEYCODE_KEY1_SHORT && current_screen == previous_screen) main_ToggleAutoselect(current_screen->data); } void restoreSettingsCallback (uint8_t keycode) { main_RestoreSettings(); } void invertDisplayCallback (uint8_t keycode) { global_invert = !global_invert; }