//*****************************************************************************
//
// usb_stick_update.c - Example to update flash from a USB memory stick.
//
// Copyright (c) 2013 Texas Instruments Incorporated.  All rights reserved.
// Software License Agreement
// 
// Texas Instruments (TI) is supplying this software for use solely and
// exclusively on TI's microcontroller products. The software is owned by
// TI and/or its suppliers, and is protected under applicable copyright
// laws. You may not combine this software with "viral" open-source
// software in order to form a larger program.
// 
// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
// NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
// NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
// CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
// DAMAGES, FOR ANY REASON WHATSOEVER.
// 
// This is part of revision 2.0 of the DK-TM4C129X Firmware Package.
//
//*****************************************************************************
#define		MONITOR_DEF_MAIN
#include "Monitorbase.h"

////////////////////////////////////////////////////////////////////////////[[[
// SD-RAMのテスト用
WORD	*gwarrSDRAMtmp;
DWORD	dwTmp;
DWORD	dwA;
DWORD	dwB;
////////////////////////////////////////////////////////////////////////////]]]



//*****************************************************************************
//
//! \addtogroup example_list
//! <h1>USB Memory Stick Updater (usb_stick_update)</h1>
//!
//! This example application behaves the same way as a boot loader.  It resides
//! at the beginning of flash, and will read a binary file from a USB memory
//! stick and program it into another location in flash.  Once the user
//! application has been programmed into flash, this program will always start
//! the user application until requested to load a new application.
//!
//! When this application starts, if there is a user application already in
//! flash (at \b APP_START_ADDRESS), then it will just run the user application.
//! It will attempt to load a new application from a USB memory stick under
//! the following conditions:
//!
//! - no user application is present at \b APP_START_ADDRESS
//! - the user application has requested an update by transferring control
//! to the updater
//! - the user holds down the eval board push button when the board is reset
//!
//! When this application is attempting to perform an update, it will wait
//! forever for a USB memory stick to be plugged in.  Once a USB memory stick
//! is found, it will search the root directory for a specific file name, which
//! is \e FIRMWARE.BIN by default.  This file must be a binary image of the
//! program you want to load (the .bin file), linked to run from the correct
//! address, at \b APP_START_ADDRESS.
//!
//! The USB memory stick must be formatted as a FAT16 or FAT32 file system
//! (the normal case), and the binary file must be located in the root
//! directory.  Other files can exist on the memory stick but they will be
//! ignored.
//
//*****************************************************************************

//*****************************************************************************
//
// Defines the number of times to call to check if the attached device is
// ready.
//
//*****************************************************************************
#define USBMSC_DRIVE_RETRY      4

//*****************************************************************************
//
// The name of the binary firmware file on the USB stick.  This is the user
// application that will be searched for and loaded into flash if it is found.
// Note that the name of the file must be 11 characters total, 8 for the base
// name and 3 for the extension.  If the actual file name has fewer characters
// then it must be padded with spaces.  This macro should not contain the dot
// "." for the extension.
//
// Examples: firmware.bin --> "FIRMWAREBIN"
//           myfile.bn    --> "MYFILE  BN "
//
//*****************************************************************************
#define USB_UPDATE_FILENAME "FIRMWAREBIN"

//*****************************************************************************
//
// The size of the flash for this microcontroller.
//
//*****************************************************************************
#define FLASH_SIZE (1 * 1024 * 1024)

//*****************************************************************************
//
// The starting address for the application that will be loaded into flash
// memory from the USB stick.  This address must be high enough to be above
// the USB stick updater, and must be on a 1K boundary.
// Note that the application that will be loaded must also be linked to run
// from this address.
//
//*****************************************************************************
#define APP_START_ADDRESS 0x8000

//*****************************************************************************
//
// A memory location and value that is used to indicate that the application
// wants to force an update.
//
//*****************************************************************************
#define FORCE_UPDATE_ADDR 0x20004000
#define FORCE_UPDATE_VALUE 0x1234cdef

//*****************************************************************************
//
// The prototype for the function that is used to call the user application.
//
//*****************************************************************************
void CallApplication(uint_fast32_t ui32StartAddr);

//*****************************************************************************
//
// The control table used by the uDMA controller.  This table must be aligned
// to a 1024 byte boundary.  In this application uDMA is only used for USB,
// so only the first 6 channels are needed.
//
//*****************************************************************************
#if defined(ewarm)
#pragma data_alignment=1024
tDMAControlTable g_sDMAControlTable[6];
#elif defined(ccs)
#pragma DATA_ALIGN(g_sDMAControlTable, 1024)
tDMAControlTable g_sDMAControlTable[6];
#else
tDMAControlTable g_sDMAControlTable[6] __attribute__ ((aligned(1024)));
#endif

//*****************************************************************************
//
// The global that holds all of the host drivers in use in the application.
// In this case, only the MSC class is loaded.
//
//*****************************************************************************
static tUSBHostClassDriver const * const g_ppHostClassDrivers[] =
{
    &g_sUSBHostMSCClassDriver
};

//*****************************************************************************
//
// This global holds the number of class drivers in the g_ppHostClassDrivers
// list.
//
//*****************************************************************************
#define NUM_CLASS_DRIVERS       (sizeof(g_ppHostClassDrivers) /               \
                                 sizeof(g_ppHostClassDrivers[0]))

//*****************************************************************************
//
// Hold the current state for the application.
//
//*****************************************************************************
volatile enum
{
    //
    // No device is present.
    //
    STATE_NO_DEVICE,

    //
    // Mass storage device is being enumerated.
    //
    STATE_DEVICE_ENUM,
}
g_eState;

//*****************************************************************************
//
// The instance data for the MSC driver.
//
//*****************************************************************************
tUSBHMSCInstance *g_psMSCInstance = 0;

//*****************************************************************************
//
// The size of the host controller's memory pool in bytes.
//
//*****************************************************************************
#define HCD_MEMORY_SIZE         128

//*****************************************************************************
//
// The memory pool to provide to the Host controller driver.
//
//*****************************************************************************
uint8_t g_pHCDPool[HCD_MEMORY_SIZE];

//*****************************************************************************
//
// A buffer for holding sectors read from the storage device
//
//*****************************************************************************
static uint8_t g_ui8SectorBuf[512];

//*****************************************************************************
//
// Global to hold the clock rate. Set once read many.
//
//*****************************************************************************
uint32_t g_ui32SysClock;

//*****************************************************************************
//
// The error routine that is called if the driver library encounters an error.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, uint32_t ui32Line)
{
}
#endif

//*****************************************************************************
//
// Read a sector from the USB mass storage device.
//
// \param ui32Sector is the sector to read from the connected USB mass storage
// device (memory stick)
// \param pui8Buf is a pointer to the buffer where the sector data should be
// stored
//
// This is the application-specific implementation of a function to read
// sectors from a storage device, in this case a USB mass storage device.
// This function is called from the \e simple_fs.c file when it needs to read
// data from the storage device.
//
// \return Non-zero if data was read from the device, 0 if no data was read.
//
//*****************************************************************************
uint32_t
SimpleFsReadMediaSector(uint_fast32_t ui32Sector, uint8_t *pui8Buf)
{
    //
    // Return the requested sector from the connected USB mass storage
    // device.
    //
    return(USBHMSCBlockRead(g_psMSCInstance, ui32Sector, pui8Buf, 1));
}

//*****************************************************************************
//
// This is the callback from the MSC driver.
//
// \param ui32Instance is the driver instance which is needed when communicating
// with the driver.
// \param ui32Event is one of the events defined by the driver.
// \param pvData is a pointer to data passed into the initial call to register
// the callback.
//
// This function handles callback events from the MSC driver.  The only events
// currently handled are the \b MSC_EVENT_OPEN and \b MSC_EVENT_CLOSE.  This
// allows the main routine to know when an MSC device has been detected and
// enumerated and when an MSC device has been removed from the system.
//
// \return Returns \e true on success or \e false on failure.
//
//*****************************************************************************
static void
MSCCallback(tUSBHMSCInstance *psMSCInstance, uint32_t ui32Event, void *pvData)
{
    //
    // Determine the event.
    //
    switch(ui32Event)
    {
        //
        // Called when the device driver has successfully enumerated an MSC
        // device.
        //
        case MSC_EVENT_OPEN:
        {
            //
            // Proceed to the enumeration state.
            //
            g_eState = STATE_DEVICE_ENUM;
            break;
        }

        //
        // Called when the device driver has been unloaded due to error or
        // the device is no longer present.
        //
        case MSC_EVENT_CLOSE:
        {
            //
            // Go back to the "no device" state and wait for a new connection.
            //
            g_eState = STATE_NO_DEVICE;
            break;
        }

        default:
        {
            break;
        }
    }
}

