From 7f4da522479c0f00126219f0c23b804c3a93d7a6 Mon Sep 17 00:00:00 2001 From: Yuval Adam Date: Sun, 16 Mar 2014 14:40:16 +0200 Subject: Add driver lib for projects which require it --- driverlib/lcd.c | 1805 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1805 insertions(+) create mode 100644 driverlib/lcd.c (limited to 'driverlib/lcd.c') diff --git a/driverlib/lcd.c b/driverlib/lcd.c new file mode 100644 index 0000000..9a0e16c --- /dev/null +++ b/driverlib/lcd.c @@ -0,0 +1,1805 @@ +//***************************************************************************** +// +// lcd.c - Defines and Macros for the LCD Controller module. +// +// Copyright (c) 2012-2014 Texas Instruments Incorporated. All rights reserved. +// Software License Agreement +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// +// Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the +// distribution. +// +// Neither the name of Texas Instruments Incorporated nor the names of +// its contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// This is part of revision 2.1.0.12573 of the Tiva Peripheral Driver Library. +// +//***************************************************************************** + +//***************************************************************************** +// +//! \addtogroup lcd_api +//! @{ +// +//***************************************************************************** + +#include +#include +#include +#include "inc/hw_memmap.h" +#include "inc/hw_types.h" +#include "inc/hw_ints.h" +#include "inc/hw_lcd.h" +#include "driverlib/interrupt.h" +#include "driverlib/sysctl.h" +#include "driverlib/lcd.h" +#include "driverlib/debug.h" + +//***************************************************************************** +// +// These are currently missing from hw_lcd.h and included here as a stopgap +// until the hardware header is updated. +// +//***************************************************************************** +#ifndef LCD_RASTRTIM0_MSBPPL_S +#define LCD_RASTRTIM0_MSBPPL_S 3 +#endif +#ifndef LCD_RASTRTIM2_MSBLPP_S +#define LCD_RASTRTIM2_MSBLPP_S 26 +#endif + +//***************************************************************************** +// +//! Configures the basic operating mode and clock rate for the LCD controller. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui8Mode specifies the basic operating mode to be used. +//! \param ui32PixClk specifies the desired LCD controller pixel or master +//! clock rate in Hz. +//! \param ui32SysClk specifies the current system clock rate in Hz. +//! +//! This function sets the basic operating mode of the LCD controller and also +//! its master clock. The \e ui8Mode parameter may be set to either \b +//! LCD_MODE_LIDD or \b LCD_MODE_RASTER. \b LCD_MODE_LIDD is used to select +//! LCD Interface Display Driver mode for character panels connected via +//! an asynchronous interface (CS, WE, OE, ALE, data) and \b LCD_MODE_RASTER +//! is used to communicate with panels via a synchronous video interface using +//! data and sync signals. Additionally, \b LCD_MODE_AUTO_UFLOW_RESTART may +//! be ORed with either of these modes to indicate that the hardware should +//! restart automatically if a data underflow occurs. +//! +//! The \e ui32PixClk parameter specifies the desired master clock for the +//! the LCD controller. In LIDD mode, this value controls the MCLK used in +//! communication with the display and valid values are between \e ui32SysClk +//! and \e ui32SysClk/255. In raster mode, \e ui32PixClk specifies the pixel +//! clock rate for the raster interface and valid values are between \e +//! ui32SysClk/2 and \e ui32SysClk/255. The actual clock rate set may differ +//! slightly from the desired rate due to the fact that only integer dividers +//! are supported. The rate set will, however, be no higher than the requested +//! value. +//! +//! The \e ui32SysClk parameter provides the current system clock rate and is +//! used to allow the LCD controller clock rate divisor to be correctly set +//! to give the desired \e ui32PixClk rate. +//! +//! \return Returns the actual LCD controller pixel clock or MCLK rate set. +// +//***************************************************************************** +uint32_t +LCDModeSet(uint32_t ui32Base, uint8_t ui8Mode, uint32_t ui32PixClk, + uint32_t ui32SysClk) +{ + uint32_t ui32Div; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui8Mode & ~(LCD_MODE_RASTER | LCD_MODE_LIDD | + LCD_MODE_AUTO_UFLOW_RESTART)) == 0); + + // + // Enable clocks to the LCD controller submodules. + // + HWREG(ui32Base + LCD_O_CLKEN) = (LCD_CLKEN_DMA | LCD_CLKEN_CORE | + LCD_CLKEN_LIDD); + + // + // Determine the clock divider to use to get as close as possible to the + // desired pixel clock. Note that we set the division up so that we + // round the divisor up and ensure that the clock used is never faster + // than the requested rate. + // + ui32Div = (ui32SysClk + (ui32PixClk - 1)) / ui32PixClk; + + // + // Check that the calculated value is valid. + // + ASSERT(ui32Div); + ASSERT(ui32Div < 256); + ASSERT(!((ui8Mode & LCD_MODE_RASTER) && (ui32Div < 2))); + + // + // Write the LCDCTL register to set the mode. + // + HWREG(ui32Base + LCD_O_CTL) = (uint32_t)ui8Mode | + (ui32Div << LCD_CTL_CLKDIV_S); + + // + // Return the selected clock rate. Finding ui32Div set to 0 should not + // happen unless someone passed pathological arguments and builds without + // the ASSERTS, but we guard against it just in case. + // + return(ui32Div ? (ui32SysClk / ui32Div) : ui32SysClk); +} + +//***************************************************************************** +// +//! Resets one or more of the LCD controller clock domains. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32Clocks defines the subset of clock domains to be reset. +//! +//! This function allows sub-modules of the LCD controller to be reset under +//! software control. The \e ui32Clocks parameter is the logical OR of the +//! following clocks: +//! +//! - \b LCD_CLOCK_MAIN causes the entire LCD controller module to be reset. +//! - \b LCD_CLOCK_DMA causes the DMA controller submodule to be reset. +//! - \b LCD_CLOCK_LIDD causes the LIDD submodule to be reset. +//! - \b LCD_CLOCK_CORE causes the core module, including the raster logic to +//! be reset. +//! +//! In all cases, LCD controller register values are preserved across these +//! resets. +//! +//! \return None. +// +//***************************************************************************** +void +LCDClockReset(uint32_t ui32Base, uint32_t ui32Clocks) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32Clocks & ~(LCD_CLOCK_MAIN | LCD_CLOCK_LIDD | LCD_CLOCK_DMA | + LCD_CLOCK_CORE))); + + // + // Reset the required LCD controller sub-module(s). + // + HWREG(LCD0_BASE + 0x70) = ui32Clocks; + + // + // Wait a while. + // + SysCtlDelay(10); + + // + // Remove software reset. + // + HWREG(LCD0_BASE + 0x70) = 0x00000000; + + // + // Wait a while. + // + SysCtlDelay(10); +} + +//***************************************************************************** +// +//! Sets the LCD controller communication parameters when in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32Config defines the display interface configuration. +//! +//! This function is used when the LCD controller is configured in LIDD +//! mode and specifies the configuration of the interface between the +//! controller and the display panel. The \e ui32Config parameter is +//! comprised of one of the following modes: +//! +//! - \b LIDD_CONFIG_SYNC_MPU68 selects Sync MPU68 mode. LCDCP = EN, LCDLP = +//! DIR, LCDFP = ALE, LCDAC = CS0, LCDMCLK = MCLK. +//! - \b LIDD_CONFIG_ASYNC_MPU68 selects Async MPU68 mode. LCDCP = EN, LCDLP = +//! DIR, LCDFP = ALE, LCDAC = CS0, LCDMCLK = CS1. +//! - \b LIDD_CONFIG_SYNC_MPU80 selects Sync MPU80 mode. LCDCP = RS, LCDLP = +//! WS, LCDFP = ALE, LCDAC = CS0, LCDMCLK = MCLK. +//! - \b LIDD_CONFIG_ASYNC_MPU80 selects Async MPU80 mode. LCDCP = RS, LCDLP = +//! WS, LCDFP = ALE, LCDAC = CS0, LCDMCLK = CS1. +//! - \b LIDD_CONFIG_ASYNC_HITACHI selects Hitachi (async) mode. LCDCP = N/C, +//! LCDLP = DIR, LCDFP = ALE, LCDAC = E0, LCDMCLK = E1. +//! +//! Additional flags may be ORed into \e ui32Config to control the polarities +//! of various control signals: +//! +//! - \b LIDD_CONFIG_INVERT_ALE - Address Latch Enable (ALE) polarity control. +//! By default, ALE is active low. If this flag is set, it becomes active +//! high. +//! - \b LIDD_CONFIG_INVERT_RS_EN - Read Strobe/Enable polarity control. By +//! default, RS is active low and Enable is active high. If this flag is set, +//! RS becomes active high and Enable active low. +//! - \b LIDD_CONFIG_INVERT_WS_DIR - Write Strobe/Direction polarity control. +//! By default, WS is active low and Direction write low/read high. If this +//! flag is set, WS becomes active high and Direction becomes write high/read +//! low. +//! - \b LIDD_CONFIG_INVERT_CS0 - Chip Select 0/Enable 0 polarity control. By +//! default, CS0 and E0 are active high. If this flag is set, they become +//! active low. +//! - \b LIDD_CONFIG_INVERT_CS1 - Chip Select 1/Enable 1 polarity control. By +//! default, CS1 and E1 are active high. If this flag is set, they become +//! active low. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIDDConfigSet(uint32_t ui32Base, uint32_t ui32Config) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32Config & ~(LIDD_CONFIG_SYNC_MPU68 | LIDD_CONFIG_ASYNC_MPU68 | + LIDD_CONFIG_SYNC_MPU80 | LIDD_CONFIG_ASYNC_MPU80 | + LIDD_CONFIG_ASYNC_HITACHI | + LIDD_CONFIG_INVERT_ALE | + LIDD_CONFIG_INVERT_RS_EN | + LIDD_CONFIG_INVERT_WS_DIR | + LIDD_CONFIG_INVERT_CS0 | LIDD_CONFIG_INVERT_CS1))); + + // + // Write the LIDD Control Register. + // + HWREG(ui32Base + LCD_O_LIDDCTL) = ui32Config; +} + +//***************************************************************************** +// +//! Sets the LCD controller interface timing when in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select whose timings are to be set. +//! \param pTiming points to a structure containing the desired timing +//! parameters. +//! +//! This function is used in LIDD mode to set the setup, strobe and hold times +//! for the various interface control signals. Independent timings are stored +//! for each of the two supported chip selects offered by the LCD controller. +//! +//! For a definition of the timing parameters required, see the definition of +//! tLCDIDDTiming. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return None +// +//***************************************************************************** +void +LCDIDDTimingSet(uint32_t ui32Base, uint32_t ui32CS, + const tLCDIDDTiming *pTiming) +{ + uint32_t ui32Val; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + ASSERT(pTiming); + ASSERT(pTiming->ui8WSSetup < 32); + ASSERT(pTiming->ui8WSDuration && (pTiming->ui8WSDuration < 64)); + ASSERT(pTiming->ui8WSHold && (pTiming->ui8WSHold < 16)); + ASSERT(pTiming->ui8RSSetup < 32); + ASSERT(pTiming->ui8RSDuration && (pTiming->ui8RSDuration < 64)); + ASSERT(pTiming->ui8RSHold && (pTiming->ui8RSHold < 16)); + ASSERT(pTiming->ui8DelayCycles && (pTiming->ui8DelayCycles < 5)); + + // + // Convert the timings provided into a value ready for the register. + // + ui32Val = + (((uint32_t)(pTiming->ui8WSSetup) << LCD_LIDDCS0CFG_WRSU_S) | + ((uint32_t)(pTiming->ui8WSDuration) << LCD_LIDDCS0CFG_WRDUR_S) | + ((uint32_t)(pTiming->ui8WSHold) << LCD_LIDDCS0CFG_WRHOLD_S) | + ((uint32_t)(pTiming->ui8RSSetup) << LCD_LIDDCS0CFG_RDSU_S) | + ((uint32_t)(pTiming->ui8RSDuration) << LCD_LIDDCS0CFG_RDDUR_S) | + ((uint32_t)(pTiming->ui8RSHold) << LCD_LIDDCS0CFG_RDHOLD_S) | + ((uint32_t)(pTiming->ui8DelayCycles - 1) << LCD_LIDDCS0CFG_GAP_S)); + + // + // Write the appropriate LCD LIDD CS configuration register. + // + if(!ui32CS) + { + HWREG(ui32Base + LCD_O_LIDDCS0CFG) = ui32Val; + } + else + { + HWREG(ui32Base + LCD_O_LIDDCS1CFG) = ui32Val; + } +} + +//***************************************************************************** +// +//! Disables internal DMA operation when the LCD controller is in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! +//! When the LCD controller is operating in LCD Interface Display Driver mode, +//! this function must be called after completion of a DMA transaction and +//! before calling LCDIDDCommandWrite(), LCDIDDDataWrite(), LCDIDDStatusRead(), +//! LCDIDDIndexedWrite(), LCDIDDIndexedRead() or LCDIDDDataRead() to disable +//! DMA mode and allow CPU-initiated transactions to the display. +//! +//! \note LIDD DMA mode is enabled automatically when LCDIDDDMAWrite() is +//! called. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIDDDMADisable(uint32_t ui32Base) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Disable DMA. + // + HWREG(ui32Base + LCD_O_LIDDCTL) &= ~LCD_LIDDCTL_DMAEN; +} + +//***************************************************************************** +// +//! Writes a command to the display when the LCD controller is in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! \param ui16Cmd is the 16-bit command word to write. +//! +//! This function writes a 16-bit command word to the display when the LCD +//! controller is in LIDD mode. A command write occurs with the ALE signal +//! active. +//! +//! This function must not be called if the LIDD interface is currently +//! configured to expect DMA transactions. If DMA was previously used to +//! write to the panel, LCDIDDDMADisable() must be called before this function +//! can be used. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIDDCommandWrite(uint32_t ui32Base, uint32_t ui32CS, uint16_t ui16Cmd) +{ + uint32_t ui32Reg; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + + // + // Determine the register to write based on the CS value supplied. + // + ui32Reg = ui32CS ? LCD_O_LIDDCS1ADDR : LCD_O_LIDDCS0ADDR; + + // + // Write the command/address to the register. + // + HWREG(ui32Base + ui32Reg) = ui16Cmd; +} + +//***************************************************************************** +// +//! Writes a data value to the display when the LCD controller is in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! \param ui16Data is the 16-bit data word to write. +//! +//! This function writes a 16-bit data word to the display when the LCD +//! controller is in LIDD mode. A data write occurs with the ALE signal +//! inactive. +//! +//! This function must not be called if the LIDD interface is currently +//! configured to expect DMA transactions. If DMA was previously used to +//! write to the panel, LCDIDDDMADisable() must be called before this function +//! can be used. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIDDDataWrite(uint32_t ui32Base, uint32_t ui32CS, uint16_t ui16Data) +{ + uint32_t ui32Reg; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + + // + // Determine the register to write based on the CS value supplied. + // + ui32Reg = ui32CS ? LCD_O_LIDDCS1DATA : LCD_O_LIDDCS0DATA; + + // + // Write the data value to the register. + // + HWREG(ui32Base + ui32Reg) = ui16Data; +} + +//***************************************************************************** +// +//! Writes data to a given display register when the LCD controller is in LIDD +//! mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! \param ui16Addr is the address of the display register to write. +//! \param ui16Data is the data to write. +//! +//! This function writes a 16-bit data word to a register in the display when +//! the LCD controller is in LIDD mode and configured to use either the +//! Motorola (\b LIDD_CONFIG_SYNC_MPU68 or \b LIDD_CONFIG_ASYNC_MPU68) or +//! Intel (\b LIDD_CONFIG_SYNC_MPU80 or \b LIDD_CONFIG_ASYNC_MPU80) modes +//! that employ an external address latch. +//! +//! When configured in Hitachi mode (\b LIDD_CONFIG_ASYNC_HITACHI), this +//! function should not be used. In this case the functions +//! LCDIDDCommandWrite() and LCDIDDDataWrite() may be used to transfer +//! command and data bytes to the panel. +//! +//! This function must not be called if the LIDD interface is currently +//! configured to expect DMA transactions. If DMA was previously used to +//! write to the panel, LCDIDDDMADisable() must be called before this function +//! can be used. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIDDIndexedWrite(uint32_t ui32Base, uint32_t ui32CS, uint16_t ui16Addr, + uint16_t ui16Data) +{ + uint32_t ui32Addr; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + + // + // Determine the address register to write. + // + ui32Addr = ui32CS ? LCD_O_LIDDCS1ADDR : LCD_O_LIDDCS0ADDR; + + // + // Write the address. + // + HWREG(ui32Base + ui32Addr) = ui16Addr; + + // + // Determine the data register to write. + // + ui32Addr = ui32CS ? LCD_O_LIDDCS1DATA : LCD_O_LIDDCS0DATA; + + // + // Write the data. + // + HWREG(ui32Base + ui32Addr) = ui16Data; +} + +//***************************************************************************** +// +//! Reads a status word from the display when the LCD controller is in LIDD +//! mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! +//! This function reads the 16-bit status word from the display when the LCD +//! controller is in LIDD mode. A status read occurs with the ALE signal +//! active. If the interface is configured in Hitachi mode (\b +//! LIDD_CONFIG_ASYNC_HITACHI), this operation corresponds to a command mode +//! read. +//! +//! This function must not be called if the LIDD interface is currently +//! configured to expect DMA transactions. If DMA was previously used to +//! write to the panel, LCDIDDDMADisable() must be called before this function +//! can be used. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return Returns the status word read from the display panel. +// +//***************************************************************************** +uint16_t +LCDIDDStatusRead(uint32_t ui32Base, uint32_t ui32CS) +{ + uint32_t ui32Reg; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + + // + // Determine the register to read based on the CS value supplied. + // + ui32Reg = ui32CS ? LCD_O_LIDDCS1ADDR : LCD_O_LIDDCS0ADDR; + + // + // Read the relevant status register. + // + return((uint16_t)HWREG(ui32Base + ui32Reg)); +} + +//***************************************************************************** +// +//! Reads a data word from the display when the LCD controller is in LIDD +//! mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! +//! This function reads the 16-bit data word from the display when the LCD +//! controller is in LIDD mode. A data read occurs with the ALE signal +//! inactive. +//! +//! This function must not be called if the LIDD interface is currently +//! configured to expect DMA transactions. If DMA was previously used to +//! write to the panel, LCDIDDDMADisable() must be called before this function +//! can be used. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return Returns the status word read from the display panel. +// +//***************************************************************************** +uint16_t +LCDIDDDataRead(uint32_t ui32Base, uint32_t ui32CS) +{ + uint32_t ui32Reg; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + + // + // Determine the register to read based on the CS value supplied. + // + ui32Reg = ui32CS ? LCD_O_LIDDCS1DATA : LCD_O_LIDDCS0DATA; + + // + // Read the relevant data register. + // + return((uint16_t)HWREG(ui32Base + ui32Reg)); +} + +//***************************************************************************** +// +//! Reads a given display register when the LCD controller is in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! \param ui16Addr is the address of the display register to read. +//! +//! This function reads a 16-bit word from a register in the display when +//! the LCD controller is in LIDD mode and configured to use either the +//! Motorola (\b LIDD_CONFIG_SYNC_MPU68 or \b LIDD_CONFIG_ASYNC_MPU68) or +//! Intel (\b LIDD_CONFIG_SYNC_MPU80 or \b LIDD_CONFIG_ASYNC_MPU80) modes +//! that employ an external address latch. +//! +//! When configured in Hitachi mode (\b LIDD_CONFIG_ASYNC_HITACHI), this +//! function should not be used. In this case, the functions +//! LCDIDDStatusRead() and LCDIDDDataRead() may be used to read status +//! and data bytes from the panel. +//! +//! This function must not be called if the LIDD interface is currently +//! configured to expect DMA transactions. If DMA was previously used to +//! write to the panel, LCDIDDDMADisable() must be called before this function +//! can be used. +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return None. +// +//***************************************************************************** +uint16_t +LCDIDDIndexedRead(uint32_t ui32Base, uint32_t ui32CS, uint16_t ui16Addr) +{ + uint32_t ui32Addr; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + + // + // Determine the address register to write. + // + ui32Addr = ui32CS ? LCD_O_LIDDCS1ADDR : LCD_O_LIDDCS0ADDR; + + // + // Write the address. + // + HWREG(ui32Base + ui32Addr) = ui16Addr; + + // + // Determine the data register to read. + // + ui32Addr = ui32CS ? LCD_O_LIDDCS1DATA : LCD_O_LIDDCS0DATA; + + // + // Return the data read. + // + return((uint16_t)HWREG(ui32Base + ui32Addr)); +} + +//***************************************************************************** +// +//! Writes a block of data to the display using DMA when the LCD controller is +//! in LIDD mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32CS specifies the chip select to use. Valid values are 0 and 1. +//! \param pui32Data is the address of the first 16-bit word to write. This +//! address must be aligned on a 32-bit word boundary. +//! \param ui32Count is the number of 16-bit words to write. This value must +//! be a multiple of 2. +//! +//! This function writes a block of 16-bit data words to the display using +//! DMA. It is only valid when the LCD controller is in LIDD mode. +//! Completion of the DMA transfer is signaled by the \b +//! LCD_INT_DMA_DONE interrupt. +//! +//! This function enables DMA mode prior to starting the transfer. The +//! caller is responsible for ensuring that any earlier DMA transfer has +//! completed before initiating another transfer. +//! +//! During the time that DMA is enabled, none of the other LCD LIDD data +//! transfer functions may be called. When the DMA transfer is complete and +//! the application wishes to use the CPU to communicate with the display, +//! LCDIDDDMADisable() must be called to disable DMA access prior to calling +//! LCDIDDCommandWrite(), LCDIDDDataWrite(), LCDIDDStatusRead(), +//! LCDIDDIndexedWrite(), LCDIDDIndexedRead() or LCDIDDDataRead(). +//! +//! \note CS1 is not available when operating in Sync MPU68 or Sync MPU80 +//! modes. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIDDDMAWrite(uint32_t ui32Base, uint32_t ui32CS, const uint32_t *pui32Data, + uint32_t ui32Count) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32CS == 0) || (ui32CS == 1)); + ASSERT(!((uint32_t)pui32Data & 3)); + ASSERT(!(ui32Count & 1)); + + // + // Make sure DMA is disabled so that enabling it triggers this new + // transfer. + // + HWREG(ui32Base + LCD_O_LIDDCTL) &= ~LCD_LIDDCTL_DMAEN; + + // + // Set up the transfer. Note that the ceiling register must contain the + // address of the last word which contains data we want transfered and NOT + // the first location after the data we want written. + // + HWREG(ui32Base + LCD_O_DMABAFB0) = (uint32_t)pui32Data; + HWREG(ui32Base + LCD_O_DMACAFB0) = ((uint32_t)pui32Data + + (ui32Count * 2) - 4); + + // + // Tell the controller which CS to use for the DMA transaction. + // + if(!ui32CS) + { + // + // Use CS0. + // + HWREG(ui32Base + LCD_O_LIDDCTL) &= ~LCD_LIDDCTL_DMACS; + } + else + { + // + // Use CS1. + // + HWREG(ui32Base + LCD_O_LIDDCTL) |= LCD_LIDDCTL_DMACS; + } + + // + // Enable the DMA engine and start the transaction. + // + HWREG(ui32Base + LCD_O_LIDDCTL) |= LCD_LIDDCTL_DMAEN; +} + +//***************************************************************************** +// +//! Sets the LCD controller interface timing when in raster mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param ui32Config specifies properties of the raster interface and the +//! attached display panel. +//! \param ui8PalLoadDelay specifies the number of system clocks to wait +//! between each 16 halfword (16-bit) burst when loading the palette from +//! SRAM into the internal palette RAM of the controller. +//! +//! This function configures the basic operating mode of the raster interface +//! and specifies the type of panel that the controller is to drive. +//! +//! The \e ui32Config parameter must be defined as one of the following to +//! select the required target panel type and output pixel format: +//! +//! - \b RASTER_FMT_ACTIVE_24BPP_PACKED selects an active matrix display +//! and uses a packed 24-bit per pixel packet frame buffer where 4 pixels +//! are described within 3 consecutive 32-bit words. +//! - \b RASTER_FMT_ACTIVE_24BPP_UNPACKED selects an active matrix display +//! and uses an unpacked 24-bit per pixel packet frame buffer where each +//! 32-bit word contains a single pixel and 8 bits of padding. +//! - \b RASTER_FMT_ACTIVE_16BPP selects an active matrix display +//! and uses a 16-bit per pixel frame buffer with 2 pixels in each 32-bit +//! word. +//! - \b RASTER_FMT_ACTIVE_PALETTIZED_12BIT selects an active matrix display +//! and uses a 1, 2, 4 or 8bpp frame buffer with palette lookup. Output color +//! data is described in 12-bit format using bits 11:0 of the data bus. The +//! frame buffer pixel format is defined by the value passed in the \e ui32Type +//! parameter to LCDRasterPaletteSet(). +//! - \b RASTER_FMT_ACTIVE_PALETTIZED_16BIT selects an active matrix display +//! and uses a 1, 2, 4 or 8bpp frame buffer with palette lookup. Output color +//! data is described in 16-bit 5:6:5 format. The frame buffer pixel format is +//! defined by the value passed in the \e ui32Type parameter to +//! LCDRasterPaletteSet(). +//! - \b RASTER_FMT_PASSIVE_MONO_4PIX selects a monochrome, passive matrix +//! display that outputs 4 pixels on each pixel clock. +//! - \b RASTER_FMT_PASSIVE_MONO_8PIX selects a monochrome, passive matrix +//! display that outputs 8 pixels on each pixel clock. +//! - \b RASTER_FMT_PASSIVE_COLOR_12BIT selects a passive matrix display +//! and uses a 12bpp frame buffer. The palette is bypassed and 12-bit pixel +//! data is sent to the grayscaler for the display. +//! - \b RASTER_FMT_PASSIVE_COLOR_16BIT selects a passive matrix display +//! and uses a 16bpp frame buffer with pixels in 5:6:5 format. Only the 4 +//! most significant bits of each color component are sent to the grayscaler +//! for the display. +//! +//! Additionally, the following flags may be ORed into \e ui32Config: +//! +//! - \b RASTER_ACTVID_DURING_BLANK sets Actvid to toggle during vertical +//! blanking. +//! - \b RASTER_NIBBLE_MODE_ENABLED enables nibble mode. This parameter works +//! with \b RASTER_READ_ORDER_REVERSED to determine how 1, 2 and 4bpp pixels +//! are extracted from words read from the frame buffer. If specified, words +//! read from the frame buffer are byte swapped prior to individual pixels +//! being parsed from them. +//! - \b RASTER_LOAD_DATA_ONLY tells the controller to read only pixel data +//! from the frame buffer and to use the last palette read. No palette load +//! is performed. +//! - \b RASTER_LOAD_PALETTE_ONLY tells the controller to read only the palette +//! data from the frame buffer. +//! - \b RASTER_READ_ORDER_REVERSED when using 1, 2, 4 and 8bpp frame buffers, +//! this option reverses the order in which frame buffer words are parsed. +//! When this option is specified, the leftmost pixel in a word is taken from +//! the most significant bits. When absent, the leftmost pixel is parsed from +//! the least significant bits. +//! +//! If the LCD controller's raster engine is enabled when this function is +//! called, it is disabled as a result of the call. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterConfigSet(uint32_t ui32Base, uint32_t ui32Config, + uint8_t ui8PalLoadDelay) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32Config & ~(RASTER_FMT_ACTIVE_24BPP_PACKED | + RASTER_FMT_ACTIVE_24BPP_UNPACKED | + RASTER_FMT_ACTIVE_PALETTIZED_12BIT | + RASTER_FMT_ACTIVE_PALETTIZED_16BIT | + RASTER_FMT_PASSIVE_MONO_4PIX | + RASTER_FMT_PASSIVE_MONO_8PIX | + RASTER_FMT_PASSIVE_PALETTIZED | + RASTER_FMT_PASSIVE_COLOR_12BIT | + RASTER_FMT_PASSIVE_COLOR_16BIT | + RASTER_ACTVID_DURING_BLANK | + RASTER_NIBBLE_MODE_ENABLED | + RASTER_LOAD_DATA_ONLY | + RASTER_LOAD_PALETTE_ONLY | + RASTER_READ_ORDER_REVERSED))); + + // + // Write the raster control register. + // + HWREG(ui32Base + LCD_O_RASTRCTL) = (ui32Config | + ((uint32_t)ui8PalLoadDelay << + LCD_RASTRCTL_REQDLY_S)); +} + +//***************************************************************************** +// +//! Sets the LCD controller interface timing when in raster mode. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param pTiming points to a structure containing the desired timing +//! parameters. +//! +//! This function is used in raster mode to set the panel size and sync timing +//! parameters. +//! +//! For a definition of the timing parameters required, see the definition of +//! tLCDRasterTiming. +//! +//! \return None +// +//***************************************************************************** +void +LCDRasterTimingSet(uint32_t ui32Base, const tLCDRasterTiming *pTiming) +{ + uint32_t ui32T0, ui32T1, ui32T2; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(pTiming); + ASSERT(!(pTiming->ui32Flags & ~(RASTER_TIMING_SYNCS_OPPOSITE_PIXCLK | + RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK | + RASTER_TIMING_SYNCS_ON_RISING_PIXCLK | + RASTER_TIMING_ACTIVE_LOW_OE | + RASTER_TIMING_ACTIVE_LOW_PIXCLK | + RASTER_TIMING_ACTIVE_LOW_HSYNC | + RASTER_TIMING_ACTIVE_LOW_VSYNC))); + ASSERT(pTiming->ui16PanelWidth && (pTiming->ui16PanelWidth <= 2048) && + ((pTiming->ui16PanelWidth % 16) == 0)); + ASSERT(pTiming->ui16PanelHeight && (pTiming->ui16PanelHeight <= 2048)); + ASSERT(pTiming->ui16HFrontPorch && (pTiming->ui16HFrontPorch <= 1024)); + ASSERT(pTiming->ui16HBackPorch && (pTiming->ui16HBackPorch <= 1024)); + ASSERT(pTiming->ui16HSyncWidth && (pTiming->ui16HSyncWidth <= 1024)); + ASSERT(pTiming->ui8VSyncWidth && (pTiming->ui8VSyncWidth <= 64)); + + // + // Construct the values we need for the three raster timing registers. + // + ui32T0 = ((uint32_t)((pTiming->ui16HBackPorch - 1) & 0xFF) << + LCD_RASTRTIM0_HBP_S) | + ((uint32_t)((pTiming->ui16HFrontPorch - 1) & 0xFF) << + LCD_RASTRTIM0_HFP_S) | + ((uint32_t)((pTiming->ui16HSyncWidth - 1) & 0x3F) << + LCD_RASTRTIM0_HSW_S) | + (((uint32_t)((pTiming->ui16PanelWidth - 1) & 0x3F0) >> 4) << + LCD_RASTRTIM0_PPL_S) | + (((uint32_t)((pTiming->ui16PanelWidth - 1) & 0x400) >> 10) << + LCD_RASTRTIM0_MSBPPL_S); + ui32T1 = ((uint32_t)pTiming->ui8VBackPorch << LCD_RASTRTIM1_VBP_S) | + ((uint32_t)pTiming->ui8VFrontPorch << LCD_RASTRTIM1_VFP_S) | + ((uint32_t)((pTiming->ui8VSyncWidth - 1) & 0x3F) << + LCD_RASTRTIM1_VSW_S) | + ((uint32_t)(pTiming->ui16PanelHeight - 1) & 0x3FF) << + LCD_RASTRTIM1_LPP_S; + ui32T2 = pTiming->ui32Flags | + ((((pTiming->ui16HSyncWidth - 1) & 0x3C0) >> 6) << + LCD_RASTRTIM2_HSW_S) | + ((((pTiming->ui16PanelHeight - 1) & 0x400) >> 10) << + LCD_RASTRTIM2_MSBLPP_S) | + ((((pTiming->ui16HBackPorch - 1) & 0x300) >> 8) << + LCD_RASTRTIM2_MSBHBP_S) | + ((((pTiming->ui16HFrontPorch - 1) & 0x300) >> 8) << + LCD_RASTRTIM2_MSBHFP_S) | + (pTiming->ui8ACBiasLineCount << LCD_RASTRTIM2_ACBF_S); + + // + // Write the timing registers, taking care to preserve any existing value + // in the AC Bias interrupt field of RASTRTIM2. + // + HWREG(ui32Base + LCD_O_RASTRTIM0) = ui32T0; + HWREG(ui32Base + LCD_O_RASTRTIM1) = ui32T1; + HWREG(ui32Base + LCD_O_RASTRTIM2) = (HWREG(ui32Base + LCD_O_RASTRTIM2) & + LCD_RASTRTIM2_ACBI_M) | ui32T2; +} + +//***************************************************************************** +// +//! Sets the number of AC bias pin transitions per interrupt. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui8Count is the number of AC bias pin transitions to count before +//! the AC bias count interrupt is asserted. Valid values are from 0 to 15. +//! +//! This function is used to set the number of AC bias transitions between +//! each AC bias count interrupt (\b LCD_INT_AC_BIAS_CNT). If \e ui8Count is +//! 0, no AC bias count interrupt is generated. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterACBiasIntCountSet(uint32_t ui32Base, uint8_t ui8Count) +{ + uint32_t ui32Val; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(ui8Count < 16); + + // + // Get the existing raster timing 2 register value and mask in the new + // AC Bias interrupt count. + // + ui32Val = HWREG(ui32Base + LCD_O_RASTRTIM2); + ui32Val &= ~LCD_RASTRTIM2_ACBI_M; + ui32Val |= ((ui8Count << LCD_RASTRTIM2_ACBI_S) & LCD_RASTRTIM2_ACBI_M); + + // + // Write the new value back to the register. + // + HWREG(ui32Base + LCD_O_RASTRTIM2) = ui32Val; +} + +//***************************************************************************** +// +//! Enables the raster output. +//! +//! \param ui32Base is the base address of the controller. +//! +//! This function enables the LCD controller raster output and starts +//! displaying the content of the current frame buffer on the attached panel. +//! Prior to enabling the raster output, LCDModeSet(), LCDRasterConfigSet(), +//! LCDDMAConfigSet(), LCDRasterTimingSet(), LCDRasterPaletteSet() and +//! LCDRasterFrameBufferSet() must have been called. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterEnable(uint32_t ui32Base) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Reset the module prior to starting the raster. This is required to + // ensure correct operation of the raster engine. + // + LCDClockReset(ui32Base, LCD_CLOCK_MAIN); + + // + // Enable the raster engine. + // + HWREG(ui32Base + LCD_O_RASTRCTL) |= LCD_RASTRCTL_LCDEN; +} + +//***************************************************************************** +// +//! Determines whether or not the raster output is currently enabled. +//! +//! \param ui32Base is the base address of the controller. +//! +//! This function may be used to query whether or not the raster output is +//! currently enabled. +//! +//! \return Returns \b true if the raster is enabled or \b false if it is +//! disabled. +// +//***************************************************************************** +bool +LCDRasterEnabled(uint32_t ui32Base) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Return the current raster engine status. + // + return((HWREG(ui32Base + LCD_O_RASTRCTL) & LCD_RASTRCTL_LCDEN) ? + true : false); +} + +//***************************************************************************** +// +//! Disables the raster output. +//! +//! \param ui32Base is the base address of the controller. +//! +//! This function disables the LCD controller raster output and stops driving +//! the attached display. +//! +//! \note Once disabled, the raster engine continues to scan data until the +//! end of the current frame. If the display is to be re-enabled, wait until +//! after the final \b LCD_INT_RASTER_FRAME_DONE has been received, indicating +//! that the raster engine has stopped. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterDisable(uint32_t ui32Base) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Disable the raster engine. + // + HWREG(ui32Base + LCD_O_RASTRCTL) &= ~LCD_RASTRCTL_LCDEN; +} + +//***************************************************************************** +// +//! Sets the position and size of the subpanel on the raster display. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui32Flags may be either \b LCD_SUBPANEL_AT_TOP to show frame buffer +//! image data in the top portion of the display and default color in the +//! bottom portion, or \b LCD_SUBPANEL_AT_BOTTOM to show image data at the +//! bottom of the display and default color at the top. +//! \param ui32BottomLines defines the number of lines comprising the bottom +//! portion of the display. If \b LCD_SUBPANEL_AT_TOP is set in \e ui32Flags, +//! these lines contain the default pixel color when the subpanel is +//! enabled, otherwise they contain image data. +//! \param ui32DefaultPixel is the 24-bit RGB color to show in the portion of +//! the display not configured to show image data. +//! +//! The LCD controller provides a feature that allows a portion of the display +//! to be filled with a default color rather than image data from the frame +//! buffer. This feature reduces SRAM bandwidth requirements because no data +//! is fetched for lines containing the default color. This feature is only +//! available when the LCD controller is in raster mode and configured to drive +//! an active matrix display. +//! +//! The subpanel area containing image data from the frame buffer may be +//! positioned either at the top or bottom of the display as controlled by +//! the value of \e ui32Flags. The height of the bottom portion of the display +//! is defined by \e ui32BottomLines. +//! +//! When a subpanel is configured, the application must also reconfigure the +//! frame buffer to ensure that it contains the correct number of lines for +//! the subpanel size in use. This configuration can be achieved by calling +//! LCDRasterFrameBufferSet() with the \e ui32NumBytes parameter set +//! appropriately to describe the required number of active video lines in +//! the subpanel area. +//! +//! The subpanel display mode is not enabled using this function. To enable +//! the subpanel once it has been configured, call LCDRasterSubPanelEnable(). +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterSubPanelConfigSet(uint32_t ui32Base, uint32_t ui32Flags, + uint32_t ui32BottomLines, uint32_t ui32DefaultPixel) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT((ui32Flags == LCD_SUBPANEL_AT_TOP) || + (ui32Flags == LCD_SUBPANEL_AT_BOTTOM)); + ASSERT(ui32BottomLines && (ui32BottomLines <= 2048)); + + // + // Adjust the line count into the 0-2047 range. + // + ui32BottomLines--; + + // + // Set the first subpanel configuration register, taking care to leave the + // subpanel enabled if it already was. + // + HWREG(ui32Base + LCD_O_RASTRSUBP1) = (HWREG(ui32Base + LCD_O_RASTRSUBP1) & + LCD_RASTRSUBP1_SPEN) | ui32Flags | + ((ui32DefaultPixel & 0xFFFF) << + LCD_RASTRSUBP1_DPDLSB_S) | + ((ui32BottomLines << + LCD_RASTRSUBP1_LPPT_S) & + LCD_RASTRSUBP1_LPPT_M); + + // + // Set the second subpanel configuration register. + // + HWREG(ui32Base + LCD_O_RASTRSUBP2) = + ((ui32DefaultPixel >> 16) & LCD_RASTRSUBP2_DPDMSB_M) | + (((ui32BottomLines >> LCD_RASTRSUBP1_LPPT_S) & 1) << 8); +} + +//***************************************************************************** +// +//! Enables subpanel display mode. +//! +//! \param ui32Base is the base address of the controller. +//! +//! This function enables subpanel display mode and displays a default color +//! rather than image data in the number of lines and at the position specified +//! by a previous call to LCDRasterSubPanelConfigSet(). Prior to calling +//! LCDRasterSubPanelEnable(), the frame buffer should have been reconfigured +//! to match the desired subpanel size using a call to +//! LCDRasterFrameBufferSet(). +//! +//! Subpanel display is only possible when the LCD controller is in raster +//! mode and is configured to drive an active matrix display. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterSubPanelEnable(uint32_t ui32Base) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Enable the subpanel. + // + HWREG(ui32Base + LCD_O_RASTRSUBP1) |= LCD_RASTRSUBP1_SPEN; +} + +//***************************************************************************** +// +//! Disables subpanel display mode. +//! +//! \param ui32Base is the base address of the controller. +//! +//! This function disables subpanel display mode and reverts to showing the +//! entire frame buffer image on the display. After the subpanel is disabled, +//! the frame buffer size must be reconfigured to match the full dimensions of +//! the display area by calling LCDRasterFrameBufferSet() with an appropriate +//! value for the \e ui32NumBytes parameter. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterSubPanelDisable(uint32_t ui32Base) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Disable the subpanel. + // + HWREG(ui32Base + LCD_O_RASTRSUBP1) &= ~LCD_RASTRSUBP1_SPEN; +} + +//***************************************************************************** +// +//! Configures the LCD controller's internal DMA engine. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui32Config provides flags defining the desired DMA parameters. +//! +//! This function is used to configure the DMA engine within the LCD +//! controller. This engine is responsible for performing bulk data transfers +//! to the display when in LIDD mode or for transferring palette and pixel data +//! from SRAM to the display panel when in raster mode. +//! +//! The \e ui32Config parameter is a logical OR of various flags. It must +//! contain one value from each of the following groups. +//! +//! The first group of flags set the number of words that have to be in the +//! FIFO before it signals that it is ready: +//! +//! - \b LCD_DMA_FIFORDY_8_WORDS +//! - \b LCD_DMA_FIFORDY_16_WORDS +//! - \b LCD_DMA_FIFORDY_32_WORDS +//! - \b LCD_DMA_FIFORDY_64_WORDS +//! - \b LCD_DMA_FIFORDY_128_WORDS +//! - \b LCD_DMA_FIFORDY_256_WORDS +//! - \b LCD_DMA_FIFORDY_512_WORDS +//! +//! The second group of flags set the number of 32-bit words in each DMA burst +//! transfer: +//! +//! - \b LCD_DMA_BURST_1 +//! - \b LCD_DMA_BURST_2 +//! - \b LCD_DMA_BURST_4 +//! - \b LCD_DMA_BURST_8 +//! - \b LCD_DMA_BURST_16 +//! +//! The final group of flags set internal byte lane controls and allow byte +//! swapping within the DMA engine. The label represents the output byte order +//! for an input 32-bit word ordered ``0123''. +//! +//! - \b LCD_DMA_BYTE_ORDER_0123 +//! - \b LCD_DMA_BYTE_ORDER_1023 +//! - \b LCD_DMA_BYTE_ORDER_3210 +//! - \b LCD_DMA_BYTE_ORDER_2301 +//! +//! Additionally, \b LCD_DMA_PING_PONG may be specified. This flag configures +//! the controller to operate in double-buffered mode. When data is scanned +//! out from the first frame buffer, the DMA engine immediately moves to +//! the second frame buffer and scans from there before moving back to the +//! first. If this flag is clear, the DMA engine uses a single frame buffer, +//! restarting the scan from the beginning of the buffer each time it completes +//! a frame. +//! +//! \note DMA burst size \b LCD_DMA_BURST_16 should be set when using frame +//! buffers in external, EPI-connected memory. Using a smaller burst size in +//! this case is likely to result in occasional FIFO underflows and associated +//! display glitches. +//! +//! \return None. +// +//***************************************************************************** +void +LCDDMAConfigSet(uint32_t ui32Base, uint32_t ui32Config) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32Config & ~(LCD_DMACTL_FIFORDY_M | LCD_DMACTL_BURSTSZ_M | + LCD_DMACTL_BYTESWAP | LCD_DMACTL_BIGDEND | + LCD_DMACTL_FMODE))); + + // + // Write the DMA control register. + // + HWREG(ui32Base + LCD_O_DMACTL) = ui32Config; +} + +//***************************************************************************** +// +//! Initializes the color palette in a frame buffer. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui32Type specifies the type of pixel data to be held in the frame +//! buffer and also the format of the source color values passed. +//! \param pui32Addr points to the start of the frame buffer into which the +//! palette information is to be written. +//! \param pui32SrcColors points to the first color value that is to be +//! written into the frame buffer palette. +//! \param ui32Start specifies the index of the first color in the palette +//! to update. +//! \param ui32Count specifies the number of source colors to be copied into +//! the frame buffer palette. +//! +//! This function is used to initialize the color palette stored at the +//! beginning of a frame buffer. It writes the relevant pixel type into the +//! first entry of the frame buffer and copies the requested number of colors +//! from a source buffer into the palette starting at the required index, +//! optionally converting them from 24-bit color format into the 12-bit format +//! used by the LCD controller. +//! +//! \e ui32Type must be set to one of the following values to indicate the +//! type of frame buffer for which the palette is being initialized: +//! +//! - \b LCD_PALETTE_TYPE_1BPP indicates a 1 bit per pixel +//! (monochrome) frame buffer. This format requires a 2 entry palette. +//! - \b LCD_PALETTE_TYPE_2BPP indicates a 2 bit per pixel frame +//! buffer. This format requires a 4 entry palette. +//! - \b LCD_PALETTE_TYPE_4BPP indicates a 4 bit per pixel frame +//! buffer. This format requires a 4 entry palette. +//! - \b LCD_PALETTE_TYPE_8BPP indicates an 8 bit per pixel frame +//! buffer. This format requires a 256 entry palette. +//! - \b LCD_PALETTE_TYPE_DIRECT indicates a direct color (12, 16 or +//! 24 bit per pixel). The color palette is not used in these modes, but the +//! frame buffer type must still be initialized to ensure that the hardware +//! uses the correct pixel type. When this value is used, the format of the +//! pixels in the frame buffer is defined by the \e ui32Config parameter +//! previously passed to LCDRasterConfigSet(). +//! +//! Optionally, the \b LCD_PALETTE_SRC_24BIT flag may be ORed into \e ui32Type +//! to indicate that the supplied colors in the \e pui32SrcColors array are in +//! the 24-bit format as used by the TivaWare Graphics Library with one color +//! stored in each 32-bit word. In this case, the colors read from the source +//! array are converted to the 12-bit format used by the LCD controller before +//! being written into the frame buffer palette. +//! +//! If \b LCD_PALETTE_SRC_24BIT is not present, it is assumed that the +//! \e pui32SrcColors array contains 12-bit colors in the format required by +//! the LCD controller with 2 colors stored in each 32-bit word. In this case, +//! the values are copied directly into the frame buffer palette without any +//! reformatting. +//! +//! \return None. +// +//***************************************************************************** +void +LCDRasterPaletteSet(uint32_t ui32Base, uint32_t ui32Type, uint32_t *pui32Addr, + const uint32_t *pui32SrcColors, uint32_t ui32Start, + uint32_t ui32Count) +{ + uint16_t *pui16Pal; + uint16_t *pui16Src; + uint32_t ui32Loop; + + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(ui32Start < 256); + ASSERT((ui32Start + ui32Count) <= 256); + ASSERT(pui32Addr); + ASSERT((pui32SrcColors) || (ui32Count == 0)); + ASSERT(!(ui32Type & ~(LCD_PALETTE_SRC_24BIT | LCD_PALETTE_TYPE_DIRECT | + LCD_PALETTE_TYPE_8BPP | LCD_PALETTE_TYPE_4BPP | + LCD_PALETTE_TYPE_2BPP | LCD_PALETTE_TYPE_1BPP))); + + // + // Get a pointer to the start of the palette. + // + pui16Pal = (uint16_t *)pui32Addr; + + // + // Are we converting the palette color format? + // + if(ui32Type & LCD_PALETTE_SRC_24BIT) + { + // + // Yes - loop through each of the supplied 24-bit colors converting + // and storing each. + // + ui32Loop = 0; + while(ui32Count) + { + pui16Pal[ui32Start + ui32Loop] = + PAL_FROM_RGB(pui32SrcColors[ui32Loop]); + ui32Loop++; + ui32Count--; + } + } + else + { + // + // No - loop through the supplied 12-bit colors storing each. + // + + pui16Src = (uint16_t *)pui32SrcColors; + while(ui32Count) + { + pui16Pal[ui32Start] = pui16Src[ui32Start]; + ui32Start++; + ui32Count--; + } + } + + // + // Write the pixel type into the first palette entry. + // + pui16Pal[0] &= ~(LCD_PALETTE_TYPE_8BPP | LCD_PALETTE_TYPE_DIRECT); + pui16Pal[0] |= (ui32Type & ~LCD_PALETTE_SRC_24BIT); +} + +//***************************************************************************** +// +//! Sets the LCD controller frame buffer start address and size in raster mode. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui8Buffer specifies which frame buffer to configure. Valid values +//! are 0 and 1. +//! \param pui32Addr points to the first byte of the frame buffer. This +//! pointer must be aligned on a 32-bit (word) boundary. +//! \param ui32NumBytes specifies the size of the frame buffer in bytes. This +//! value must be a multiple of 4. +//! +//! This function is used to configure the position and size of one of the +//! two supported frame buffers while in raster mode. The second frame buffer +//! (configured when ui8Buffer is set to 1) is only used if the controller +//! is set to operate in ping-pong mode (by specifying the \b LCD_DMA_PING_PONG +//! configuration flag on a call to LCDDMAConfigSet()). +//! +//! The format of the frame buffer depends on the image type in use and +//! the current raster configuration settings. If \b RASTER_LOAD_DATA_ONLY +//! was specified in a previous call to LCDRasterConfigSet(), the frame buffer +//! contains only packed pixel data in the required bit depth and format. +//! In other cases, the frame buffer comprises a palette of either 8 or 128 +//! 32-bit words followed by the packed pixel data. The palette size is 8 +//! words (16 16-bit entries) for all pixel formats other than 8bpp which +//! uses a palette of 128 words (256 16-bit entries). Note that the 8 word +//! palette is still present even for 12, 16 and 24-bit formats, which do not +//! use the lookup table. +//! +//! The frame buffer size, specified using the \e ui32NumBytes parameter, must +//! be the palette size (if any) plus the size of the image bitmap required +//! for the currently configured display resolution. +//! +//! \e ui32NumBytes = (Palette Size) + ((Width * Height) * BPP) / 8) +//! +//! If \b RASTER_LOAD_DATA_ONLY is not specified, frame buffers passed to this +//! function must be initialized using a call to LCDRasterPaletteSet() prior to +//! enabling the raster output. If this is not done, the pixel format +//! identifier and color table required by the hardware is not present +//! and the results are unpredictable. +//! +//! \return None. +//***************************************************************************** +void +LCDRasterFrameBufferSet(uint32_t ui32Base, uint8_t ui8Buffer, + uint32_t *pui32Addr, uint32_t ui32NumBytes) +{ + // + // Sanity check parameters. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!((uint32_t)pui32Addr & 3)); + ASSERT(!(ui32NumBytes & 3)); + ASSERT(ui8Buffer < 2); + + // + // Are we setting the values for frame buffer 0? + // + if(!ui8Buffer) + { + // + // Yes - set the registers for frame buffer 0. + // + HWREG(ui32Base + LCD_O_DMABAFB0) = (uint32_t)pui32Addr; + HWREG(ui32Base + LCD_O_DMACAFB0) = (uint32_t)pui32Addr + + ui32NumBytes - 4; + } + else + { + // + // No - set the registers for frame buffer 1. + // + HWREG(ui32Base + LCD_O_DMABAFB1) = (uint32_t)pui32Addr; + HWREG(ui32Base + LCD_O_DMACAFB1) = (uint32_t)pui32Addr + + ui32NumBytes - 4; + } +} + +//***************************************************************************** +// +//! Enables individual LCD controller interrupt sources. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui32IntFlags is the bit mask of the interrupt sources to be enabled. +//! +//! This function enables the indicated LCD controller interrupt sources. +//! Only the sources that are enabled can be reflected to the processor +//! interrupt; disabled sources have no effect on the processor. +//! +//! The \e ui32IntFlags parameter is the logical OR of any of the following: +//! +//! - \b LCD_INT_DMA_DONE - indicates that a LIDD DMA transfer is complete. +//! - \b LCD_INT_RASTER_FRAME_DONE - indicates that a raster-mode frame is +//! complete. +//! - \b LCD_INT_SYNC_LOST - indicates that frame synchronization was lost. +//! - \b LCD_INT_AC_BIAS_CNT - indicates that that AC bias transition counter +//! has decremented to zero and is is valid for passive matrix panels only. +//! The counter, set by a call to LCDRasterACBiasIntCountSet(), is reloaded +//! but remains disabled until this interrupt is cleared. +//! - \b LCD_INT_UNDERFLOW - indicates that a data underflow occurred. The +//! internal FIFO was empty when the output logic attempted to read data to +//! send to the display. +//! - \b LCD_INT_PAL_LOAD - indicates that the color palette has been loaded. +//! - \b LCD_INT_EOF0 - indicates that the raw End-of-Frame 0 has been +//! signaled. +//! - \b LCD_INT_EOF2 - indicates that the raw End-of-Frame 1 has been +//! signaled. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIntEnable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32IntFlags & ~(LCD_INT_DMA_DONE | LCD_INT_SYNC_LOST | + LCD_INT_AC_BIAS_CNT | LCD_INT_UNDERFLOW | + LCD_INT_PAL_LOAD | LCD_INT_EOF0 | LCD_INT_EOF1 | + LCD_INT_RASTER_FRAME_DONE))); + + // + // Enable the interrupt sources by setting the appropriate bits in the + // mask register. + // + HWREG(ui32Base + LCD_O_IM) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Disables individual LCD controller interrupt sources. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui32IntFlags is the bit mask of the interrupt sources to be +//! disabled. +//! +//! This function disables the indicated LCD controller interrupt sources. +//! Only the sources that are enabled can be reflected to the processor +//! interrupt; disabled sources have no effect on the processor. +//! +//! The \e ui32IntFlags parameter is the logical OR of any of the following: +//! +//! - \b LCD_INT_DMA_DONE - indicates that a LIDD DMA transfer is complete. +//! - \b LCD_INT_RASTER_FRAME_DONE - indicates that a raster-mode frame is +//! complete. +//! - \b LCD_INT_SYNC_LOST - indicates that frame synchronization was lost. +//! - \b LCD_INT_AC_BIAS_CNT - indicates that that AC bias transition counter +//! has decremented to zero and is is valid for passive matrix panels only. +//! The counter, set by a call to LCDRasterACBiasIntCountSet(), is reloaded +//! but remains disabled until this interrupt is cleared. +//! - \b LCD_INT_UNDERFLOW - indicates that a data underflow occurred. The +//! internal FIFO was empty when the output logic attempted to read data to +//! send to the display. +//! - \b LCD_INT_PAL_LOAD - indicates that the color palette has been loaded. +//! - \b LCD_INT_EOF0 - indicates that the raw End-of-Frame 0 has been +//! signaled. +//! - \b LCD_INT_EOF2 - indicates that the raw End-of-Frame 1 has been +//! signaled. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIntDisable(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32IntFlags & ~(LCD_INT_DMA_DONE | LCD_INT_SYNC_LOST | + LCD_INT_AC_BIAS_CNT | LCD_INT_UNDERFLOW | + LCD_INT_PAL_LOAD | LCD_INT_EOF0 | LCD_INT_EOF1 | + LCD_INT_RASTER_FRAME_DONE))); + + // + // Disable the interrupt sources by clearing the appropriate bits in the + // mask register. + // + HWREG(ui32Base + LCD_O_IENC) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Gets the current LCD controller interrupt status. +//! +//! \param ui32Base is the base address of the controller. +//! \param bMasked is false if the raw interrupt status is required and true +//! if the masked interrupt status is required. +//! +//! This function returns the interrupt status for the LCD controller. +//! Either the raw interrupt status or the status of interrupts that are +//! allowed to reflect to the processor can be returned. +//! +//! \return Returns the current interrupt status as the logical OR of any of +//! the following: +//! +//! - \b LCD_INT_DMA_DONE - indicates that a LIDD DMA transfer is complete. +//! - \b LCD_INT_RASTER_FRAME_DONE - indicates that a raster-mode frame is +//! complete. +//! - \b LCD_INT_SYNC_LOST - indicates that frame synchronization was lost. +//! - \b LCD_INT_AC_BIAS_CNT - indicates that that AC bias transition counter +//! has decremented to zero and is is valid for passive matrix panels only. +//! The counter, set by a call to LCDRasterACBiasIntCountSet(), is reloaded +//! but remains disabled until this interrupt is cleared. +//! - \b LCD_INT_UNDERFLOW - indicates that a data underflow occurred. The +//! internal FIFO was empty when the output logic attempted to read data to +//! send to the display. +//! - \b LCD_INT_PAL_LOAD - indicates that the color palette has been loaded. +//! - \b LCD_INT_EOF0 - indicates that the raw End-of-Frame 0 has been +//! signaled. +//! - \b LCD_INT_EOF2 - indicates that the raw End-of-Frame 1 has been +//! signaled. +// +//***************************************************************************** +uint32_t +LCDIntStatus(uint32_t ui32Base, bool bMasked) +{ + ASSERT(ui32Base == LCD0_BASE); + + // + // Were we asked for the masked or raw interrupt status? + // + if(bMasked) + { + // + // Return the masked interrupt status. + // + return(HWREG(ui32Base + LCD_O_MISCLR)); + } + else + { + // + // Return the raw interrupts status. + // + return(HWREG(ui32Base + LCD_O_RISSET)); + } +} + +//***************************************************************************** +// +//! Clears LCD controller interrupt sources. +//! +//! \param ui32Base is the base address of the controller. +//! \param ui32IntFlags is a bit mask of the interrupt sources to be cleared. +//! +//! The specified LCD controller interrupt sources are cleared so that they no +//! longer assert. This function must be called in the interrupt handler to +//! keep the interrupt from being triggered again immediately upon exit. +//! +//! The \e ui32IntFlags parameter is the logical OR of any of the following: +//! +//! - \b LCD_INT_DMA_DONE - indicates that a LIDD DMA transfer is complete. +//! - \b LCD_INT_RASTER_FRAME_DONE - indicates that a raster-mode frame is +//! complete. +//! - \b LCD_INT_SYNC_LOST - indicates that frame synchronization was lost. +//! - \b LCD_INT_AC_BIAS_CNT - indicates that that AC bias transition counter +//! has decremented to zero and is is valid for passive matrix panels only. +//! The counter, set by a call to LCDRasterACBiasIntCountSet(), is reloaded +//! but remains disabled until this interrupt is cleared. +//! - \b LCD_INT_UNDERFLOW - indicates that a data underflow occurred. The +//! internal FIFO was empty when the output logic attempted to read data to +//! send to the display. +//! - \b LCD_INT_PAL_LOAD - indicates that the color palette has been loaded. +//! - \b LCD_INT_EOF0 - indicates that the raw End-of-Frame 0 has been +//! signaled. +//! - \b LCD_INT_EOF2 - indicates that the raw End-of-Frame 1 has been +//! signaled. +//! +//! \note Because there is a write buffer in the Cortex-M processor, it may +//! take several clock cycles before the interrupt source is actually cleared. +//! Therefore, it is recommended that the interrupt source be cleared early in +//! the interrupt handler (as opposed to the very last action) to avoid +//! returning from the interrupt handler before the interrupt source is +//! actually cleared. Failure to do so may result in the interrupt handler +//! being immediately reentered (because the interrupt controller still sees +//! the interrupt source asserted). +//! +//! \return None. +// +//***************************************************************************** +void +LCDIntClear(uint32_t ui32Base, uint32_t ui32IntFlags) +{ + ASSERT(ui32Base == LCD0_BASE); + ASSERT(!(ui32IntFlags & ~(LCD_INT_DMA_DONE | LCD_INT_SYNC_LOST | + LCD_INT_AC_BIAS_CNT | LCD_INT_UNDERFLOW | + LCD_INT_PAL_LOAD | LCD_INT_EOF0 | LCD_INT_EOF1 | + LCD_INT_RASTER_FRAME_DONE))); + + // + // Clear the requested interrupts. + // + HWREG(ui32Base + LCD_O_MISCLR) = ui32IntFlags; +} + +//***************************************************************************** +// +//! Registers an interrupt handler for the LCD controller module. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! \param pfnHandler is a pointer to the function to be called when the LCD +//! controller interrupt occurs. +//! +//! This function registers the handler to be called when the LCD controller +//! module interrupt occurs. +//! +//! \note This function need not be called if the appropriate interrupt vector +//! is statically linked into the vector table in the application startup code. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIntRegister(uint32_t ui32Base, void (*pfnHandler)(void)) +{ + // + // Check the arguments. + // + ASSERT(ui32Base == LCD0_BASE); + ASSERT(pfnHandler); + + // + // Register the interrupt handler. + // + IntRegister(INT_LCD0_TM4C129, pfnHandler); + + // + // Enable the interrupt in the interrupt controller. + // + IntEnable(INT_LCD0_TM4C129); +} + +//***************************************************************************** +// +//! Unregisters the interrupt handler for the LCD controller module. +//! +//! \param ui32Base specifies the LCD controller module base address. +//! +//! This function unregisters the interrupt handler and disables the global LCD +//! controller interrupt in the interrupt controller. +//! +//! \note This function need not be called if the appropriate interrupt vector +//! is statically linked into the vector table in the application startup code. +//! +//! \sa IntRegister() for important information about registering interrupt +//! handlers. +//! +//! \return None. +// +//***************************************************************************** +void +LCDIntUnregister(uint32_t ui32Base) +{ + // + // Check the arguments. + // + ASSERT(ui32Base == LCD0_BASE); + + // + // Disable the interrupt in the interrupt controller. + // + IntDisable(INT_LCD0_TM4C129); + + // + // Unregister the interrupt handler. + // + IntUnregister(INT_LCD0_TM4C129); +} + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** -- cgit v1.3.1