diff --git a/examples/stm32f469_discovery/display/project.xml b/examples/stm32f469_discovery/display/project.xml index b33b598aac..47606d0c28 100644 --- a/examples/stm32f469_discovery/display/project.xml +++ b/examples/stm32f469_discovery/display/project.xml @@ -1,5 +1,5 @@ - modm:disco-f469ni + modm:disco-f469ni:b-08 diff --git a/src/modm/board/disco_f469ni/board_dsi_nt35510.cpp b/src/modm/board/disco_f469ni/board_dsi_nt35510.cpp new file mode 100644 index 0000000000..ab24e23965 --- /dev/null +++ b/src/modm/board/disco_f469ni/board_dsi_nt35510.cpp @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2016-2017, Niklas Hauser + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include +#include + +extern void +nt35510_init(uint8_t); + +// ---------------------------------- DISPLAY ---------------------------------- +void +board_initialize_display(uint8_t ColorCoding) +{ + using namespace modm::platform; + if (Rcc::isEnabled()) return; + // Enable clock to LTDC, DSI interface + Rcc::enable(); + Rcc::enable(); + + { + // Expanded `HAL_DSI_Init()`: + // Enable regulator + DSI->WRPCR = DSI_WRPCR_REGEN; + // Wait until stable + for (int t = 1'024; not (DSI->WISR & DSI_WISR_RRS) and t; t--) { + modm::delay_ms(1); + } + // Set up PLL and enable it + DSI->WRPCR |= (0 << 16) | (2 << 11) | (125 << 2) | DSI_WRPCR_PLLEN; + // Wait until stable + for (int t = 1'024; not (DSI->WISR & DSI_WISR_PLLLS) and t; t--) { + modm::delay_ms(1); + } + // D-PHY clock and digital enable + DSI->PCTLR = DSI_PCTLR_CKE | DSI_PCTLR_DEN; + // Clock lane configuration + DSI->CLCR = DSI_CLCR_DPCC; + // Configure the number of active data lanes + DSI->PCONFR = 1; + // Set the TX escape clock division factor + DSI->CCR = 4; + // Calculate the bit period in high-speed mode in unit of 0.25 ns (UIX4) + // The equation is : UIX4 = IntegerPart( (1000/F_PHY_Mhz) * 4 ) + // Where : F_PHY_Mhz = (NDIV * HSE_Mhz) / (IDF * ODF) + // Set the bit period in high-speed mode + DSI->WPCR[0] = 8; + // Disable all error interrupts and reset the Error Mask + DSI->IER[0] = 0; + DSI->IER[1] = 0; + } + + constexpr uint32_t VSA = 2; + constexpr uint32_t VBP = 34; + constexpr uint32_t VFP = 34; + + constexpr uint32_t HSA = 120; + constexpr uint32_t HBP = 150; + constexpr uint32_t HFP = 150; + + constexpr uint32_t HACT = 800; + constexpr uint32_t VACT = 480; + const uint8_t pixel_size = (ColorCoding == 0) ? sizeof(uint32_t) : sizeof(uint16_t); + constexpr float ClockRatio = 62500.f / 27429; + + { + // Expanded `HAL_DSI_ConfigVideoMode()` + // Select video mode by resetting CMDM and DSIM bits + DSI->MCR = 0; + DSI->WCFGR = 0; + // Configure the video mode transmission type + DSI->VMCR = 2; + // Configure the video packet size + DSI->VPCR = HACT; + // Set the chunks number to be transmitted through the DSI link + DSI->VCCR = 0; + // Set the size of the null packet + DSI->VNPCR = 0xFFF; + // Select the virtual channel for the LTDC interface traffic + DSI->LVCIDR = 0; + // Configure the polarity of control signals + DSI->LPCR = 0; + // Select the color coding for the host + DSI->LCOLCR = ColorCoding; + // Select the color coding for the wrapper + DSI->WCFGR = ColorCoding << 1; + // DSI_VSYNC_RISING + DSI->WCFGR = DSI_WCFGR_VSPOL; + // Set the Horizontal Synchronization Active (HSA) in lane byte clock cycles + DSI->VHSACR = HSA * ClockRatio; + // Set the Horizontal Back Porch (HBP) in lane byte clock cycles + DSI->VHBPCR = HBP * ClockRatio; + // Set the total line time (HLINE=HSA+HBP+HACT+HFP) in lane byte clock cycles + DSI->VLCR = (HACT + HSA + HBP + HFP) * ClockRatio; + // Set the Vertical Synchronization Active (VSA) + DSI->VVSACR = VSA; + // Set the Vertical Back Porch (VBP) + DSI->VVBPCR = VBP; + // Set the Vertical Front Porch (VFP) + DSI->VVFPCR = VFP; + // Set the Vertical Active period + DSI->VVACR = VACT; + // Low power largest packet size + // Low power VACT largest packet size + DSI->LPMCR = (64 << 16) | 64; + // Configure the command transmission mode + // Enable LP transition in HFP period + // Enable LP transition in HBP period + DSI->VMCR |= DSI_VMCR_LPCE | DSI_VMCR_LPHFPE | DSI_VMCR_LPHBPE | DSI_VMCR_LPVAE | + DSI_VMCR_LPVFPE | DSI_VMCR_LPVBPE | DSI_VMCR_LPVSAE; + } + { + // Enable the DSI host + DSI->CR = DSI_CR_EN; + // Enable the DSI wrapper + DSI->WCR = DSI_WCR_DSIEN; + } + + /* done by SystemClock::enable() + { + // LCD clock configuration + // PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz + // PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 384 Mhz + // PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 384 MHz / 7 = 54.857 MHz + // LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 54.857 MHz / 2 = 27.429 MHz + RCC->PLLSAICFGR = (7 << 28) | (15 << 24) | (3 << 16) | (384 << 6); + // Select PLLSAI clock for 48MHz clocks + RCC->DCKCFGR = RCC_DCKCFGR_CK48MSEL; + // Enable PLLSAI + RCC->CR |= RCC_CR_PLLSAION; + for (int t = 1'024; not (RCC->CR & RCC_CR_PLLSAIRDY) and t; t--) { + modm::delay_ms(1); + } + } + */ + + // What we messed up maybe -- just following what ST example does LOL + // { + // // HAL_LTDC_Init(&hltdc_eval); + // // Configures the HS, VS, DE and PC polarity + // // sets HS Polarity and VS Polarity to active high (LTDC_HSPOLARITY_AH, LTDC_VSPOLARITY_AH) + // LTDC->GCR = (1 << 31) | (1 << 30); + // // Sets Synchronization size + // LTDC->SSCR = (1 << 16) | (1); + // // Sets Accumulated Back porch + // LTDC->BPCR = (2 << 16) | (2); + // // Sets Accumulated Active Width + // LTDC->AWCR = (202 << 16) | (482); + // // Sets Total Width and Height + // LTDC->TWCR = (203 << 16) | (483); + // // Sets the background color value + // LTDC->BCCR = 0; + // // Enable LTDC by setting LTDCEN bit + // LTDC->GCR |= LTDC_GCR_LTDCEN; + // } + + + // what is done in otm8009a + // This actually makes LPWRE error goe + { + // HAL_LTDC_Init(&hltdc_eval); + // Configures the HS, VS, DE and PC polarity + LTDC->GCR = 0; + // Sets Synchronization size + LTDC->SSCR = ((HSA - 1) << 16) | (VSA - 1); + // Sets Accumulated Back porch + LTDC->BPCR = ((HSA + HBP - 1) << 16) | (VSA + VBP - 1); + // Sets Accumulated Active Width + LTDC->AWCR = ((HACT + HSA + HBP - 1) << 16) | (VACT + VSA + VBP - 1); + // Sets Total Width and Height + LTDC->TWCR = ((HACT + HSA + HBP + HFP - 1) << 16) | (VACT + VSA + VBP + VFP - 1); + // Sets the background color value + LTDC->BCCR = 0; + // Enable LTDC by setting LTDCEN bit + LTDC->GCR |= LTDC_GCR_LTDCEN; + } + + { + + // we might have messed this up + // HAL_LTDC_ConfigLayer() + // Configures the horizontal start and stop position + LTDC_Layer1->WHPCR = + (0 + ((LTDC->BPCR & LTDC_BPCR_AHBP) >> 16) + 1) + | ((200 + ((LTDC->BPCR & LTDC_BPCR_AHBP) >> 16)) << 16); // tmp + // Configures the vertical start and stop position + LTDC_Layer1->WVPCR = (0 + (LTDC->BPCR & LTDC_BPCR_AVBP) + 1) + | ((480 + (LTDC->BPCR & LTDC_BPCR_AVBP)) << 16); + // Specifies the pixel format + LTDC_Layer1->PFCR = ColorCoding; + // Configures the default color values + LTDC_Layer1->DCCR = 0x00000000; + // Specifies the constant alpha value + LTDC_Layer1->CACR = 0xff; + // Specifies the blending factors + LTDC_Layer1->BFCR = 0x00000005U | 0x00000400U; + // Configures the color frame buffer pitch in byte + LTDC_Layer1->CFBLR = ((800 * pixel_size) << 16) | ((800 * pixel_size) + 3); + // Configures the frame buffer line number + LTDC_Layer1->CFBLNR = 480; + + /* Configured in display.cpp + // Configures the color frame buffer start address + LTDC_Layer1->CFBAR = buffer_address; + // Enable LTDC_Layer by setting LEN bit + LTDC_Layer1->CR = LTDC_LxCR_LEN; + // Sets the Reload type + LTDC->SRCR = LTDC_SRCR_IMR; + */ + } + + nt35510_init(ColorCoding); +} \ No newline at end of file diff --git a/src/modm/board/disco_f469ni/board_dsi.cpp b/src/modm/board/disco_f469ni/board_dsi_otm8009a.cpp similarity index 99% rename from src/modm/board/disco_f469ni/board_dsi.cpp rename to src/modm/board/disco_f469ni/board_dsi_otm8009a.cpp index f9f86792ae..6abc715625 100644 --- a/src/modm/board/disco_f469ni/board_dsi.cpp +++ b/src/modm/board/disco_f469ni/board_dsi_otm8009a.cpp @@ -185,4 +185,4 @@ board_initialize_display(uint8_t ColorCoding) LTDC->SRCR = LTDC_SRCR_IMR; */ } -} +} \ No newline at end of file diff --git a/src/modm/board/disco_f469ni/board_init.cpp b/src/modm/board/disco_f469ni/board_init.cpp index 362d0facf2..c381dfa143 100644 --- a/src/modm/board/disco_f469ni/board_init.cpp +++ b/src/modm/board/disco_f469ni/board_init.cpp @@ -18,6 +18,7 @@ void modm_board_init(void) { // Reset LCD + Board::DisplayReset::setOutput(Gpio::OutputType::PushPull, Gpio::OutputSpeed::High); Board::DisplayReset::setOutput(modm::Gpio::Low); modm::delay_ms(20); Board::DisplayReset::set(); diff --git a/src/modm/board/disco_f469ni/board_nt35510.cpp b/src/modm/board/disco_f469ni/board_nt35510.cpp new file mode 100644 index 0000000000..ef6409e247 --- /dev/null +++ b/src/modm/board/disco_f469ni/board_nt35510.cpp @@ -0,0 +1,356 @@ + +#include + +static void dsi_write_command(uint32_t count, uint8_t const * const p) +{ + /* Wait for Command FIFO Empty */ + for (int t = 1'024; not (DSI->GPSR & DSI_GPSR_CMDFE) and t; t--) { + modm::delay_ms(1); + } + + if(count <= 1) + { + DSI->GHCR = (0x00000015 | (0 << 6) | (p[0] << 8) | (p[1] << 16)); + } + else + { + DSI->GPDR = p[count] | + (p[0] << 8) | + (p[1] << 16) | + (p[2] << 24); + uint16_t counter = 3; + + for (int t = 1'024; not (DSI->GPSR & DSI_GPSR_CMDFE) and t; t--) { + modm::delay_ms(1); + } + + while(counter < count) + { + DSI->GPDR = p[counter] | + (p[counter + 1] << 8) | + (p[counter + 2] << 16) | + (p[counter + 3] << 24); + counter += 4; + + for (int t = 1'024; not (DSI->GPSR & DSI_GPSR_CMDFE) and t; t--) { + modm::delay_ms(1); + } + } + + /* Configure the packet to send a long DCS command */ + DSI->GHCR = (0x00000039 | (0 << 6) | (((count + 1) & 0xFF) << 8) | (((count + 1) & 0xFF00) << 8)); + } +} + + + +/** + ****************************************************************************** + * @file nt35510.c + * @author MCD Application Team + * @brief This file provides the LCD Driver for Frida Techshine 3K138 (WVGA) + * DSI LCD Display NT35510. + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2020 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + + /** + * @brief LCD_OrientationTypeDef + * Possible values of Display Orientation + */ +constexpr uint32_t NT35510_ORIENTATION_PORTRAIT = ((uint32_t)0x00); /* Portrait orientation choice of LCD screen */ +constexpr uint32_t NT35510_ORIENTATION_LANDSCAPE = ((uint32_t)0x01); /* Landscape orientation choice of LCD screen */ + +/** + * @brief Possible values of + * pixel data format (ie color coding) transmitted on DSI Data lane in DSI packets + */ +constexpr uint32_t NT35510_FORMAT_RGB888 = ((uint32_t)0x00); /* Pixel format chosen is RGB888 : 24 bpp */ +constexpr uint32_t NT35510_FORMAT_RBG565 = ((uint32_t)0x02); /* Pixel format chosen is RGB565 : 16 bpp */ + +/** + * @brief nt35510_480x800 Size + */ + +/* Width and Height in Portrait mode */ +constexpr uint16_t NT35510_480X800_WIDTH = ((uint16_t)480); /* LCD PIXEL WIDTH */ +constexpr uint16_t NT35510_480X800_HEIGHT = ((uint16_t)800); /* LCD PIXEL HEIGHT */ + +/* Width and Height in Landscape mode */ +constexpr uint16_t NT35510_800X480_WIDTH = ((uint16_t)800); /* LCD PIXEL WIDTH */ +constexpr uint16_t NT35510_800X480_HEIGHT = ((uint16_t)480); /* LCD PIXEL HEIGHT */ + +/** + * @brief NT35510_480X800 Timing parameters for Portrait orientation mode + */ +constexpr uint16_t NT35510_480X800_HSYNC = ((uint16_t)2); /* Horizontal synchronization */ +constexpr uint16_t NT35510_480X800_HBP = ((uint16_t)34); /* Horizontal back porch */ +constexpr uint16_t NT35510_480X800_HFP = ((uint16_t)34); /* Horizontal front porch */ +constexpr uint16_t NT35510_480X800_VSYNC = ((uint16_t)120); /* Vertical synchronization */ +constexpr uint16_t NT35510_480X800_VBP = ((uint16_t)150); /* Vertical back porch */ +constexpr uint16_t NT35510_480X800_VFP = ((uint16_t)150); /* Vertical front porch */ + +/** + * @brief NT35510_800X480 Timing parameters for Landscape orientation mode + * Same values as for Portrait mode in fact. + */ +constexpr uint16_t NT35510_800X480_HSYNC = NT35510_480X800_VSYNC; /* Horizontal synchronization */ +constexpr uint16_t NT35510_800X480_HBP = NT35510_480X800_VBP; /* Horizontal back porch */ +constexpr uint16_t NT35510_800X480_HFP = NT35510_480X800_VFP; /* Horizontal front porch */ +constexpr uint16_t NT35510_800X480_VSYNC = NT35510_480X800_HSYNC; /* Vertical synchronization */ +constexpr uint16_t NT35510_800X480_VBP = NT35510_480X800_HBP; /* Vertical back porch */ +constexpr uint16_t NT35510_800X480_VFP = NT35510_480X800_HFP; /* Vertical front porch */ + + +/* List of NT35510 used commands */ +/* Detailed in NT35510 Data Sheet v0.80 */ +/* Version of 10/28/2011 */ +/* Command, NumberOfArguments */ + +constexpr uint8_t NT35510_CMD_NOP = 0x00; /* NOP */ +constexpr uint8_t NT35510_CMD_SWRESET = 0x01; /* SW reset */ +constexpr uint8_t NT35510_CMD_RDDID = 0x04; /* Read display ID */ +constexpr uint8_t NT35510_CMD_RDNUMED = 0x05; /* Read number of errors on DSI */ +constexpr uint8_t NT35510_CMD_RDDPM = 0x0A; /* Read display power mode */ +constexpr uint8_t NT35510_CMD_RDDMADCTL = 0x0B; /* Read display MADCTL */ +constexpr uint8_t NT35510_CMD_RDDCOLMOD = 0x0C; /* Read display pixel format */ +constexpr uint8_t NT35510_CMD_RDDIM = 0x0D; /* Read display image mode */ +constexpr uint8_t NT35510_CMD_RDDSM = 0x0E; /* Read display signal mode */ +constexpr uint8_t NT35510_CMD_RDDSDR = 0x0F; /* Read display self-diagnostics result */ +constexpr uint8_t NT35510_CMD_SLPIN = 0x10; /* Sleep in */ +constexpr uint8_t NT35510_CMD_SLPOUT = 0x11; /* Sleep out */ +constexpr uint8_t NT35510_CMD_PTLON = 0x12; /* Partial mode on */ +constexpr uint8_t NT35510_CMD_NORON = 0x13; /* Normal display mode on */ +constexpr uint8_t NT35510_CMD_INVOFF = 0x20; /* Display inversion off */ +constexpr uint8_t NT35510_CMD_INVON = 0x21; /* Display inversion on */ +constexpr uint8_t NT35510_CMD_ALLPOFF = 0x22; /* All pixel off */ +constexpr uint8_t NT35510_CMD_ALLPON = 0x23; /* All pixel on */ +constexpr uint8_t NT35510_CMD_GAMSET = 0x26; /* Gamma set */ +constexpr uint8_t NT35510_CMD_DISPOFF = 0x28; /* Display off */ +constexpr uint8_t NT35510_CMD_DISPON = 0x29; /* Display on */ +constexpr uint8_t NT35510_CMD_CASET = 0x2A; /* Column address set */ +constexpr uint8_t NT35510_CMD_RASET = 0x2B; /* Row address set */ +constexpr uint8_t NT35510_CMD_RAMWR = 0x2C; /* Memory write */ +constexpr uint8_t NT35510_CMD_RAMRD = 0x2E; /* Memory read */ +constexpr uint8_t NT35510_CMD_PLTAR = 0x30; /* Partial area */ +constexpr uint8_t NT35510_CMD_TOPC = 0x32; /* Turn On Peripheral Command */ +constexpr uint8_t NT35510_CMD_TEOFF = 0x34; /* Tearing effect line off */ +constexpr uint8_t NT35510_CMD_TEEON = 0x35; /* Tearing effect line on */ +constexpr uint8_t NT35510_CMD_MADCTL = 0x36; /* Memory data access control */ +constexpr uint8_t NT35510_CMD_IDMOFF = 0x38; /* Idle mode off */ +constexpr uint8_t NT35510_CMD_IDMON = 0x39; /* Idle mode on */ +constexpr uint8_t NT35510_CMD_COLMOD = 0x3A; /* Interface pixel format */ +constexpr uint8_t NT35510_CMD_RAMWRC = 0x3C; /* Memory write continue */ +constexpr uint8_t NT35510_CMD_RAMRDC = 0x3E; /* Memory read continue */ +constexpr uint8_t NT35510_CMD_STESL = 0x44; /* Set tearing effect scan line */ +constexpr uint8_t NT35510_CMD_GSL = 0x45; /* Get scan line */ +constexpr uint8_t NT35510_CMD_DSTBON = 0x4F; /* Deep standby mode on */ +constexpr uint8_t NT35510_CMD_WRPFD = 0x50; /* Write profile value for display */ +constexpr uint8_t NT35510_CMD_WRDISBV = 0x51; /* Write display brightness */ +constexpr uint8_t NT35510_CMD_RDDISBV = 0x52; /* Read display brightness */ +constexpr uint8_t NT35510_CMD_WRCTRLD = 0x53; /* Write CTRL display */ +constexpr uint8_t NT35510_CMD_RDCTRLD = 0x54; /* Read CTRL display value */ +constexpr uint8_t NT35510_CMD_WRCABC = 0x55; /* Write content adaptative brightness control */ +constexpr uint8_t NT35510_CMD_RDCABC = 0x56; /* Read content adaptive brightness control */ +constexpr uint8_t NT35510_CMD_WRHYSTE = 0x57; /* Write hysteresis */ +constexpr uint8_t NT35510_CMD_WRGAMMSET = 0x58; /* Write gamme setting */ +constexpr uint8_t NT35510_CMD_RDFSVM = 0x5A; /* Read FS value MSBs */ +constexpr uint8_t NT35510_CMD_RDFSVL = 0x5B; /* Read FS value LSBs */ +constexpr uint8_t NT35510_CMD_RDMFFSVM = 0x5C; /* Read median filter FS value MSBs */ +constexpr uint8_t NT35510_CMD_RDMFFSVL = 0x5D; /* Read median filter FS value LSBs */ +constexpr uint8_t NT35510_CMD_WRCABCMB = 0x5E; /* Write CABC minimum brightness */ +constexpr uint8_t NT35510_CMD_RDCABCMB = 0x5F; /* Read CABC minimum brightness */ +constexpr uint8_t NT35510_CMD_WRLSCC = 0x65; /* Write light sensor compensation coefficient value */ +constexpr uint8_t NT35510_CMD_RDLSCCM = 0x66; /* Read light sensor compensation coefficient value MSBs */ +constexpr uint8_t NT35510_CMD_RDLSCCL = 0x67; /* Read light sensor compensation coefficient value LSBs */ +constexpr uint8_t NT35510_CMD_RDBWLB = 0x70; /* Read black/white low bits */ +constexpr uint8_t NT35510_CMD_RDBKX = 0x71; /* Read Bkx */ +constexpr uint8_t NT35510_CMD_RDBKY = 0x72; /* Read Bky */ +constexpr uint8_t NT35510_CMD_RDWX = 0x73; /* Read Wx */ +constexpr uint8_t NT35510_CMD_RDWY = 0x74; /* Read Wy */ +constexpr uint8_t NT35510_CMD_RDRGLB = 0x75; /* Read red/green low bits */ +constexpr uint8_t NT35510_CMD_RDRX = 0x76; /* Read Rx */ +constexpr uint8_t NT35510_CMD_RDRY = 0x77; /* Read Ry */ +constexpr uint8_t NT35510_CMD_RDGX = 0x78; /* Read Gx */ +constexpr uint8_t NT35510_CMD_RDGY = 0x79; /* Read Gy */ +constexpr uint8_t NT35510_CMD_RDBALB = 0x7A; /* Read blue/acolor low bits */ +constexpr uint8_t NT35510_CMD_RDBX = 0x7B; /* Read Bx */ +constexpr uint8_t NT35510_CMD_RDBY = 0x7C; /* Read By */ +constexpr uint8_t NT35510_CMD_RDAX = 0x7D; /* Read Ax */ +constexpr uint8_t NT35510_CMD_RDAY = 0x7E; /* Read Ay */ +constexpr uint8_t NT35510_CMD_RDDDBS = 0xA1; /* Read DDB start */ +constexpr uint8_t NT35510_CMD_RDDDBC = 0xA8; /* Read DDB continue */ +constexpr uint8_t NT35510_CMD_RDDCS = 0xAA; /* Read first checksum */ +constexpr uint8_t NT35510_CMD_RDCCS = 0xAF; /* Read continue checksum */ +constexpr uint8_t NT35510_CMD_RDID1 = 0xDA; /* Read ID1 value */ +constexpr uint8_t NT35510_CMD_RDID2 = 0xDB; /* Read ID2 value */ +constexpr uint8_t NT35510_CMD_RDID3 = 0xDC; /* Read ID3 value */ + +/* Parameter TELOM : Tearing Effect Line Output Mode : possible values */ +constexpr uint8_t NT35510_TEEON_TELOM_VBLANKING_INFO_ONLY = 0x00; +constexpr uint8_t NT35510_TEEON_TELOM_VBLANKING_AND_HBLANKING_INFO = 0x01; + +/* Possible used values of MADCTR */ +constexpr uint8_t NT35510_MADCTR_MODE_PORTRAIT = 0x00; +constexpr uint8_t NT35510_MADCTR_MODE_LANDSCAPE = 0x60; /* MY = 0, MX = 1, MV = 1, ML = 0, RGB = 0 */ + +/* Possible values of COLMOD parameter corresponding to used pixel formats */ +constexpr uint8_t NT35510_COLMOD_RGB565 = 0x55; +constexpr uint8_t NT35510_COLMOD_RGB888 = 0x77; + +/** + * @brief NT35510_480X800 frequency divider + */ +constexpr uint8_t NT35510_480X800_FREQUENCY_DIVIDER = 2; /* LCD Frequency divider */ + + +/* ************************************************************************** */ +/* Proprietary Initialization */ +/* ************************************************************************** */ +const uint8_t nt35510_reg[] = {0x55, 0xAA, 0x52, 0x08, 0x01, 0xF0}; +const uint8_t nt35510_reg1[] = {0x03, 0x03, 0x03, 0xB0}; +const uint8_t nt35510_reg2[] = {0x46, 0x46, 0x46, 0xB6}; +const uint8_t nt35510_reg3[] = {0x03, 0x03, 0x03, 0xB1}; +const uint8_t nt35510_reg4[] = {0x36, 0x36, 0x36, 0xB7}; +const uint8_t nt35510_reg5[] = {0x00, 0x00, 0x02, 0xB2}; +const uint8_t nt35510_reg6[] = {0x26, 0x26, 0x26, 0xB8}; +const uint8_t nt35510_reg7[] = {0xBF, 0x01}; +const uint8_t nt35510_reg8[] = {0x09, 0x09, 0x09, 0xB3}; +const uint8_t nt35510_reg9[] = {0x36, 0x36, 0x36, 0xB9}; +const uint8_t nt35510_reg10[] = {0x08, 0x08, 0x08, 0xB5}; +const uint8_t nt35510_reg12[] = {0x26, 0x26, 0x26, 0xBA}; +const uint8_t nt35510_reg13[] = {0x00, 0x80, 0x00, 0xBC}; +const uint8_t nt35510_reg14[] = {0x00, 0x80, 0x00, 0xBD}; +const uint8_t nt35510_reg15[] = {0x00, 0x50, 0xBE}; +const uint8_t nt35510_reg16[] = {0x55, 0xAA, 0x52, 0x08, 0x00, 0xF0}; +const uint8_t nt35510_reg17[] = {0xFC, 0x00, 0xB1}; +const uint8_t nt35510_reg18[] = {0xB6, 0x03}; +const uint8_t nt35510_reg19[] = {0xB5, 0x51}; +const uint8_t nt35510_reg20[] = {0x00, 0x00, 0xB7}; +const uint8_t nt35510_reg21[] = {0x01, 0x02, 0x02, 0x02, 0xB8}; +const uint8_t nt35510_reg22[] = {0x00, 0x00, 0x00, 0xBC}; +const uint8_t nt35510_reg23[] = {0x03, 0x00, 0x00, 0xCC}; +const uint8_t nt35510_reg24[] = {0xBA, 0x01}; +const uint8_t nt35510_madctl_portrait[] = {NT35510_CMD_MADCTL ,0x00}; +const uint8_t nt35510_caset_portrait[] = {0x00, 0x00, 0x01, 0xDF ,NT35510_CMD_CASET}; +const uint8_t nt35510_raset_portrait[] = {0x00, 0x00, 0x03, 0x1F ,NT35510_CMD_RASET}; +const uint8_t nt35510_madctl_landscape[] = {NT35510_CMD_MADCTL, 0x60}; +const uint8_t nt35510_caset_landscape[] = {0x00, 0x00, 0x03, 0x1F ,NT35510_CMD_CASET}; +const uint8_t nt35510_raset_landscape[] = {0x00, 0x00, 0x01, 0xDF ,NT35510_CMD_RASET}; +const uint8_t nt35510_reg26[] = {NT35510_CMD_TEEON, 0x00}; /* Tear on */ +const uint8_t nt35510_reg27[] = {NT35510_CMD_SLPOUT, 0x00}; /* Sleep out */ +const uint8_t nt35510_reg30[] = {NT35510_CMD_DISPON, 0x00}; + +const uint8_t nt35510_reg31[] = {NT35510_CMD_WRDISBV, 0x7F}; +const uint8_t nt35510_reg32[] = {NT35510_CMD_WRCTRLD, 0x2C}; +const uint8_t nt35510_reg33[] = {NT35510_CMD_WRCABC, 0x02}; +const uint8_t nt35510_reg34[] = {NT35510_CMD_WRCABCMB, 0xFF}; +const uint8_t nt35510_reg35[] = {NT35510_CMD_RAMWR, 0x00}; +const uint8_t nt35510_reg36[] = {NT35510_CMD_COLMOD, NT35510_COLMOD_RGB565}; +const uint8_t nt35510_reg37[] = {NT35510_CMD_COLMOD, NT35510_COLMOD_RGB888}; + +uint8_t nt35510_init(uint8_t ColorCoding) +{ + modm::delay_ms(120); + + dsi_write_command(5, nt35510_reg); /* LV2: Page 1 enable */ + dsi_write_command(3, nt35510_reg1);/* AVDD: 5.2V */ + dsi_write_command(3, nt35510_reg2);/* AVDD: Ratio */ + dsi_write_command(3, nt35510_reg3);/* AVEE: -5.2V */ + dsi_write_command(3, nt35510_reg4);/* AVEE: Ratio */ + dsi_write_command(3, nt35510_reg5);/* VCL: -2.5V */ + dsi_write_command(3, nt35510_reg6);/* VCL: Ratio */ + dsi_write_command(1, nt35510_reg7);/* VGH: 15V (Free Pump) */ + dsi_write_command(3, nt35510_reg8); + dsi_write_command(3, nt35510_reg9);/* VGH: Ratio */ + dsi_write_command(3, nt35510_reg10);/* VGL_REG: -10V */ + dsi_write_command(3, nt35510_reg12);/* VGLX: Ratio */ + dsi_write_command(3, nt35510_reg13);/* VGMP/VGSP: 4.5V/0V */ + dsi_write_command(3, nt35510_reg14);/* VGMN/VGSN:-4.5V/0V */ + dsi_write_command(2, nt35510_reg15);/* VCOM: -1.325V */ + +/* ************************************************************************** */ +/* Proprietary DCS Initialization */ +/* ************************************************************************** */ + dsi_write_command(5, nt35510_reg16);/* LV2: Page 0 enable */ + dsi_write_command(2, nt35510_reg17);/* Display control */ + dsi_write_command(1, nt35510_reg18);/* Src hold time */ + dsi_write_command(1, nt35510_reg19); + dsi_write_command(2, nt35510_reg20);/* Gate EQ control */ + dsi_write_command(4, nt35510_reg21);/* Src EQ control(Mode2) */ + dsi_write_command(3, nt35510_reg22);/* Inv. mode(2-dot) */ + dsi_write_command(3, nt35510_reg23); + dsi_write_command(1, nt35510_reg24); + /* Tear on */ + dsi_write_command(0, nt35510_reg26); + /* Set Pixel color format to RGB888 */ + dsi_write_command(0, nt35510_reg37); + +/* ************************************************************************** */ +/* Standard DCS Initialization */ +/* ************************************************************************** */ + + /* Add a delay, otherwise MADCTL not taken */ + modm::delay_ms(200); + + /* Configure orientation */ + // if(orientation == NT35510_ORIENTATION_PORTRAIT) + // { + // dsi_write_command(1, nt35510_madctl_portrait); + // dsi_write_command(4, nt35510_caset_portrait); + // dsi_write_command(4, nt35510_raset_portrait); + // } + // else + // { + dsi_write_command(1, (uint8_t *)nt35510_madctl_landscape); + dsi_write_command(4, (uint8_t *)nt35510_caset_landscape); + dsi_write_command(4, (uint8_t *)nt35510_raset_landscape); + // } + + dsi_write_command(0, (uint8_t *)nt35510_reg27); + /* Wait for sleep out exit */ + modm::delay_ms(120); + + switch(ColorCoding) + { + case NT35510_FORMAT_RBG565 : + /* Set Pixel color format to RGB565 */ + dsi_write_command(1, nt35510_reg36); + break; + case NT35510_FORMAT_RGB888: + default : + /* Set Pixel color format to RGB888 */ + dsi_write_command(1, nt35510_reg37); + break; + } + + /** CABC : Content Adaptive Backlight Control section start >> */ + /* Note : defaut is 0 (lowest Brightness), 0xFF is highest Brightness, try 0x7F : intermediate value */ + dsi_write_command(1, nt35510_reg31); + /* defaut is 0, try 0x2C - Brightness Control Block, Display Dimming & BackLight on */ + dsi_write_command(1, nt35510_reg32); + /* defaut is 0, try 0x02 - image Content based Adaptive Brightness [Still Picture] */ + dsi_write_command(1, nt35510_reg33); + /* defaut is 0 (lowest Brightness), 0xFF is highest Brightness */ + dsi_write_command(1, nt35510_reg34); + /** CABC : Content Adaptive Backlight Control section end << */ + + /* Display on */ + dsi_write_command(0, nt35510_reg30); + + /* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */ + /* DSI host from LTDC incoming pixels in video mode */ + dsi_write_command(0, nt35510_reg35); + + return 0; +} \ No newline at end of file diff --git a/src/modm/board/disco_f469ni/board_otm8009a.cpp b/src/modm/board/disco_f469ni/board_otm8009a.cpp index dac6343d76..7e978514a2 100644 --- a/src/modm/board/disco_f469ni/board_otm8009a.cpp +++ b/src/modm/board/disco_f469ni/board_otm8009a.cpp @@ -452,4 +452,4 @@ void otm8009a_init(uint8_t ColorCoding) /* Send Command GRAM memory write (no parameters) : this initiates frame write via other DSI commands sent by */ /* DSI host from LTDC incoming pixels in video mode */ dsi_write_command(0, ShortRegData45); -} +} \ No newline at end of file diff --git a/src/modm/board/disco_f469ni/module.lb b/src/modm/board/disco_f469ni/module.lb index 3a54579cd6..49110d3f50 100644 --- a/src/modm/board/disco_f469ni/module.lb +++ b/src/modm/board/disco_f469ni/module.lb @@ -14,7 +14,7 @@ def init(module): module.name = ":board:disco-f469ni" module.description = FileReader("module.md") - # Revisions = [b-03, b-02, b-01] + # Revisions = [c-01, b-08, b-03, b-02, b-01] def prepare(module, options): if not options[":target"].partname.startswith("stm32f469nih"): @@ -45,9 +45,15 @@ def build(env): } env.template("../board.cpp.in", "board.cpp") env.copy("board_display.cpp") - env.copy("board_dsi.cpp") + + if env[":disco-f469ni"] in ["b-08", "c-01"]: + env.copy("board_dsi_nt35510.cpp") + env.copy("board_nt35510.cpp") + else: + env.copy("board_dsi_otm8009a.cpp") + env.copy("board_otm8009a.cpp") + env.copy("board_init.cpp") - env.copy("board_otm8009a.cpp") env.copy("board_sdram.cpp") env.template("board.hpp.in") env.collect(":build:openocd.source", "board/stm32f469discovery.cfg")