//*****************************************************************************
//
// Read the application image from the file system and program it into flash.
//
// This function will attempt to open and read the firmware image file from
// the mass storage device.  If the file is found it will be programmed into
// flash.  The name of the file to be read is configured by the macro
// \b USB_UPDATE_FILENAME.  It will be programmed into flash starting at the
// address specified by APP_START_ADDRESS.
//
// \return Zero if successful or non-zero if the file cannot be read or
// programmed.
//
//*****************************************************************************
uint32_t
ReadAppAndProgram(void)
{
    uint_fast32_t ui32FlashEnd;
    uint_fast32_t ui32FileSize;
    uint_fast32_t ui32DataSize;
    uint_fast32_t ui32Remaining;
    uint_fast32_t ui32ProgAddr;
    uint_fast32_t ui32SavedRegs[2];
    volatile uint_fast32_t ui32Idx;
    uint_fast32_t ui32DriveTimeout;

    //
    // Initialize the drive timeout.
    //
    ui32DriveTimeout = USBMSC_DRIVE_RETRY;

    //
    // Check to see if the mass storage device is ready.  Some large drives
    // take a while to be ready, so retry until they are ready.
    //
    while(USBHMSCDriveReady(g_psMSCInstance))
    {
        //
        // Wait about 500ms before attempting to check if the
        // device is ready again.
        //
        SysCtlDelay(g_ui32SysClock/(3*2));

        //
        // Decrement the retry count.
        //
        ui32DriveTimeout--;

        //
        // If the timeout is hit then return with a failure.
        //
        if(ui32DriveTimeout == 0)
        {
            return(1);
        }
    }

    //
    // Initialize the file system and return if error.
    //
    if(SimpleFsInit(g_ui8SectorBuf))
    {
        return(1);
    }

    //
    // Attempt to open the firmware file, retrieving the file/image size.
    // A file size of error means the file was not there, or there was an
    // error.
    //
    ui32FileSize = SimpleFsOpen(USB_UPDATE_FILENAME);
    if(ui32FileSize == 0)
    {
        return(1);
    }

    //
    // Get the size of flash.  This is the ending address of the flash.
    // If reserved space is configured, then the ending address is reduced
    // by the amount of the reserved block.
    //
    ui32FlashEnd = FLASH_SIZE;
#ifdef FLASH_RSVD_SPACE
    ui32FlashEnd -= FLASH_RSVD_SPACE;
#endif

    //
    // If flash code protection is not used, then change the ending address
    // to be the ending of the application image.  This will be the highest
    // flash page that will be erased and so only the necessary pages will
    // be erased.  If flash code protection is enabled, then all of the
    // application area pages will be erased.
    //
#ifndef FLASH_CODE_PROTECTION
    ui32FlashEnd = ui32FileSize + APP_START_ADDRESS;
#endif

    //
    // Check to make sure the file size is not too large to fit in the flash.
    // If it is too large, then return an error.
    //
    if((ui32FileSize + APP_START_ADDRESS) > ui32FlashEnd)
    {
        return(1);
    }

    //
    // Enter a loop to erase all the requested flash pages beginning at the
    // application start address (above the USB stick updater).
    //
    for(ui32Idx = APP_START_ADDRESS; ui32Idx < ui32FlashEnd; ui32Idx += 1024)
    {
        ROM_FlashErase(ui32Idx);
    }

    //
    // Enter a loop to read sectors from the application image file and
    // program into flash.  Start at the user app start address (above the USB
    // stick updater).
    //
    ui32ProgAddr = APP_START_ADDRESS;
    ui32Remaining = ui32FileSize;
    while(SimpleFsReadFileSector())
    {
        //
        // Compute how much data was read from this sector and adjust the
        // remaining amount.
        //
        ui32DataSize = ui32Remaining >= 512 ? 512 : ui32Remaining;
        ui32Remaining -= ui32DataSize;

        //
        // Special handling for the first block of the application.
        // This block contains as the first two location the application's
        // initial stack pointer and instruction pointer.  The USB updater
        // relied on the values in these locations to determine if a valid
        // application is present.  When there is a valid application the
        // updater runs the user application.  Otherwise the updater attempts
        // to load a new application.
        // In order to prevent a partially programmed imaged (due to some
        // error occurring while programming), the first two locations are
        // not programmed until all of the rest of the image has been
        // successfully loaded into the flash.  This way if there is some error,
        // the updater will detect that a user application is not present and
        // will not attempt to run it.
        //
        // For the first block, do not program the first two word locations
        // (8 bytes).  These two words will be programmed later, after
        // everything else.
        //
        if(ui32ProgAddr == APP_START_ADDRESS)
        {
            uint32_t *pui32Temp;

            pui32Temp = (uint32_t *)g_ui8SectorBuf;
            ui32SavedRegs[0] = pui32Temp[0];
            ui32SavedRegs[1] = pui32Temp[1];

            //
            // Call the function to program a block of flash.  Skip the first
            // two words (8 bytes) since these contain the initial SP and PC.
            //
            ROM_FlashProgram((uint32_t *)&g_ui8SectorBuf[8],
                             ui32ProgAddr + 8,
                             ((ui32DataSize - 8) + 3) & ~3);
        }

        //
        // All other blocks except the first block
        //
        else
        {
            //
            // Call the function to program a block of flash.  The length of the
            // block passed to the flash function must be divisible by 4.
            //
            ROM_FlashProgram((uint32_t *)g_ui8SectorBuf, ui32ProgAddr,
                             (ui32DataSize + 3) & ~3);
        }

        //
        // If there is more image to program, then update the programming
        // address.  Progress will continue to the next iteration of
        // the while loop.
        //
        if(ui32Remaining)
        {
            ui32ProgAddr += ui32DataSize;
        }

        //
        // Otherwise we are done programming so perform final steps.
        // Program the first two words of the image that were saved earlier,
        // and return a success indication.
        //
        else
        {
            ROM_FlashProgram((uint32_t *)ui32SavedRegs, APP_START_ADDRESS,
                              8);

            return(0);
        }
    }

    //
    // If we make it here, that means that an attempt to read a sector of
    // data from the device was not successful.  That means that the complete
    // user app has not been programmed into flash, so just return an error
    // indication.
    //
    return(1);
}

//*****************************************************************************
//
// This is the main routine for performing an update from a mass storage
// device.
//
// This function forms the main loop of the USB stick updater.  It polls for
// a USB mass storage device to be connected,  Once a device is connected
// it will attempt to read a firmware image from the device and load it into
// flash.
//
// \return None.
//
//*****************************************************************************
void
UpdaterUSB(void)
{
    //
    // Loop forever, running the USB host driver.
    //
    while(1)
    {
        USBHCDMain();

        //
        // Check for a state change from the USB driver.
        //
        switch(g_eState)
        {
            //
            // This state means that a mass storage device has been
            // plugged in and enumerated.
            //
            case STATE_DEVICE_ENUM:
            {
                //
                // Attempt to read the application image from the storage
                // device and load it into flash memory.
                //
                if(ReadAppAndProgram())
                {
                    //
                    // There was some error reading or programming the app,
                    // so reset the state to no device which will cause a
                    // wait for a new device to be plugged in.
                    //
                    g_eState = STATE_NO_DEVICE;
                }
                else
                {
                    //
                    // User app load and programming was successful, so reboot
                    // the micro.  Perform a software reset request.  This
                    // will cause the microcontroller to reset; no further
                    // code will be executed.
                    //
                    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY |
                                        NVIC_APINT_SYSRESETREQ;

                    //
                    // The microcontroller should have reset, so this should
                    // never be reached.  Just in case, loop forever.
                    //
                    while(1)
                    {
                    }
                }
                break;
            }

            //
            // This state means that there is no device present, so just
            // do nothing until something is plugged in.
            //
            case STATE_NO_DEVICE:
            {
                break;
            }
        }
    }
}

