I am trying a LCD controller of TM4C1299 in raster mode.
However , the color data is not output correctly.
I'm using an external SDRAM as a frame buffer via DMA. So , I suspect that DMA settings are not good .
Could you tell me the DMA settings ?
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I am trying a LCD controller of TM4C1299 in raster mode.
However , the color data is not output correctly.
I'm using an external SDRAM as a frame buffer via DMA. So , I suspect that DMA settings are not good .
Could you tell me the DMA settings ?
Hello Amit
System clock is 120MHz.
And configuration is as follows:
ui32SysClock = ROM_SysCtlClockFreqSet( SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480, 120000000 );
Regards
Daisuke
Hello Daisuke,
Which of the two work-spaces do I have to use? Also I found a working code for LCD Raster on a 24bpp panel with SDRAM. You may want to check against this working C file.
//*****************************************************************************
//
// tm4c129_lcdraster_episdram.c - Example demonstrating how to configure the
// LCD for raster mode and EPI bus in SDRAM mode for dual buffer
// image display
//
// Copyright (c) 2014-2015 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.1.71 of the Tiva Firmware Development Package.
//
//*****************************************************************************
#include <stdbool.h>
#include <stdint.h>
#include "inc/hw_epi.h"
#include "inc/hw_ints.h"
#include "inc/hw_lcd.h"
#include "inc/hw_memmap.h"
#include "inc/hw_types.h"
#include "inc/hw_gpio.h"
#include "driverlib/epi.h"
#include "driverlib/lcd.h"
#include "driverlib/interrupt.h"
#include "driverlib/gpio.h"
#include "driverlib/pin_map.h"
#include "driverlib/rom.h"
#include "driverlib/rom_map.h"
#include "driverlib/sysctl.h"
#include "driverlib/uart.h"
#include "utils/uartstdio.h"
//*****************************************************************************
//
//! \addtogroup epi_examples_list
//! <h1>TM4C129 LCD Raster EPI SDRAM Mode (tm4c129_lcdraster_episdram)</h1>
//!
//! This example shows how to configure the TM4C129 EPI bus in SDRAM mode and
//! LCD controller for a 800x480 Raster. It assumes that a 512Mbit SDRAM is
//! attached to EPI0.
//!
//! For the EPI SDRAM mode, the pinout is as follows:
//! Address11:0 - EPI0S11:0
//! Bank1:0 - EPI0S14:13
//! Data15:0 - EPI0S15:0
//! DQML - EPI0S16
//! DQMH - EPI0S17
//! /CAS - EPI0S18
//! /RAS - EPI0S19
//! /WE - EPI0S28
//! /CS - EPI0S29
//! SDCKE - EPI0S30
//! SDCLK - EPI0S31
//!
//! This example uses the following peripherals and I/O signals. You must
//! review these and change as needed for your own board:
//! - EPI0 peripheral
//! - GPIO Port A peripheral (for EPI0 pins)
//! - GPIO Port B peripheral (for EPI0 pins)
//! - GPIO Port C peripheral (for EPI0 pins)
//! - GPIO Port G peripheral (for EPI0 pins)
//! - GPIO Port K peripheral (for EPI0 pins)
//! - GPIO Port L peripheral (for EPI0 pins)
//! - GPIO Port M peripheral (for EPI0 pins)
//! - GPIO Port N peripheral (for EPI0 pins)
//! - EPI0S0 - PK0
//! - EPI0S1 - PK1
//! - EPI0S2 - PK2
//! - EPI0S3 - PK3
//! - EPI0S4 - PC7
//! - EPI0S5 - PC6
//! - EPI0S6 - PC5
//! - EPI0S7 - PC4
//! - EPI0S8 - PA6
//! - EPI0S9 - PA7
//! - EPI0S10 - PG1
//! - EPI0S11 - PG0
//! - EPI0S12 - PM3
//! - EPI0S13 - PM2
//! - EPI0S14 - PM1
//! - EPI0S15 - PM0
//! - EPI0S16 - PL0
//! - EPI0S17 - PL1
//! - EPI0S18 - PL2
//! - EPI0S19 - PL3
//! - EPI0S28 - PB3
//! - EPI0S29 - PN2
//! - EPI0S30 - PN3
//! - EPI0S31 - PK5
//!
//! The following UART signals are configured only for displaying console
//! messages for this example. These are not required for operation of EPI0.
//! - UART0 peripheral
//! - GPIO Port A peripheral (for UART0 pins)
//! - UART0RX - PA0
//! - UART0TX - PA1
//!
//! This example uses the following interrupt handlers. To use this example
//! in your own application you must add these interrupt handlers to your
//! vector table.
//! - None.
//
//*****************************************************************************
//*****************************************************************************
//
// Use the following to specify the GPIO pins used by the SDRAM EPI bus.
//
//*****************************************************************************
#define EPI_PORTA_PINS (GPIO_PIN_7 | GPIO_PIN_6)
#define EPI_PORTB_PINS (GPIO_PIN_3)
#define EPI_PORTC_PINS (GPIO_PIN_7 | GPIO_PIN_6 | GPIO_PIN_5 | GPIO_PIN_4)
#define EPI_PORTG_PINS (GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTK_PINS (GPIO_PIN_5 | GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | \
GPIO_PIN_0)
#define EPI_PORTL_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTM_PINS (GPIO_PIN_3 | GPIO_PIN_2 | GPIO_PIN_1 | GPIO_PIN_0)
#define EPI_PORTN_PINS (GPIO_PIN_3 | GPIO_PIN_2)
//*****************************************************************************
//
// The starting and ending address for the 64MB SDRAM chip (32Meg x 16bits) on
// the SDRAM daughter board.
//
//*****************************************************************************
#define SDRAM_START_ADDRESS 0x00000000
#define SDRAM_END_ADDRESS 0x01FFFFFF
//*****************************************************************************
//
// The Mapping address space for the EPI SDRAM.
//
//*****************************************************************************
#define SDRAM_MAPPING_ADDRESS 0x60000000
//*****************************************************************************
//
// The define for the LCD Raster Panel BPP, Width and Height
//
//*****************************************************************************
#define RASTER_WIDTH 800
#define RASTER_HEIGHT 480
#define SCREEN_BPP 16
#define SIZE_BUFFER ((RASTER_WIDTH * RASTER_HEIGHT * SCREEN_BPP) / 8)
//*****************************************************************************
//
// A pointer to the EPI memory aperture. Note that g_pui16EPISdram is declared
// as volatile so the compiler should not optimize reads out of the image.
//
//*****************************************************************************
static volatile uint16_t *g_pui16EPISdram;
//*****************************************************************************
//
// Variable for holding the LCD Frame Buffer addres, the frame count, flag to
// indicate frame buffer change and free frame buffer index
//
//*****************************************************************************
uint32_t *g_pui32DisplayBufferCurr;
uint32_t g_ui32FrameCounter = 0;
volatile bool g_bFrameBufferChange = false;
volatile uint8_t g_ui8AvailFrameBuffer = 0;
//*****************************************************************************
//
// A table used to determine the EPI clock frequency band in use.
//
//*****************************************************************************
typedef struct
{
uint32_t ui32SysClock;
uint32_t ui32FreqFlag;
}
tSDRAMFreqMapping;
static tSDRAMFreqMapping g_psSDRAMFreq[] =
{
//
// SysClock >= 100MHz, EPI clock >= 50Mhz (divided by 2)
//
{100000000, EPI_SDRAM_CORE_FREQ_50_100},
//
// SysClock >= 60MHz, EPI clock >= 30MHz (divided by 2)
//
{60000000, EPI_SDRAM_CORE_FREQ_50_100},
//
// SysClock >= 50MHz, EPI clock >= 50MHz (no divider)
//
{50000000, EPI_SDRAM_CORE_FREQ_50_100},
//
// SysClock >= 30MHz, EPI clock >= 30MHz (no divider)
//
{50000000, EPI_SDRAM_CORE_FREQ_30_50},
//
// SysClock >= 15MHz, EPI clock >= 15MHz (no divider)
//
{15000000, EPI_SDRAM_CORE_FREQ_15_30},
//
// SysClock < 15Mhz, EPI clock < 15Mhz (no divider)
//
{0, EPI_SDRAM_CORE_FREQ_0_15}
};
#define NUM_SDRAM_FREQ (sizeof(g_psSDRAMFreq) / sizeof(tSDRAMFreqMapping))
//*****************************************************************************
//
// A table used to configure the LCD Panel.
//
//*****************************************************************************
typedef struct
{
//
// A text description of the display mode.
//
char *pcMode;
//
// The required pixel clock for the display mode in Hz.
//
uint32_t ui32PixClock;
//
// The PLL VCO frequency recommended to allow the desired pixel clock
// frequency to be achieved using an integer system clock divider.
//
uint32_t ui32VCOFrequency;
//
// The recommended system clock frequency to set to allow the pixel clock
// to be achieved using an integer system clock divider. Other values are
// possible so this is merely a recommendation.
//
uint32_t ui32SysClockFrequency;
//
// LCD controller raster display timings for the display mode.
//
tLCDRasterTiming sTiming;
//
// A pointer to an additional, display-specific function which, of not
// NULL, must be called to perform display initialization prior to
// enabling the LCD controller raster engine.
//
void (*pfnInitDisplay)(uint32_t);
}
tRasterDisplayInfo;
const tRasterDisplayInfo g_sOptrex800x480x75Hz =
{
"800x480 at 75Hz on Optrex T-55226D043J-LW-A-AAN",
30000000,
SYSCTL_CFG_VCO_480,
120000000,
{
(RASTER_TIMING_ACTIVE_HIGH_PIXCLK |
RASTER_TIMING_SYNCS_ON_RISING_PIXCLK),
RASTER_WIDTH, RASTER_HEIGHT,
2, 30, 8,
10, 10, 8,
0
},
0
};
const tRasterDisplayInfo *g_psDisplayMode = &g_sOptrex800x480x75Hz;
//*****************************************************************************
//
// LCD Controller Interrupt Handler
//
//*****************************************************************************
void
LCD0IntHandler(void)
{
uint32_t ui32Status;
//
// Get the current interrupt status and clear any active interrupts.
//
ui32Status = LCDIntStatus(LCD0_BASE, true);
LCDIntClear(LCD0_BASE, ui32Status);
//
// If Frame Done interrupt is asserted then check if a new frame
// is available for updating.
//
if(ui32Status & LCD_INT_RASTER_FRAME_DONE)
{
if(!g_bFrameBufferChange)
{
LCDRasterDisable(LCD0_BASE);
MAP_LCDRasterFrameBufferSet(LCD0_BASE, 0, g_pui32DisplayBufferCurr,
SIZE_BUFFER);
LCDRasterEnable(LCD0_BASE);
//
// Inform the application that frame buffer has been changed
//
g_bFrameBufferChange = true;
}
}
//
// If we saw an underflow interrupt, restart the raster.
//
if(ui32Status & LCD_INT_UNDERFLOW)
{
LCDRasterEnable(LCD0_BASE);
}
}
//*****************************************************************************
//
// LCD controller Display Intiialization function
//
//*****************************************************************************
static void
DisplayInit(uint32_t ui32SysClkHz)
{
//
// Enable the GPIO peripherals used to interface to the LCD panel.
//
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_LCD0);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOQ);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOR);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOS);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOT);
//
// Configure all the LCD controller pins for hardware control.
//
GPIOPinTypeGPIOOutput(GPIO_PORTQ_BASE, GPIO_PIN_5);
GPIOPinWrite(GPIO_PORTQ_BASE, GPIO_PIN_5, GPIO_PIN_5);
GPIOPinTypeLCD(GPIO_PORTF_BASE, 0x80);
GPIOPinTypeLCD(GPIO_PORTJ_BASE, 0x7C);
GPIOPinTypeLCD(GPIO_PORTN_BASE, 0xC0);
GPIOPinTypeLCD(GPIO_PORTR_BASE, 0xFF);
GPIOPinTypeLCD(GPIO_PORTS_BASE, 0xF9);
GPIOPinTypeLCD(GPIO_PORTT_BASE, 0x0F);
//
// Set the pin muxing to ensure that LCD signals appear on the required
// pins. Note that we take advantage of the fact that we know the mux
// selector is F here to allow us to OR the value without first masking
// off anything that may have been there before.
//
HWREG(GPIO_PORTF_BASE + GPIO_O_PCTL) |= 0xF0000000;
HWREG(GPIO_PORTJ_BASE + GPIO_O_PCTL) |= 0x0FFFFF00;
HWREG(GPIO_PORTN_BASE + GPIO_O_PCTL) |= 0xFF000000;
HWREG(GPIO_PORTR_BASE + GPIO_O_PCTL) |= 0xFFFFFFFF;
HWREG(GPIO_PORTS_BASE + GPIO_O_PCTL) |= 0xFFFFF00F;
HWREG(GPIO_PORTT_BASE + GPIO_O_PCTL) |= 0x0000FFFF;
//
// Configure the LCD controller for raster operation with a pixel clock
// as close to the requested pixel clock as possible.
//
MAP_LCDModeSet(LCD0_BASE, (LCD_MODE_RASTER | LCD_MODE_AUTO_UFLOW_RESTART),
g_psDisplayMode->ui32PixClock, ui32SysClkHz);
//
// Set the output format for the raster interface.
//
MAP_LCDRasterConfigSet(LCD0_BASE, (RASTER_FMT_ACTIVE_PALETTIZED_16BIT |
RASTER_NIBBLE_MODE_ENABLED |
RASTER_READ_ORDER_REVERSED), 0);
MAP_LCDRasterTimingSet(LCD0_BASE, &(g_psDisplayMode->sTiming));
//
// Configure DMA-related parameters.
//
MAP_LCDDMAConfigSet(LCD0_BASE, LCD_DMA_BURST_16 | LCD_DMA_FIFORDY_64_WORDS);
//
// If the chosen display has an initialization function, call it now.
//
if(g_psDisplayMode->pfnInitDisplay)
{
g_psDisplayMode->pfnInitDisplay(ui32SysClkHz);
}
//
// Set up the frame buffer. Note that we allow this buffer to extend
// outside the available SRAM. This allows us to easily test modes where
// we can't fit the whole frame in memory, realizing, of course, that
// part of the display will contain crud.
//
MAP_LCDRasterFrameBufferSet(LCD0_BASE, 0, g_pui32DisplayBufferCurr,
SIZE_BUFFER);
//
// Enable the LCD interrupts.
//
MAP_LCDIntEnable(LCD0_BASE, (LCD_INT_DMA_DONE | LCD_INT_SYNC_LOST |
LCD_INT_UNDERFLOW | LCD_INT_RASTER_FRAME_DONE | LCD_INT_EOF0));
MAP_IntEnable(INT_LCD0);
//
// Enable the raster output.
//
MAP_LCDRasterEnable(LCD0_BASE);
}
//*****************************************************************************
//
// This function sets up UART0 to be used for a console to display information
// as the example is running.
//
//*****************************************************************************
void
InitConsole(void)
{
//
// Enable GPIO port A which is used for UART0 pins.
// TODO: change this to whichever GPIO port you are using.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Configure the pin muxing for UART0 functions on port A0 and A1.
// This step is not necessary if your part does not support pin muxing.
// TODO: change this to select the port/pin you are using.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
//
// Enable UART0 so that we can configure the clock.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
//
// Use the internal 16MHz oscillator as the UART clock source.
//
UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);
//
// Select the alternate (UART) function for these pins.
// TODO: change this to select the port/pin you are using.
//
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);
//
// Initialize the UART for console I/O.
//
UARTStdioConfig(0, 115200, 16000000);
}
//*****************************************************************************
//
// Create a barrel shifter to move the final image pixel to be shown on the
// screen
//
//*****************************************************************************
void
GetBarrelValue(uint16_t *pui16Value)
{
switch(*pui16Value)
{
case 0x001F:
*pui16Value = 0x003E;
break;
case 0x003E:
*pui16Value = 0x007C;
break;
case 0x007C:
*pui16Value = 0x00F8;
break;
case 0x00F8:
*pui16Value = 0x01F0;
break;
case 0x01F0:
*pui16Value = 0x03E0;
break;
case 0x03E0:
*pui16Value = 0x07C0;
break;
case 0x07C0:
*pui16Value = 0x0F80;
break;
case 0x0F80:
*pui16Value = 0x1F00;
break;
case 0x1F00:
*pui16Value = 0x3E00;
break;
case 0x3E00:
*pui16Value = 0x7C00;
break;
case 0x7C00:
*pui16Value = 0xF800;
break;
case 0xF800:
*pui16Value = 0xF001;
break;
case 0xF001:
*pui16Value = 0xE003;
break;
case 0xE003:
*pui16Value = 0xC007;
break;
case 0xC007:
*pui16Value = 0x800F;
break;
case 0x800F:
*pui16Value = 0x001F;
break;
default:
*pui16Value = 0x001F;
break;
}
}
//*****************************************************************************
//
// Configure EPI0 in SDRAM mode. The EPI memory space is setup using an a
// simple C array. This example shows how to read and write to an SDRAM card
// using the EPI bus in SDRAM mode.
//
//*****************************************************************************
int
main(void)
{
uint32_t ui32Val, ui32Freq, ui32SysClock;
uint16_t ui16BarrelLoad = 0x001F;
//
// Set the clocking to run at 120MHz from the PLL.
// TODO: Update this call to set the system clock frequency your
// application requires.
//
ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
SYSCTL_CFG_VCO_480), 120000000);
//
// Set up the serial console to use for displaying messages. This is
// just for this example program and is not needed for EPI operation.
//
InitConsole();
g_ui32FrameCounter = 0;
//
// Display the setup on the console.
//
UARTprintf("EPI SDRAM Mode ->\n");
UARTprintf(" Type: SDRAM\n");
UARTprintf(" Starting Address: 0x%08x\n", SDRAM_MAPPING_ADDRESS);
UARTprintf(" End Address: 0x%08x\n",
(SDRAM_MAPPING_ADDRESS + SDRAM_END_ADDRESS));
UARTprintf(" Data: 16-bit\n");
UARTprintf(" Size: 64MB (32Meg x 16bits)\n\n");
//
// The EPI0 peripheral must be enabled for use.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_EPI0);
//
// For this example EPI0 is used with multiple pins on PortA, B, C, G, H,
// K, L, M and N. The actual port and pins used may be different on your
// part, consult the data sheet for more information.
// TODO: Update based upon the EPI pin assignment on your target part.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOG);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOK);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOM);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);
//
// This step configures the internal pin muxes to set the EPI pins for use
// with EPI. Please refer to the datasheet for more information about pin
// muxing. Note that EPI0S27:20 are not used for the EPI SDRAM
// implementation.
// TODO: Update this section based upon the EPI pin assignment on your
// target part.
//
//
// EPI0S4 ~ EPI0S7: C4 ~ 7
//
ui32Val = HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL);
ui32Val &= 0x0000FFFF;
ui32Val |= 0xFFFF0000;
HWREG(GPIO_PORTC_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S8 ~ EPI0S9: A6 ~ 7
//
ui32Val = HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL);
ui32Val &= 0x00FFFFFF;
ui32Val |= 0xFF000000;
HWREG(GPIO_PORTA_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S10 ~ EPI0S11: G0 ~ 1
//
ui32Val = HWREG(GPIO_PORTG_BASE + GPIO_O_PCTL);
ui32Val &= 0xFFFFFF00;
ui32Val |= 0x000000FF;
HWREG(GPIO_PORTG_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S12 ~ EPI0S15: M0 ~ 3
//
ui32Val = HWREG(GPIO_PORTM_BASE + GPIO_O_PCTL);
ui32Val &= 0xFFFF0000;
ui32Val |= 0x0000FFFF;
HWREG(GPIO_PORTM_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S16 ~ EPI0S19: L0 ~ 3
//
ui32Val = HWREG(GPIO_PORTL_BASE + GPIO_O_PCTL);
ui32Val &= 0xFFFF0000;
ui32Val |= 0x0000FFFF;
HWREG(GPIO_PORTL_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S28 : B3
//
ui32Val = HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL);
ui32Val &= 0xFFFF0FFF;
ui32Val |= 0x0000F000;
HWREG(GPIO_PORTB_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S29 ~ EPI0S30: N2 ~ 3
//
ui32Val = HWREG(GPIO_PORTN_BASE + GPIO_O_PCTL);
ui32Val &= 0xFFFF00FF;
ui32Val |= 0x0000FF00;
HWREG(GPIO_PORTN_BASE + GPIO_O_PCTL) = ui32Val;
//
// EPI0S00 ~ EPI0S03, EPI0S31 : K0 ~ 3, K5
//
ui32Val = HWREG(GPIO_PORTK_BASE + GPIO_O_PCTL);
ui32Val &= 0xFF0F0000;
ui32Val |= 0x00F0FFFF;
HWREG(GPIO_PORTK_BASE + GPIO_O_PCTL) = ui32Val;
//
// Configure the GPIO pins for EPI mode. All the EPI pins require 8mA
// drive strength in push-pull operation. This step also gives control of
// pins to the EPI module.
//
GPIOPinTypeEPI(GPIO_PORTA_BASE, EPI_PORTA_PINS);
GPIOPinTypeEPI(GPIO_PORTB_BASE, EPI_PORTB_PINS);
GPIOPinTypeEPI(GPIO_PORTC_BASE, EPI_PORTC_PINS);
GPIOPinTypeEPI(GPIO_PORTG_BASE, EPI_PORTG_PINS);
GPIOPinTypeEPI(GPIO_PORTK_BASE, EPI_PORTK_PINS);
GPIOPinTypeEPI(GPIO_PORTL_BASE, EPI_PORTL_PINS);
GPIOPinTypeEPI(GPIO_PORTM_BASE, EPI_PORTM_PINS);
GPIOPinTypeEPI(GPIO_PORTN_BASE, EPI_PORTN_PINS);
//
// Is our current system clock faster than we can drive the SDRAM clock?
//
if(ui32SysClock > 60000000)
{
//
// Yes. Set the EPI clock to half the system clock.
//
EPIDividerSet(EPI0_BASE, 1);
}
else
{
//
// With a system clock of 60MHz or lower, we can drive the SDRAM at
// the same rate so set the divider to 0.
//
EPIDividerSet(EPI0_BASE, 0);
}
//
// Sets the usage mode of the EPI module. For this example we will use
// the SDRAM mode to talk to the external 64MB SDRAM daughter card.
//
EPIModeSet(EPI0_BASE, EPI_MODE_SDRAM);
//
// Keep the compiler happy by setting a default value for the frequency
// flag.
//
ui32Freq = g_psSDRAMFreq[NUM_SDRAM_FREQ - 1].ui32FreqFlag;
//
// Examine the system clock frequency to determine how to set the SDRAM
// controller's frequency flag.
//
for(ui32Val = 0; ui32Val < NUM_SDRAM_FREQ; ui32Val++)
{
//
// Is the system clock frequency above the break point in the table?
//
if(ui32SysClock >= g_psSDRAMFreq[ui32Val].ui32SysClock)
{
//
// Yes - remember the frequency flag to use and exit the loop.
//
ui32Freq = g_psSDRAMFreq[ui32Val].ui32FreqFlag;
break;
}
}
//
// Configure the SDRAM mode. We configure the SDRAM according to our core
// clock frequency. We will use the normal (or full power) operating
// state which means we will not use the low power self-refresh state.
// Set the SDRAM size to 64MB with a refresh interval of 1024 clock ticks.
//
EPIConfigSDRAMSet(EPI0_BASE, (ui32Freq | EPI_SDRAM_FULL_POWER |
EPI_SDRAM_SIZE_512MBIT), 468);
//
// Set the address map. The EPI0 is mapped from 0x60000000 to 0x01FFFFFF.
// For this example, we will start from a base address of 0x60000000 with
// a size of 256MB. Although our SDRAM is only 64MB, there is no 64MB
// aperture option so we pick the next larger size.
//
EPIAddressMapSet(EPI0_BASE, EPI_ADDR_RAM_SIZE_256MB | EPI_ADDR_RAM_BASE_6);
//
// Wait for the SDRAM wake-up to complete by polling the SDRAM
// initialization sequence bit. This bit is true when the SDRAM interface
// is going through the initialization and false when the SDRAM interface
// it is not in a wake-up period.
//
while(HWREG(EPI0_BASE + EPI_O_STAT) & EPI_STAT_INITSEQ)
{
}
//
// Set the EPI memory pointer to the base of EPI memory space. Note that
// g_pui16EPISdram is declared as volatile so the compiler should not
// optimize reads out of the memory. With this pointer, the memory space
// is accessed like a simple array.
//
g_pui16EPISdram = (uint16_t *)0x60000000;
//
// Read the initial data in SDRAM, and display it on the console.
//
UARTprintf(" SDRAM Initial Data:\n");
UARTprintf(" Mem[0x6000.0000] = 0x%4x\n",
g_pui16EPISdram[SDRAM_START_ADDRESS]);
UARTprintf(" Mem[0x6000.0001] = 0x%4x\n",
g_pui16EPISdram[SDRAM_START_ADDRESS + 1]);
UARTprintf(" Mem[0x603F.FFFE] = 0x%4x\n",
g_pui16EPISdram[SDRAM_END_ADDRESS - 1]);
UARTprintf(" Mem[0x603F.FFFF] = 0x%4x\n\n",
g_pui16EPISdram[SDRAM_END_ADDRESS]);
//
// Display what writes we are doing on the console.
//
UARTprintf(" SDRAM Write:\n");
UARTprintf(" Mem[0x6000.0000] <- 0xabcd\n");
UARTprintf(" Mem[0x6000.0001] <- 0x1234\n");
UARTprintf(" Mem[0x603F.FFFE] <- 0xdcba\n");
UARTprintf(" Mem[0x603F.FFFF] <- 0x4321\n\n");
//
// Write to the first 2 and last 2 address of the SDRAM card. Since the
// SDRAM card is word addressable, we will write words.
//
g_pui16EPISdram[SDRAM_START_ADDRESS] = 0xabcd;
g_pui16EPISdram[SDRAM_START_ADDRESS + 1] = 0x1234;
g_pui16EPISdram[SDRAM_END_ADDRESS - 1] = 0xdcba;
g_pui16EPISdram[SDRAM_END_ADDRESS] = 0x4321;
//
// Read back the data you wrote, and display it on the console.
//
UARTprintf(" SDRAM Read:\n");
UARTprintf(" Mem[0x6000.0000] = 0x%4x\n",
g_pui16EPISdram[SDRAM_START_ADDRESS]);
UARTprintf(" Mem[0x6000.0001] = 0x%4x\n",
g_pui16EPISdram[SDRAM_START_ADDRESS + 1]);
UARTprintf(" Mem[0x603F.FFFE] = 0x%4x\n",
g_pui16EPISdram[SDRAM_END_ADDRESS - 1]);
UARTprintf(" Mem[0x603F.FFFF] = 0x%4x\n\n",
g_pui16EPISdram[SDRAM_END_ADDRESS]);
//
// Check the validity of the data.
//
if((g_pui16EPISdram[SDRAM_START_ADDRESS] == 0xabcd) &&
(g_pui16EPISdram[SDRAM_START_ADDRESS + 1] == 0x1234) &&
(g_pui16EPISdram[SDRAM_END_ADDRESS - 1] == 0xdcba) &&
(g_pui16EPISdram[SDRAM_END_ADDRESS] == 0x4321))
{
//
// Read and write operations were successful. Return with no errors.
//
UARTprintf("Read and write to external SDRAM was successful!\n");
}
else
{
//
// Display on the console that there was an error.
//
UARTprintf("Read and/or write failure!");
UARTprintf(" Check if your SDRAM card is plugged in.");
while(1)
{
}
}
//
// Frame buffer 1 is assigned already to have the first image and set the
// flag that the next buffer is ready for a new image
//
g_ui8AvailFrameBuffer = 2;
g_bFrameBufferChange = true;
//
// Set the address of the first frame buffer
//
g_pui32DisplayBufferCurr = (uint32_t *)g_pui16EPISdram;
//
// Fill the SDRAM with the frame buffer pixel color
//
for(ui32Val=0; ui32Val < SIZE_BUFFER; ui32Val++)
{
g_pui16EPISdram[SDRAM_START_ADDRESS + ui32Val] = ui16BarrelLoad;
}
//
// Initialize the Display and put out the first image
//
DisplayInit(ui32SysClock);
//
// Read and/or write operations were unsuccessful. Wait in while(1) loop
// for debugging.
//
while(1)
{
//
// Barrel Shift the current pixel value
//
GetBarrelValue(&ui16BarrelLoad);
//
// Wait for the LCD interrupt handler to tell the application that the
// last frame buffer has been loaded and it has freed up the previous
// frame buffer being used
//
while(!g_bFrameBufferChange);
//
// Check which frame buffer is free and populate it with the new pixel
// value
//
if(g_ui8AvailFrameBuffer == 1)
{
for(ui32Val=0; ui32Val < SIZE_BUFFER; ui32Val++)
{
g_pui16EPISdram[SDRAM_START_ADDRESS + ui32Val] = ui16BarrelLoad;
SysCtlDelay(30);
}
g_ui8AvailFrameBuffer = 2;
g_pui32DisplayBufferCurr = (uint32_t *)g_pui16EPISdram;
}
else if(g_ui8AvailFrameBuffer == 2)
{
for(ui32Val=0; ui32Val < SIZE_BUFFER; ui32Val++)
{
g_pui16EPISdram[SDRAM_START_ADDRESS + SIZE_BUFFER + ui32Val] = ui16BarrelLoad;
SysCtlDelay(30);
}
g_ui8AvailFrameBuffer = 1;
g_pui32DisplayBufferCurr = (uint32_t *)g_pui16EPISdram + (SIZE_BUFFER/2);
}
//
// Set the flag for the interrupt handle that buffer change is complete
// and the next image buffer is available
//
g_bFrameBufferChange = false;
}
}
Regards
Amit
Hello Amit,
>Which of the two work-spaces do I have to use?
Monitorworkspace.eww is.
It is the overall workspace that contains the tiva libraries.
Monitor.eww is just a sub-workspace.
>You may want to check against this working C file.
Okey, I'll check it.
Regards
Daisuke
Hello Amit,
It worked fine.
It seems DMA configuration was not good.
Thank you , Boss has very pleased.
Regards
Daisuke
Amit Ashara said:attach it to the reply post by clicking on "Use rich formatting" on the bottom left.
Cb1 staffers (gleefully) note that cb1 (more than once) has made that same "left/right" transposition... Rich is to the right - as is "proper" politics...