#include "../Inc/ltdc.hpp" /*****************************************************************************/ /* Globals and Static Initialization */ /*****************************************************************************/ uint8 DATA_HARDWARE_0(LTDC::m_fps); uint8 DATA_HARDWARE_0(LTDC::m_thread); /*****************************************************************************/ /* Private */ /*****************************************************************************/ /*****************************************************************************/ /* Public */ /*****************************************************************************/ CODE_HARDWARE(LTDC::LTDC)() { m_thread = 0xFF; } feedback CODE_HARDWARE(LTDC::startup)(RCC& rcc) { rcc.module_reset(RCC::e_module::LTDC); rcc.module_clockInit(RCC::e_module::LTDC, true); return(OK); } feedback CODE_HARDWARE(LTDC::init)(s_displayData displayData, RectGraphic* layer, uint32 numberOfLayer) { if(numberOfLayer > c_layer_number) { return(FAIL); } for(uint32 i = 0; i < numberOfLayer; i++) { if(layer[i].position.x >= displayData.h_active || layer[i].position.y >= displayData.v_active) { return(FAIL); } if(layer[i].get_topRightCorner().x >= displayData.h_active || layer[i].get_topRightCorner().y >= displayData.v_active) { return(FAIL); } if(layer[i].get_topRightCorner().x < layer[i].position.x || layer[i].get_topRightCorner().y < layer[i].position.y) { return(FAIL); } if(layer[i].size.x < 1 || layer[i].size.y < 1) { return(FAIL); } } m_thread = 0xFF; for(uint32 i = 0; i < numberOfLayer; i++) { m_layer[i] = layer[i]; } for(uint32 i = numberOfLayer; i < c_layer_number; i++) { m_layer[i] = RectGraphic(); } LTDC_SSCR = ((displayData.h_syncwidth - 1) << 16) | (displayData.v_syncwidth - 1); LTDC_BPCR = ((displayData.h_syncwidth + displayData.h_backporch - 1) << 16) | (displayData.v_syncwidth + displayData.v_backporch - 1); LTDC_AWCR = ((displayData.h_syncwidth + displayData.h_backporch + displayData.h_active - 1) << 16) | (displayData.v_syncwidth + displayData.v_backporch + displayData.v_active - 1); LTDC_TWCR = ((displayData.h_syncwidth + displayData.h_backporch + displayData.h_active + displayData.h_frontporch - 1) << 16) | (displayData.v_syncwidth + displayData.v_backporch + displayData.v_active + displayData.v_frontporch - 1); LTDC_BCCR = 0x00000000; // Set Background Color to Black for(uint32 i = 0; i < numberOfLayer; i++) { uint32* reg_cr = ((uint32*) <DC_L1_CR) + i * 0x20; uint32* reg_whpcr = ((uint32*) <DC_L1_WHPCR) + i * 0x20; uint32* reg_wvpcr = ((uint32*) <DC_L1_WVPCR) + i * 0x20; //uint32* reg_ckcr = ((uint32*) <DC_L1_CKCR) + i * 0x20; uint32* reg_pfcr = ((uint32*) <DC_L1_PFCR) + i * 0x20; uint32* reg_cacr = ((uint32*) <DC_L1_CACR) + i * 0x20; //uint32* reg_dccr = ((uint32*) <DC_L1_DCCR) + i * 0x20; //uint32* reg_bfcr = ((uint32*) <DC_L1_BFCR) + i * 0x20; uint32* reg_cfbar = ((uint32*) <DC_L1_CFBAR) + i * 0x20; uint32* reg_cfblr = ((uint32*) <DC_L1_CFBLR) + i * 0x20; uint32* reg_cfblnr = ((uint32*) <DC_L1_CFBLNR) + i * 0x20; //uint32* reg_clutwr = ((uint32*) <DC_L1_CLUTWR) + i * 0x20; *reg_whpcr = ((displayData.h_syncwidth + displayData.h_backporch + layer[i].get_topRightCorner().x) << 16) | (displayData.h_syncwidth + displayData.h_backporch + layer[i].position.x); // Set Window Horizontal Position *reg_wvpcr = ((displayData.v_syncwidth + displayData.v_backporch + layer[i].get_topRightCorner().y) << 16) | (displayData.v_syncwidth + displayData.v_backporch + layer[i].position.y); // Set Window Vertical Position *reg_pfcr = 0x00000000; // Set Layer Pixel Format to ARGB8888 *reg_cacr = 0x000000FF; // Set Alpha Value 255 = not transparent *reg_cfbar = (uint32) layer[i].data; // Set Buffer Address *reg_cfblr = ((layer[i].size.x * 4) << 16) | (layer[i].size.x * 4 + 7); // Set Buffer Pitch and Line Length *reg_cfblnr = layer[i].size.y; // Set Buffer Line Number sbi(*reg_cr, 0); // Enable Layer } for(uint32 i = numberOfLayer; i < c_layer_number; i++) { uint32* reg_cr = ((uint32*) <DC_L1_CR) + i * 0x20; cbi(*reg_cr, 0); // Disable Layer } sbi(LTDC_SRCR, 1); // Reload Shadow Registers sbi(LTDC_IER, 3); // Enable Register Reload Interrupt m_displayData = displayData; m_layerNumber = numberOfLayer; return(OK); } feedback CODE_HARDWARE(LTDC::set_thread)() { if(m_thread == 0xFF) { m_thread = System::get().get_runningThreadID(); return(OK); } return(FAIL); } uint16 CODE_HARDWARE(LTDC::get_wakeUpInterrupt)() { return(Interrupt::LTDC); } feedback CODE_HARDWARE(LTDC::start)() { sbi(LTDC_GCR, 0); return(OK); } feedback CODE_HARDWARE(LTDC::stop)() { cbi(LTDC_GCR, 0); return(OK); } feedback CODE_HARDWARE(LTDC::set_layerBuffer)(uint32 layer, Color* buffer) { if(layer < c_layer_number) { m_layer[layer].data = buffer; uint32* reg_cr = ((uint32*) <DC_L1_CR) + layer * 0x20; uint32* reg_cfbar = ((uint32*) <DC_L1_CFBAR) + layer * 0x20; cbi(*reg_cr, 0); *reg_cfbar = (uint32) m_layer[layer].data; sbi(*reg_cr, 0); return(OK); } return(FAIL); } feedback CODE_HARDWARE(LTDC::clear)(uint32 layer) { if(layer > c_layer_number) { return(FAIL); } uint32 surface = m_layer[layer].get_surface(); for(uint32 i = 0; i < surface; i++) { *(m_layer[layer].data + i) = Colors::transparent; } return(OK); } feedback CODE_HARDWARE(LTDC::set_colorBackground)(uint8 red, uint8 green, uint8 blue) { LTDC_BCCR = (red << 16) | (green << 8) | blue; m_colorBackground.red = red; m_colorBackground.green = green; m_colorBackground.blue = blue; return(OK); } feedback CODE_HARDWARE(LTDC::set_pixel)(Vec2& position, Color color, uint32 layer) { if(position.x < m_layer[layer].size.x || position.x >= m_layer[layer].size.x || position.y < m_layer[layer].size.y || position.y >= m_layer[layer].size.y) { return(FAIL); } position.y = m_layer[layer].size.y - position.y - 1; Color* pixel = m_layer[layer].data + position.y * m_layer[layer].size.x + position.x; *pixel = color; return(OK); } LTDC::s_displayData& CODE_HARDWARE(LTDC::get_displayData)() { return(m_displayData); } Vec2 CODE_HARDWARE(LTDC::get_displayDimensions)() { return(Vec2(m_displayData.h_active, m_displayData.v_active)); } RectGraphic& CODE_HARDWARE(LTDC::get_layerData)(uint32 layer) { return(m_layer[layer]); } uint32 CODE_HARDWARE(LTDC::get_numberOfLayers)() { return(m_layerNumber); } uint32 CODE_HARDWARE(LTDC::get_fps)() { return(m_fps); } Color CODE_HARDWARE(LTDC::get_colorBackground)() { return(m_colorBackground); } CODE_ISR void ISR_LTDC() { static uint8 DATA_HARDWARE_0(counter); static uint8 DATA_HARDWARE_0(second); System& system = System::get(); uint8 second_new = system.get_time().get_second(); if(second != second_new) { LTDC::m_fps = counter; second = second_new; counter = 0; } else { counter++; } sbi(LTDC_ICR, 3); // Clear Register Reload Flag sbi(LTDC_SRCR, 1); // Reload Shadow Registers system.send_event(LTDC::m_thread); }