//*****************************************************************************
//
// Configure the USB controller and power the bus.
//
// This function configures the USB controller for host operation.
// It is assumed that the main system clock has been configured at this point.
//
// \return None.
//
//*****************************************************************************
void
ConfigureUSBInterface(void)
{
    //
    // Enable the uDMA controller and set up the control table base.
    // This is required by usblib.
    //
    SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
    SysCtlDelay(80);
    uDMAEnable();
    uDMAControlBaseSet(g_sDMAControlTable);

    //
    // Enable the USB controller.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_USB0);

    //
    // Set the USB pins to be controlled by the USB controller.
    //
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    ROM_GPIOPinConfigure(GPIO_PD6_USB0EPEN);
    ROM_GPIOPinTypeUSBDigital(GPIO_PORTD_BASE, GPIO_PIN_6);
    ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOL);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTL_BASE, GPIO_PIN_6 | GPIO_PIN_7);
    ROM_GPIOPinTypeUSBAnalog(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);

    //
    // Register the host class driver
    //
    USBHCDRegisterDrivers(0, g_ppHostClassDrivers, NUM_CLASS_DRIVERS);

    //
    // Open an instance of the mass storage class driver.
    //
    g_psMSCInstance = USBHMSCDriveOpen(0, MSCCallback);

    //
    // Initialize the power configuration. This sets the power enable signal
    // to be active high and does not enable the power fault.
    //
    USBHCDPowerConfigInit(0, USBHCD_VBUS_AUTO_HIGH | USBHCD_VBUS_FILTER);

    //
    // Force the USB mode to host with no callback on mode changes since
    // there should not be any.
    //
    USBStackModeSet(0, eUSBModeForceHost, 0);

    //
    // Wait 10ms for the pin to go low.
    //
    SysCtlDelay(g_ui32SysClock/100);

    //
    // Initialize the host controller.
    //
    USBHCDInit(0, g_pHCDPool, HCD_MEMORY_SIZE);
}

//*****************************************************************************
//
// Generic configuration is handled in this function.
//
// This function is called by the start up code to perform any configuration
// necessary before calling the update routine.  It is responsible for setting
// the system clock to the expected rate and setting flash programming
// parameters prior to calling ConfigureUSBInterface() to set up the USB
// hardware.
//
// \return None.
//
//*****************************************************************************
void
UpdaterMain(void)
{
    //
    // Make sure NVIC points at the correct vector table.
    //
    HWREG(NVIC_VTABLE) = 0; 

    //
    // Run from the PLL at 120 MHz.
    //
		/*
    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_PLL |
                                       SYSCTL_CFG_VCO_480), 120000000);
		*/
    g_ui32SysClock = SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ |
                                       SYSCTL_OSC_MAIN |
                                       SYSCTL_USE_PLL |
                                       SYSCTL_CFG_VCO_480), 120000000);

    //
    // Enable lazy stacking for interrupt handlers.  This allows floating-point
    // instructions to be used within interrupt handlers, but at the expense of
    // extra stack usage.
    //
    ROM_FPULazyStackingEnable();

    //
    // Configure the USB interface and power the bus.
    //
    ConfigureUSBInterface();

    //
    // Call the updater function.  This will attempt to load a new image
    // into flash from a USB memory stick.
    //
    UpdaterUSB();
}

//*****************************************************************************
//
// Main entry point for the USB stick update example.
//
// This function will check to see if a flash update should be performed from
// the USB memory stick, or if the user application should just be run without
// any update.
//
// The following checks are made, any of which mean that an update should be
// performed:
// - the PC and SP for the user app do not appear to be valid
// - a memory location contains a certain value, meaning the user app wants
//   to force an update
// - the user button on the eval board is being pressed, meaning the user wants
//   to force an update even if there is a valid user app in memory
//
// If any of the above checks are true, then that means that an update should
// be attempted.  The USB stick updater will then wait for a USB stick to be
// plugged in, and once it is look for a firmware update file.
//
// If none of the above checks are true, then the user application that is
// already in flash is run and no update is performed.
//
// \return None.
//
//*****************************************************************************
#define	CLOCK_120MHZ			(120000000)
#define	CLOCK_85MHZ				(85000000)
#define	CLOCK_66MHZ				(66666666)
#define	CLOCK_40MHZ				(40000000)
#define	CLOCK_30MHZ				(30000000)
#define	CLOCK_30M4HZ			(30400000)
#define	CLOCK_25MHZ				(25000000)
#define	CLOCK_20MHZ				(20000000)
#define	CLOCK_12MHZ				(12000000)
#define	CLOCK_12M5HZ			(12500000)				// SDカードの限界？
#define	CLOCK_10MHZ				(10000000)

BYTE	bRet;
BYTE	bFactID;
WORD	wDeviceID;

#define	EXFLASH_CSA_LOW		(ROM_GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_6,(BYTE)~(GPIO_PIN_6)))
#define	EXFLASH_CSA_HIGH	(ROM_GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_6,GPIO_PIN_6))
#define	EXFLASH_CSB_LOW		(ROM_GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_7,(BYTE)~(GPIO_PIN_7)))
#define	EXFLASH_CSB_HIGH	(ROM_GPIOPinWrite(GPIO_PORTE_BASE,GPIO_PIN_7,GPIO_PIN_7))

#define	SDCARD_CS_LOW			(ROM_GPIOPinWrite(GPIO_PORTP_BASE,GPIO_PIN_6,(BYTE)~(GPIO_PIN_6)))
#define	SDCARD_CS_HIGH		(ROM_GPIOPinWrite(GPIO_PORTP_BASE,GPIO_PIN_6,GPIO_PIN_6))

// SDカードの有無チェック true でアリ
#define	SDCARD_IS_FIND		( (ROM_GPIOPinRead(GPIO_PORTP_BASE,GPIO_PIN_7) == 0)? true : false )

#define	EXRESET_LOW				(ROM_GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,(BYTE)~(GPIO_PIN_2)))
#define	EXRESET_HIGH			(ROM_GPIOPinWrite(GPIO_PORTB_BASE,GPIO_PIN_2,GPIO_PIN_2))

// LCD
#define	USE_PALET_TEST							(0)						// パレットを使う場合 1
#define	USE_WBUFFER_API							(1)						// 1の場合、TIのAPIによるWバッファリングを使う
#define	USE_SINGLEBUF								(0)						// 1の場合、なんちゃってWバッファもしない

#define	LCD_BACKLED_HIGH	(ROM_GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_5,GPIO_PIN_5))
#define	LCD_BACKLED_LOW		(ROM_GPIOPinWrite(GPIO_PORTF_BASE,GPIO_PIN_5,(BYTE)~(GPIO_PIN_5)))

#define	LCD_WIDTH										(800)
#define	LCD_HEIGHT									(480)
#if	USE_PALET_TEST == 0		//[[[
#define	SDRAM_GBUF_SIZE							(0x00177000)							// 800 * 480 * 32bit / 8 = 1536000 = 0x00177000
//#define	SDRAM_GBUF_SIZE							(0x00119400)							// 800 * 480 * 24bit / 8 = 1152000 = 0x00119400
#endif		//]]]
#if	USE_PALET_TEST == 1		//[[[
#define	SDRAM_GBUF_SIZE							(0x0002EE00)							// 800 * 480 * 4bit / 8 = 192000 = 0x0002EE00
#define	PALET_COLS									(16)
#define	PALET_SIZE									(PALET_COLS * 2)
const	uint32_t	cgdwaPalet[PALET_COLS] = {
	0x00000000 ,
	0x00FFFFFF ,
	0x000000FF ,
	0x0000FF00 ,
	0x00FF0000 ,
	0x0000FFFF ,
	0x00FFFF00 ,
	0x00FF00FF ,
	0x00606060 ,
	0x00a0a0a0 ,
	0x00000080 ,
	0x00008000 ,
	0x00800000 ,
	0x00008080 ,
	0x00808000 ,
	0x00800080
};
#endif		//]]]


#define	LCD_MODEFLAG		(LCD_MODE_RASTER | LCD_MODE_AUTO_UFLOW_RESTART)
//#define	LCD_MODEFLAG		(LCD_MODE_RASTER)

#define	LCD_MODEFLAG_A	(LCD_MODE_RASTER | LCD_MODE_AUTO_UFLOW_RESTART)
#define	LCD_MODEFLAG_B	(LCD_MODE_RASTER)

//#define RASTER_TIMING_SYNCS_OPPOSITE_PIXCLK     (0x00000000)
//#define RASTER_TIMING_SYNCS_ON_RISING_PIXCLK    (0x02000000)
//#define RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK   (0x03000000)
//#define RASTER_TIMING_ACTIVE_HIGH_OE            (0x00000000)
//#define RASTER_TIMING_ACTIVE_LOW_OE             (0x00800000)
//#define RASTER_TIMING_ACTIVE_HIGH_PIXCLK        (0x00000000)
//#define RASTER_TIMING_ACTIVE_LOW_PIXCLK         (0x00400000)
//#define RASTER_TIMING_ACTIVE_HIGH_HSYNC         (0x00000000)
//#define RASTER_TIMING_ACTIVE_LOW_HSYNC          (0x00200000)
//#define RASTER_TIMING_ACTIVE_HIGH_VSYNC         (0x00000000)
//#define RASTER_TIMING_ACTIVE_LOW_VSYNC          (0x00100000)
#define	TIMING_FLAG			(RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_OE | RASTER_TIMING_ACTIVE_HIGH_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_HSYNC | RASTER_TIMING_ACTIVE_HIGH_VSYNC)
//#define	TIMING_FLAG			(RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK | RASTER_TIMING_ACTIVE_LOW_OE | RASTER_TIMING_ACTIVE_LOW_PIXCLK | RASTER_TIMING_ACTIVE_LOW_HSYNC | RASTER_TIMING_ACTIVE_LOW_VSYNC)
//#define	TIMING_FLAG			(RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK)

#define	TIMING_FLAG_A		(RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_OE | RASTER_TIMING_ACTIVE_HIGH_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_HSYNC | RASTER_TIMING_ACTIVE_HIGH_VSYNC)
#define	TIMING_FLAG_B		(RASTER_TIMING_SYNCS_ON_FALLING_PIXCLK | RASTER_TIMING_ACTIVE_LOW_OE | RASTER_TIMING_ACTIVE_LOW_PIXCLK | RASTER_TIMING_ACTIVE_LOW_HSYNC | RASTER_TIMING_ACTIVE_LOW_VSYNC)
#define	TIMING_FLAG_C		(RASTER_TIMING_SYNCS_ON_RISING_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_OE | RASTER_TIMING_ACTIVE_HIGH_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_HSYNC | RASTER_TIMING_ACTIVE_HIGH_VSYNC)
#define	TIMING_FLAG_D		(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)
#define	TIMING_FLAG_E		(RASTER_TIMING_SYNCS_OPPOSITE_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_OE | RASTER_TIMING_ACTIVE_HIGH_PIXCLK | RASTER_TIMING_ACTIVE_HIGH_HSYNC | RASTER_TIMING_ACTIVE_HIGH_VSYNC)
#define	TIMING_FLAG_F		(RASTER_TIMING_SYNCS_OPPOSITE_PIXCLK | RASTER_TIMING_ACTIVE_LOW_OE | RASTER_TIMING_ACTIVE_LOW_PIXCLK | RASTER_TIMING_ACTIVE_LOW_HSYNC | RASTER_TIMING_ACTIVE_LOW_VSYNC)

//#define	RASTER_CONFIG		(RASTER_FMT_ACTIVE_24BPP_PACKED)
//#define	RASTER_CONFIG		(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_LOAD_DATA_ONLY)
//#define	RASTER_CONFIG		(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
//#define	RASTER_CONFIG		(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_ACTVID_DURING_BLANK | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG		(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_ACTVID_DURING_BLANK)
//#define	RASTER_CONFIG		(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_LOAD_DATA_ONLY)

#if USE_PALET_TEST == 0		//[[[
#define	RASTER_CONFIG_A	(RASTER_FMT_ACTIVE_24BPP_PACKED)
#define	RASTER_CONFIG_B	(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_ACTVID_DURING_BLANK)
#define	RASTER_CONFIG_C	(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_ACTVID_DURING_BLANK | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_D	(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_E	(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_F	(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_G	(RASTER_FMT_ACTIVE_24BPP_PACKED | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_H	(RASTER_FMT_ACTIVE_24BPP_UNPACKED)
#define	RASTER_CONFIG_I	(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_ACTVID_DURING_BLANK)
#define	RASTER_CONFIG_J	(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_ACTVID_DURING_BLANK | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_K	(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_L	(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_M	(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_N	(RASTER_FMT_ACTIVE_24BPP_UNPACKED | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#endif		//]]]
#if USE_PALET_TEST == 1		//[[[
#define	RASTER_CONFIG_A	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT)
#define	RASTER_CONFIG_B	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK)
#define	RASTER_CONFIG_C	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_D	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_E	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_F	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_G	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_H	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT)
#define	RASTER_CONFIG_I	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK)
#define	RASTER_CONFIG_J	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_K	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_L	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#define	RASTER_CONFIG_M	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED)
#define	RASTER_CONFIG_N	(RASTER_FMT_ACTIVE_PALETTIZED_16BIT | RASTER_ACTVID_DURING_BLANK | RASTER_NIBBLE_MODE_ENABLED | RASTER_LOAD_DATA_ONLY)
#endif		//]]]

//#define	LCDDMA_CONFIG		(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_PING_PONG)
//#define	LCDDMA_CONFIG		(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
//#define	LCDDMA_CONFIG		(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG		(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
//#define	LCDDMA_CONFIG		(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)

#if USE_WBUFFER_API == 0		//[[[ 1 bufferring
#define	LCDDMA_CONFIG_A	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_B	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_C	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_D	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_E	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_F	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_G	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_H	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_I	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_J	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_K	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_L	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_M	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_N	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_O	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_P	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_Q	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_R	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_S	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_T	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_U	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_V	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_W	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS)
#define	LCDDMA_CONFIG_X	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS)
#endif		//]]]
#if USE_WBUFFER_API == 1		//[[[ W buffering
#define	LCDDMA_CONFIG_A	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_B	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_C	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_D	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_E	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_F	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_G	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_H	(LCD_DMA_PRIORITY_7 | LCD_DMA_BURST_16 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_I	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_J	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_K	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_L	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_8 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_M	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_N	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_O	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_P	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_4 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_Q	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_R	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_S	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_T	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_2 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_U	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_3210 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_V	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_0123 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_W	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_1023 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#define	LCDDMA_CONFIG_X	(LCD_DMA_PRIORITY_3 | LCD_DMA_BURST_1 | LCD_DMA_BYTE_ORDER_2301 | LCD_DMA_FIFORDY_512_WORDS | LCD_DMA_PING_PONG)
#endif		//]]]

tLCDRasterTiming	glcdTasterTiming = {
	TIMING_FLAG,
	LCD_WIDTH,
	LCD_HEIGHT,
	40,						// HFront Porch 1-1024
	40,						// HBack Porch  1-1024
	48,					// HSync Width  1-1024
	13,						// VFront Porch 0-255
	29,						// VBack Porch  0-255
	3,						// VSync Width  1-64
	0							// ACBias Line Count
};

	WORD	wHPorch = 160;		// for test
	BYTE	bVPorch = 32;		// for test

// SDカード and FatFs
FATFS		gFatFs;									// FatFs
FIL			gfObj;									// file object
DIR			gdObj;									// directory object
FILINFO	gfInfo;									// file info
FRESULT	gfRet;									// 戻り値

// for flash
FATFS		gaFatFs[2];							// FatFs
FIL			gafObj[2];							// file object
DIR			gadObj[2];							// directory object
FILINFO	gafInfo[2];							// file info
FRESULT	gafRet[2];							// 戻り値

// ドライブ番号 diskio.h で定義しているので異ならないように注意！
#define	DRV_SDRAM			(0)
#define	DRV_FLS_A			(1)
#define	DRV_FLS_B			(2)
#define	DRV_SDCARD		(3)

DWORD		gdwaFlashID[2] = {	DRV_FLS_A , DRV_FLS_B };

//WORD	gwaRamTmp[8];

#define	INNER_EEPROM_TEST				(0)				// 内蔵EEPROMの書き読みテストをする場合 1
#if	INNER_EEPROM_TEST == 1		//[[[
void	InnerFlashTest(void);
#endif		//]]]

int	main(void){
	// ローカル変数宣言等
	uint32_t *pui32App;
	uint32_t	ui32SysClock;
	WORD	w;
	WORD	wDotX,wDotY;
	BYTE	b;
	DWORD	dw;	
	
	
	// メイン本体開始
	
	ui32SysClock = ROM_SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), CLOCK_120MHZ);
	g_ui32SysClock = ui32SysClock;
	PinoutSet();													// pinmux で作成した初期化関数
	ROM_IntMasterEnable();								// 大本の割り込みの許可
	
	LED0_OFF;
	LED1_OFF;
	LED2_OFF;
	LED3_OFF;
	
	LED0_ON;

	EXRESET_LOW;													// LOWでリセット
	EXRESET_HIGH;													// 周辺機器のリセット復帰

	KEYLED_OFF;
	KEYLED_ON;
	KEYLED_OFF;

	////////////////////////////////////////////////////////////////// SDRAM
	// SDRAM初期化
	SDramInit(ui32SysClock);
	gwarrSDRAMtmp = (WORD *)GetSDRAMBaseAddress();

	///////////////////////////////////////////////////////////////// LCD明るさ関連
	// LCD明るさ関連
	LCD_BACKLED_HIGH;
	// 明るさ調整用PWM
	ROM_PWMGenConfigure(PWM0_BASE,PWM_GEN_1,PWM_GEN_MODE_DOWN | PWM_GEN_MODE_NO_SYNC);
	ROM_PWMClockSet(PWM0_BASE,PWM_SYSCLK_DIV_64);
	ROM_PWMGenDisable(PWM0_BASE,PWM_GEN_1);

	ROM_PWMGenPeriodSet(PWM0_BASE,PWM_GEN_1,(DWORD)(ui32SysClock / (6.4 * 2000)) );
	ROM_PWMPulseWidthSet(PWM0_BASE,PWM_OUT_2,(DWORD)(ui32SysClock / (6.4 * 2000)) >> 1 );
	ROM_PWMGenEnable(PWM0_BASE,PWM_GEN_1);
	ROM_PWMOutputState(PWM0_BASE,PWM_OUT_2_BIT,true);

	////////////////////////////////////////////////////////////////// SDRAMのテスト
	// SARAMのテスト

	// 領域テスト
	// 値格納
	for(dwTmp = SDRAM_START_ADDRESS;dwTmp < SDRAM_END_ADDRESS + 1;dwTmp++){
		dwB = XorShift16((WORD)dwTmp);
		gwarrSDRAMtmp[dwTmp] = dwB;
	}
	// 値確認
	for(dwTmp = SDRAM_START_ADDRESS;dwTmp < SDRAM_END_ADDRESS + 1;dwTmp++){
		dwA = gwarrSDRAMtmp[dwTmp];
		dwB = XorShift16((WORD)dwTmp);
		if(dwA != dwB){
			LED1_ON;
		}
	}

	// SDRAMの型テスト
	/* OKだったのでコメントアウト
	DWORD	*pdwSDtest;
	pdwSDtest = (DWORD*)&gwarrSDRAMtmp[0];
	*(pdwSDtest + 0) = 0x01234567;
	*(pdwSDtest + 1) = 0x89ABCDEF;
	LED1_OFF;
	if(*(pdwSDtest + 0) != 0x01234567){
		LED1_ON;
	}
	if(*(pdwSDtest + 1) != 0x89ABCDEF){
		LED1_ON;
	}
	for(b=0;b<8;b++){
		gwaRamTmp[b] = gwarrSDRAMtmp[b];
		// gwarrSDRAMtmp[0] = 0x4567
		// gwarrSDRAMtmp[1] = 0x0123
		// gwarrSDRAMtmp[2] = 0xCDEF
		// gwarrSDRAMtmp[3] = 0x89AB
	}

	QWORD	*pqwSDtest;
	pqwSDtest = (QWORD*)&gwarrSDRAMtmp[0];
	*(pqwSDtest + 0) = 0xFEDCBA8976543210;
	*(pqwSDtest + 1) = 0x0123456789ABCDEF;
	LED1_OFF;
	if(*(pqwSDtest + 0) != 0xFEDCBA8976543210){
		LED1_ON;
	}
	if(*(pqwSDtest + 1) != 0x0123456789ABCDEF){
		LED1_ON;
	}
	for(b=0;b<8;b++){
		gwaRamTmp[b] = gwarrSDRAMtmp[b];
		// gwarrSDRAMtmp[0] = 0x3210
		// gwarrSDRAMtmp[1] = 0x7654
		// gwarrSDRAMtmp[2] = 0xBA89
		// gwarrSDRAMtmp[3] = 0xFEDC
	}
	
	BYTE	*pbSDtest;
	pbSDtest = (BYTE*)&gwarrSDRAMtmp[0];
	for(b=0;b<16;b++){
		*(pbSDtest + b) = 0xA0 + b;
	}
	LED1_OFF;
	for(b=0;b<16;b++){
		if(*(pbSDtest + b) != 0xA0 + b){
			LED1_ON;
		}
	}
	for(b=0;b<8;b++){
		gwaRamTmp[b] = gwarrSDRAMtmp[b];
		// gwarrSDRAMtmp[0] = 0xA1A0
		// gwarrSDRAMtmp[1] = 0xA3A2
		// gwarrSDRAMtmp[2] = 0xA5A4
		// gwarrSDRAMtmp[3] = 0xA6A3
		// ....
		// gwarrSDRAMtmp[6] = 0xADAC
		// gwarrSDRAMtmp[7] = 0xAFAE
	}
	OKだったのでコメントアウト */
	LED2_ON;

	////////////////////////////////////////////////////////////////// 内蔵EEPROM関連
	// 内蔵EEPROM
	LED0_OFF;
	LED1_OFF;
	LED2_OFF;
	LED3_OFF;
	/*
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_EEPROM0);		// EEPROMに関するHWの許可
	ROM_EEPROMInit();
	LED0_ON;
#if	INNER_EEPROM_TEST == 1		//[[[
	InnerFlashTest();
	LED1_ON;
#endif		//]]]
	ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_EEPROM0);		// EEPROMに関するHWの禁止
	*/
	// EEPROMを有効にしたままだと、LCDの書き換えループが終わらなくなる。

	TimerXInit(ui32SysClock);						// タイマーの初期化

	//////////////////////////////////////////////////////////////// LCD関連
	// LCD関連
	DWORD*	pLCDBuf[2];
	pLCDBuf[0] = (DWORD*)GetSDRAMLCDBufAddressA();			// SDRAMのアドレス取得
	pLCDBuf[1] = (DWORD*)GetSDRAMLCDBufAddressB();			// SDRAMのアドレス取得
	
	// LCD Mode : ラスター
	ROM_LCDModeSet(LCD0_BASE,LCD_MODEFLAG,CLOCK_30M4HZ,ui32SysClock);

	// Output format
	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_A,0);

	// Raster timing
	glcdTasterTiming.ui32Flags = TIMING_FLAG_A;
	ROM_LCDRasterTimingSet(LCD0_BASE,&glcdTasterTiming);

	// DMA config
	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_A);

	// Frame buffer set
#if USE_PALET_TEST == 0		//[[[ パレットを使わないタイプ
#if USE_WBUFFER_API == 1		// [[[ ダブルバッファー
	for(b=0;b<2;b++){
		ROM_LCDRasterFrameBufferSet(LCD0_BASE,b,pLCDBuf[b],SDRAM_GBUF_SIZE);
	}
#endif		//]]]
#if USE_WBUFFER_API == 0		//[[[ シングルバッファー
	ROM_LCDRasterFrameBufferSet(LCD0_BASE,0,pLCDBuf[0],SDRAM_GBUF_SIZE);
#endif		//]]]
	// Palette set
	ROM_LCDRasterPaletteSet(LCD0_BASE,LCD_PALETTE_TYPE_DIRECT,(uint32_t *)(pLCDBuf[0]), 0, 0, 0);
#endif		//]]]
#if USE_PALET_TEST == 1		//[[[ パレットを使うタイプ
#if USE_WBUFFER_API == 1		// [[[ ダブルバッファ−
	for(b=0;b<2;b++){
		ROM_LCDRasterFrameBufferSet(LCD0_BASE,b,pLCDBuf[b],SDRAM_GBUF_SIZE + PALET_SIZE);
	}
#endif		//]]]
#if USE_WBUFFER_API == 0		//[[[ シングルバッファー
	ROM_LCDRasterFrameBufferSet(LCD0_BASE,0,pLCDBuf[0],SDRAM_GBUF_SIZE + PALET_SIZE);
#endif		//]]]
	// Palette set
	ROM_LCDRasterPaletteSet(LCD0_BASE,LCD_PALETTE_TYPE_4BPP,(uint32_t *)(pLCDBuf[0]), cgdwaPalet, 0, PALET_COLS);
#endif		//]]]

	//////////////////////////////////////////////////////////////// LCDバッファのクリア
	// バッファのクリア
	LED0_OFF;
	LED1_OFF;
	for(dw=0;dw<LCD_WIDTH * LCD_HEIGHT;dw++){
		*(pLCDBuf[0] + dw) = 0xFFFFFFFF;
		//*(pLCDBuf[0] + dw) = 0x40404040;
		*(pLCDBuf[1] + dw) = 0xFFFFFFFF;
		if((dw & 0xfff) == 0){	if(LED2_CHK_OFF == true){	LED2_ON;	} else {	LED2_OFF;	}	}
		if(*(pLCDBuf[0] + dw) != 0xFFFFFFFF){		// 値の確認
			LED0_ON;
		}
		if(*(pLCDBuf[1] + dw) != 0xFFFFFFFF){		// 値の確認
			LED1_ON;
		}
	}
	LED0_OFF;
	LED1_OFF;
	// 有効化
	ROM_LCDRasterEnable(LCD0_BASE);
	

	//////////////////////////////////////////////////////////////// タッチパネル
	// タッチパネル
	TouchInit(ui32SysClock);
	TouchInterruptEnable(true);
	TouchEnable(true);

	//////////////////////////////////////////////////////////////// Flashのテスト
	// Flashのテスト
	// チップセレクト（どれも選択せず）
	SDCARD_CS_HIGH;
	EXFLASH_CSA_HIGH;
	EXFLASH_CSB_HIGH;

	// SSI1の許可
	ROM_SysCtlPeripheralDisable(SYSCTL_PERIPH_SSI1);
	ROM_SysCtlPeripheralReset(SYSCTL_PERIPH_SSI1);
	ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_SSI1);
	while(!(ROM_SysCtlPeripheralReady(SYSCTL_PERIPH_SSI1)));
	// ポートのセッティング
	ROM_SPIFlashInit(SSI1_BASE,ui32SysClock,CLOCK_12M5HZ);
	ROM_SSIEnable(SSI1_BASE);

	LED3_OFF;
	LED2_OFF;
	LED1_OFF;
	LED0_OFF;
	WORD	wCnt = 0;
	bRet = 0xff;
	wDeviceID = 0;
	//////////////////////////////////////////////////////////////// SDとFlash
	// SDとFlash
	while(1){
		if(SDCARD_IS_FIND == true){
			// SDカードアリ
			LED3_ON;
			Wait1msec(1000);
			gfRet = f_mount(DRV_SDCARD,&gFatFs);				// マウント
			if(gfRet == FR_OK){
				/* ファイル書き込みのテスト 2015/12/01 OK */
				gfRet = f_open(&gfObj,"3:/testfile.txt",FA_WRITE | FA_CREATE_ALWAYS);		// ファイル書き込み＋作成でオープン
				if(gfRet == FR_OK){
					gfRet = f_write(&gfObj,"It works!\r\n",11,(FS_UINT*)&w);		// 書き込み、書き込みバイト数、書き込まれたバイト数
					gfRet = f_write(&gfObj,VERSION_STRING,36,(FS_UINT*)&w);			// 書き込み、書き込みバイト数、書き込まれたバイト数
					gfRet = f_write(&gfObj,"\r\n",2,(FS_UINT*)&w);							// 書き込み、書き込みバイト数、書き込まれたバイト数
				}
				f_close(&gfObj);
				/**/
				/* ディレクトリーの取得テスト 2015/12/02 */
				/*
				gfRet = f_opendir(&gdObj,"3:/");								// ディレクトリーのオープン
				if(gfRet == FR_OK){
					gfRet = f_readdir(&gdObj,&gfInfo);
					if(gfRet == FR_OK){
						break;
					}
				}
				if(gfRet == FR_OK){	break;	}
				*/
			}
			f_mount(0,NULL);							// アンマウント
			break;
		} else {
			// SDカードナシ
			LED3_OFF;
			// チップセレクト（Flash）
			SDCARD_CS_HIGH;
			EXFLASH_CSA_LOW;
			EXFLASH_CSB_HIGH;
			Wait1usec(1);
			if(bRet != 0){
				bRet = ROM_SPIFlashReadStatus(SSI1_BASE);					// Get Status
			} else {
				LED1_ON;
				ROM_SPIFlashReadID(SSI1_BASE,&bFactID,&wDeviceID);
			}
			// チップセレクト（どれも選択せず）
			SDCARD_CS_HIGH;
			EXFLASH_CSA_HIGH;
			EXFLASH_CSB_HIGH;
			if(wDeviceID != 0){
				LED2_ON;
				break;
			}
			Wait1usec(1);
		}
		wCnt++;	wCnt &= 0x01ff;
		if(wCnt == 0){	if(LED0_CHK_OFF == true){	LED0_ON;	} else {	LED0_OFF;	}	}
	}
	LED0_ON;
	
	//////////////////////////////////////////////////////////////// FlashのFAT
	// FlashのFAT
	LED1_OFF;
	LED2_OFF;
	LED3_OFF;
	if(wDeviceID != 0){
	}


	//////////////////////////////////////////////////////////////// タイマー
	// タイマー
	DWORD	dwCountTmpA;
	DWORD	dwCountTmpD;
	DWORD	dwTimeOutA = 200;
	DWORD	dwTimeOutD = 200;
	if((wDeviceID != 0x0000) && (wDeviceID != 0xFFFF)){
		// SPIフラッシュでデバイスIDが取得できていれば間隔を遅くする
		dwTimeOutD = 500;
	}
	dwCountTmpD = Get1msecTimeCounter();
	for(b=0;b<5;){
		if(CheckLoop1msecTimeOut(dwCountTmpD,dwTimeOutD) == true){
			if(LED3_CHK_OFF == true){
				LED3_ON;
			} else {
				LED3_OFF;
			}
			if(KEYLED_CHK_OFF == true){
				KEYLED_ON;
			} else {
				KEYLED_OFF;
			}
			dwCountTmpD = Get1msecTimeCounter();
			b++;
		}
	}

	//////////////////////////////////////////////////////////////// キー
	// キー
	LED0_OFF;
	LED1_OFF;
	LED2_OFF;
	LED3_OFF;
	BYTE	bLEDflag = 0;
	dwCountTmpD = Get1000msecTimeCounter();
	dwCountTmpA = COUNT_FALSE_VAL;
	dwTimeOutD = 10;

	BYTE	bLCDBlightness = 5;
	//////////////////////////////////////////////////////////////// LCD 明るさ
	// LCD 明るさを n * 10％出力
	ROM_PWMPulseWidthSet(PWM0_BASE,PWM_OUT_2,(DWORD)( (ui32SysClock * bLCDBlightness) / (6.4 * 2000 * 10)) );

	bool	bPushOnce = false;
#if USE_WBUFFER_API == 1		//[[[ W buffering
	BYTE	bLCDbufPage = 0;
#endif		//]]]
#if USE_WBUFFER_API == 0		//[[[ single buffering
#if USE_SINGLEBUF == 0			//[[[ [[[ なんちゃってWバッファ
	BYTE	bLCDbufPage = 1;
#endif		//]]] ]]]
#if USE_SINGLEBUF == 1			//[[[ [[[ なんちゃっても禁止
	BYTE	bLCDbufPage = 0;
#endif		//]]] ]]]
#endif		//]]]

#if USE_PALET_TEST == 0		//[[[
	DWORD	dwarColTmpA[8] = {
		0x000000FF,
		0x0000FF00,
		0x00FF0000,
		0xFF000000,
		0x00FFFF00,
		0xFFFF0000,
		0xFFFFFFFF,
		0x00000000
	};
	DWORD	dwarColTmpB[8] = {
		0x0000004F,
		0x00004F00,
		0x004F0000,
		0x00004F4F,
		0x004F4F00,
		0x4F4F0000,
		0x4F4F4F4F,
		0x40404040
	};
#endif		//]]]
#if	USE_PALET_TEST == 1		//[[[
	DWORD	dwarColTmpA[8] = {
		1 , 2 , 3 , 4 , 5 , 6 , 7 , 8
	};
#endif		//]]]
	BYTE	bPalet = 0;
	BYTE	bPaletOld = 0;
	DWORD	dwLcdTimeCount = 0;
	bool	bHCountStop = true;
	bool	bVCountStop = true;
	bool	bRasterChange[5];
	BYTE	bRasterStep[5];
	for(b=0;b<5;b++){
		bRasterStep[b] = 0;
		bRasterChange[b] = false;
	}
	//////////////////////////////////////////////////////////////// メインループ
	// メインループ
	while(1){
		if(KEY_MENU_ONCHECK != true){
			//LED0_OFF;
			//bLEDflag &= ~(0x01);
			b = 3;
			bRasterChange[b] = false;
		} else {
			//LED0_ON;
			//bLEDflag |= 0x01;
			//bVCountStop = false;
			b = 3;
			if(bRasterChange[b] == false){
				ROM_LCDRasterDisable(LCD0_BASE);
				switch(bRasterStep[b]){
				case 0:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_A);	bRasterStep[b]++;	break;
				case 1:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_B);	bRasterStep[b]++;	break;
				case 2:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_C);	bRasterStep[b]++;	break;
				case 3:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_D);	bRasterStep[b]++;	break;
				case 4:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_E);	bRasterStep[b]++;	break;
				case 5:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_F);	bRasterStep[b]++;	break;
				case 6:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_G);	bRasterStep[b]++;	break;
				case 7:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_H);	bRasterStep[b]++;	break;
				case 8:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_I);	bRasterStep[b]++;	break;
				case 9:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_J);	bRasterStep[b]++;	break;
				case 10:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_K);	bRasterStep[b]++;	break;
				case 11:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_L);	bRasterStep[b]++;	break;
				case 12:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_M);	bRasterStep[b]++;	break;
				case 13:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_N);	bRasterStep[b]++;	break;
				case 14:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_O);	bRasterStep[b]++;	break;
				case 15:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_P);	bRasterStep[b]++;	break;
				case 16:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_Q);	bRasterStep[b]++;	break;
				case 17:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_R);	bRasterStep[b]++;	break;
				case 18:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_S);	bRasterStep[b]++;	break;
				case 19:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_T);	bRasterStep[b]++;	break;
				case 20:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_U);	bRasterStep[b]++;	break;
				case 21:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_V);	bRasterStep[b]++;	break;
				case 22:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_W);	bRasterStep[b]++;	break;
				case 23:	ROM_LCDDMAConfigSet(LCD0_BASE,LCDDMA_CONFIG_X);	bRasterStep[b] = 0;	break;
				}
				ROM_LCDRasterEnable(LCD0_BASE);
				bRasterChange[b] = true;
			}
		}
		if(KEY_WS_ONCHECK != true){
			//LED1_OFF;
			//bLEDflag &= ~(0x02);
			b = 2;
			bRasterChange[b] = false;
		} else {
			//LED1_ON;
			//bLEDflag |= 0x02;
			//bVCountStop = true;
			b = 2;
			if(bRasterChange[b] == false){
				ROM_LCDRasterDisable(LCD0_BASE);
				switch(bRasterStep[b]){
				case 0:	glcdTasterTiming.ui32Flags = TIMING_FLAG_A;	bRasterStep[b]++;	break;
				case 1:	glcdTasterTiming.ui32Flags = TIMING_FLAG_B;	bRasterStep[b]++;	break;
				case 2:	glcdTasterTiming.ui32Flags = TIMING_FLAG_C;	bRasterStep[b]++;	break;
				case 3:	glcdTasterTiming.ui32Flags = TIMING_FLAG_D;	bRasterStep[b]++;	break;
				case 4:	glcdTasterTiming.ui32Flags = TIMING_FLAG_E;	bRasterStep[b]++;	break;
				case 5:	glcdTasterTiming.ui32Flags = TIMING_FLAG_F;	bRasterStep[b] = 0;	break;
				}
				ROM_LCDRasterTimingSet(LCD0_BASE,&glcdTasterTiming);
				ROM_LCDRasterEnable(LCD0_BASE);
				bRasterChange[b] = true;
			}
		}
		if(KEY_WI_ONCHECK != true){
			//LED2_OFF;
			LED0_OFF;
			//bLEDflag &= ~(0x04);
			b = 1;
			bRasterChange[b] = false;
		} else {
			//LED2_ON;
			LED0_ON;
			//bLEDflag |= 0x04;
			//bHCountStop = false;
			b = 1;
			if(bRasterChange[b] == false){
				ROM_LCDRasterDisable(LCD0_BASE);
				switch(bRasterStep[b]){
				case 0:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_A,0);	bRasterStep[b]++;	break;
				case 1:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_B,0);	bRasterStep[b]++;	break;
				case 2:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_C,0);	bRasterStep[b]++;	break;
				case 3:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_D,0);	bRasterStep[b]++;	break;
				case 4:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_E,0);	bRasterStep[b]++;	break;
				case 5:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_F,0);	bRasterStep[b]++;	break;
				case 6:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_G,0);	bRasterStep[b]++;	break;
				case 7:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_H,0);	bRasterStep[b]++;	break;
				case 8:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_I,0);	bRasterStep[b]++;	break;
				case 9:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_J,0);	bRasterStep[b]++;	break;
				case 10:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_K,0);	bRasterStep[b]++;	break;
				case 11:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_L,0);	bRasterStep[b]++;	break;
				case 12:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_M,0);	bRasterStep[b]++;	break;
				case 13:	ROM_LCDRasterConfigSet(LCD0_BASE,RASTER_CONFIG_N,0);	bRasterStep[b] = 0;	break;
				}
				ROM_LCDRasterEnable(LCD0_BASE);
				bRasterChange[b] = true;
			}
		}
		if(KEY_LI_ONCHECK != true){
			//LED3_OFF;
			//bLEDflag &= ~(0x08);
			b = 0;
			bRasterChange[b] = false;
		} else {
			//LED3_ON;
			//bLEDflag |= 0x08;
			//bHCountStop = true;
			b = 0;
			if(bRasterChange[b] == false){
				ROM_LCDRasterDisable(LCD0_BASE);
				switch(bRasterStep[b]){
				case 0:	ROM_LCDModeSet(LCD0_BASE,LCD_MODEFLAG_A,CLOCK_30M4HZ,ui32SysClock);	bRasterStep[b]++;	break;
				case 1:	ROM_LCDModeSet(LCD0_BASE,LCD_MODEFLAG_B,CLOCK_30M4HZ,ui32SysClock);	bRasterStep[b] = 0;	break;
				}
				ROM_LCDRasterEnable(LCD0_BASE);
				bRasterChange[b] = true;
			}
		}
		if(KEY_HOME_ONCHECK != true){
			bLEDflag &= ~(0x10);
			b = 4;
			bRasterChange[b] = false;
		} else {
			bLEDflag |= 0x10;
		}
		if(CheckLoop1000msecTimeOut(dwCountTmpD,dwTimeOutD) == true){
			//2015/12/17 点滅コメントアウト //bLEDflag |= 0x80;
			dwCountTmpA = Get1msecTimeCounter();
			dwCountTmpD = Get1000msecTimeCounter();
		}
		if(dwCountTmpA != COUNT_FALSE_VAL){
			if(CheckLoop1msecTimeOut(dwCountTmpA,dwTimeOutA) == true){
				//2015/12/17 点滅コメントアウト //bLEDflag &= ~(0x80);
				dwCountTmpA = COUNT_FALSE_VAL;
				//dwCountTmpD = Get1000msecTimeCounter();
			}
		}
		if(CheckLoop100msecTimeOut(dwLcdTimeCount,2) == true){
			if(bHCountStop == false){
				wHPorch += 10;
				if(wHPorch > 1024){
					wHPorch = 1;
				}
			}
			if(bVCountStop == false){
				bVPorch += 5;
				if(bVPorch >= 255){
					bVPorch = 0;
				}
			}
			if( (bHCountStop == false) || (bVCountStop == false) ){
				ROM_LCDRasterDisable(LCD0_BASE);
				glcdTasterTiming.ui16HBackPorch = wHPorch;
				glcdTasterTiming.ui8VBackPorch = bVPorch;
				ROM_LCDRasterTimingSet(LCD0_BASE,&glcdTasterTiming);
				ROM_LCDRasterEnable(LCD0_BASE);
			}
			dwLcdTimeCount = Get100msecTimeCounter();
		}
		if(bLEDflag != 0x00){
			KEYLED_ON;
			/* 明るさの確認はできたので一旦コメントアウト 2015/12/17
			if(bPushOnce == false){
				bLCDBlightness -= 1;
				if(bLCDBlightness == 0){
					LCD_BACKLED_LOW;
					bLCDBlightness = 10 + 1;
				} else {
					LCD_BACKLED_HIGH;
					//ROM_PWMOutputState(PWM0_BASE,PWM_OUT_2_BIT,false);
					//ROM_PWMGenPeriodSet(PWM0_BASE,PWM_GEN_1,(DWORD)(ui32SysClock / (6.4 * 2000)) );
					ROM_PWMPulseWidthSet(PWM0_BASE,PWM_OUT_2,(DWORD)( (ui32SysClock * bLCDBlightness) / (6.4 * 2000 * 10)) );
					//ROM_PWMGenEnable(PWM0_BASE,PWM_GEN_1);
					//ROM_PWMOutputState(PWM0_BASE,PWM_OUT_2_BIT,true);
				}
			}
			*/
			if(bPushOnce == false){
				bPalet++;
				bPalet &= 0x07;
			}
			bPushOnce = true;
		} else {
			KEYLED_OFF;
			bPushOnce = false;
		}
		if(wDeviceID != 0){
			// フラッシュのテスト
			if(bLEDflag != 0){
				
			}
		}
		// LCDテスト
		//LED2_ON;
		{	if(LED2_CHK_OFF == true){	LED2_ON;	} else {	LED2_OFF;	}	}
		if(bPalet != bPaletOld){
			for(wDotY=0;wDotY<LCD_HEIGHT;wDotY++){
				for(wDotX=0;wDotX<LCD_WIDTH;wDotX++){
					dw = wDotY * LCD_WIDTH + wDotX;
					//*(pLCDBuf[bLCDbufPage] + dw) = dwarColTmpA[bPalet];
					*(pLCDBuf[0] + dw) = dwarColTmpA[bPalet];
					*(pLCDBuf[1] + dw) = dwarColTmpA[bPalet];
					/*
					if( (wDotX & 0x10 == 0) && (wDotY & 0x10 == 0) ){
						// *(pLCDBuf[bLCDbufPage] + dw) = dwarColTmp[bPalet];
						*(pLCDBuf[bLCDbufPage] + dw) = dwarColTmpA[bPalet];
					} else {
						// *(pLCDBuf[bLCDbufPage] + dw) = ~dwarColTmp[bPalet];
						*(pLCDBuf[bLCDbufPage] + dw) = dwarColTmpA[bPalet];
					}
					*/
#if USE_WBUFFER_API == 0		//[[[	自前でバッファーを切り替える
					//ROM_LCDRasterDisable(LCD0_BASE);
					ROM_LCDRasterFrameBufferSet(LCD0_BASE,0,pLCDBuf[bLCDbufPage],SDRAM_GBUF_SIZE);
					//ROM_LCDRasterEnable(LCD0_BASE);
#if USE_SINGLEBUF == 0		//[[[ [[[ なんちゃってWバッファなのでページ切り替え
					if(bLCDbufPage == 0){
						bLCDbufPage++;
					} else {
						bLCDbufPage = 0;
					}
#endif		//]]] ]]]
#endif		//]]]
					//bLCDbufPage++;
					//bLCDbufPage &= 0x01;
				}
				if(LED0_CHK_OFF == true){	LED0_ON;	} else {	LED0_OFF;	}
			}
			bPaletOld = bPalet;
		}
		//LED2_OFF;

	}
}

///////////////////////////////////////////////////////////////
// 内部フラッシュテスト
// 引数
//		ナシ
// 戻り値
//		ナシ
///////////////////////////////////////////////////////////////
#if	INNER_EEPROM_TEST == 1		//[[[
void	InnerFlashTest(void){
	WORD	i;
	BYTE	b;
	BYTE	bflag;
	DWORD	dwarrWriteTmp[4];
	DWORD	dwarrReadTmp[4];
	DWORD	dwRet;

	// まずは書き込み
	//dwTmp = ROM_EEPROMSizeGet();
	for(i=0;i<ROM_EEPROMSizeGet();i+=16){
		if(ROM_EEPROMStatusGet()==0){
			dwarrWriteTmp[0] = XorShift16(i) | (XorShift16(i+4) << 16);
			dwarrWriteTmp[1] = XorShift16(i+1) | (XorShift16(i+5) << 16);
			dwarrWriteTmp[2] = XorShift16(i+2) | (XorShift16(i+6) << 16);
			dwarrWriteTmp[3] = XorShift16(i+3) | (XorShift16(i+7) << 16);
			dwRet = ROM_EEPROMProgram(dwarrReadTmp,i,sizeof(dwarrReadTmp));
			if(dwRet != 0){
				// エラーらしい
				LED2_ON;
			}
		}
		if(ROM_EEPROMStatusGet()!=0){
			// エラーらしいのでLEDを点ける
			LED2_ON;
		}
	}

	// 読み込み
	for(i=0;i<ROM_EEPROMSizeGet();i+=16){
		if(ROM_EEPROMStatusGet()==0){
			dwarrWriteTmp[0] = XorShift16(i) | (XorShift16(i+4) << 16);
			dwarrWriteTmp[1] = XorShift16(i+1) | (XorShift16(i+5) << 16);
			dwarrWriteTmp[2] = XorShift16(i+2) | (XorShift16(i+6) << 16);
			dwarrWriteTmp[3] = XorShift16(i+3) | (XorShift16(i+7) << 16);
			ROM_EEPROMRead(dwarrReadTmp,i,sizeof(dwarrReadTmp));
			bflag = 0;
			for(b=0;b<4;b++){
				if(dwarrReadTmp[b] != dwarrWriteTmp[b]){
					bflag = 0xff;
				}
			}
			if(bflag == 0xff){
				//LED3_ON;
			}
		}
		if(ROM_EEPROMStatusGet()!=0){
			// エラーらしいのでLEDを点ける
			LED3_ON;
		}
	}
	return;
}
#endif		//]]]

//*****************************************************************************
//
// This function is called from the application to request an update.  The
// address of this function is stored in the SVC vector at offset 0x2C, so
// the user application can call it by using a statement like this:
//
//      (*((void (*)(void))(*(uint32_t *)0x2c)))();
//
//*****************************************************************************
void
AppForceUpdate(void)
{
    //
    // Set a value in a memory location to indicate that the app requests
    // an update.  Then cause the processor to reset.
    //
    HWREG(FORCE_UPDATE_ADDR) = FORCE_UPDATE_VALUE;
    HWREG(NVIC_APINT) = NVIC_APINT_VECTKEY | NVIC_APINT_SYSRESETREQ;
}

//*****************************************************************************
//
// This function is used to call the user application.  It will set the NVIC
// to point at the user app's vector table, load up the user app's stack
// pointer, and then jump to the application.
//
// This function must be programmed in assembly since it needs to directly
// manipulate the value in the stack pointer, and because it needs to perform
// a direct branch to the user app and not a function call (bl).
//
//*****************************************************************************
#if defined(codered) || defined(gcc) || defined(sourcerygxx)
void __attribute__((naked))
CallApplication(uint_fast32_t ui32StartAddr)
{
    //
    // Set the vector table to the beginning of the app in flash.
    //
    HWREG(NVIC_VTABLE) = ui32StartAddr;

    //
    // Load the stack pointer from the application's vector table.
    //
    __asm("    ldr     r1, [r0]\n"
          "    mov     sp, r1");

    //
    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    //
    __asm("    ldr     r0, [r0, #4]\n"
          "    bx      r0\n");
}
#elif defined(ewarm)
void
CallApplication(uint_fast32_t ui32StartAddr)
{
    //
    // Set the vector table to the beginning of the app in flash.
    //
    HWREG(NVIC_VTABLE) = ui32StartAddr;

    //
    // Load the stack pointer from the application's vector table.
    //
    __asm("    ldr     r1, [r0]\n"
          "    mov     sp, r1");

    //
    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    //
    __asm("    ldr     r0, [r0, #4]\n"
          "    bx      r0\n");
}
#elif defined(rvmdk) || defined(__ARMCC_VERSION)
__asm void
CallApplication(uint_fast32_t ui32StartAddr)
{
    //
    // Set the vector table address to the beginning of the application.
    //
    ldr     r1, =0xe000ed08
    str     r0, [r1]

    //
    // Load the stack pointer from the application's vector table.
    //
    ldr     r1, [r0]
    mov     sp, r1

    //
    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    //
    ldr     r0, [r0, #4]
    bx      r0
}
#elif defined(ccs)
void
CallApplication(uint_fast32_t ui32StartAddr)
{
    //
    // Set the vector table to the beginning of the app in flash.
    //
    HWREG(NVIC_VTABLE) = ui32StartAddr;

    //
    // Load the stack pointer from the application's vector table.
    //
    __asm("    ldr     r1, [r0]\n"
          "    mov     sp, r1\n");

    //
    // Load the initial PC from the application's vector table and branch to
    // the application's entry point.
    //
    __asm("    ldr     r0, [r0, #4]\n"
          "    bx      r0\n");
}
#else
#error Undefined compiler!
#endif

