mirror of
https://gitea.osmocom.org/sim-card/simtrace2.git
synced 2026-03-18 14:28:33 +03:00
Makefile with libs and atmel source
This commit is contained in:
@@ -0,0 +1,197 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of ADS7843 driver.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#define ADS_CTRL_PD0 (1 << 0) /* PD0 */
|
||||
#define ADS_CTRL_PD1 (1 << 1) /* PD1 */
|
||||
#define ADS_CTRL_DFR (1 << 2) /* SER/DFR */
|
||||
#define ADS_CTRL_EIGHT_BITS_MOD (1 << 3) /* Mode */
|
||||
#define ADS_CTRL_START (1 << 7) /* Start Bit */
|
||||
#define ADS_CTRL_SWITCH_SHIFT 4 /* Address setting */
|
||||
|
||||
/* Get X position command */
|
||||
#define CMD_Y_POSITION ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
|
||||
/* Get Y position command */
|
||||
#define CMD_X_POSITION ((5 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START | ADS_CTRL_PD0 | ADS_CTRL_PD1)
|
||||
|
||||
/* Enable penIRQ */
|
||||
#define CMD_ENABLE_PENIRQ ((1 << ADS_CTRL_SWITCH_SHIFT) | ADS_CTRL_START)
|
||||
|
||||
|
||||
#define ADS7843_TIMEOUT 5000000
|
||||
|
||||
#define DELAY_BEFORE_SPCK 200 /* 2us min (tCSS) <=> 200/100 000 000 = 2us */
|
||||
#define DELAY_BETWEEN_CONS_COM 0xf /* 5us min (tCSH) <=> (32 * 15) / (100 000 000) = 5us */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Pins used by SPI */
|
||||
static const Pin pinsSPI[] = {BOARD_TSC_SPI_PINS, BOARD_TSC_NPCS_PIN};
|
||||
|
||||
/** Touch screen BUSY pin */
|
||||
static const Pin pinBusy[] = {PIN_TSC_BUSY};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Generic function to send a command to the touchscreen controller.
|
||||
*
|
||||
* \param bCmd command to send
|
||||
*
|
||||
* \return command result
|
||||
*/
|
||||
static uint32_t SendCommand( uint8_t bCmd )
|
||||
{
|
||||
uint32_t uResult = 0;
|
||||
uint32_t uTimeout = 0;
|
||||
|
||||
/* (volatile declaration needed for code optimisation by compiler) */
|
||||
volatile uint8_t bufferRX[3];
|
||||
volatile uint8_t bufferTX[3];
|
||||
|
||||
Pdc *pPdc = (Pdc *)SPI;
|
||||
uint32_t dStatus;
|
||||
|
||||
bufferRX[0] = 0;
|
||||
bufferRX[1] = 0;
|
||||
bufferRX[2] = 0;
|
||||
|
||||
bufferTX[0] = bCmd;
|
||||
bufferTX[1] = 0;
|
||||
bufferTX[2] = 0;
|
||||
|
||||
/* Send Command and data through the SPI */
|
||||
pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;
|
||||
pPdc->PERIPH_RPR = (uint32_t) bufferRX;
|
||||
pPdc->PERIPH_RCR = 3;
|
||||
|
||||
pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS;
|
||||
pPdc->PERIPH_TPR = (uint32_t) bufferTX;
|
||||
pPdc->PERIPH_TCR = 3;
|
||||
|
||||
pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTEN;
|
||||
pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTEN;
|
||||
|
||||
do
|
||||
{
|
||||
dStatus = REG_SPI_SR;
|
||||
uTimeout++;
|
||||
}
|
||||
while ((( dStatus & SPI_SR_RXBUFF) != SPI_SR_RXBUFF) && (uTimeout < ADS7843_TIMEOUT));
|
||||
|
||||
pPdc->PERIPH_PTCR = PERIPH_PTCR_RXTDIS;
|
||||
pPdc->PERIPH_PTCR = PERIPH_PTCR_TXTDIS;
|
||||
|
||||
uResult = (uint32_t)bufferRX[1] << 8;
|
||||
uResult |= (uint32_t)bufferRX[2];
|
||||
uResult = uResult >> 4;
|
||||
|
||||
return uResult;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Get position of the pen by ask the ADS controller (SPI).
|
||||
*
|
||||
* \param px_pos pointer to the horizontal position
|
||||
* \param py_pos pointer to the vertical position
|
||||
*
|
||||
*/
|
||||
extern void ADS7843_GetPosition( uint32_t *px_pos, uint32_t *py_pos )
|
||||
{
|
||||
/* Get X position */
|
||||
*px_pos = SendCommand(CMD_X_POSITION);
|
||||
/* Get Y position */
|
||||
*py_pos = SendCommand(CMD_Y_POSITION);
|
||||
/* Switch to full power mode */
|
||||
SendCommand(CMD_ENABLE_PENIRQ);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialization of the SPI for communication with ADS7843 component.
|
||||
*/
|
||||
extern void ADS7843_Initialize( void )
|
||||
{
|
||||
volatile uint32_t uDummy;
|
||||
|
||||
/* Configure pins */
|
||||
PIO_Configure(pinsSPI, PIO_LISTSIZE(pinsSPI));
|
||||
|
||||
PIO_Configure(pinBusy, PIO_LISTSIZE(pinBusy));
|
||||
|
||||
SPI_Configure(BOARD_TSC_SPI_BASE,
|
||||
BOARD_TSC_SPI_ID,
|
||||
SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_PCS(BOARD_TSC_NPCS) /* Value of the SPI configuration register. */
|
||||
);
|
||||
|
||||
SPI_ConfigureNPCS(BOARD_TSC_SPI_BASE, BOARD_TSC_NPCS,
|
||||
SPI_CSR_NCPHA | SPI_CSR_DLYBS(DELAY_BEFORE_SPCK) |
|
||||
SPI_CSR_DLYBCT(DELAY_BETWEEN_CONS_COM) | SPI_CSR_SCBR(0xC8) );
|
||||
|
||||
SPI_Enable(BOARD_TSC_SPI_BASE);
|
||||
|
||||
for (uDummy=0; uDummy<100000; uDummy++);
|
||||
|
||||
uDummy = REG_SPI_SR;
|
||||
uDummy = REG_SPI_RDR;
|
||||
|
||||
SendCommand(CMD_ENABLE_PENIRQ);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reset the ADS7843
|
||||
*/
|
||||
void ADS7843_Reset( void )
|
||||
{
|
||||
/* Disable SPI */
|
||||
SPI_Disable( BOARD_TSC_SPI_BASE ) ;
|
||||
}
|
||||
@@ -0,0 +1,316 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/** \addtogroup spi_at45_module SPI AT45 driver
|
||||
* \ingroup at45d_module
|
||||
* The Dataflash driver is based on top of the corresponding Spi driver.
|
||||
* A Dataflash structure instance has to be initialized using the DF_Init
|
||||
* function. Then basic dataflash operations can be launched using macros such
|
||||
* as DF_continuous_read. These macros invoke the DF_Command() function which
|
||||
* invokes the DPI low driver using the SPI_SendCommand() function.
|
||||
* Beware to compute the dataflash internal address, the dataflash sector
|
||||
* description must be known (DataflashDesc). Dataflash can be automatically
|
||||
* detected using the DF_Scan() function.
|
||||
*
|
||||
* \section Usage
|
||||
* <ul>
|
||||
* <li> Initializes an AT45 instance and configures SPI chip select pin
|
||||
* using AT45_Configure(). </li>
|
||||
* <li> Detect DF and returns DF description corresponding to the device
|
||||
* connected using AT45_FindDevice().This function shall be called by
|
||||
* the application before AT45_SendCommand.</li>
|
||||
* <li>Sends a command to the DF through the SPI using AT45_SendCommand().
|
||||
* The command is identified by its command code and the number of
|
||||
* bytes to transfer.</li>
|
||||
* <li>Example code for sending command to write a page to DF. </li>
|
||||
* \code
|
||||
* // Issue a page write through buffer 1 command
|
||||
* error = AT45_SendCommand(pAt45, AT45_PAGE_WRITE_BUF1, 4,
|
||||
* pBuffer, size, address, 0, 0);
|
||||
* \endcode
|
||||
* <li>Example code for sending command to read a page from DF.
|
||||
* If data needs to be received, then a data buffer must be
|
||||
* provided.</li>
|
||||
* \code
|
||||
* // Issue a continuous read array command
|
||||
* error = AT45_SendCommand(pAt45, AT45_CONTINUOUS_READ_LEG, 8,
|
||||
* pBuffer, size, address, 0, 0);
|
||||
* \endcode
|
||||
* <li> This function does not block; its optional callback will
|
||||
* be invoked when the transfer completes.</li>
|
||||
* <li> Check the AT45 driver is ready or not by polling AT45_IsBusy().
|
||||
* </ul>
|
||||
* Related files :\n
|
||||
* \ref spi_at45.c\n
|
||||
* \ref spi_at45.h.\n
|
||||
*/
|
||||
/*@{*/
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of SPI At45 driver.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Internal definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Number of dataflash which can be recognized.*/
|
||||
#define NUMDATAFLASH (sizeof(at45Devices) / sizeof(At45Desc))
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** indicate if the device is configured as binary page or not.*/
|
||||
static uint8_t configuredBinaryPage;
|
||||
|
||||
/** At45 device descriptor structure. */
|
||||
static const At45Desc at45Devices[] = {
|
||||
{ 512, 1, 264, 9, 0x0C, "AT45DB011D"},
|
||||
{ 1024, 1, 264, 9, 0x14, "AT45DB021D"},
|
||||
{ 2048, 1, 264, 9, 0x1C, "AT45DB041D"},
|
||||
{ 4096, 1, 264, 9, 0x24, "AT45DB081D"},
|
||||
{ 4096, 1, 528, 10, 0x2C, "AT45DB161D"},
|
||||
{ 8192, 1, 528, 10, 0x34, "AT45DB321D"},
|
||||
{ 8192, 1, 1056, 11, 0x3C, "AT45DB642D"},
|
||||
{16384, 1, 1056, 11, 0x10, "AT45DB1282"},
|
||||
{16384, 1, 2112, 12, 0x18, "AT45DB2562"},
|
||||
{32768, 1, 2112, 12, 0x20, "AT45DB5122"}
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Initializes an AT45 instance and configures SPI chip select register.
|
||||
*
|
||||
* \param pAt45 Pointer to the At45 instance to initialize.
|
||||
* \param pSpid Pointer to the underlying SPI driver.
|
||||
* \param spiCs Chip select value to connect to the At45.
|
||||
* \return 0.
|
||||
*/
|
||||
extern uint32_t AT45_Configure( At45* pAt45, Spid* pSpid, uint8_t ucSpiCs )
|
||||
{
|
||||
SpidCmd* pCommand ;
|
||||
|
||||
/* Sanity checks */
|
||||
assert( pSpid != NULL ) ;
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
/* Initialize the At45 instance */
|
||||
pAt45->pSpid = pSpid ;
|
||||
pAt45->pDesc = 0 ;
|
||||
memset( pAt45->pCmdBuffer, 0, 8 ) ;
|
||||
|
||||
/* Initialize the spidCmd structure */
|
||||
pCommand = &(pAt45->command) ;
|
||||
pCommand->pCmd = pAt45->pCmdBuffer ;
|
||||
pCommand->callback = 0 ;
|
||||
pCommand->pArgument = 0 ;
|
||||
pCommand->spiCs = ucSpiCs ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if the At45 driver is in busy.
|
||||
*
|
||||
* \param pAt45 Pointer to the At45 instance to initialize.
|
||||
* \return 1 if the At45 driver is not executing any command,otherwise it returns 0.
|
||||
*/
|
||||
extern uint32_t AT45_IsBusy( At45* pAt45 )
|
||||
{
|
||||
return SPID_IsBusy( pAt45->pSpid ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sends a command to the dataflash through the SPI.
|
||||
* The command is identified by its command code and the number of bytes to transfer
|
||||
* (1 + number of address bytes + number of dummy bytes).If data needs to be received,
|
||||
* then a data buffer must be provided.
|
||||
* \note This function does not block; its optional callback will be invoked when
|
||||
* the transfer completes.
|
||||
* \param pAt45 Pointer to the At45 instance to initialize.
|
||||
* \param cmd Command code.
|
||||
* \param cmdSize Size of command code + address bytes + dummy bytes.
|
||||
* \param pData Data buffer.
|
||||
* \param dataSize Number of data bytes to send/receive.
|
||||
* \param address Address at which the command is performed if meaningful.
|
||||
* \param callback Optional callback to invoke at end of transfer.
|
||||
* \param pArgument Optional parameter to the callback function.
|
||||
* \return 0.
|
||||
*/
|
||||
extern uint32_t AT45_SendCommand( At45* pAt45, uint8_t ucCmd, uint8_t ucCmdSize, uint8_t *pucData, uint32_t dwDataSize,
|
||||
uint32_t dwAddress, SpidCallback pCallback, void *pArgument )
|
||||
{
|
||||
SpidCmd *pCommand ;
|
||||
const At45Desc *pDesc;
|
||||
uint32_t dfAddress = 0 ;
|
||||
|
||||
/* Sanity checks */
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
pDesc = pAt45->pDesc ;
|
||||
|
||||
assert( pDesc || (ucCmd == AT45_STATUS_READ) ) ;
|
||||
|
||||
/* Check if the SPI driver is available*/
|
||||
if ( AT45_IsBusy( pAt45 ) )
|
||||
{
|
||||
return AT45_ERROR_LOCK ;
|
||||
}
|
||||
|
||||
/* Compute command pattern*/
|
||||
pAt45->pCmdBuffer[0] = ucCmd ;
|
||||
|
||||
/* Add address bytes if necessary*/
|
||||
if ( ucCmdSize > 1 )
|
||||
{
|
||||
assert( pDesc != NULL ) ;
|
||||
if ( !configuredBinaryPage )
|
||||
{
|
||||
dfAddress = ((dwAddress / (pDesc->pageSize)) << pDesc->pageOffset)
|
||||
+ (dwAddress % (pDesc->pageSize));
|
||||
}
|
||||
else
|
||||
{
|
||||
dfAddress = dwAddress ;
|
||||
}
|
||||
|
||||
/* Write address bytes */
|
||||
if ( pDesc->pageNumber >= 16384 )
|
||||
{
|
||||
pAt45->pCmdBuffer[1] = ((dfAddress & 0x0F000000) >> 24);
|
||||
pAt45->pCmdBuffer[2] = ((dfAddress & 0x00FF0000) >> 16);
|
||||
pAt45->pCmdBuffer[3] = ((dfAddress & 0x0000FF00) >> 8);
|
||||
pAt45->pCmdBuffer[4] = ((dfAddress & 0x000000FF) >> 0);
|
||||
|
||||
if ( (ucCmd != AT45_CONTINUOUS_READ) && (ucCmd != AT45_PAGE_READ) )
|
||||
{
|
||||
ucCmdSize++ ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pAt45->pCmdBuffer[1] = ((dfAddress & 0x00FF0000) >> 16);
|
||||
pAt45->pCmdBuffer[2] = ((dfAddress & 0x0000FF00) >> 8);
|
||||
pAt45->pCmdBuffer[3] = ((dfAddress & 0x000000FF) >> 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Update the SPI Transfer descriptors */
|
||||
pCommand = &(pAt45->command) ;
|
||||
pCommand->cmdSize = ucCmdSize ;
|
||||
pCommand->pData = pucData ;
|
||||
pCommand->dataSize = dwDataSize ;
|
||||
pCommand->callback = pCallback ;
|
||||
pCommand->pArgument = pArgument ;
|
||||
|
||||
/* Send Command and data through the SPI */
|
||||
if ( SPID_SendCommand( pAt45->pSpid, pCommand ) )
|
||||
{
|
||||
return AT45_ERROR_SPI ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief returns the At45Desc structure corresponding to the device connected.
|
||||
* It automatically initializes pAt45->pDesc field structure.
|
||||
*
|
||||
* \note This function shall be called by the application before AT45_SendCommand.
|
||||
*
|
||||
* \param pAt45 Pointer to the At45 instance to initialize.
|
||||
* \param status Device status register value.
|
||||
*
|
||||
* \return 0 if successful; Otherwise, returns AT45_ERROR_LOCK if the At45
|
||||
* driver is in use or AT45_ERROR_SPI if there was an error with the SPI driver.
|
||||
*/
|
||||
extern const At45Desc * AT45_FindDevice( At45 *pAt45, uint8_t status )
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t id = AT45_STATUS_ID(status);
|
||||
|
||||
/* Check if status is all one; in which case, it is assumed that no device is connected*/
|
||||
if ( status == 0xFF )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Look in device array */
|
||||
i = 0 ;
|
||||
pAt45->pDesc = 0 ;
|
||||
while ( (i < NUMDATAFLASH) && !(pAt45->pDesc) )
|
||||
{
|
||||
if ( at45Devices[i].id == id )
|
||||
{
|
||||
pAt45->pDesc = &(at45Devices[i]) ;
|
||||
}
|
||||
i++ ;
|
||||
}
|
||||
|
||||
configuredBinaryPage = AT45_STATUS_BINARY(status);
|
||||
|
||||
return pAt45->pDesc ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief returns the pagesize corresponding to the device connected.
|
||||
* \param pAt45 Pointer to the At45 instance to initialize.
|
||||
* \return page size.
|
||||
*/
|
||||
extern uint32_t AT45_PageSize( At45 *pAt45 )
|
||||
{
|
||||
uint32_t dwPageSize = pAt45->pDesc->pageSize ;
|
||||
|
||||
if ( ((pAt45->pDesc->hasBinaryPage) == 0) || !configuredBinaryPage )
|
||||
{
|
||||
return dwPageSize ;
|
||||
}
|
||||
|
||||
return ((dwPageSize >> 8) << 8) ;
|
||||
}
|
||||
@@ -0,0 +1,254 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \addtogroup external_component External Component
|
||||
*
|
||||
* \addtogroup at45d_module AT45 driver
|
||||
* \ingroup external_component
|
||||
* The AT45 Dataflash driver is based on the corresponding AT45 driver.
|
||||
* A AT45 instance has to be initialized using the Dataflash levle function
|
||||
* AT45_Configure(). AT45 Dataflash can be automatically detected using
|
||||
* the AT45_FindDevice() function. Then AT45 dataflash operations such as
|
||||
* read, write and erase DF can be launched using AT45_SendCommand function
|
||||
* with corresponding AT45 command set.
|
||||
*
|
||||
* \section Usage
|
||||
* <ul>
|
||||
* <li> Reads data from the At45 at the specified address using AT45D_Read().</li>
|
||||
* <li> Writes data on the At45 at the specified address using AT45D_Write().</li>
|
||||
* <li> Erases a page of data at the given address using AT45D_Erase().</li>
|
||||
* <li> Poll until the At45 has completed of corresponding operations using
|
||||
* AT45D_WaitReady().</li>
|
||||
* <li> Retrieves and returns the At45 current using AT45D_GetStatus().</li>
|
||||
* </ul>
|
||||
* Related files :\n
|
||||
* \ref at45d.c\n
|
||||
* \ref at45d.h.\n
|
||||
*/
|
||||
/*@{*/
|
||||
/*@}*/
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of At45 driver.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Wait for transfer to finish calling the SPI driver ISR (interrupts are
|
||||
* disabled).
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
*/
|
||||
static void AT45D_Wait( At45* pAt45 )
|
||||
{
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
/* Wait for transfer to finish */
|
||||
while ( AT45_IsBusy( pAt45 ) )
|
||||
{
|
||||
SPID_Handler( pAt45->pSpid ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Global functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Waits for the At45 to be ready to accept new commands.
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
*/
|
||||
extern void AT45D_WaitReady( At45* pAt45 )
|
||||
{
|
||||
uint8_t ready = 0;
|
||||
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
/* Poll device until it is ready. */
|
||||
while (!ready)
|
||||
{
|
||||
ready = AT45_STATUS_READY(AT45D_GetStatus(pAt45));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves and returns the At45 current status, or 0 if an error happened.
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
*/
|
||||
extern uint32_t AT45D_GetStatus( At45* pAt45 )
|
||||
{
|
||||
uint32_t dwError ;
|
||||
uint8_t ucStatus ;
|
||||
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
/* Issue a status register read command */
|
||||
dwError = AT45_SendCommand( pAt45, AT45_STATUS_READ, 1, &ucStatus, 1, 0, 0, 0 ) ;
|
||||
assert( !dwError ) ;
|
||||
|
||||
/* Wait for command to terminate */
|
||||
while ( AT45_IsBusy( pAt45 ) )
|
||||
{
|
||||
AT45D_Wait( pAt45 ) ;
|
||||
}
|
||||
|
||||
return ucStatus ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Reads data from the At45 inside the provided buffer. Since a continuous
|
||||
* read command is used, there is no restriction on the buffer size and read address.
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
* \param pBuffer Data buffer.
|
||||
* \param size Number of bytes to read.
|
||||
* \param address Address at which data shall be read.
|
||||
*/
|
||||
extern void AT45D_Read( At45* pAt45, uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
|
||||
{
|
||||
uint32_t dwError ;
|
||||
|
||||
assert( pAt45 != NULL ) ;
|
||||
assert( pucBuffer != NULL ) ;
|
||||
|
||||
/* Issue a continuous read array command. */
|
||||
dwError = AT45_SendCommand( pAt45, AT45_CONTINUOUS_READ_LEG, 8, pucBuffer, dwSize, dwAddress, 0, 0 ) ;
|
||||
assert( !dwError ) ;
|
||||
|
||||
/* Wait for the read command to execute. */
|
||||
while ( AT45_IsBusy( pAt45 ) )
|
||||
{
|
||||
AT45D_Wait( pAt45 ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes data on the At45 at the specified address. Only one page of
|
||||
* data is written that way; if the address is not at the beginning of the
|
||||
* page, the data is written starting from this address and wraps around to
|
||||
* the beginning of the page.
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
* \param pucBuffer Data buffer.
|
||||
* \param dwSize Number of bytes to write.
|
||||
* \param dwAddress Destination address on the At45.
|
||||
*/
|
||||
extern void AT45D_Write( At45* pAt45, uint8_t *pucBuffer, uint32_t dwSize, uint32_t dwAddress )
|
||||
{
|
||||
uint8_t dwError ;
|
||||
|
||||
assert( pAt45 != NULL ) ;
|
||||
assert( pucBuffer != NULL ) ;
|
||||
assert( dwSize <= pAt45->pDesc->pageSize ) ;
|
||||
|
||||
/* Issue a page write through buffer 1 command. */
|
||||
dwError = AT45_SendCommand( pAt45, AT45_PAGE_WRITE_BUF1, 4, pucBuffer, dwSize, dwAddress, 0, 0 ) ;
|
||||
assert( !dwError ) ;
|
||||
|
||||
/* Wait until the command is sent. */
|
||||
while ( AT45_IsBusy( pAt45 ) )
|
||||
{
|
||||
AT45D_Wait( pAt45 ) ;
|
||||
}
|
||||
|
||||
/* Wait until the At45 becomes ready again.*/
|
||||
AT45D_WaitReady( pAt45 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Erases a page of data at the given address in the At45.
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
* \param dwAddress Address of page to erase.
|
||||
*/
|
||||
extern void AT45D_Erase( At45* pAt45, uint32_t dwAddress )
|
||||
{
|
||||
uint32_t dwError ;
|
||||
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
/* Issue a page erase command. */
|
||||
dwError = AT45_SendCommand( pAt45, AT45_PAGE_ERASE, 4, 0, 0, dwAddress, 0, 0 ) ;
|
||||
assert( !dwError ) ;
|
||||
|
||||
/* Wait for end of transfer. */
|
||||
while ( AT45_IsBusy(pAt45 ) )
|
||||
{
|
||||
AT45D_Wait( pAt45 ) ;
|
||||
}
|
||||
|
||||
/* Poll until the At45 has completed the erase operation. */
|
||||
AT45D_WaitReady( pAt45 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure power-of-2 binary page size in the At45.
|
||||
*
|
||||
* \param pAt45 Pointer to an AT45 driver instance.
|
||||
*/
|
||||
extern void AT45D_BinaryPage( At45* pAt45 )
|
||||
{
|
||||
uint8_t dwError ;
|
||||
uint8_t opcode[3]= {AT45_BINARY_PAGE};
|
||||
assert( pAt45 != NULL ) ;
|
||||
|
||||
/* Issue a binary page command. */
|
||||
|
||||
dwError = AT45_SendCommand( pAt45, AT45_BINARY_PAGE_FIRST_OPCODE, 1, opcode, 3, 0, 0, 0 ) ;
|
||||
|
||||
assert( !dwError ) ;
|
||||
|
||||
/* Wait for end of transfer.*/
|
||||
while ( AT45_IsBusy( pAt45 ) )
|
||||
{
|
||||
AT45D_Wait( pAt45 ) ;
|
||||
}
|
||||
|
||||
/* Wait until the At45 becomes ready again.*/
|
||||
AT45D_WaitReady( pAt45 ) ;
|
||||
}
|
||||
@@ -0,0 +1,319 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Headers
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Define
|
||||
//-----------------------------------------------------------------------------
|
||||
/// BMP offset for header
|
||||
#define IMAGE_OFFSET 0x100
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Internal constants
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Internal types
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Describe the BMP palette
|
||||
//------------------------------------------------------------------------------
|
||||
typedef struct _BMPPaletteEntry
|
||||
{
|
||||
/// Blue value
|
||||
uint8_t b;
|
||||
/// Green value
|
||||
uint8_t g;
|
||||
/// Red value
|
||||
uint8_t r;
|
||||
/// Filler character value
|
||||
uint8_t filler;
|
||||
} BMPPaletteEntry ;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Exported functions
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Test if BMP is valid
|
||||
/// \param file Buffer holding the file to examinate.
|
||||
/// \return 1 if the header of a BMP file is valid; otherwise returns 0.
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t BMP_IsValid( void *file )
|
||||
{
|
||||
return ((BMPHeader*) file)->type == BMP_TYPE ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Returns the size of a BMP image given at least its header (the file does
|
||||
/// not have to be complete).
|
||||
/// \param file Pointer to the buffer which holds the BMP file.
|
||||
/// \return size of BMP image
|
||||
//------------------------------------------------------------------------------
|
||||
uint32_t BMP_GetFileSize( void *file )
|
||||
{
|
||||
return ((BMPHeader *) file)->fileSize ;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/// Write a BMP header
|
||||
/// \param pAddressHeader Begin address of the BMP
|
||||
/// \param bmpHSize BMP heigth size
|
||||
/// \param bmpVSize BMP width size
|
||||
/// \param nbByte_Pixels Number of byte per pixels
|
||||
//-----------------------------------------------------------------------------
|
||||
void WriteBMPheader( uint32_t* pAddressHeader, uint32_t bmpHSize, uint32_t bmpVSize, uint8_t nbByte_Pixels )
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t* fill;
|
||||
BMPHeader *Header;
|
||||
|
||||
fill = pAddressHeader;
|
||||
for ( i=0 ; i < IMAGE_OFFSET ; i+=4 )
|
||||
{
|
||||
*fill++ = 0;
|
||||
}
|
||||
|
||||
Header = (BMPHeader*) pAddressHeader;
|
||||
|
||||
Header->type = BMP_TYPE;
|
||||
Header->fileSize = (bmpHSize * bmpVSize * nbByte_Pixels) + IMAGE_OFFSET;
|
||||
Header->reserved1 = 0;
|
||||
Header->reserved2 = 0;
|
||||
Header->offset = IMAGE_OFFSET;
|
||||
Header->headerSize = BITMAPINFOHEADER;
|
||||
Header->width = bmpHSize;
|
||||
Header->height = bmpVSize;
|
||||
Header->planes = 1;
|
||||
Header->bits = nbByte_Pixels * 8;
|
||||
Header->compression = 0;
|
||||
Header->imageSize = bmpHSize * bmpVSize * nbByte_Pixels;
|
||||
Header->xresolution = 0;
|
||||
Header->yresolution = 0;
|
||||
Header->ncolours = 0;
|
||||
Header->importantcolours = 0;
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// debug function, dislay BMP header
|
||||
/// \param pAddressHeader Address of the BMP
|
||||
//------------------------------------------------------------------------------
|
||||
#if (TRACE_LEVEL >= TRACE_LEVEL_INFO)
|
||||
void BMP_displayHeader( uint32_t* pAddressHeader )
|
||||
{
|
||||
BMPHeader *header;
|
||||
|
||||
header = (BMPHeader*) pAddressHeader;
|
||||
|
||||
TRACE_INFO("BMP\n\r");
|
||||
TRACE_INFO("type 0x%X \n\r", header->type);
|
||||
TRACE_INFO("fileSize %d \n\r", header->fileSize);
|
||||
TRACE_INFO("reserved1 %d \n\r", header->reserved1);
|
||||
TRACE_INFO("reserved2 %d \n\r", header->reserved2);
|
||||
TRACE_INFO("offset %d \n\r", header->offset);
|
||||
TRACE_INFO("headerSize %d \n\r", header->headerSize);
|
||||
TRACE_INFO("width %d \n\r", header->width);
|
||||
TRACE_INFO("height %d \n\r", header->height);
|
||||
TRACE_INFO("planes %d \n\r", header->planes);
|
||||
TRACE_INFO("bits %d \n\r", header->bits);
|
||||
TRACE_INFO("compression %d \n\r", header->compression);
|
||||
TRACE_INFO("imageSize %d \n\r", header->imageSize);
|
||||
TRACE_INFO("xresolution %d \n\r", header->xresolution);
|
||||
TRACE_INFO("yresolution %d \n\r", header->yresolution);
|
||||
TRACE_INFO("ncolours %d \n\r", header->ncolours);
|
||||
TRACE_INFO("importantcolours %d\n\r", header->importantcolours);
|
||||
}
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Loads a BMP image located at the given address, decodes it and stores the
|
||||
/// resulting image inside the provided buffer. Image must have the specified
|
||||
/// width & height.
|
||||
/// If no buffer is provided, this function simply checks if it is able to
|
||||
/// decode the image.
|
||||
/// \param file Buffer which holds the BMP file.
|
||||
/// \param buffer Buffer in which to store the decoded image.
|
||||
/// \param width Buffer width in pixels.
|
||||
/// \param height Buffer height in pixels.
|
||||
/// \param bpp Number of bits per pixels that the buffer stores.
|
||||
/// \return 0 if the image has been loaded; otherwise returns an error code.
|
||||
//------------------------------------------------------------------------------
|
||||
uint8_t BMP_Decode( void *file, uint8_t *buffer, uint32_t width, uint32_t height, uint8_t bpp )
|
||||
{
|
||||
BMPHeader *header;
|
||||
uint32_t i, j;
|
||||
uint8_t r, g, b;
|
||||
uint8_t *image;
|
||||
|
||||
// Read header information
|
||||
header = (BMPHeader*) file;
|
||||
|
||||
// Verify that the file is valid
|
||||
if ( !BMP_IsValid( file ) )
|
||||
{
|
||||
TRACE_ERROR("BMP_Decode: File type is not 'BM' (0x%04X).\n\r",header->type);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check that parameters match
|
||||
if ( (header->compression != 0) || (header->width != width) || (header->height != height))
|
||||
{
|
||||
TRACE_ERROR("BMP_Decode: File format not supported\n\r");
|
||||
TRACE_ERROR(" -> .compression = %u\n\r", (unsigned int)header->compression);
|
||||
TRACE_ERROR(" -> .width = %u\n\r", (unsigned int)header->width);
|
||||
TRACE_ERROR(" -> .height = %u\n\r", (unsigned int)header->height);
|
||||
TRACE_ERROR(" -> .bits = %d\n\r", (int)header->bits);
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Get image data
|
||||
image = (uint8_t *) ((uint32_t) file + header->offset);
|
||||
|
||||
// Check that the bpp resolution is supported
|
||||
// Only a 24-bit output & 24- or 8-bit input are supported
|
||||
if ( bpp != 24 )
|
||||
{
|
||||
TRACE_ERROR("BMP_Decode: Output resolution not supported\n\r");
|
||||
|
||||
return 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (header->bits == 24)
|
||||
{
|
||||
// Decoding is ok
|
||||
if (!buffer) return 0;
|
||||
|
||||
// Get image data (swapping red & blue)
|
||||
for ( i=0 ; i < height ; i++ )
|
||||
{
|
||||
for ( j=0 ; j < width; j++ )
|
||||
{
|
||||
r = image[((height - i - 1) * width + j) * 3 + 2];
|
||||
g = image[((height - i - 1) * width + j) * 3 + 1];
|
||||
b = image[((height - i - 1) * width + j) * 3];
|
||||
|
||||
#if defined(BOARD_LCD_RGB565)
|
||||
// Interlacing
|
||||
r = ((r << 1) & 0xF0) | ((g & 0x80) >> 4) | ((r & 0x80) >> 5);
|
||||
g = (g << 1) & 0xF8;
|
||||
b = b & 0xF8;
|
||||
|
||||
buffer[(i * width + j) * 3] = b;
|
||||
buffer[(i * width + j) * 3 + 1] = g;
|
||||
buffer[(i * width + j) * 3 + 2] = r;
|
||||
|
||||
#else
|
||||
buffer[(i * width + j) * 3] = r;
|
||||
buffer[(i * width + j) * 3 + 1] = g;
|
||||
buffer[(i * width + j) * 3 + 2] = b;
|
||||
#endif //#if defined(BOARD_LCD_RGB565)
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( header->bits == 8 )
|
||||
{
|
||||
BMPPaletteEntry palette[256];
|
||||
|
||||
// Decoding is ok
|
||||
if (!buffer) return 0;
|
||||
|
||||
// Retrieve palette
|
||||
memcpy( palette, (uint8_t *) ((uint32_t) file + sizeof( BMPHeader )), header->offset - sizeof( BMPHeader ) ) ;
|
||||
|
||||
// Decode image (reversing row order)
|
||||
for ( i=0 ; i < height ; i++ )
|
||||
{
|
||||
for (j=0; j < width; j++)
|
||||
{
|
||||
r = palette[image[(height - i - 1) * width + j]].r;
|
||||
g = palette[image[(height - i - 1) * width + j]].g;
|
||||
b = palette[image[(height - i - 1) * width + j]].b;
|
||||
|
||||
buffer[(i * width + j) * 3] = r;
|
||||
buffer[(i * width + j) * 3 + 1] = g;
|
||||
buffer[(i * width + j) * 3 + 2] = b;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
TRACE_ERROR("BMP_Decode: Input resolution not supported\n\r");
|
||||
TRACE_INFO("header->bits 0x%X \n\r", header->bits);
|
||||
return 4 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
/// Convert RGB 565 to RGB 555 (RGB 555 is adapted to LCD)
|
||||
/// \param fileSource Buffer which holds the RGB file
|
||||
/// \param fileDestination Buffer in which to store the decoded image
|
||||
/// \param width Buffer width in pixels.
|
||||
/// \param height Buffer height in pixels.
|
||||
/// \param bpp Number of bits per pixels that the buffer stores.
|
||||
//------------------------------------------------------------------------------
|
||||
void RGB565toBGR555( uint8_t *fileSource, uint8_t *fileDestination, uint32_t width, uint32_t height, uint8_t bpp )
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t row;
|
||||
|
||||
for (i=0; i < height*(bpp/8); i++)
|
||||
{
|
||||
row = (i*width*(bpp/8));
|
||||
|
||||
for (j=0; j <= width*(bpp/8); j+=2)
|
||||
{
|
||||
fileDestination[row+j] = ((fileSource[row+j+1]>>3)&0x1F)
|
||||
| (fileSource[row+j]&0xE0);
|
||||
fileDestination[row+j+1] = (fileSource[row+j+1]&0x03)
|
||||
| ((fileSource[row+j]&0x1F)<<2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2010, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
#include "board_lowlevel.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Stack Configuration */
|
||||
#define STACK_SIZE 0x900 /** Stack size (in DWords) */
|
||||
__attribute__ ((aligned(8),section(".stack")))
|
||||
uint32_t pdwStack[STACK_SIZE] ;
|
||||
|
||||
/* Initialize segments */
|
||||
extern uint32_t _sfixed;
|
||||
extern uint32_t _efixed;
|
||||
extern uint32_t _etext;
|
||||
extern uint32_t _srelocate;
|
||||
extern uint32_t _erelocate;
|
||||
extern uint32_t _szero;
|
||||
extern uint32_t _ezero;
|
||||
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* ProtoTypes
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** \cond DOXYGEN_SHOULD_SKIP_THIS */
|
||||
extern int main( void ) ;
|
||||
/** \endcond */
|
||||
void ResetException( void ) ;
|
||||
extern void __libc_init_array( void ) ;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Exception Table
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
__attribute__((section(".vectors")))
|
||||
IntFunc exception_table[] = {
|
||||
|
||||
/* Configure Initial Stack Pointer, using linker-generated symbols */
|
||||
(IntFunc)(&pdwStack[STACK_SIZE-1]),
|
||||
ResetException,
|
||||
|
||||
NMI_Handler,
|
||||
HardFault_Handler,
|
||||
MemManage_Handler,
|
||||
BusFault_Handler,
|
||||
UsageFault_Handler,
|
||||
0, 0, 0, 0, /* Reserved */
|
||||
SVC_Handler,
|
||||
DebugMon_Handler,
|
||||
0, /* Reserved */
|
||||
PendSV_Handler,
|
||||
SysTick_Handler,
|
||||
|
||||
/* Configurable interrupts */
|
||||
SUPC_IrqHandler, /* 0 Supply Controller */
|
||||
RSTC_IrqHandler, /* 1 Reset Controller */
|
||||
RTC_IrqHandler, /* 2 Real Time Clock */
|
||||
RTT_IrqHandler, /* 3 Real Time Timer */
|
||||
WDT_IrqHandler, /* 4 Watchdog Timer */
|
||||
PMC_IrqHandler, /* 5 PMC */
|
||||
EEFC_IrqHandler, /* 6 EEFC */
|
||||
IrqHandlerNotUsed, /* 7 Reserved */
|
||||
UART0_IrqHandler, /* 8 UART0 */
|
||||
UART1_IrqHandler, /* 9 UART1 */
|
||||
SMC_IrqHandler, /* 10 SMC */
|
||||
PIOA_IrqHandler, /* 11 Parallel IO Controller A */
|
||||
PIOB_IrqHandler, /* 12 Parallel IO Controller B */
|
||||
PIOC_IrqHandler, /* 13 Parallel IO Controller C */
|
||||
USART0_IrqHandler, /* 14 USART 0 */
|
||||
USART1_IrqHandler, /* 15 USART 1 */
|
||||
IrqHandlerNotUsed, /* 16 Reserved */
|
||||
IrqHandlerNotUsed, /* 17 Reserved */
|
||||
MCI_IrqHandler, /* 18 MCI */
|
||||
TWI0_IrqHandler, /* 19 TWI 0 */
|
||||
TWI1_IrqHandler, /* 20 TWI 1 */
|
||||
SPI_IrqHandler, /* 21 SPI */
|
||||
SSC_IrqHandler, /* 22 SSC */
|
||||
TC0_IrqHandler, /* 23 Timer Counter 0 */
|
||||
TC1_IrqHandler, /* 24 Timer Counter 1 */
|
||||
TC2_IrqHandler, /* 25 Timer Counter 2 */
|
||||
TC3_IrqHandler, /* 26 Timer Counter 3 */
|
||||
TC4_IrqHandler, /* 27 Timer Counter 4 */
|
||||
TC5_IrqHandler, /* 28 Timer Counter 5 */
|
||||
ADC_IrqHandler, /* 29 ADC controller */
|
||||
DAC_IrqHandler, /* 30 DAC controller */
|
||||
PWM_IrqHandler, /* 31 PWM */
|
||||
CRCCU_IrqHandler, /* 32 CRC Calculation Unit */
|
||||
ACC_IrqHandler, /* 33 Analog Comparator */
|
||||
USBD_IrqHandler, /* 34 USB Device Port */
|
||||
IrqHandlerNotUsed /* 35 not used */
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief This is the code that gets called on processor reset.
|
||||
* To initialize the device, and call the main() routine.
|
||||
*/
|
||||
void ResetException( void )
|
||||
{
|
||||
uint32_t *pSrc, *pDest ;
|
||||
|
||||
/* Low level Initialize */
|
||||
LowLevelInit() ;
|
||||
|
||||
/* Initialize the relocate segment */
|
||||
pSrc = &_etext ;
|
||||
pDest = &_srelocate ;
|
||||
|
||||
if ( pSrc != pDest )
|
||||
{
|
||||
for ( ; pDest < &_erelocate ; )
|
||||
{
|
||||
*pDest++ = *pSrc++ ;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the zero segment */
|
||||
for ( pDest = &_szero ; pDest < &_ezero ; )
|
||||
{
|
||||
*pDest++ = 0;
|
||||
}
|
||||
|
||||
/* Set the vector table base address */
|
||||
pSrc = (uint32_t *)&_sfixed;
|
||||
SCB->VTOR = ( (uint32_t)pSrc & SCB_VTOR_TBLOFF_Msk ) ;
|
||||
|
||||
if ( ((uint32_t)pSrc >= IRAM_ADDR) && ((uint32_t)pSrc < IRAM_ADDR+IRAM_SIZE) )
|
||||
{
|
||||
SCB->VTOR |= 1 << SCB_VTOR_TBLBASE_Pos ;
|
||||
}
|
||||
|
||||
/* Initialize the C library */
|
||||
__libc_init_array() ;
|
||||
|
||||
/* Branch to main function */
|
||||
main() ;
|
||||
|
||||
/* Infinite loop */
|
||||
while ( 1 ) ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Provides the low-level initialization function that called on chip startup.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Clock settings at 48MHz for 12 MHz crystal */
|
||||
#if (BOARD_MCK == 48000000)
|
||||
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||
| CKGR_PLLAR_MULA(0x7) \
|
||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||
| CKGR_PLLAR_DIVA(0x1))
|
||||
#define BOARD_MCKR (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)
|
||||
|
||||
/* Clock settings at 64MHz for 12 MHz crystal */
|
||||
#elif (BOARD_MCK == 64000000)
|
||||
#define BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8))
|
||||
#define BOARD_PLLAR (CKGR_PLLAR_STUCKTO1 \
|
||||
| CKGR_PLLAR_MULA(0x0f) \
|
||||
| CKGR_PLLAR_PLLACOUNT(0x1) \
|
||||
| CKGR_PLLAR_DIVA(0x3))
|
||||
#define BOARD_MCKR (PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)
|
||||
|
||||
#else
|
||||
#error "No settings for current BOARD_MCK."
|
||||
#endif
|
||||
|
||||
/* Define clock timeout */
|
||||
#define CLOCK_TIMEOUT 0xFFFFFFFF
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Performs the low-level initialization of the chip.
|
||||
* This includes EFC and master clock configuration.
|
||||
* It also enable a low level on the pin NRST triggers a user reset.
|
||||
*/
|
||||
extern WEAK void LowLevelInit( void )
|
||||
{
|
||||
uint32_t timeout = 0;
|
||||
|
||||
/* Set 3 FWS for Embedded Flash Access */
|
||||
EFC->EEFC_FMR = EEFC_FMR_FWS(3);
|
||||
|
||||
/* Select external slow clock */
|
||||
/* if ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) != SUPC_SR_OSCSEL_CRYST)
|
||||
{
|
||||
SUPC->SUPC_CR = (uint32_t)(SUPC_CR_XTALSEL_CRYSTAL_SEL | SUPC_CR_KEY(0xA5));
|
||||
timeout = 0;
|
||||
while (!(SUPC->SUPC_SR & SUPC_SR_OSCSEL_CRYST) );
|
||||
}
|
||||
*/
|
||||
|
||||
/* Initialize main oscillator */
|
||||
/* if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) )
|
||||
{
|
||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN;
|
||||
timeout = 0;
|
||||
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS) && (timeout++ < CLOCK_TIMEOUT));
|
||||
}*/
|
||||
|
||||
/* Switch to 3-20MHz Xtal oscillator */
|
||||
PMC->CKGR_MOR = CKGR_MOR_KEY(0x37) | BOARD_OSCOUNT | CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | CKGR_MOR_MOSCSEL;
|
||||
timeout = 0;
|
||||
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS) && (timeout++ < CLOCK_TIMEOUT));
|
||||
PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||
|
||||
/* Initialize PLLA */
|
||||
PMC->CKGR_PLLAR = BOARD_PLLAR;
|
||||
timeout = 0;
|
||||
while (!(PMC->PMC_SR & PMC_SR_LOCKA) && (timeout++ < CLOCK_TIMEOUT));
|
||||
|
||||
/* Switch to main clock */
|
||||
PMC->PMC_MCKR = (BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||
|
||||
PMC->PMC_MCKR = BOARD_MCKR ;
|
||||
for ( timeout = 0; !(PMC->PMC_SR & PMC_SR_MCKRDY) && (timeout++ < CLOCK_TIMEOUT) ; );
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of memories configuration on board.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Configures the EBI for NandFlash access.
|
||||
*/
|
||||
extern void BOARD_ConfigureNandFlash( Smc* pSmc )
|
||||
{
|
||||
/* Enable peripheral clock */
|
||||
PMC_EnablePeripheral( ID_SMC ) ;
|
||||
|
||||
/* NCS0 is assigned to a NAND Flash (NANDOE and NANWE used for NCS0) */
|
||||
MATRIX->CCFG_SMCNFCS = CCFG_SMCNFCS_SMC_NFCS0;
|
||||
|
||||
pSmc->SMC_CS_NUMBER[0].SMC_SETUP = SMC_SETUP_NWE_SETUP(0)
|
||||
| SMC_SETUP_NCS_WR_SETUP(1)
|
||||
| SMC_SETUP_NRD_SETUP(0)
|
||||
| SMC_SETUP_NCS_RD_SETUP(1);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[0].SMC_PULSE = SMC_PULSE_NWE_PULSE(2)
|
||||
| SMC_PULSE_NCS_WR_PULSE(3)
|
||||
| SMC_PULSE_NRD_PULSE(4)
|
||||
| SMC_PULSE_NCS_RD_PULSE(4);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[0].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE(4)
|
||||
| SMC_CYCLE_NRD_CYCLE(7);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[0].SMC_MODE = SMC_MODE_READ_MODE
|
||||
| SMC_MODE_WRITE_MODE
|
||||
| SMC_MODE_DBW_8_BIT;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configures the EBI for %NorFlash access.
|
||||
*/
|
||||
extern void BOARD_ConfigureNorFlash( Smc* pSmc )
|
||||
{
|
||||
/* Enable peripheral clock */
|
||||
PMC_EnablePeripheral( ID_SMC ) ;
|
||||
|
||||
/* Configure SMC, NCS3 is assigned to a norflash */
|
||||
pSmc->SMC_CS_NUMBER[3].SMC_SETUP = SMC_SETUP_NWE_SETUP(2)
|
||||
| SMC_SETUP_NCS_WR_SETUP(0)
|
||||
| SMC_SETUP_NRD_SETUP(0)
|
||||
| SMC_SETUP_NCS_RD_SETUP(0);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[3].SMC_PULSE = SMC_PULSE_NWE_PULSE(6)
|
||||
| SMC_PULSE_NCS_WR_PULSE(0xA)
|
||||
| SMC_PULSE_NRD_PULSE(0xA)
|
||||
| SMC_PULSE_NCS_RD_PULSE(0xA);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[3].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE(0xA)
|
||||
| SMC_CYCLE_NRD_CYCLE(0xA);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[3].SMC_MODE = SMC_MODE_READ_MODE
|
||||
| SMC_MODE_WRITE_MODE
|
||||
| SMC_MODE_DBW_8_BIT
|
||||
| SMC_MODE_EXNW_MODE_DISABLED
|
||||
| SMC_MODE_TDF_CYCLES(0x1);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief An accurate one-to-one comparison is necessary between PSRAM and SMC waveforms for
|
||||
* a complete SMC configuration.
|
||||
* \note The system is running at 48 MHz for the EBI Bus.
|
||||
* Please refer to the "AC Characteristics" section of the customer product datasheet.
|
||||
*/
|
||||
extern void BOARD_ConfigurePSRAM( Smc* pSmc )
|
||||
{
|
||||
uint32_t dwTmp ;
|
||||
|
||||
/* Enable peripheral clock */
|
||||
PMC_EnablePeripheral( ID_SMC ) ;
|
||||
|
||||
/* Configure SMC, NCS1 is assigned to a external PSRAM */
|
||||
/**
|
||||
* PSRAM IS66WV51216BLL
|
||||
* 55 ns Access time
|
||||
* tdoe = 25 ns max
|
||||
* SMC1 (timing SAM3S read mode SMC) = 21 ns of setup
|
||||
* 21 + 55 = 76 ns => at least 5 cycles at 64 MHz
|
||||
* Write pulse width minimum = 45 ns (PSRAM)
|
||||
*/
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_SETUP = SMC_SETUP_NWE_SETUP( 1 )
|
||||
| SMC_SETUP_NCS_WR_SETUP( 0 )
|
||||
| SMC_SETUP_NRD_SETUP( 2 )
|
||||
| SMC_SETUP_NCS_RD_SETUP( 0 ) ;
|
||||
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_PULSE = SMC_PULSE_NWE_PULSE( 3 )
|
||||
| SMC_PULSE_NCS_WR_PULSE( 4 )
|
||||
| SMC_PULSE_NRD_PULSE( 3 )
|
||||
| SMC_PULSE_NCS_RD_PULSE( 5 ) ;
|
||||
|
||||
/* NWE_CYCLE: The total duration of the write cycle.
|
||||
NWE_CYCLE = NWE_SETUP + NWE_PULSE + NWE_HOLD
|
||||
= NCS_WR_SETUP + NCS_WR_PULSE + NCS_WR_HOLD
|
||||
(tWC) Write Cycle Time min. 70ns
|
||||
NRD_CYCLE: The total duration of the read cycle.
|
||||
NRD_CYCLE = NRD_SETUP + NRD_PULSE + NRD_HOLD
|
||||
= NCS_RD_SETUP + NCS_RD_PULSE + NCS_RD_HOLD
|
||||
(tRC) Read Cycle Time min. 70ns. */
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE( 4 )
|
||||
| SMC_CYCLE_NRD_CYCLE( 5 ) ;
|
||||
|
||||
dwTmp = SMC->SMC_CS_NUMBER[0].SMC_MODE & (uint32_t)(~(SMC_MODE_DBW_Msk)) ;
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_MODE = dwTmp
|
||||
| SMC_MODE_READ_MODE
|
||||
| SMC_MODE_WRITE_MODE
|
||||
| SMC_MODE_DBW_8_BIT ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Types
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* \brief Describes a possible clock configuration (processor clock & master clock),
|
||||
* including the necessary register values.
|
||||
*/
|
||||
typedef struct _ClockConfiguration
|
||||
{
|
||||
|
||||
/** Processor clock frequency (in MHz). */
|
||||
uint16_t pck;
|
||||
/** Master clock frequency (in MHz). */
|
||||
uint16_t mck;
|
||||
/** CKGR_PLL reqister value. */
|
||||
uint32_t pllr;
|
||||
/** PMC_MCKR register value. */
|
||||
uint32_t mckr;
|
||||
} ClockConfiguration ;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Clock configurations for the AT91SAM3S4-EK */
|
||||
#define CKGR_MUL_SHIFT 16
|
||||
#define CKGR_PLLCOUNT_SHIFT 8
|
||||
#define CKGR_DIV_SHIFT 0
|
||||
|
||||
/* Clock configuration for the AT91SAM3S */
|
||||
static const ClockConfiguration clockConfigurations[] = {
|
||||
|
||||
/* PCK = 24 MHz, MCK = 24 MHz
|
||||
* PCK = 12000000 * (7+1) / 2 / 2 = 24 MHz
|
||||
*/
|
||||
{24, 24, (CKGR_PLLAR_STUCKTO1 | (7 << CKGR_MUL_SHIFT) \
|
||||
| (0x3f << CKGR_PLLCOUNT_SHIFT) \
|
||||
| (2 << CKGR_DIV_SHIFT)),
|
||||
( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)},
|
||||
/* PCK = 48 MHz, MCK = 48 MHz
|
||||
* PCK = 12000000 * (7+1) / 1 / 2 = 48 MHz
|
||||
*/
|
||||
{48, 48, (CKGR_PLLAR_STUCKTO1 | (7 << CKGR_MUL_SHIFT) \
|
||||
| (0x3f << CKGR_PLLCOUNT_SHIFT) \
|
||||
| (1 << CKGR_DIV_SHIFT)),
|
||||
( PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK)},
|
||||
/* PCK = 64 MHz, MCK = 64 MHz
|
||||
* PCK = 12000000 * (15+1) / 3 / 1 = 64 MHz
|
||||
*/
|
||||
{64, 64, (CKGR_PLLAR_STUCKTO1 | (15 << CKGR_MUL_SHIFT) \
|
||||
| (0x3f << CKGR_PLLCOUNT_SHIFT) \
|
||||
| (3 << CKGR_DIV_SHIFT)),
|
||||
( PMC_MCKR_PRES_CLK | PMC_MCKR_CSS_PLLA_CLK)}
|
||||
};
|
||||
|
||||
/* Number of available clock configurations */
|
||||
#define NB_CLOCK_CONFIGURATION (sizeof(clockConfigurations)/sizeof(clockConfigurations[0]))
|
||||
|
||||
/* Current clock configuration */
|
||||
uint32_t currentConfig = 0; /* 0 have to be the default configuration */
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Sets the specified clock configuration.
|
||||
*
|
||||
* \param configuration Index of the configuration to set.
|
||||
*/
|
||||
void CLOCK_SetConfig(uint8_t configuration)
|
||||
{
|
||||
TRACE_DEBUG("Setting clock configuration #%d ... ", configuration);
|
||||
currentConfig = configuration;
|
||||
|
||||
/* Switch to main oscillator in two operations */
|
||||
PMC->PMC_MCKR = (PMC->PMC_MCKR & (uint32_t)~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||
while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
|
||||
|
||||
/* Configure PLL */
|
||||
PMC->CKGR_PLLAR = clockConfigurations[configuration].pllr;
|
||||
while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0);
|
||||
|
||||
/* Configure master clock in two operations */
|
||||
PMC->PMC_MCKR = (clockConfigurations[configuration].mckr & (uint32_t)~PMC_MCKR_CSS_Msk) | PMC_MCKR_CSS_MAIN_CLK;
|
||||
while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
|
||||
PMC->PMC_MCKR = clockConfigurations[configuration].mckr;
|
||||
while ((PMC->PMC_SR & PMC_SR_MCKRDY) == 0);
|
||||
|
||||
/* DBGU reconfiguration */
|
||||
UART_Configure(115200, clockConfigurations[configuration].mck*1000000);
|
||||
TRACE_DEBUG("done.\n\r");
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Display the user menu on the DBGU.
|
||||
*/
|
||||
void CLOCK_DisplayMenu(void)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
printf("\n\rMenu Clock configuration:\n\r");
|
||||
for (i = 0; i < NB_CLOCK_CONFIGURATION; i++) {
|
||||
|
||||
printf(" %u: Set PCK = %3u MHz, MCK = %3u MHz %s\n\r",
|
||||
(unsigned int)i,
|
||||
(unsigned int)clockConfigurations[i].pck,
|
||||
(unsigned int)clockConfigurations[i].mck,
|
||||
(currentConfig==i)?"(curr)":"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current MCK
|
||||
*/
|
||||
uint16_t CLOCK_GetCurrMCK(void)
|
||||
{
|
||||
return clockConfigurations[currentConfig].mck;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get the current PCK
|
||||
*/
|
||||
uint16_t CLOCK_GetCurrPCK(void)
|
||||
{
|
||||
return clockConfigurations[currentConfig].pck;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Change clock configuration.
|
||||
*/
|
||||
void CLOCK_UserChangeConfig(void)
|
||||
{
|
||||
uint8_t key = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
CLOCK_DisplayMenu();
|
||||
key = UART_GetChar();
|
||||
|
||||
if ((key >= '0') && (key <= ('0' + NB_CLOCK_CONFIGURATION - 1)))
|
||||
{
|
||||
CLOCK_SetConfig(key - '0');
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,435 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2010, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/** Frame buffer color cache size used to optimize memcpy */
|
||||
#define FB_COLOR_CACHE_SIZE 8
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
/** Pointer to frame buffer. It is 16 bit aligned to allow PDC operations
|
||||
* LcdColor_t shall be defined in the physical lcd API (ili9225.c)
|
||||
*/
|
||||
static LcdColor_t *gpBuffer;
|
||||
/** Frame buffer width */
|
||||
static uint8_t gucWidth;
|
||||
/** Frame buffer height */
|
||||
static uint8_t gucHeight;
|
||||
/* Pixel color cache */
|
||||
static LcdColor_t gFbPixelCache[FB_COLOR_CACHE_SIZE];
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Static functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Check Box coordinates. Return upper left and bottom right coordinates.
|
||||
*
|
||||
* \param pX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param pY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param pX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param pY2 Y-coordinate of lower-right corner on LCD.
|
||||
*/
|
||||
static void CheckBoxCoordinates( uint32_t *pX1, uint32_t *pY1, uint32_t *pX2, uint32_t *pY2 )
|
||||
{
|
||||
uint32_t dw;
|
||||
|
||||
if ( *pX1 >= gucWidth )
|
||||
*pX1=gucWidth-1 ;
|
||||
|
||||
if ( *pX2 >= gucWidth )
|
||||
*pX2=gucWidth-1 ;
|
||||
|
||||
if ( *pY1 >= gucHeight )
|
||||
*pY1=gucHeight-1 ;
|
||||
|
||||
if ( *pY2 >= gucHeight )
|
||||
*pY2=gucHeight-1 ;
|
||||
|
||||
if (*pX1 > *pX2) {
|
||||
dw = *pX1;
|
||||
*pX1 = *pX2;
|
||||
*pX2 = dw;
|
||||
}
|
||||
if (*pY1 > *pY2) {
|
||||
dw = *pY1;
|
||||
*pY1 = *pY2;
|
||||
*pY2 = dw;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a line on LCD, which is not horizontal or vertical.
|
||||
*
|
||||
* \param x X-coordinate of line start.
|
||||
* \param y Y-coordinate of line start.
|
||||
* \param length line length.
|
||||
* \param direction line direction: 0 - horizontal, 1 - vertical.
|
||||
* \param color Pixel color.
|
||||
*/
|
||||
static uint32_t DrawLineBresenham( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
int dx, dy ;
|
||||
int i ;
|
||||
int xinc, yinc, cumul ;
|
||||
int x, y ;
|
||||
|
||||
x = dwX1 ;
|
||||
y = dwY1 ;
|
||||
dx = dwX2 - dwX1 ;
|
||||
dy = dwY2 - dwY1 ;
|
||||
|
||||
xinc = ( dx > 0 ) ? 1 : -1 ;
|
||||
yinc = ( dy > 0 ) ? 1 : -1 ;
|
||||
dx = ( dx > 0 ) ? dx : -dx ;
|
||||
dy = ( dy > 0 ) ? dy : -dy ;
|
||||
|
||||
FB_DrawPixel(x, y);
|
||||
|
||||
if ( dx > dy )
|
||||
{
|
||||
cumul = dx / 2 ;
|
||||
for ( i = 1 ; i <= dx ; i++ )
|
||||
{
|
||||
x += xinc ;
|
||||
cumul += dy ;
|
||||
|
||||
if ( cumul >= dx )
|
||||
{
|
||||
cumul -= dx ;
|
||||
y += yinc ;
|
||||
}
|
||||
FB_DrawPixel(x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cumul = dy / 2 ;
|
||||
for ( i = 1 ; i <= dy ; i++ )
|
||||
{
|
||||
y += yinc ;
|
||||
cumul += dx ;
|
||||
|
||||
if ( cumul >= dy )
|
||||
{
|
||||
cumul -= dy ;
|
||||
x += xinc ;
|
||||
}
|
||||
|
||||
FB_DrawPixel(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* External functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Configure the current frame buffer.
|
||||
* Next frame buffer operations will take place in this frame buffer area.
|
||||
* \param pBuffer 16 bit aligned sram buffer. PDC shall be able to access this
|
||||
* memory area.
|
||||
* \param ucWidth frame buffer width
|
||||
* \param ucHeight frame buffer height
|
||||
*/
|
||||
extern void FB_SetFrameBuffer(LcdColor_t *pBuffer, uint8_t ucWidth, uint8_t ucHeight)
|
||||
{
|
||||
/* Sanity check */
|
||||
assert(pBuffer != NULL);
|
||||
|
||||
gpBuffer = pBuffer;
|
||||
gucWidth = ucWidth;
|
||||
gucHeight = ucHeight;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Configure the current color that will be used in the next graphical operations.
|
||||
*
|
||||
* \param dwRgb24Bits 24 bit rgb color
|
||||
*/
|
||||
extern void FB_SetColor(uint32_t dwRgb24Bits)
|
||||
{
|
||||
uint16_t i;
|
||||
// LcdColor_t wColor;
|
||||
|
||||
// wColor = (dwRgb24Bits & 0xF80000) >> 8 |
|
||||
// (dwRgb24Bits & 0x00FC00) >> 5 |
|
||||
// (dwRgb24Bits & 0x0000F8) >> 3;
|
||||
|
||||
/* Fill the cache with selected color */
|
||||
for (i = 0; i < FB_COLOR_CACHE_SIZE; ++i) {
|
||||
gFbPixelCache[i] = dwRgb24Bits ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* \brief Draw a pixel on FB of given color.
|
||||
*
|
||||
* \param x X-coordinate of pixel.
|
||||
* \param y Y-coordinate of pixel.
|
||||
*
|
||||
* \return 0 is operation is successful, 1 if pixel is out of the fb
|
||||
*/
|
||||
extern uint32_t FB_DrawPixel(
|
||||
uint32_t dwX,
|
||||
uint32_t dwY)
|
||||
{
|
||||
if ((dwX >= gucWidth) || (dwY >= gucHeight)) {
|
||||
return 1;
|
||||
}
|
||||
gpBuffer[dwX + dwY * gucWidth] = gFbPixelCache[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write several pixels with the same color to FB.
|
||||
*
|
||||
* Pixel color is set by the LCD_SetColor() function.
|
||||
* This function is optimized using an sram buffer to transfer block instead of
|
||||
* individual pixels in order to limit the number of SPI interrupts.
|
||||
* \param dwX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param dwY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param dwX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param dwY2 Y-coordinate of lower-right corner on LCD.
|
||||
*
|
||||
* \return 0 if operation is successfull
|
||||
*/
|
||||
extern uint32_t FB_DrawFilledRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
LcdColor_t *pFbBuffer, *pDestFbBuffer;
|
||||
uint32_t dwY, blocks, bytes;
|
||||
|
||||
/* Swap coordinates if necessary */
|
||||
CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
|
||||
|
||||
blocks = ((dwX2 - dwX1 + 1) / FB_COLOR_CACHE_SIZE);
|
||||
bytes = ((dwX2 - dwX1 + 1) % FB_COLOR_CACHE_SIZE);
|
||||
|
||||
/* Each row is sent by block to benefit from memcpy optimizations */
|
||||
pFbBuffer = &(gpBuffer[dwY1 * gucWidth + dwX1]);
|
||||
for (dwY = dwY1; dwY <= dwY2; ++dwY) {
|
||||
pDestFbBuffer = pFbBuffer;
|
||||
while (blocks--) {
|
||||
memcpy(pDestFbBuffer, gFbPixelCache, FB_COLOR_CACHE_SIZE * sizeof(LcdColor_t));
|
||||
pDestFbBuffer += FB_COLOR_CACHE_SIZE;
|
||||
|
||||
}
|
||||
memcpy(pDestFbBuffer, gFbPixelCache, bytes * sizeof(LcdColor_t));
|
||||
pFbBuffer += gucWidth;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write several pixels pre-formatted in a bufer to FB.
|
||||
*
|
||||
* \param dwX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param dwY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param dwX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param dwY2 Y-coordinate of lower-right corner on LCD.
|
||||
* \param pBuffer pixel buffer area (no constraint on alignment).
|
||||
*/
|
||||
extern uint32_t FB_DrawPicture( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2, const void *pBuffer )
|
||||
{
|
||||
LcdColor_t *pFbBuffer;
|
||||
uint32_t dwY;
|
||||
|
||||
/* Swap coordinates if necessary */
|
||||
CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
|
||||
|
||||
pFbBuffer = &(gpBuffer[dwY1 * gucWidth + dwX1]);
|
||||
for (dwY = dwY1; dwY <= dwY2; ++dwY) {
|
||||
memcpy(pFbBuffer, pBuffer, (dwX2 - dwX1 + 1) * sizeof(LcdColor_t));
|
||||
pFbBuffer += gucWidth;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a line on LCD, horizontal and vertical line are supported.
|
||||
*
|
||||
* \param dwX1 X-coordinate of line start.
|
||||
* \param dwY1 Y-coordinate of line start.
|
||||
* \param dwX2 X-coordinate of line end.
|
||||
* \param dwY2 Y-coordinate of line end.
|
||||
*
|
||||
* \return 0 if operation is successful
|
||||
*/
|
||||
extern uint32_t FB_DrawLine ( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
/* Optimize horizontal or vertical line drawing */
|
||||
if (( dwY1 == dwY2 ) || (dwX1 == dwX2)) {
|
||||
FB_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY2 );
|
||||
}
|
||||
else {
|
||||
DrawLineBresenham( dwX1, dwY1, dwX2, dwY2 ) ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws a circle in FB, at the given coordinates.
|
||||
*
|
||||
* \param dwX X-coordinate of circle center.
|
||||
* \param dwY Y-coordinate of circle center.
|
||||
* \param dwR circle radius.
|
||||
*
|
||||
* \return 0 if operation is successful
|
||||
*/
|
||||
extern uint32_t FB_DrawCircle(
|
||||
uint32_t dwX,
|
||||
uint32_t dwY,
|
||||
uint32_t dwR)
|
||||
{
|
||||
int32_t d; /* Decision Variable */
|
||||
uint32_t curX; /* Current X Value */
|
||||
uint32_t curY; /* Current Y Value */
|
||||
|
||||
if (dwR == 0)
|
||||
return 0;
|
||||
d = 3 - (dwR << 1);
|
||||
curX = 0;
|
||||
curY = dwR;
|
||||
|
||||
while (curX <= curY)
|
||||
{
|
||||
FB_DrawPixel(dwX + curX, dwY + curY);
|
||||
FB_DrawPixel(dwX + curX, dwY - curY);
|
||||
FB_DrawPixel(dwX - curX, dwY + curY);
|
||||
FB_DrawPixel(dwX - curX, dwY - curY);
|
||||
FB_DrawPixel(dwX + curY, dwY + curX);
|
||||
FB_DrawPixel(dwX + curY, dwY - curX);
|
||||
FB_DrawPixel(dwX - curY, dwY + curX);
|
||||
FB_DrawPixel(dwX - curY, dwY - curX);
|
||||
|
||||
if (d < 0) {
|
||||
d += (curX << 2) + 6;
|
||||
}
|
||||
else {
|
||||
d += ((curX - curY) << 2) + 10;
|
||||
curY--;
|
||||
}
|
||||
curX++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws a filled circle in FB, at the given coordinates.
|
||||
*
|
||||
* \param dwX X-coordinate of circle center.
|
||||
* \param dwY Y-coordinate of circle center.
|
||||
* \param dwR circle radius.
|
||||
*
|
||||
* \return 0 if operation is successful
|
||||
*/
|
||||
extern uint32_t FB_DrawFilledCircle( uint32_t dwX, uint32_t dwY, uint32_t dwRadius)
|
||||
{
|
||||
signed int d ; // Decision Variable
|
||||
uint32_t dwCurX ; // Current X Value
|
||||
uint32_t dwCurY ; // Current Y Value
|
||||
uint32_t dwXmin, dwYmin;
|
||||
|
||||
if (dwRadius == 0)
|
||||
return 0;
|
||||
d = 3 - (dwRadius << 1) ;
|
||||
dwCurX = 0 ;
|
||||
dwCurY = dwRadius ;
|
||||
|
||||
while ( dwCurX <= dwCurY )
|
||||
{
|
||||
dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
|
||||
dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
|
||||
FB_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurX, dwYmin ) ;
|
||||
FB_DrawFilledRectangle( dwXmin, dwY+dwCurY, dwX+dwCurX, dwY+dwCurY ) ;
|
||||
dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
|
||||
dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
|
||||
FB_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurY, dwYmin ) ;
|
||||
FB_DrawFilledRectangle( dwXmin, dwY+dwCurX, dwX+dwCurY, dwY+dwCurX ) ;
|
||||
|
||||
if ( d < 0 )
|
||||
{
|
||||
d += (dwCurX << 2) + 6 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
d += ((dwCurX - dwCurY) << 2) + 10;
|
||||
dwCurY-- ;
|
||||
}
|
||||
|
||||
dwCurX++ ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pixel color is set by the LCD_SetColor() function.
|
||||
* This function is optimized using an sram buffer to transfer block instead of
|
||||
* individual pixels in order to limit the number of SPI interrupts.
|
||||
* \param dwX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param dwY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param dwX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param dwY2 Y-coordinate of lower-right corner on LCD.
|
||||
*
|
||||
* \return 0 if operation is successfull
|
||||
*/
|
||||
extern uint32_t FB_DrawRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
|
||||
|
||||
FB_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY1 ) ;
|
||||
FB_DrawFilledRectangle( dwX1, dwY2, dwX2, dwY2 ) ;
|
||||
|
||||
FB_DrawFilledRectangle( dwX1, dwY1, dwX1, dwY2 ) ;
|
||||
FB_DrawFilledRectangle( dwX2, dwY1, dwX2, dwY2 ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,339 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Internal function
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Counts and return the number of bits set to '1' in the given byte.
|
||||
* \param byte Byte to count.
|
||||
*/
|
||||
static uint8_t CountBitsInByte(uint8_t byte)
|
||||
{
|
||||
uint8_t count = 0;
|
||||
|
||||
while (byte > 0)
|
||||
{
|
||||
if (byte & 1)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
byte >>= 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts and return the number of bits set to '1' in the given hamming code.
|
||||
* \param code Hamming code.
|
||||
*/
|
||||
static uint8_t CountBitsInCode256(uint8_t *code)
|
||||
{
|
||||
return CountBitsInByte(code[0]) + CountBitsInByte(code[1]) + CountBitsInByte(code[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the 22-bit hamming code for a 256-bytes block of data.
|
||||
* \param data Data buffer to calculate code for.
|
||||
* \param code Pointer to a buffer where the code should be stored.
|
||||
*/
|
||||
static void Compute256(const uint8_t *data, uint8_t *code)
|
||||
{
|
||||
uint32_t i;
|
||||
uint8_t columnSum = 0;
|
||||
uint8_t evenLineCode = 0;
|
||||
uint8_t oddLineCode = 0;
|
||||
uint8_t evenColumnCode = 0;
|
||||
uint8_t oddColumnCode = 0;
|
||||
|
||||
// Xor all bytes together to get the column sum;
|
||||
// At the same time, calculate the even and odd line codes
|
||||
for (i=0; i < 256; i++)
|
||||
{
|
||||
columnSum ^= data[i];
|
||||
|
||||
// If the xor sum of the byte is 0, then this byte has no incidence on
|
||||
// the computed code; so check if the sum is 1.
|
||||
if ((CountBitsInByte(data[i]) & 1) == 1)
|
||||
{
|
||||
// Parity groups are formed by forcing a particular index bit to 0
|
||||
// (even) or 1 (odd).
|
||||
// Example on one byte:
|
||||
//
|
||||
// bits (dec) 7 6 5 4 3 2 1 0
|
||||
// (bin) 111 110 101 100 011 010 001 000
|
||||
// '---'---'---'----------.
|
||||
// |
|
||||
// groups P4' ooooooooooooooo eeeeeeeeeeeeeee P4 |
|
||||
// P2' ooooooo eeeeeee ooooooo eeeeeee P2 |
|
||||
// P1' ooo eee ooo eee ooo eee ooo eee P1 |
|
||||
// |
|
||||
// We can see that: |
|
||||
// - P4 -> bit 2 of index is 0 --------------------'
|
||||
// - P4' -> bit 2 of index is 1.
|
||||
// - P2 -> bit 1 of index if 0.
|
||||
// - etc...
|
||||
// We deduce that a bit position has an impact on all even Px if
|
||||
// the log2(x)nth bit of its index is 0
|
||||
// ex: log2(4) = 2, bit2 of the index must be 0 (-> 0 1 2 3)
|
||||
// and on all odd Px' if the log2(x)nth bit of its index is 1
|
||||
// ex: log2(2) = 1, bit1 of the index must be 1 (-> 0 1 4 5)
|
||||
//
|
||||
// As such, we calculate all the possible Px and Px' values at the
|
||||
// same time in two variables, evenLineCode and oddLineCode, such as
|
||||
// evenLineCode bits: P128 P64 P32 P16 P8 P4 P2 P1
|
||||
// oddLineCode bits: P128' P64' P32' P16' P8' P4' P2' P1'
|
||||
//
|
||||
evenLineCode ^= (255 - i);
|
||||
oddLineCode ^= i;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point, we have the line parities, and the column sum. First, We
|
||||
// must caculate the parity group values on the column sum.
|
||||
for (i=0; i < 8; i++)
|
||||
{
|
||||
if (columnSum & 1)
|
||||
{
|
||||
evenColumnCode ^= (7 - i);
|
||||
oddColumnCode ^= i;
|
||||
}
|
||||
columnSum >>= 1;
|
||||
}
|
||||
|
||||
// Now, we must interleave the parity values, to obtain the following layout:
|
||||
// Code[0] = Line1
|
||||
// Code[1] = Line2
|
||||
// Code[2] = Column
|
||||
// Line = Px' Px P(x-1)- P(x-1) ...
|
||||
// Column = P4' P4 P2' P2 P1' P1 PadBit PadBit
|
||||
code[0] = 0;
|
||||
code[1] = 0;
|
||||
code[2] = 0;
|
||||
|
||||
for (i=0; i < 4; i++)
|
||||
{
|
||||
code[0] <<= 2;
|
||||
code[1] <<= 2;
|
||||
code[2] <<= 2;
|
||||
|
||||
// Line 1
|
||||
if ((oddLineCode & 0x80) != 0)
|
||||
{
|
||||
code[0] |= 2;
|
||||
}
|
||||
|
||||
if ((evenLineCode & 0x80) != 0)
|
||||
{
|
||||
code[0] |= 1;
|
||||
}
|
||||
|
||||
// Line 2
|
||||
if ((oddLineCode & 0x08) != 0)
|
||||
{
|
||||
code[1] |= 2;
|
||||
}
|
||||
|
||||
if ((evenLineCode & 0x08) != 0)
|
||||
{
|
||||
code[1] |= 1;
|
||||
}
|
||||
|
||||
// Column
|
||||
if ((oddColumnCode & 0x04) != 0)
|
||||
{
|
||||
code[2] |= 2;
|
||||
}
|
||||
|
||||
if ((evenColumnCode & 0x04) != 0)
|
||||
{
|
||||
code[2] |= 1;
|
||||
}
|
||||
|
||||
oddLineCode <<= 1;
|
||||
evenLineCode <<= 1;
|
||||
oddColumnCode <<= 1;
|
||||
evenColumnCode <<= 1;
|
||||
}
|
||||
|
||||
// Invert codes (linux compatibility)
|
||||
code[0] = (~(uint32_t)code[0]);
|
||||
code[1] = (~(uint32_t)code[1]);
|
||||
code[2] = (~(uint32_t)code[2]);
|
||||
|
||||
TRACE_DEBUG("Computed code = %02X %02X %02X\n\r",
|
||||
code[0], code[1], code[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies and corrects a 256-bytes block of data using the given 22-bits
|
||||
* hamming code.
|
||||
*
|
||||
* \param data Data buffer to check.
|
||||
* \param originalCode Hamming code to use for verifying the data.
|
||||
*
|
||||
* \return 0 if there is no error, otherwise returns a HAMMING_ERROR code.
|
||||
*/
|
||||
static uint8_t Verify256( uint8_t* pucData, const uint8_t* pucOriginalCode )
|
||||
{
|
||||
/* Calculate new code */
|
||||
uint8_t computedCode[3] ;
|
||||
uint8_t correctionCode[3] ;
|
||||
|
||||
Compute256( pucData, computedCode ) ;
|
||||
|
||||
/* Xor both codes together */
|
||||
correctionCode[0] = computedCode[0] ^ pucOriginalCode[0] ;
|
||||
correctionCode[1] = computedCode[1] ^ pucOriginalCode[1] ;
|
||||
correctionCode[2] = computedCode[2] ^ pucOriginalCode[2] ;
|
||||
|
||||
TRACE_DEBUG( "Correction code = %02X %02X %02X\n\r", correctionCode[0], correctionCode[1], correctionCode[2] ) ;
|
||||
|
||||
// If all bytes are 0, there is no error
|
||||
if ( (correctionCode[0] == 0) && (correctionCode[1] == 0) && (correctionCode[2] == 0) )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* If there is a single bit error, there are 11 bits set to 1 */
|
||||
if ( CountBitsInCode256( correctionCode ) == 11 )
|
||||
{
|
||||
// Get byte and bit indexes
|
||||
uint8_t byte ;
|
||||
uint8_t bit ;
|
||||
|
||||
byte = correctionCode[0] & 0x80;
|
||||
byte |= (correctionCode[0] << 1) & 0x40;
|
||||
byte |= (correctionCode[0] << 2) & 0x20;
|
||||
byte |= (correctionCode[0] << 3) & 0x10;
|
||||
|
||||
byte |= (correctionCode[1] >> 4) & 0x08;
|
||||
byte |= (correctionCode[1] >> 3) & 0x04;
|
||||
byte |= (correctionCode[1] >> 2) & 0x02;
|
||||
byte |= (correctionCode[1] >> 1) & 0x01;
|
||||
|
||||
bit = (correctionCode[2] >> 5) & 0x04;
|
||||
bit |= (correctionCode[2] >> 4) & 0x02;
|
||||
bit |= (correctionCode[2] >> 3) & 0x01;
|
||||
|
||||
/* Correct bit */
|
||||
TRACE_DEBUG("Correcting byte #%d at bit %d\n\r", byte, bit ) ;
|
||||
pucData[byte] ^= (1 << bit) ;
|
||||
|
||||
return Hamming_ERROR_SINGLEBIT ;
|
||||
}
|
||||
|
||||
/* Check if ECC has been corrupted */
|
||||
if ( CountBitsInCode256( correctionCode ) == 1 )
|
||||
{
|
||||
return Hamming_ERROR_ECC ;
|
||||
}
|
||||
/* Otherwise, this is a multi-bit error */
|
||||
else
|
||||
{
|
||||
return Hamming_ERROR_MULTIPLEBITS ;
|
||||
}
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Computes 3-bytes hamming codes for a data block whose size is multiple of
|
||||
* 256 bytes. Each 256 bytes block gets its own code.
|
||||
* \param data Data to compute code for.
|
||||
* \param size Data size in bytes.
|
||||
* \param code Codes buffer.
|
||||
*/
|
||||
void Hamming_Compute256x( const uint8_t *pucData, uint32_t dwSize, uint8_t* puCode )
|
||||
{
|
||||
TRACE_DEBUG("Hamming_Compute256x()\n\r");
|
||||
|
||||
while ( dwSize > 0 )
|
||||
{
|
||||
Compute256( pucData, puCode ) ;
|
||||
|
||||
pucData += 256;
|
||||
puCode += 3;
|
||||
dwSize -= 256;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies 3-bytes hamming codes for a data block whose size is multiple of
|
||||
* 256 bytes. Each 256-bytes block is verified with its own code.
|
||||
*
|
||||
* \return 0 if the data is correct, Hamming_ERROR_SINGLEBIT if one or more
|
||||
* block(s) have had a single bit corrected, or either Hamming_ERROR_ECC
|
||||
* or Hamming_ERROR_MULTIPLEBITS.
|
||||
*
|
||||
* \param data Data buffer to verify.
|
||||
* \param size Size of the data in bytes.
|
||||
* \param code Original codes.
|
||||
*/
|
||||
uint8_t Hamming_Verify256x( uint8_t* pucData, uint32_t dwSize, const uint8_t* pucCode )
|
||||
{
|
||||
uint8_t error ;
|
||||
uint8_t result = 0 ;
|
||||
|
||||
TRACE_DEBUG( "Hamming_Verify256x()\n\r" ) ;
|
||||
|
||||
while ( dwSize > 0 )
|
||||
{
|
||||
error = Verify256( pucData, pucCode ) ;
|
||||
|
||||
if ( error == Hamming_ERROR_SINGLEBIT )
|
||||
{
|
||||
result = Hamming_ERROR_SINGLEBIT ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( error )
|
||||
{
|
||||
return error ;
|
||||
}
|
||||
}
|
||||
|
||||
pucData += 256;
|
||||
pucCode += 3;
|
||||
dwSize -= 256;
|
||||
}
|
||||
|
||||
return result ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,907 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2010, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of ILI9325 driver.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include "board.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef BOARD_LCD_ILI9325
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* Pixel cache used to speed up communication */
|
||||
#define LCD_DATA_CACHE_SIZE BOARD_LCD_WIDTH
|
||||
static LcdColor_t gLcdPixelCache[LCD_DATA_CACHE_SIZE];
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Export functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Write data to LCD Register.
|
||||
*
|
||||
* \param reg Register address.
|
||||
* \param data Data to be written.
|
||||
*/
|
||||
static void LCD_WriteReg( uint8_t reg, uint16_t data )
|
||||
{
|
||||
LCD_IR() = 0;
|
||||
LCD_IR() = reg;
|
||||
LCD_D() = (data >> 8) & 0xFF;
|
||||
LCD_D() = data & 0xFF;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read data from LCD Register.
|
||||
*
|
||||
* \param reg Register address.
|
||||
*
|
||||
* \return Readed data.
|
||||
*/
|
||||
static uint16_t LCD_ReadReg( uint8_t reg )
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
LCD_IR() = 0;
|
||||
LCD_IR() = reg;
|
||||
|
||||
value = LCD_D();
|
||||
value = (value << 8) | LCD_D();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Prepare to write GRAM data.
|
||||
*/
|
||||
extern void LCD_WriteRAM_Prepare( void )
|
||||
{
|
||||
LCD_IR() = 0 ;
|
||||
LCD_IR() = ILI9325_R22H ; /* Write Data to GRAM (R22h) */
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write data to LCD GRAM.
|
||||
*
|
||||
* \param color 24-bits RGB color.
|
||||
*/
|
||||
extern void LCD_WriteRAM( LcdColor_t dwColor )
|
||||
{
|
||||
LCD_D() = ((dwColor >> 16) & 0xFF);
|
||||
LCD_D() = ((dwColor >> 8) & 0xFF);
|
||||
LCD_D() = (dwColor & 0xFF);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write mutiple data in buffer to LCD controller.
|
||||
*
|
||||
* \param pBuf data buffer.
|
||||
* \param size size in pixels.
|
||||
*/
|
||||
static void LCD_WriteRAMBuffer(const LcdColor_t *pBuf, uint32_t size)
|
||||
{
|
||||
uint32_t addr ;
|
||||
|
||||
for ( addr = 0 ; addr < size ; addr++ )
|
||||
{
|
||||
LCD_WriteRAM(pBuf[addr]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Prepare to read GRAM data.
|
||||
*/
|
||||
extern void LCD_ReadRAM_Prepare( void )
|
||||
{
|
||||
LCD_IR() = 0 ;
|
||||
LCD_IR() = ILI9325_R22H ; /* Write Data to GRAM (R22h) */
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read data to LCD GRAM.
|
||||
*
|
||||
* \note Because pixel data LCD GRAM is 18-bits, so convertion to RGB 24-bits
|
||||
* will cause low color bit lose.
|
||||
*
|
||||
* \return color 24-bits RGB color.
|
||||
*/
|
||||
extern uint32_t LCD_ReadRAM( void )
|
||||
{
|
||||
uint8_t value[2];
|
||||
uint32_t color;
|
||||
|
||||
value[0] = LCD_D(); /* dummy read */
|
||||
value[1] = LCD_D(); /* dummy read */
|
||||
value[0] = LCD_D(); /* data upper byte */
|
||||
value[1] = LCD_D(); /* data lower byte */
|
||||
|
||||
/* Convert RGB565 to RGB888 */
|
||||
/* For BGR format */
|
||||
color = ((value[0] & 0xF8)) | /* R */
|
||||
((value[0] & 0x07) << 13) | ((value[1] & 0xE0) << 5) | /* G */
|
||||
((value[1] & 0x1F) << 19); /* B */
|
||||
return color;
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Basic ILI9225 primitives
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Check Box coordinates. Return upper left and bottom right coordinates.
|
||||
*
|
||||
* \param pX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param pY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param pX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param pY2 Y-coordinate of lower-right corner on LCD.
|
||||
*/
|
||||
static void CheckBoxCoordinates( uint32_t *pX1, uint32_t *pY1, uint32_t *pX2, uint32_t *pY2 )
|
||||
{
|
||||
uint32_t dw;
|
||||
|
||||
if ( *pX1 >= BOARD_LCD_WIDTH )
|
||||
{
|
||||
*pX1 = BOARD_LCD_WIDTH-1 ;
|
||||
}
|
||||
if ( *pX2 >= BOARD_LCD_WIDTH )
|
||||
{
|
||||
*pX2 = BOARD_LCD_WIDTH-1 ;
|
||||
}
|
||||
if ( *pY1 >= BOARD_LCD_HEIGHT )
|
||||
{
|
||||
*pY1 = BOARD_LCD_HEIGHT-1 ;
|
||||
}
|
||||
if ( *pY2 >= BOARD_LCD_HEIGHT )
|
||||
{
|
||||
*pY2 = BOARD_LCD_HEIGHT-1 ;
|
||||
}
|
||||
if (*pX1 > *pX2)
|
||||
{
|
||||
dw = *pX1;
|
||||
*pX1 = *pX2;
|
||||
*pX2 = dw;
|
||||
}
|
||||
if (*pY1 > *pY2)
|
||||
{
|
||||
dw = *pY1;
|
||||
*pY1 = *pY2;
|
||||
*pY2 = dw;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize the LCD controller.
|
||||
*/
|
||||
extern uint32_t LCD_Initialize( void )
|
||||
{
|
||||
uint16_t chipid ;
|
||||
|
||||
/* Check ILI9325 chipid */
|
||||
chipid = LCD_ReadReg( ILI9325_R00H ) ; /* Driver Code Read (R00h) */
|
||||
if ( chipid != ILI9325_DEVICE_CODE )
|
||||
{
|
||||
printf( "Read ILI9325 chip ID (0x%04x) error, skip initialization.\r\n", chipid ) ;
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
/* Turn off LCD */
|
||||
LCD_PowerDown() ;
|
||||
|
||||
/* Start initial sequence */
|
||||
LCD_WriteReg(ILI9325_R10H, 0x0000); /* DSTB = LP = STB = 0 */
|
||||
LCD_WriteReg(ILI9325_R00H, 0x0001); /* start internal OSC */
|
||||
LCD_WriteReg(ILI9325_R01H, ILI9325_R01H_SS ) ; /* set SS and SM bit */
|
||||
LCD_WriteReg(ILI9325_R02H, 0x0700); /* set 1 line inversion */
|
||||
//LCD_WriteReg(ILI9325_R03H, 0xD030); /* set GRAM write direction and BGR=1. */
|
||||
LCD_WriteReg(ILI9325_R04H, 0x0000); /* Resize register */
|
||||
LCD_WriteReg(ILI9325_R08H, 0x0207); /* set the back porch and front porch */
|
||||
LCD_WriteReg(ILI9325_R09H, 0x0000); /* set non-display area refresh cycle ISC[3:0] */
|
||||
LCD_WriteReg(ILI9325_R0AH, 0x0000); /* FMARK function */
|
||||
LCD_WriteReg(ILI9325_R0CH, 0x0000); /* RGB interface setting */
|
||||
LCD_WriteReg(ILI9325_R0DH, 0x0000); /* Frame marker Position */
|
||||
LCD_WriteReg(ILI9325_R0FH, 0x0000); /* RGB interface polarity */
|
||||
|
||||
/* Power on sequence */
|
||||
LCD_WriteReg(ILI9325_R10H, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
|
||||
LCD_WriteReg(ILI9325_R11H, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */
|
||||
LCD_WriteReg(ILI9325_R12H, 0x0000); /* VREG1OUT voltage */
|
||||
LCD_WriteReg(ILI9325_R13H, 0x0000); /* VDV[4:0] for VCOM amplitude */
|
||||
Wait( 200 ) ; /* Dis-charge capacitor power voltage */
|
||||
LCD_WriteReg(ILI9325_R10H, 0x1290); /* SAP, BT[3:0], AP, DSTB, SLP, STB */
|
||||
LCD_WriteReg(ILI9325_R11H, 0x0227); /* DC1[2:0], DC0[2:0], VC[2:0] */
|
||||
Wait( 50 ) ;
|
||||
LCD_WriteReg(ILI9325_R12H, 0x001B); /* Internal reference voltage= Vci; */
|
||||
Wait( 50 ) ;
|
||||
LCD_WriteReg(ILI9325_R13H, 0x1100); /* Set VDV[4:0] for VCOM amplitude */
|
||||
LCD_WriteReg(ILI9325_R29H, 0x0019); /* Set VCM[5:0] for VCOMH */
|
||||
LCD_WriteReg(ILI9325_R2BH, 0x000D); /* Set Frame Rate */
|
||||
Wait( 50 ) ;
|
||||
|
||||
/* Adjust the Gamma Curve */
|
||||
LCD_WriteReg(ILI9325_R30H, 0x0000);
|
||||
LCD_WriteReg(ILI9325_R31H, 0x0204);
|
||||
LCD_WriteReg(ILI9325_R32H, 0x0200);
|
||||
LCD_WriteReg(ILI9325_R35H, 0x0007);
|
||||
LCD_WriteReg(ILI9325_R36H, 0x1404);
|
||||
LCD_WriteReg(ILI9325_R37H, 0x0705);
|
||||
LCD_WriteReg(ILI9325_R38H, 0x0305);
|
||||
LCD_WriteReg(ILI9325_R39H, 0x0707);
|
||||
LCD_WriteReg(ILI9325_R3CH, 0x0701);
|
||||
LCD_WriteReg(ILI9325_R3DH, 0x000e);
|
||||
|
||||
LCD_SetDisplayPortrait( 0 ) ;
|
||||
/* Vertical Scrolling */
|
||||
LCD_WriteReg( ILI9325_R61H, 0x0001 ) ;
|
||||
LCD_WriteReg( ILI9325_R6AH, 0x0000 ) ;
|
||||
|
||||
/* Partial Display Control */
|
||||
LCD_WriteReg(ILI9325_R80H, 0x0000);
|
||||
LCD_WriteReg(ILI9325_R81H, 0x0000);
|
||||
LCD_WriteReg(ILI9325_R82H, 0x0000);
|
||||
LCD_WriteReg(ILI9325_R83H, 0x0000);
|
||||
LCD_WriteReg(ILI9325_R84H, 0x0000);
|
||||
LCD_WriteReg(ILI9325_R85H, 0x0000);
|
||||
|
||||
/* Panel Control */
|
||||
LCD_WriteReg(ILI9325_R90H, 0x0010);
|
||||
LCD_WriteReg(ILI9325_R92H, 0x0600);
|
||||
LCD_WriteReg(ILI9325_R95H, 0x0110);
|
||||
|
||||
LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
|
||||
LCD_SetCursor( 0, 0 ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn on the LCD.
|
||||
*/
|
||||
extern void LCD_On( void )
|
||||
{
|
||||
/* Display Control 1 (R07h) */
|
||||
/* When BASEE = “1”, the base image is displayed. */
|
||||
/* GON and DTE Set the output level of gate driver G1 ~ G320 : Normal Display */
|
||||
/* D1=1 D0=1 BASEE=1: Base image display Operate */
|
||||
LCD_WriteReg( ILI9325_R07H, ILI9325_R07H_BASEE
|
||||
| ILI9325_R07H_GON | ILI9325_R07H_DTE
|
||||
| ILI9325_R07H_D1 | ILI9325_R07H_D0 ) ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Turn off the LCD.
|
||||
*/
|
||||
extern void LCD_Off( void )
|
||||
{
|
||||
/* Display Control 1 (R07h) */
|
||||
/* When BASEE = “0”, no base image is displayed. */
|
||||
/* When the display is turned off by setting D[1:0] = “00”, the ILI9325 internal display
|
||||
operation is halted completely. */
|
||||
/* PTDE1/0 = 0: turns off partial image. */
|
||||
LCD_WriteReg( ILI9325_R07H, 0x00 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Power down the LCD.
|
||||
*/
|
||||
extern void LCD_PowerDown( void )
|
||||
{
|
||||
/* Display Control 1 (R07h) */
|
||||
/* When BASEE = “0”, no base image is displayed. */
|
||||
/* GON and DTE Set the output level of gate driver G1 ~ G320 : Normal Display */
|
||||
/* D1=1 D0=1 BASEE=1: Base image display Operate */
|
||||
LCD_WriteReg( ILI9325_R07H, ILI9325_R07H_GON | ILI9325_R07H_DTE
|
||||
| ILI9325_R07H_D1 | ILI9325_R07H_D0 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert 24 bit RGB color into 5-6-5 rgb color space.
|
||||
*
|
||||
* Initialize the LcdColor_t cache with the color pattern.
|
||||
* \param x 24-bits RGB color.
|
||||
* \return 0 for successfull operation.
|
||||
*/
|
||||
extern uint32_t LCD_SetColor( uint32_t dwRgb24Bits )
|
||||
{
|
||||
uint32_t i ;
|
||||
|
||||
/* Fill the cache with selected color */
|
||||
for ( i = 0 ; i < LCD_DATA_CACHE_SIZE ; ++i )
|
||||
{
|
||||
gLcdPixelCache[i] = dwRgb24Bits ;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set cursor of LCD srceen.
|
||||
*
|
||||
* \param x X-coordinate of upper-left corner on LCD.
|
||||
* \param y Y-coordinate of upper-left corner on LCD.
|
||||
*/
|
||||
extern void LCD_SetCursor( uint16_t x, uint16_t y )
|
||||
{
|
||||
/* GRAM Horizontal/Vertical Address Set (R20h, R21h) */
|
||||
LCD_WriteReg( ILI9325_R20H, x ) ; /* column */
|
||||
LCD_WriteReg( ILI9325_R21H, y ) ; /* row */
|
||||
}
|
||||
|
||||
extern void LCD_SetWindow( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight )
|
||||
{
|
||||
/* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
|
||||
|
||||
/* Set Horizontal Address Start Position */
|
||||
LCD_WriteReg( ILI9325_R50H, (uint16_t)dwX ) ;
|
||||
|
||||
/* Set Horizontal Address End Position */
|
||||
LCD_WriteReg( ILI9325_R51H, (uint16_t)dwX+dwWidth-1 ) ;
|
||||
|
||||
/* Set Vertical Address Start Position */
|
||||
LCD_WriteReg( ILI9325_R52H, (uint16_t)dwY ) ;
|
||||
|
||||
/* Set Vertical Address End Position */
|
||||
LCD_WriteReg( ILI9325_R53H, (uint16_t)dwY+dwHeight-1 ) ;
|
||||
}
|
||||
|
||||
extern void LCD_SetDisplayLandscape( uint32_t dwRGB )
|
||||
{
|
||||
uint16_t dwValue ;
|
||||
|
||||
/* When AM = “1”, the address is updated in vertical writing direction. */
|
||||
/* DFM Set the mode of transferring data to the internal RAM when TRI = “1”. */
|
||||
/* When TRI = “1”, data are transferred to the internal RAM in 8-bit x 3 transfers mode via the 8-bit interface. */
|
||||
/* Use the high speed write mode (HWM=1) */
|
||||
/* ORG = “1”: The original address “00000h” moves according to the I/D[1:0] setting. */
|
||||
/* I/D[1:0] = 00 Horizontal : decrement Vertical : decrement, AM=0:Horizontal */
|
||||
dwValue = ILI9325_R03H_AM | ILI9325_R03H_DFM | ILI9325_R03H_TRI | ILI9325_R03H_HWM | ILI9325_R03H_ORG ;
|
||||
|
||||
if ( dwRGB == 0 )
|
||||
{
|
||||
/* BGR=”1”: Swap the RGB data to BGR in writing into GRAM. */
|
||||
dwValue |= ILI9325_R03H_BGR ;
|
||||
}
|
||||
LCD_WriteReg( ILI9325_R03H, dwValue ) ;
|
||||
|
||||
// LCD_WriteReg( ILI9325_R60H, (0x1d<<8)|0x00 ) ; /*Gate Scan Control */
|
||||
|
||||
LCD_SetWindow( 0, 0, BOARD_LCD_HEIGHT, BOARD_LCD_WIDTH ) ;
|
||||
}
|
||||
|
||||
extern void LCD_SetDisplayPortrait( uint32_t dwRGB )
|
||||
{
|
||||
uint16_t dwValue ;
|
||||
|
||||
/* Use the high speed write mode (HWM=1) */
|
||||
/* When TRI = “1”, data are transferred to the internal RAM in 8-bit x 3 transfers mode via the 8-bit interface. */
|
||||
/* DFM Set the mode of transferring data to the internal RAM when TRI = “1”. */
|
||||
/* I/D[1:0] = 11 Horizontal : increment Vertical : increment, AM=0:Horizontal */
|
||||
dwValue = ILI9325_R03H_HWM | ILI9325_R03H_TRI | ILI9325_R03H_DFM | ILI9325_R03H_ID1 | ILI9325_R03H_ID0 ;
|
||||
|
||||
if ( dwRGB == 0 )
|
||||
{
|
||||
/* BGR=”1”: Swap the RGB data to BGR in writing into GRAM. */
|
||||
dwValue |= ILI9325_R03H_BGR ;
|
||||
}
|
||||
LCD_WriteReg( ILI9325_R03H, dwValue ) ;
|
||||
/* Gate Scan Control (R60h, R61h, R6Ah) */
|
||||
/* SCN[5:0] = 00 */
|
||||
/* NL[5:0]: Sets the number of lines to drive the LCD at an interval of 8 lines. */
|
||||
LCD_WriteReg( ILI9325_R60H, ILI9325_R60H_GS|(0x27<<8)|0x00 ) ;
|
||||
}
|
||||
|
||||
|
||||
extern void LCD_VerticalScroll( uint16_t wY )
|
||||
{
|
||||
/* Gate Scan Control (R60h, R61h, R6Ah) */
|
||||
/* Enables the grayscale inversion of the image by setting REV=1. */
|
||||
/* VLE: Vertical scroll display enable bit */
|
||||
LCD_WriteReg( ILI9325_R61H, 3 ) ;
|
||||
LCD_WriteReg( ILI9325_R6AH, wY ) ;
|
||||
}
|
||||
|
||||
|
||||
extern void LCD_SetPartialImage1( uint32_t dwDisplayPos, uint32_t dwStart, uint32_t dwEnd )
|
||||
{
|
||||
assert( dwStart <= dwEnd ) ;
|
||||
|
||||
/* Partial Image 1 Display Position (R80h) */
|
||||
LCD_WriteReg( ILI9325_R80H, dwDisplayPos&0x1ff ) ;
|
||||
/* Partial Image 1 RAM Start/End Address (R81h, R82h) */
|
||||
LCD_WriteReg( ILI9325_R81H, dwStart&0x1ff ) ;
|
||||
LCD_WriteReg( ILI9325_R82H, dwEnd&0x1ff ) ;
|
||||
}
|
||||
|
||||
extern void LCD_SetPartialImage2( uint32_t dwDisplayPos, uint32_t dwStart, uint32_t dwEnd )
|
||||
{
|
||||
assert( dwStart <= dwEnd ) ;
|
||||
|
||||
/* Partial Image 2 Display Position (R83h) */
|
||||
LCD_WriteReg( ILI9325_R83H, dwDisplayPos&0x1ff ) ;
|
||||
/* Partial Image 2 RAM Start/End Address (R84h, R85h) */
|
||||
LCD_WriteReg( ILI9325_R84H, dwStart&0x1ff ) ;
|
||||
LCD_WriteReg( ILI9325_R85H, dwEnd&0x1ff ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draw a LcdColor_t on LCD of given color.
|
||||
*
|
||||
* \param x X-coordinate of pixel.
|
||||
* \param y Y-coordinate of pixel.
|
||||
*/
|
||||
extern uint32_t LCD_DrawPixel( uint32_t x, uint32_t y )
|
||||
{
|
||||
if( (x >= BOARD_LCD_WIDTH) || (y >= BOARD_LCD_HEIGHT) )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Set cursor */
|
||||
LCD_SetCursor( x, y );
|
||||
|
||||
/* Prepare to write in GRAM */
|
||||
LCD_WriteRAM_Prepare();
|
||||
LCD_WriteRAM( *gLcdPixelCache );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
extern void LCD_TestPattern( uint32_t dwRGB )
|
||||
{
|
||||
uint32_t dwLine ;
|
||||
uint32_t dw ;
|
||||
|
||||
LCD_SetWindow( 10, 10, 100, 20 ) ;
|
||||
LCD_SetCursor( 10, 10 ) ;
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
|
||||
for ( dwLine=0 ; dwLine < 20 ; dwLine++ )
|
||||
{
|
||||
/* Draw White bar */
|
||||
for ( dw=0 ; dw < 20 ; dw++ )
|
||||
{
|
||||
LCD_D() = 0xff ;
|
||||
LCD_D() = 0xff ;
|
||||
LCD_D() = 0xff ;
|
||||
}
|
||||
/* Draw Red bar */
|
||||
for ( dw=0 ; dw < 20 ; dw++ )
|
||||
{
|
||||
if ( dwRGB == 0 )
|
||||
{
|
||||
LCD_D() = 0xff ;
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0x00 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0xff ;
|
||||
}
|
||||
}
|
||||
/* Draw Green bar */
|
||||
for ( dw=0 ; dw < 20 ; dw++ )
|
||||
{
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0xff ;
|
||||
LCD_D() = 0x00 ;
|
||||
}
|
||||
/* Draw Blue bar */
|
||||
for ( dw=0 ; dw < 20 ; dw++ )
|
||||
{
|
||||
if ( dwRGB == 0 )
|
||||
{
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0xff ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_D() = 0xff ;
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0x00 ;
|
||||
}
|
||||
}
|
||||
/* Draw Black bar */
|
||||
for ( dw=0 ; dw < 20 ; dw++ )
|
||||
{
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0x00 ;
|
||||
LCD_D() = 0x00 ;
|
||||
}
|
||||
}
|
||||
|
||||
LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Write several pixels with the same color to LCD GRAM.
|
||||
*
|
||||
* LcdColor_t color is set by the LCD_SetColor() function.
|
||||
* This function is optimized using an sram buffer to transfer block instead of
|
||||
* individual pixels in order to limit the number of SPI interrupts.
|
||||
* \param dwX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param dwY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param dwX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param dwY2 Y-coordinate of lower-right corner on LCD.
|
||||
*/
|
||||
extern uint32_t LCD_DrawFilledRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
uint32_t size, blocks;
|
||||
|
||||
/* Swap coordinates if necessary */
|
||||
CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
|
||||
|
||||
/* Determine the refresh window area */
|
||||
/* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
|
||||
LCD_WriteReg(ILI9325_R50H, (uint16_t)dwX1);
|
||||
LCD_WriteReg(ILI9325_R51H, (uint16_t)dwX2);
|
||||
LCD_WriteReg(ILI9325_R52H, (uint16_t)dwY1);
|
||||
LCD_WriteReg(ILI9325_R53H, (uint16_t)dwY2);
|
||||
|
||||
/* Set cursor */
|
||||
LCD_SetCursor( dwX1, dwY1 );
|
||||
|
||||
/* Prepare to write in GRAM */
|
||||
LCD_WriteRAM_Prepare();
|
||||
|
||||
size = (dwX2 - dwX1 + 1) * (dwY2 - dwY1 + 1);
|
||||
/* Send pixels blocks => one SPI IT / block */
|
||||
blocks = size / LCD_DATA_CACHE_SIZE;
|
||||
while (blocks--)
|
||||
{
|
||||
LCD_WriteRAMBuffer(gLcdPixelCache, LCD_DATA_CACHE_SIZE);
|
||||
}
|
||||
/* Send remaining pixels */
|
||||
LCD_WriteRAMBuffer(gLcdPixelCache, size % LCD_DATA_CACHE_SIZE);
|
||||
|
||||
/* Reset the refresh window area */
|
||||
/* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
|
||||
LCD_WriteReg(ILI9325_R50H, (uint16_t)0 ) ;
|
||||
LCD_WriteReg(ILI9325_R51H, (uint16_t)BOARD_LCD_WIDTH - 1 ) ;
|
||||
LCD_WriteReg(ILI9325_R52H, (uint16_t)0) ;
|
||||
LCD_WriteReg(ILI9325_R53H, (uint16_t)BOARD_LCD_HEIGHT - 1 ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write several pixels pre-formatted in a bufer to LCD GRAM.
|
||||
*
|
||||
* \param dwX1 X-coordinate of upper-left corner on LCD.
|
||||
* \param dwY1 Y-coordinate of upper-left corner on LCD.
|
||||
* \param dwX2 X-coordinate of lower-right corner on LCD.
|
||||
* \param dwY2 Y-coordinate of lower-right corner on LCD.
|
||||
* \param pBuffer LcdColor_t buffer area.
|
||||
*/
|
||||
extern uint32_t LCD_DrawPicture( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2, const LcdColor_t *pBuffer )
|
||||
{
|
||||
uint32_t size, blocks;
|
||||
LcdColor_t currentColor;
|
||||
|
||||
/* Swap coordinates if necessary */
|
||||
CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
|
||||
|
||||
/* Determine the refresh window area */
|
||||
/* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
|
||||
LCD_WriteReg(ILI9325_R50H, (uint16_t)dwX1 ) ;
|
||||
LCD_WriteReg(ILI9325_R51H, (uint16_t)dwX2 ) ;
|
||||
LCD_WriteReg(ILI9325_R52H, (uint16_t)dwY1 ) ;
|
||||
LCD_WriteReg(ILI9325_R53H, (uint16_t)dwY2 ) ;
|
||||
|
||||
/* Set cursor */
|
||||
LCD_SetCursor( dwX1, dwY1 );
|
||||
|
||||
/* Prepare to write in GRAM */
|
||||
LCD_WriteRAM_Prepare();
|
||||
|
||||
size = (dwX2 - dwX1 + 1) * (dwY2 - dwY1 + 1);
|
||||
|
||||
/* Check if the buffer is within the SRAM */
|
||||
if ((IRAM_ADDR <= (uint32_t)pBuffer) && ((uint32_t)pBuffer < (IRAM_ADDR+IRAM_SIZE)))
|
||||
{
|
||||
LCD_WriteRAMBuffer(pBuffer, size);
|
||||
}
|
||||
/* If the buffer is not in SRAM, transfer it in SRAM first before transfer */
|
||||
else
|
||||
{
|
||||
/* Use color buffer as a cache */
|
||||
currentColor = gLcdPixelCache[0];
|
||||
/* Send pixels blocks => one SPI IT / block */
|
||||
blocks = size / LCD_DATA_CACHE_SIZE;
|
||||
while (blocks--)
|
||||
{
|
||||
memcpy(gLcdPixelCache, pBuffer, LCD_DATA_CACHE_SIZE * sizeof(LcdColor_t));
|
||||
LCD_WriteRAMBuffer(gLcdPixelCache, LCD_DATA_CACHE_SIZE);
|
||||
pBuffer += LCD_DATA_CACHE_SIZE;
|
||||
}
|
||||
/* Send remaining pixels */
|
||||
memcpy(gLcdPixelCache, pBuffer, (size % LCD_DATA_CACHE_SIZE) * sizeof(LcdColor_t));
|
||||
LCD_WriteRAMBuffer(gLcdPixelCache, size % LCD_DATA_CACHE_SIZE);
|
||||
|
||||
/* Restore the color cache */
|
||||
LCD_SetColor(currentColor);
|
||||
}
|
||||
|
||||
/* Reset the refresh window area */
|
||||
/* Horizontal and Vertical RAM Address Position (R50h, R51h, R52h, R53h) */
|
||||
LCD_WriteReg(ILI9325_R50H, (uint16_t)0 ) ;
|
||||
LCD_WriteReg(ILI9325_R51H, (uint16_t)BOARD_LCD_WIDTH - 1 ) ;
|
||||
LCD_WriteReg(ILI9325_R52H, (uint16_t)0 ) ;
|
||||
LCD_WriteReg(ILI9325_R53H, (uint16_t)BOARD_LCD_HEIGHT - 1 ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a line on LCD, which is not horizontal or vertical.
|
||||
*
|
||||
* \param x X-coordinate of line start.
|
||||
* \param y Y-coordinate of line start.
|
||||
* \param length line length.
|
||||
* \param direction line direction: 0 - horizontal, 1 - vertical.
|
||||
* \param color LcdColor_t color.
|
||||
*/
|
||||
static uint32_t DrawLineBresenham( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
int dx, dy ;
|
||||
int i ;
|
||||
int xinc, yinc, cumul ;
|
||||
int x, y ;
|
||||
|
||||
x = dwX1 ;
|
||||
y = dwY1 ;
|
||||
dx = dwX2 - dwX1 ;
|
||||
dy = dwY2 - dwY1 ;
|
||||
|
||||
xinc = ( dx > 0 ) ? 1 : -1 ;
|
||||
yinc = ( dy > 0 ) ? 1 : -1 ;
|
||||
dx = ( dx > 0 ) ? dx : -dx ;
|
||||
dy = ( dy > 0 ) ? dy : -dy ;
|
||||
|
||||
LCD_DrawPixel( x, y ) ;
|
||||
|
||||
if ( dx > dy )
|
||||
{
|
||||
cumul = dx / 2 ;
|
||||
for ( i = 1 ; i <= dx ; i++ )
|
||||
{
|
||||
x += xinc ;
|
||||
cumul += dy ;
|
||||
|
||||
if ( cumul >= dx )
|
||||
{
|
||||
cumul -= dx ;
|
||||
y += yinc ;
|
||||
}
|
||||
LCD_DrawPixel( x, y ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cumul = dy / 2 ;
|
||||
for ( i = 1 ; i <= dy ; i++ )
|
||||
{
|
||||
y += yinc ;
|
||||
cumul += dx ;
|
||||
|
||||
if ( cumul >= dy )
|
||||
{
|
||||
cumul -= dy ;
|
||||
x += xinc ;
|
||||
}
|
||||
|
||||
LCD_DrawPixel( x, y ) ;
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a line on LCD, horizontal and vertical line are supported.
|
||||
*
|
||||
* \param dwX1 X-coordinate of line start.
|
||||
* \param dwY1 Y-coordinate of line start.
|
||||
* \param dwX2 X-coordinate of line end.
|
||||
* \param dwY2 Y-coordinate of line end.
|
||||
*/
|
||||
extern uint32_t LCD_DrawLine ( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
/* Optimize horizontal or vertical line drawing */
|
||||
if (( dwY1 == dwY2 ) || (dwX1 == dwX2))
|
||||
{
|
||||
LCD_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawLineBresenham( dwX1, dwY1, dwX2, dwY2 ) ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws a circle on LCD, at the given coordinates.
|
||||
*
|
||||
* \param dwX X-coordinate of circle center.
|
||||
* \param dwY Y-coordinate of circle center.
|
||||
* \param dwR circle radius.
|
||||
*/
|
||||
extern uint32_t LCD_DrawCircle( uint32_t dwX, uint32_t dwY, uint32_t dwR )
|
||||
{
|
||||
int32_t d; /* Decision Variable */
|
||||
uint32_t curX; /* Current X Value */
|
||||
uint32_t curY; /* Current Y Value */
|
||||
|
||||
if (dwR == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
d = 3 - (dwR << 1);
|
||||
curX = 0;
|
||||
curY = dwR;
|
||||
|
||||
while (curX <= curY)
|
||||
{
|
||||
LCD_DrawPixel(dwX + curX, dwY + curY);
|
||||
LCD_DrawPixel(dwX + curX, dwY - curY);
|
||||
LCD_DrawPixel(dwX - curX, dwY + curY);
|
||||
LCD_DrawPixel(dwX - curX, dwY - curY);
|
||||
LCD_DrawPixel(dwX + curY, dwY + curX);
|
||||
LCD_DrawPixel(dwX + curY, dwY - curX);
|
||||
LCD_DrawPixel(dwX - curY, dwY + curX);
|
||||
LCD_DrawPixel(dwX - curY, dwY - curX);
|
||||
|
||||
if (d < 0)
|
||||
{
|
||||
d += (curX << 2) + 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
d += ((curX - curY) << 2) + 10;
|
||||
curY--;
|
||||
}
|
||||
curX++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern uint32_t LCD_DrawFilledCircle( uint32_t dwX, uint32_t dwY, uint32_t dwRadius)
|
||||
{
|
||||
signed int d ; /* Decision Variable */
|
||||
uint32_t dwCurX ; /* Current X Value */
|
||||
uint32_t dwCurY ; /* Current Y Value */
|
||||
uint32_t dwXmin, dwYmin;
|
||||
|
||||
if (dwRadius == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
d = 3 - (dwRadius << 1) ;
|
||||
dwCurX = 0 ;
|
||||
dwCurY = dwRadius ;
|
||||
|
||||
while ( dwCurX <= dwCurY )
|
||||
{
|
||||
dwXmin = (dwCurX > dwX) ? 0 : dwX-dwCurX;
|
||||
dwYmin = (dwCurY > dwY) ? 0 : dwY-dwCurY;
|
||||
LCD_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurX, dwYmin ) ;
|
||||
LCD_DrawFilledRectangle( dwXmin, dwY+dwCurY, dwX+dwCurX, dwY+dwCurY ) ;
|
||||
dwXmin = (dwCurY > dwX) ? 0 : dwX-dwCurY;
|
||||
dwYmin = (dwCurX > dwY) ? 0 : dwY-dwCurX;
|
||||
LCD_DrawFilledRectangle( dwXmin, dwYmin, dwX+dwCurY, dwYmin ) ;
|
||||
LCD_DrawFilledRectangle( dwXmin, dwY+dwCurX, dwX+dwCurY, dwY+dwCurX ) ;
|
||||
|
||||
if ( d < 0 )
|
||||
{
|
||||
d += (dwCurX << 2) + 6 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
d += ((dwCurX - dwCurY) << 2) + 10;
|
||||
dwCurY-- ;
|
||||
}
|
||||
|
||||
dwCurX++ ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
extern uint32_t LCD_DrawRectangle( uint32_t dwX1, uint32_t dwY1, uint32_t dwX2, uint32_t dwY2 )
|
||||
{
|
||||
CheckBoxCoordinates(&dwX1, &dwY1, &dwX2, &dwY2);
|
||||
|
||||
LCD_DrawFilledRectangle( dwX1, dwY1, dwX2, dwY1 ) ;
|
||||
LCD_DrawFilledRectangle( dwX1, dwY2, dwX2, dwY2 ) ;
|
||||
|
||||
LCD_DrawFilledRectangle( dwX1, dwY1, dwX1, dwY2 ) ;
|
||||
LCD_DrawFilledRectangle( dwX2, dwY1, dwX2, dwY2 ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* \brief Set the backlight of the LCD (AAT3155).
|
||||
*
|
||||
* \param level Backlight brightness level [1..16], 1 means maximum brightness.
|
||||
*/
|
||||
extern void LCD_SetBacklight (uint32_t level)
|
||||
{
|
||||
uint32_t i;
|
||||
const Pin pPins[] = {BOARD_BACKLIGHT_PIN};
|
||||
|
||||
/* Ensure valid level */
|
||||
level = (level < 1) ? 1 : level;
|
||||
level = (level > 16) ? 16 : level;
|
||||
|
||||
/* Enable pins */
|
||||
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
|
||||
|
||||
/* Switch off backlight */
|
||||
PIO_Clear(pPins);
|
||||
i = 600 * (BOARD_MCK / 1000000); /* wait for at least 500us */
|
||||
while(i--);
|
||||
|
||||
/* Set new backlight level */
|
||||
for (i = 0; i < level; i++)
|
||||
{
|
||||
PIO_Clear(pPins);
|
||||
PIO_Clear(pPins);
|
||||
PIO_Clear(pPins);
|
||||
|
||||
PIO_Set(pPins);
|
||||
PIO_Set(pPins);
|
||||
PIO_Set(pPins);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,611 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \section Purpose
|
||||
*
|
||||
* ISO 7816 driver
|
||||
*
|
||||
* \section Usage
|
||||
*
|
||||
* Explanation on the usage of the code made available through the header file.
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*------------------------------------------------------------------------------*/
|
||||
/** Case for APDU commands*/
|
||||
#define CASE1 1
|
||||
#define CASE2 2
|
||||
#define CASE3 3
|
||||
|
||||
/** Flip flop for send and receive char */
|
||||
#define USART_SEND 0
|
||||
#define USART_RCV 1
|
||||
|
||||
#if !defined(BOARD_ISO7816_BASE_USART)
|
||||
#define BOARD_ISO7816_BASE_USART USART1
|
||||
#define BOARD_ISO7816_ID_USART ID_USART1
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
* Internal variables
|
||||
*-----------------------------------------------------------------------------*/
|
||||
/** Variable for state of send and receive froom USART */
|
||||
static uint8_t StateUsartGlobal = USART_RCV;
|
||||
/** Pin reset master card */
|
||||
static Pin st_pinIso7816RstMC;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Internal functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Get a character from ISO7816
|
||||
* \param pCharToReceive Pointer for store the received char
|
||||
* \return 0: if timeout else status of US_CSR
|
||||
*/
|
||||
static uint32_t ISO7816_GetChar( uint8_t *pCharToReceive )
|
||||
{
|
||||
uint32_t status;
|
||||
uint32_t timeout=0;
|
||||
|
||||
if( StateUsartGlobal == USART_SEND ) {
|
||||
while((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_TXEMPTY) == 0) {}
|
||||
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
|
||||
StateUsartGlobal = USART_RCV;
|
||||
}
|
||||
|
||||
/* Wait USART ready for reception */
|
||||
while( ((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_RXRDY) == 0) ) {
|
||||
if(timeout++ > 12000 * (BOARD_MCK/1000000)) {
|
||||
TRACE_DEBUG("TimeOut\n\r");
|
||||
return( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_DEBUG("T: %u\n\r", timeout);
|
||||
|
||||
|
||||
/* At least one complete character has been received and US_RHR has not yet been read. */
|
||||
|
||||
/* Get a char */
|
||||
*pCharToReceive = ((BOARD_ISO7816_BASE_USART->US_RHR) & 0xFF);
|
||||
|
||||
status = (BOARD_ISO7816_BASE_USART->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
|
||||
US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
|
||||
(1<<10)));
|
||||
|
||||
if (status != 0 ) {
|
||||
/* TRACE_DEBUG("R:0x%X\n\r", status); */
|
||||
TRACE_DEBUG("R:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_CSR);
|
||||
TRACE_DEBUG("Nb:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_NER );
|
||||
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA;
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send a char to ISO7816
|
||||
* \param CharToSend char to be send
|
||||
* \return status of US_CSR
|
||||
*/
|
||||
static uint32_t ISO7816_SendChar( uint8_t CharToSend )
|
||||
{
|
||||
uint32_t status;
|
||||
|
||||
if( StateUsartGlobal == USART_RCV ) {
|
||||
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
|
||||
StateUsartGlobal = USART_SEND;
|
||||
}
|
||||
|
||||
/* Wait USART ready for transmit */
|
||||
while((BOARD_ISO7816_BASE_USART->US_CSR & US_CSR_TXRDY) == 0) {}
|
||||
/* There is no character in the US_THR */
|
||||
|
||||
/* Transmit a char */
|
||||
BOARD_ISO7816_BASE_USART->US_THR = CharToSend;
|
||||
|
||||
status = (BOARD_ISO7816_BASE_USART->US_CSR&(US_CSR_OVRE|US_CSR_FRAME|
|
||||
US_CSR_PARE|US_CSR_TIMEOUT|US_CSR_NACK|
|
||||
(1<<10)));
|
||||
|
||||
if (status != 0 ) {
|
||||
TRACE_DEBUG("E:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_CSR);
|
||||
TRACE_DEBUG("Nb:0x%X\n\r", BOARD_ISO7816_BASE_USART->US_NER );
|
||||
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA;
|
||||
}
|
||||
|
||||
/* Return status */
|
||||
return( status );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Iso 7816 ICC power on
|
||||
*/
|
||||
static void ISO7816_IccPowerOn( void )
|
||||
{
|
||||
/* Set RESET Master Card */
|
||||
PIO_Set(&st_pinIso7816RstMC);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Iso 7816 ICC power off
|
||||
*/
|
||||
void ISO7816_IccPowerOff( void )
|
||||
{
|
||||
/* Clear RESET Master Card */
|
||||
PIO_Clear(&st_pinIso7816RstMC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfert Block TPDU T=0
|
||||
* \param pAPDU APDU buffer
|
||||
* \param pMessage Message buffer
|
||||
* \param wLength Block length
|
||||
* \return Message index
|
||||
*/
|
||||
uint16_t ISO7816_XfrBlockTPDU_T0(const uint8_t *pAPDU,
|
||||
uint8_t *pMessage,
|
||||
uint16_t wLength )
|
||||
{
|
||||
uint16_t NeNc;
|
||||
uint16_t indexApdu = 4;
|
||||
uint16_t indexMessage = 0;
|
||||
uint8_t SW1 = 0;
|
||||
uint8_t procByte;
|
||||
uint8_t cmdCase;
|
||||
|
||||
TRACE_DEBUG("pAPDU[0]=0x%X\n\r",pAPDU[0]);
|
||||
TRACE_DEBUG("pAPDU[1]=0x%X\n\r",pAPDU[1]);
|
||||
TRACE_DEBUG("pAPDU[2]=0x%X\n\r",pAPDU[2]);
|
||||
TRACE_DEBUG("pAPDU[3]=0x%X\n\r",pAPDU[3]);
|
||||
TRACE_DEBUG("pAPDU[4]=0x%X\n\r",pAPDU[4]);
|
||||
TRACE_DEBUG("pAPDU[5]=0x%X\n\r",pAPDU[5]);
|
||||
TRACE_DEBUG("wlength=%d\n\r",wLength);
|
||||
|
||||
ISO7816_SendChar( pAPDU[0] ); /* CLA */
|
||||
ISO7816_SendChar( pAPDU[1] ); /* INS */
|
||||
ISO7816_SendChar( pAPDU[2] ); /* P1 */
|
||||
ISO7816_SendChar( pAPDU[3] ); /* P2 */
|
||||
ISO7816_SendChar( pAPDU[4] ); /* P3 */
|
||||
|
||||
/* Handle the four structures of command APDU */
|
||||
indexApdu = 4;
|
||||
|
||||
if( wLength == 4 ) {
|
||||
cmdCase = CASE1;
|
||||
NeNc = 0;
|
||||
}
|
||||
else if( wLength == 5) {
|
||||
cmdCase = CASE2;
|
||||
NeNc = pAPDU[4]; /* C5 */
|
||||
if (NeNc == 0) {
|
||||
NeNc = 256;
|
||||
}
|
||||
}
|
||||
else if( wLength == 6) {
|
||||
NeNc = pAPDU[4]; /* C5 */
|
||||
cmdCase = CASE3;
|
||||
}
|
||||
else if( wLength == 7) {
|
||||
NeNc = pAPDU[4]; /* C5 */
|
||||
if( NeNc == 0 ) {
|
||||
cmdCase = CASE2;
|
||||
NeNc = (pAPDU[5]<<8)+pAPDU[6];
|
||||
}
|
||||
else {
|
||||
cmdCase = CASE3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
NeNc = pAPDU[4]; /* C5 */
|
||||
if( NeNc == 0 ) {
|
||||
cmdCase = CASE3;
|
||||
NeNc = (pAPDU[5]<<8)+pAPDU[6];
|
||||
}
|
||||
else {
|
||||
cmdCase = CASE3;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE_DEBUG("CASE=0x%X NeNc=0x%X\n\r", cmdCase, NeNc);
|
||||
|
||||
/* Handle Procedure Bytes */
|
||||
do {
|
||||
ISO7816_GetChar(&procByte);
|
||||
/* Handle NULL */
|
||||
if ( procByte == ISO_NULL_VAL ) {
|
||||
TRACE_DEBUG("INS\n\r");
|
||||
continue;
|
||||
}
|
||||
/* Handle SW1 */
|
||||
else if ( ((procByte & 0xF0) ==0x60) || ((procByte & 0xF0) ==0x90) ) {
|
||||
TRACE_DEBUG("SW1\n\r");
|
||||
SW1 = 1;
|
||||
}
|
||||
/* Handle INS */
|
||||
else if ( pAPDU[1] == procByte) {
|
||||
TRACE_DEBUG("HdlINS\n\r");
|
||||
if (cmdCase == CASE2) {
|
||||
/* receive data from card */
|
||||
do {
|
||||
ISO7816_GetChar(&pMessage[indexMessage++]);
|
||||
} while( 0 != --NeNc );
|
||||
}
|
||||
else {
|
||||
/* Send data */
|
||||
do {
|
||||
ISO7816_SendChar(pAPDU[indexApdu++]);
|
||||
} while( 0 != --NeNc );
|
||||
}
|
||||
}
|
||||
/* Handle INS ^ 0xff */
|
||||
else if ( pAPDU[1] == (procByte ^ 0xff)) {
|
||||
TRACE_DEBUG("HdlINS+\n\r");
|
||||
if (cmdCase == CASE2) {
|
||||
/* receive data from card */
|
||||
ISO7816_GetChar(&pMessage[indexMessage++]);
|
||||
}
|
||||
else {
|
||||
ISO7816_SendChar(pAPDU[indexApdu++]);
|
||||
}
|
||||
NeNc--;
|
||||
}
|
||||
else {
|
||||
/* ?? */
|
||||
TRACE_DEBUG("procByte=0x%X\n\r", procByte);
|
||||
break;
|
||||
}
|
||||
} while (NeNc != 0);
|
||||
|
||||
/* Status Bytes */
|
||||
if (SW1 == 0) {
|
||||
ISO7816_GetChar(&pMessage[indexMessage++]); /* SW1 */
|
||||
}
|
||||
else {
|
||||
pMessage[indexMessage++] = procByte;
|
||||
}
|
||||
ISO7816_GetChar(&pMessage[indexMessage++]); /* SW2 */
|
||||
|
||||
return( indexMessage );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Escape ISO7816
|
||||
*/
|
||||
void ISO7816_Escape( void )
|
||||
{
|
||||
TRACE_DEBUG("For user, if needed\n\r");
|
||||
}
|
||||
|
||||
/**
|
||||
* Restart clock ISO7816
|
||||
*/
|
||||
void ISO7816_RestartClock( void )
|
||||
{
|
||||
TRACE_DEBUG("ISO7816_RestartClock\n\r");
|
||||
BOARD_ISO7816_BASE_USART->US_BRGR = 13;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop clock ISO7816
|
||||
*/
|
||||
void ISO7816_StopClock( void )
|
||||
{
|
||||
TRACE_DEBUG("ISO7816_StopClock\n\r");
|
||||
BOARD_ISO7816_BASE_USART->US_BRGR = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* T0 APDU
|
||||
*/
|
||||
void ISO7816_toAPDU( void )
|
||||
{
|
||||
TRACE_DEBUG("ISO7816_toAPDU\n\r");
|
||||
TRACE_DEBUG("Not supported at this time\n\r");
|
||||
}
|
||||
|
||||
/**
|
||||
* Answer To Reset (ATR)
|
||||
* \param pAtr ATR buffer
|
||||
* \param pLength Pointer for store the ATR length
|
||||
*/
|
||||
void ISO7816_Datablock_ATR( uint8_t* pAtr, uint8_t* pLength )
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t y;
|
||||
|
||||
*pLength = 0;
|
||||
|
||||
/* Read ATR TS */
|
||||
ISO7816_GetChar(&pAtr[0]);
|
||||
/* Read ATR T0 */
|
||||
ISO7816_GetChar(&pAtr[1]);
|
||||
y = pAtr[1] & 0xF0;
|
||||
i = 2;
|
||||
|
||||
/* Read ATR Ti */
|
||||
while (y) {
|
||||
|
||||
if (y & 0x10) { /* TA[i] */
|
||||
ISO7816_GetChar(&pAtr[i++]);
|
||||
}
|
||||
if (y & 0x20) { /* TB[i] */
|
||||
ISO7816_GetChar(&pAtr[i++]);
|
||||
}
|
||||
if (y & 0x40) { /* TC[i] */
|
||||
ISO7816_GetChar(&pAtr[i++]);
|
||||
}
|
||||
if (y & 0x80) { /* TD[i] */
|
||||
ISO7816_GetChar(&pAtr[i]);
|
||||
y = pAtr[i++] & 0xF0;
|
||||
}
|
||||
else {
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Historical Bytes */
|
||||
y = pAtr[1] & 0x0F;
|
||||
for( j=0; j < y; j++ ) {
|
||||
ISO7816_GetChar(&pAtr[i++]);
|
||||
}
|
||||
|
||||
*pLength = i;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data rate and clock frequency
|
||||
* \param dwClockFrequency ICC clock frequency in KHz.
|
||||
* \param dwDataRate ICC data rate in bpd
|
||||
*/
|
||||
void ISO7816_SetDataRateandClockFrequency( uint32_t dwClockFrequency, uint32_t dwDataRate )
|
||||
{
|
||||
uint8_t ClockFrequency;
|
||||
|
||||
/* Define the baud rate divisor register */
|
||||
/* CD = MCK / SCK */
|
||||
/* SCK = FIDI x BAUD = 372 x 9600 */
|
||||
/* BOARD_MCK */
|
||||
/* CD = MCK/(FIDI x BAUD) = 48000000 / (372x9600) = 13 */
|
||||
BOARD_ISO7816_BASE_USART->US_BRGR = BOARD_MCK / (dwClockFrequency*1000);
|
||||
|
||||
ClockFrequency = BOARD_MCK / BOARD_ISO7816_BASE_USART->US_BRGR;
|
||||
|
||||
BOARD_ISO7816_BASE_USART->US_FIDI = (ClockFrequency)/dwDataRate;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Pin status for ISO7816 RESET
|
||||
* \return 1 if the Pin RstMC is high; otherwise 0.
|
||||
*/
|
||||
uint8_t ISO7816_StatusReset( void )
|
||||
{
|
||||
return PIO_Get(&st_pinIso7816RstMC);
|
||||
}
|
||||
|
||||
/**
|
||||
* cold reset
|
||||
*/
|
||||
void ISO7816_cold_reset( void )
|
||||
{
|
||||
volatile uint32_t i;
|
||||
|
||||
/* tb: wait 400 cycles*/
|
||||
for( i=0; i<(120*(BOARD_MCK/1000000)); i++ ) {
|
||||
}
|
||||
|
||||
BOARD_ISO7816_BASE_USART->US_RHR;
|
||||
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
|
||||
|
||||
ISO7816_IccPowerOn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Warm reset
|
||||
*/
|
||||
void ISO7816_warm_reset( void )
|
||||
{
|
||||
volatile uint32_t i;
|
||||
|
||||
ISO7816_IccPowerOff();
|
||||
|
||||
/* tb: wait 400 cycles */
|
||||
for( i=0; i<(120*(BOARD_MCK/1000000)); i++ ) {
|
||||
}
|
||||
|
||||
BOARD_ISO7816_BASE_USART->US_RHR;
|
||||
BOARD_ISO7816_BASE_USART->US_CR = US_CR_RSTSTA | US_CR_RSTIT | US_CR_RSTNACK;
|
||||
|
||||
ISO7816_IccPowerOn();
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode ATR trace
|
||||
* \param pAtr pointer on ATR buffer
|
||||
*/
|
||||
void ISO7816_Decode_ATR( uint8_t* pAtr )
|
||||
{
|
||||
uint32_t i;
|
||||
uint32_t j;
|
||||
uint32_t y;
|
||||
uint8_t offset;
|
||||
|
||||
printf("\n\r");
|
||||
printf("ATR: Answer To Reset:\n\r");
|
||||
printf("TS = 0x%X Initial character ",pAtr[0]);
|
||||
if( pAtr[0] == 0x3B ) {
|
||||
|
||||
printf("Direct Convention\n\r");
|
||||
}
|
||||
else {
|
||||
if( pAtr[0] == 0x3F ) {
|
||||
|
||||
printf("Inverse Convention\n\r");
|
||||
}
|
||||
else {
|
||||
printf("BAD Convention\n\r");
|
||||
}
|
||||
}
|
||||
|
||||
printf("T0 = 0x%X Format caracter\n\r",pAtr[1]);
|
||||
printf(" Number of historical bytes: K = %d\n\r", pAtr[1]&0x0F);
|
||||
printf(" Presence further interface byte:\n\r");
|
||||
if( pAtr[1]&0x80 ) {
|
||||
printf("TA ");
|
||||
}
|
||||
if( pAtr[1]&0x40 ) {
|
||||
printf("TB ");
|
||||
}
|
||||
if( pAtr[1]&0x20 ) {
|
||||
printf("TC ");
|
||||
}
|
||||
if( pAtr[1]&0x10 ) {
|
||||
printf("TD ");
|
||||
}
|
||||
if( pAtr[1] != 0 ) {
|
||||
printf(" present\n\r");
|
||||
}
|
||||
|
||||
i = 2;
|
||||
y = pAtr[1] & 0xF0;
|
||||
|
||||
/* Read ATR Ti */
|
||||
offset = 1;
|
||||
while (y) {
|
||||
|
||||
if (y & 0x10) { /* TA[i] */
|
||||
printf("TA[%d] = 0x%X ", offset, pAtr[i]);
|
||||
if( offset == 1 ) {
|
||||
printf("FI = %d ", (pAtr[i]>>8));
|
||||
printf("DI = %d", (pAtr[i]&0x0F));
|
||||
}
|
||||
printf("\n\r");
|
||||
i++;
|
||||
}
|
||||
if (y & 0x20) { /* TB[i] */
|
||||
printf("TB[%d] = 0x%X\n\r", offset, pAtr[i]);
|
||||
i++;
|
||||
}
|
||||
if (y & 0x40) { /* TC[i] */
|
||||
printf("TC[%d] = 0x%X ", offset, pAtr[i]);
|
||||
if( offset == 1 ) {
|
||||
printf("Extra Guard Time: N = %d", pAtr[i]);
|
||||
}
|
||||
printf("\n\r");
|
||||
i++;
|
||||
}
|
||||
if (y & 0x80) { /* TD[i] */
|
||||
printf("TD[%d] = 0x%X\n\r", offset, pAtr[i]);
|
||||
y = pAtr[i++] & 0xF0;
|
||||
}
|
||||
else {
|
||||
y = 0;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
|
||||
/* Historical Bytes */
|
||||
printf("Historical bytes:\n\r");
|
||||
y = pAtr[1] & 0x0F;
|
||||
for( j=0; j < y; j++ ) {
|
||||
|
||||
printf(" 0x%X", pAtr[i]);
|
||||
if( (pAtr[i] > 0x21) && (pAtr[i] < 0x7D) ) { /* ASCII */
|
||||
printf("(%c) ", pAtr[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
printf("\n\r\n\r");
|
||||
|
||||
}
|
||||
|
||||
/** Initializes a ISO driver
|
||||
* \param pPinIso7816RstMC Pin ISO 7816 Rst MC
|
||||
*/
|
||||
void ISO7816_Init( const Pin pPinIso7816RstMC )
|
||||
{
|
||||
TRACE_DEBUG("ISO_Init\n\r");
|
||||
|
||||
/* Pin ISO7816 initialize */
|
||||
st_pinIso7816RstMC = pPinIso7816RstMC;
|
||||
|
||||
USART_Configure( BOARD_ISO7816_BASE_USART,
|
||||
US_MR_USART_MODE_IS07816_T_0
|
||||
| US_MR_USCLKS_MCK
|
||||
| US_MR_NBSTOP_1_BIT
|
||||
| US_MR_PAR_EVEN
|
||||
| US_MR_CHRL_8_BIT
|
||||
| US_MR_CLKO
|
||||
| (3<<24), /* MAX_ITERATION */
|
||||
1,
|
||||
0);
|
||||
|
||||
/* Configure USART */
|
||||
PMC_EnablePeripheral(BOARD_ISO7816_ID_USART);
|
||||
/* Disable interrupts */
|
||||
BOARD_ISO7816_BASE_USART->US_IDR = (uint32_t) -1;
|
||||
|
||||
BOARD_ISO7816_BASE_USART->US_FIDI = 372; /* by default */
|
||||
/* Define the baud rate divisor register */
|
||||
/* CD = MCK / SCK */
|
||||
/* SCK = FIDI x BAUD = 372 x 9600 */
|
||||
/* BOARD_MCK */
|
||||
/* CD = MCK/(FIDI x BAUD) = 48000000 / (372x9600) = 13 */
|
||||
BOARD_ISO7816_BASE_USART->US_BRGR = BOARD_MCK / (372*9600);
|
||||
|
||||
/* Write the Timeguard Register */
|
||||
BOARD_ISO7816_BASE_USART->US_TTGR = 5;
|
||||
|
||||
USART_SetTransmitterEnabled(BOARD_ISO7816_BASE_USART, 1);
|
||||
USART_SetReceiverEnabled(BOARD_ISO7816_BASE_USART, 1);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,405 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of draw function on LCD, Include draw text, image
|
||||
* and basic shapes (line, rectangle, circle).
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Fills the given LCD buffer with a particular color.
|
||||
*
|
||||
* \param color Fill color.
|
||||
*/
|
||||
void LCDD_Fill( uint32_t dwColor )
|
||||
{
|
||||
uint32_t dw ;
|
||||
|
||||
LCD_SetCursor( 0, 0 ) ;
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
|
||||
for ( dw = BOARD_LCD_WIDTH * BOARD_LCD_HEIGHT; dw > 0; dw-- )
|
||||
{
|
||||
LCD_WriteRAM( dwColor ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draw a pixel on LCD of given color.
|
||||
*
|
||||
* \param x X-coordinate of pixel.
|
||||
* \param y Y-coordinate of pixel.
|
||||
* \param color Pixel color.
|
||||
*/
|
||||
extern void LCDD_DrawPixel( uint32_t x, uint32_t y, uint32_t color )
|
||||
{
|
||||
LCD_SetCursor( x, y ) ;
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
LCD_WriteRAM( color ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read a pixel from LCD.
|
||||
*
|
||||
* \param x X-coordinate of pixel.
|
||||
* \param y Y-coordinate of pixel.
|
||||
*
|
||||
* \return color Readed pixel color.
|
||||
*/
|
||||
extern uint32_t LCDD_ReadPixel( uint32_t x, uint32_t y )
|
||||
{
|
||||
uint32_t color;
|
||||
|
||||
LCD_SetCursor(x, y);
|
||||
LCD_ReadRAM_Prepare();
|
||||
color = LCD_ReadRAM();
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a line on LCD, horizontal and vertical line are supported.
|
||||
*
|
||||
* \param x X-coordinate of line start.
|
||||
* \param y Y-coordinate of line start.
|
||||
* \param length line length.
|
||||
* \param direction line direction: 0 - horizontal, 1 - vertical.
|
||||
* \param color Pixel color.
|
||||
*/
|
||||
extern void LCDD_DrawLine( uint32_t x, uint32_t y, uint32_t length, uint32_t direction, uint32_t color )
|
||||
{
|
||||
uint32_t i = 0 ;
|
||||
|
||||
LCD_SetCursor( x, y ) ;
|
||||
|
||||
if ( direction == DIRECTION_HLINE )
|
||||
{
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
for ( i = 0; i < length; i++ )
|
||||
{
|
||||
LCD_WriteRAM( color ) ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i = 0; i < length; i++ )
|
||||
{
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
LCD_WriteRAM( color ) ;
|
||||
y++ ;
|
||||
LCD_SetCursor( x, y ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draws a rectangle on LCD, at the given coordinates.
|
||||
*
|
||||
* \param x X-coordinate of upper-left rectangle corner.
|
||||
* \param y Y-coordinate of upper-left rectangle corner.
|
||||
* \param width Rectangle width in pixels.
|
||||
* \param height Rectangle height in pixels.
|
||||
* \param color Rectangle color.
|
||||
*/
|
||||
extern void LCDD_DrawRectangle( uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t color )
|
||||
{
|
||||
LCDD_DrawLine(x, y, width, DIRECTION_HLINE, color);
|
||||
LCDD_DrawLine(x, (y + height), width, DIRECTION_HLINE, color);
|
||||
|
||||
LCDD_DrawLine(x, y, height, DIRECTION_VLINE, color);
|
||||
LCDD_DrawLine((x + width), y, height, DIRECTION_VLINE, color);
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draws a rectangle with fill inside on LCD, at the given coordinates.
|
||||
*
|
||||
* \param x X-coordinate of upper-left rectangle corner.
|
||||
* \param y Y-coordinate of upper-left rectangle corner.
|
||||
* \param width Rectangle width in pixels.
|
||||
* \param height Rectangle height in pixels.
|
||||
* \param color Rectangle color.
|
||||
*/
|
||||
extern void LCDD_DrawRectangleWithFill( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )
|
||||
{
|
||||
uint32_t i ;
|
||||
|
||||
LCD_SetWindow( dwX, dwY, dwWidth, dwHeight ) ;
|
||||
LCD_SetCursor( dwX, dwY ) ;
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
|
||||
for ( i = dwWidth * dwHeight; i > 0; i-- )
|
||||
{
|
||||
LCD_WriteRAM( dwColor ) ;
|
||||
}
|
||||
LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
|
||||
LCD_SetCursor( 0, 0 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws a circle on LCD, at the given coordinates.
|
||||
*
|
||||
* \param x X-coordinate of circle center.
|
||||
* \param y Y-coordinate of circle center.
|
||||
* \param r circle radius.
|
||||
* \param color circle color.
|
||||
*/
|
||||
extern void LCDD_DrawCircle( uint32_t x, uint32_t y, uint32_t r, uint32_t color )
|
||||
{
|
||||
signed int d; /* Decision Variable */
|
||||
uint32_t curX; /* Current X Value */
|
||||
uint32_t curY; /* Current Y Value */
|
||||
|
||||
d = 3 - (r << 1);
|
||||
curX = 0;
|
||||
curY = r;
|
||||
|
||||
while (curX <= curY)
|
||||
{
|
||||
LCDD_DrawPixel(x + curX, y + curY, color);
|
||||
LCDD_DrawPixel(x + curX, y - curY, color);
|
||||
LCDD_DrawPixel(x - curX, y + curY, color);
|
||||
LCDD_DrawPixel(x - curX, y - curY, color);
|
||||
LCDD_DrawPixel(x + curY, y + curX, color);
|
||||
LCDD_DrawPixel(x + curY, y - curX, color);
|
||||
LCDD_DrawPixel(x - curY, y + curX, color);
|
||||
LCDD_DrawPixel(x - curY, y - curX, color);
|
||||
|
||||
if (d < 0) {
|
||||
d += (curX << 2) + 6;
|
||||
}
|
||||
else {
|
||||
d += ((curX - curY) << 2) + 10;
|
||||
curY--;
|
||||
}
|
||||
curX++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws a string inside a LCD buffer, at the given coordinates. Line breaks
|
||||
* will be honored.
|
||||
*
|
||||
* \param x X-coordinate of string top-left corner.
|
||||
* \param y Y-coordinate of string top-left corner.
|
||||
* \param pString String to display.
|
||||
* \param color String color.
|
||||
*/
|
||||
extern void LCDD_DrawString( uint32_t x, uint32_t y, const uint8_t *pString, uint32_t color )
|
||||
{
|
||||
uint32_t xorg = x ;
|
||||
|
||||
while ( *pString != 0 )
|
||||
{
|
||||
if ( *pString == '\n' )
|
||||
{
|
||||
y += gFont.height + 2 ;
|
||||
x = xorg ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDD_DrawChar( x, y, *pString, color ) ;
|
||||
x += gFont.width + 2 ;
|
||||
}
|
||||
|
||||
pString++ ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws a string inside a LCD buffer, at the given coordinates
|
||||
* with given background color. Line breaks will be honored.
|
||||
*
|
||||
* \param x X-coordinate of string top-left corner.
|
||||
* \param y Y-coordinate of string top-left corner.
|
||||
* \param pString String to display.
|
||||
* \param fontColor String color.
|
||||
* \param bgColor Background color.
|
||||
*/
|
||||
extern void LCDD_DrawStringWithBGColor( uint32_t x, uint32_t y, const char *pString, uint32_t fontColor, uint32_t bgColor )
|
||||
{
|
||||
unsigned xorg = x;
|
||||
|
||||
while ( *pString != 0 )
|
||||
{
|
||||
if ( *pString == '\n' )
|
||||
{
|
||||
y += gFont.height + 2 ;
|
||||
x = xorg ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDD_DrawCharWithBGColor( x, y, *pString, fontColor, bgColor ) ;
|
||||
x += gFont.width + 2;
|
||||
}
|
||||
|
||||
pString++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Returns the width & height in pixels that a string will occupy on the screen
|
||||
* if drawn using LCDD_DrawString.
|
||||
*
|
||||
* \param pString String.
|
||||
* \param pWidth Pointer for storing the string width (optional).
|
||||
* \param pHeight Pointer for storing the string height (optional).
|
||||
*
|
||||
* \return String width in pixels.
|
||||
*/
|
||||
extern void LCDD_GetStringSize( const uint8_t *pString, uint32_t *pWidth, uint32_t *pHeight )
|
||||
{
|
||||
uint32_t width = 0;
|
||||
uint32_t height = gFont.height;
|
||||
|
||||
while ( *pString != 0 )
|
||||
{
|
||||
if ( *pString == '\n' )
|
||||
{
|
||||
height += gFont.height + 2 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
width += gFont.width + 2 ;
|
||||
}
|
||||
|
||||
pString++ ;
|
||||
}
|
||||
|
||||
if ( width > 0 )
|
||||
{
|
||||
width -= 2;
|
||||
}
|
||||
|
||||
if ( pWidth != NULL )
|
||||
{
|
||||
*pWidth = width;
|
||||
}
|
||||
|
||||
if ( pHeight != NULL )
|
||||
{
|
||||
*pHeight = height ;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a raw image at given position on LCD.
|
||||
*
|
||||
* \param x X-coordinate of image start.
|
||||
* \param y Y-coordinate of image start.
|
||||
* \param pImage Image buffer.
|
||||
* \param width Image width.
|
||||
* \param height Image height.
|
||||
*/
|
||||
void LCDD_DrawImage( uint32_t dwX, uint32_t dwY, const uint8_t *pImage, uint32_t dwWidth, uint32_t dwHeight )
|
||||
{
|
||||
uint32_t dwCursor ;
|
||||
|
||||
LCD_SetWindow( dwX, dwY, dwWidth, dwHeight ) ;
|
||||
LCD_SetCursor( dwX, dwY ) ;
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
|
||||
for ( dwCursor=dwWidth*dwHeight; dwCursor != 0; dwCursor-- )
|
||||
{
|
||||
LCD_D() = *pImage++ ;
|
||||
LCD_D() = *pImage++ ;
|
||||
LCD_D() = *pImage++ ;
|
||||
}
|
||||
|
||||
LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Draw a raw image at given position on LCD.
|
||||
*
|
||||
* \param dwX X-coordinate of image start.
|
||||
* \param dwY Y-coordinate of image start.
|
||||
* \param pGIMPImage Image data.
|
||||
*/
|
||||
void LCDD_DrawGIMPImage( uint32_t dwX, uint32_t dwY, const SGIMPImage* pGIMPImage )
|
||||
{
|
||||
uint32_t dw ;
|
||||
register uint32_t dwLength ;
|
||||
uint8_t* pucData ;
|
||||
|
||||
// Draw raw RGB bitmap
|
||||
LCD_SetWindow( dwX, dwY, pGIMPImage->dwWidth, pGIMPImage->dwHeight ) ;
|
||||
LCD_SetCursor( dwX, dwY ) ;
|
||||
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
|
||||
dwLength = pGIMPImage->dwWidth*pGIMPImage->dwHeight ;
|
||||
pucData = pGIMPImage->pucPixel_data ;
|
||||
for ( dw=0; dw < dwLength; dw++ )
|
||||
{
|
||||
LCD_D() = (*pucData++) ;
|
||||
LCD_D() = (*pucData++) ;
|
||||
LCD_D() = (*pucData++) ;
|
||||
}
|
||||
|
||||
LCD_SetWindow( 0, 0, BOARD_LCD_WIDTH, BOARD_LCD_HEIGHT ) ;
|
||||
}
|
||||
|
||||
/*
|
||||
* \brief Clear a window with an color.
|
||||
*
|
||||
* \param dwX X-coordinate of the window.
|
||||
* \param dwY Y-coordinate of the window.
|
||||
* \param dwWidth window width.
|
||||
* \param dwHeight window height.
|
||||
* \param dwColor background color
|
||||
*/
|
||||
extern void LCDD_ClearWindow( uint32_t dwX, uint32_t dwY, uint32_t dwWidth, uint32_t dwHeight, uint32_t dwColor )
|
||||
{
|
||||
uint32_t dw ;
|
||||
|
||||
LCD_SetCursor( dwX, dwY) ;
|
||||
LCD_WriteRAM_Prepare() ;
|
||||
|
||||
for ( dw = dwWidth * dwHeight; dw > 0; dw-- )
|
||||
{
|
||||
LCD_WriteRAM( dwColor ) ;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of draw font on LCD.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Global variable describing the font being instancied. */
|
||||
const Font gFont = {10, 14};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Draws an ASCII character on LCD.
|
||||
*
|
||||
* \param x X-coordinate of character upper-left corner.
|
||||
* \param y Y-coordinate of character upper-left corner.
|
||||
* \param c Character to output.
|
||||
* \param color Character color.
|
||||
*/
|
||||
extern void LCDD_DrawChar( uint32_t x, uint32_t y, uint8_t c, uint32_t color )
|
||||
{
|
||||
uint32_t row, col ;
|
||||
|
||||
assert( (c >= 0x20) && (c <= 0x7F) ) ;
|
||||
|
||||
for ( col = 0 ; col < 10 ; col++ )
|
||||
{
|
||||
for ( row = 0 ; row < 8 ; row++ )
|
||||
{
|
||||
if ( (pCharset10x14[((c - 0x20) * 20) + col * 2] >> (7 - row)) & 0x1 )
|
||||
{
|
||||
LCDD_DrawPixel( x+col, y+row, color ) ;
|
||||
}
|
||||
}
|
||||
|
||||
for (row = 0; row < 6; row++ )
|
||||
{
|
||||
if ((pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1)
|
||||
{
|
||||
LCDD_DrawPixel( x+col, y+row+8, color ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Draws an ASCII character on LCD with given background color.
|
||||
*
|
||||
* \param x X-coordinate of character upper-left corner.
|
||||
* \param y Y-coordinate of character upper-left corner.
|
||||
* \param c Character to output.
|
||||
* \param fontColor Character color.
|
||||
* \param bgColor Background color.
|
||||
*/
|
||||
extern void LCDD_DrawCharWithBGColor( uint32_t x, uint32_t y, uint8_t c, uint32_t fontColor, uint32_t bgColor )
|
||||
{
|
||||
uint32_t row, col ;
|
||||
|
||||
assert( (c >= 0x20) && (c <= 0x7F) ) ;
|
||||
|
||||
for (col = 0; col < 10; col++)
|
||||
{
|
||||
for (row = 0 ; row < 8 ; row++)
|
||||
{
|
||||
if ( (pCharset10x14[((c - 0x20) * 20) + col * 2] >> (7 - row)) & 0x1 )
|
||||
{
|
||||
LCDD_DrawPixel( x+col, y+row, fontColor ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDD_DrawPixel( x+col, y+row, bgColor ) ;
|
||||
}
|
||||
}
|
||||
|
||||
for ( row = 0 ; row < 6 ; row++ )
|
||||
{
|
||||
if ( (pCharset10x14[((c - 0x20) * 20) + col * 2 + 1] >> (7 - row)) & 0x1 )
|
||||
{
|
||||
LCDD_DrawPixel( x+col, y+row+8, fontColor ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
LCDD_DrawPixel( x+col, y+row+8, bgColor ) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Font 10x14 table definition.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/** Char set of font 10x14 */
|
||||
const uint8_t pCharset10x14[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xCC,
|
||||
0xFF, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xF0, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0C, 0xC0, 0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0,
|
||||
0x0C, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0,
|
||||
0x0C, 0x60, 0x1E, 0x70, 0x3F, 0x30, 0x33, 0x30, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0x33, 0x30, 0x33, 0xF0, 0x39, 0xE0, 0x18, 0xC0,
|
||||
0x60, 0x00, 0xF0, 0x0C, 0xF0, 0x3C, 0x60, 0xF0, 0x03, 0xC0,
|
||||
0x0F, 0x00, 0x3C, 0x18, 0xF0, 0x3C, 0xC0, 0x3C, 0x00, 0x18,
|
||||
0x3C, 0xF0, 0x7F, 0xF8, 0xC3, 0x1C, 0xC7, 0x8C, 0xCF, 0xCC,
|
||||
0xDC, 0xEC, 0x78, 0x78, 0x30, 0x30, 0x00, 0xFC, 0x00, 0xCC,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x00, 0xEC, 0x00,
|
||||
0xF8, 0x00, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0F, 0xC0, 0x3F, 0xF0, 0x78, 0x78,
|
||||
0x60, 0x18, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0x60, 0x18,
|
||||
0x78, 0x78, 0x3F, 0xF0, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x60, 0x0E, 0xE0, 0x07, 0xC0, 0x03, 0x80, 0x3F, 0xF8,
|
||||
0x3F, 0xF8, 0x03, 0x80, 0x07, 0xC0, 0x0E, 0xE0, 0x0C, 0x60,
|
||||
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x3F, 0xF0,
|
||||
0x3F, 0xF0, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x00, 0x44, 0x00, 0xEC, 0x00, 0xF8, 0x00, 0x70, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x00, 0x18, 0x00, 0x3C, 0x00, 0x3C, 0x00, 0x18, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0C, 0x00, 0x3C, 0x00, 0xF0, 0x03, 0xC0,
|
||||
0x0F, 0x00, 0x3C, 0x00, 0xF0, 0x00, 0xC0, 0x00, 0x00, 0x00,
|
||||
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0xFC, 0xC1, 0xCC, 0xC3, 0x8C,
|
||||
0xC7, 0x0C, 0xCE, 0x0C, 0xFC, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
|
||||
0x00, 0x00, 0x00, 0x00, 0x30, 0x0C, 0x70, 0x0C, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x0C, 0x70, 0x1C, 0xE0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC,
|
||||
0xC1, 0xCC, 0xC3, 0x8C, 0xE7, 0x0C, 0x7E, 0x0C, 0x3C, 0x0C,
|
||||
0x30, 0x30, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x7F, 0xF8, 0x3C, 0xF0,
|
||||
0x03, 0xC0, 0x07, 0xC0, 0x0E, 0xC0, 0x1C, 0xC0, 0x38, 0xC0,
|
||||
0x70, 0xC0, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xC0, 0x00, 0xC0,
|
||||
0xFC, 0x30, 0xFC, 0x38, 0xCC, 0x1C, 0xCC, 0x0C, 0xCC, 0x0C,
|
||||
0xCC, 0x0C, 0xCC, 0x0C, 0xCE, 0x1C, 0xC7, 0xF8, 0xC3, 0xF0,
|
||||
0x3F, 0xF0, 0x7F, 0xF8, 0xE3, 0x1C, 0xC3, 0x0C, 0xC3, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x9C, 0x71, 0xF8, 0x30, 0xF0,
|
||||
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC3, 0xFC,
|
||||
0xC7, 0xFC, 0xCE, 0x00, 0xDC, 0x00, 0xF8, 0x00, 0xF0, 0x00,
|
||||
0x3C, 0xF0, 0x7F, 0xF8, 0xE7, 0x9C, 0xC3, 0x0C, 0xC3, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,
|
||||
0x3C, 0x00, 0x7E, 0x00, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x1C,
|
||||
0xC3, 0x38, 0xC3, 0x70, 0xE7, 0xE0, 0x7F, 0xC0, 0x3F, 0x80,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x60, 0x3C, 0xF0,
|
||||
0x3C, 0xF0, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x44, 0x3C, 0xEC,
|
||||
0x3C, 0xF8, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0,
|
||||
0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C, 0x00, 0x00,
|
||||
0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
|
||||
0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
|
||||
0x00, 0x00, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x38, 0x70,
|
||||
0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x70, 0x00, 0xE0, 0x00, 0xC0, 0x00, 0xC1, 0xEC,
|
||||
0xC3, 0xEC, 0xC3, 0x00, 0xE6, 0x00, 0x7E, 0x00, 0x3C, 0x00,
|
||||
0x30, 0xF0, 0x71, 0xF8, 0xE3, 0x9C, 0xC3, 0x0C, 0xC3, 0xFC,
|
||||
0xC3, 0xFC, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
|
||||
0x3F, 0xFC, 0x7F, 0xFC, 0xE0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0,
|
||||
0xC0, 0xC0, 0xC0, 0xC0, 0xE0, 0xC0, 0x7F, 0xFC, 0x3F, 0xFC,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xE7, 0x9C, 0x7F, 0xF8, 0x3C, 0xF0,
|
||||
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x70, 0x38, 0x30, 0x30,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,
|
||||
0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00, 0xC0, 0x00, 0xC0, 0x00,
|
||||
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xE3, 0x1C, 0x73, 0xF8, 0x33, 0xF0,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x03, 0x00, 0x03, 0x00, 0x03, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x00, 0x38, 0xC0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xC0, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0, 0xC0, 0x00, 0xC0, 0x00,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x07, 0x80, 0x07, 0x80, 0x0F, 0xC0,
|
||||
0x1C, 0xE0, 0x38, 0x70, 0x70, 0x38, 0xE0, 0x1C, 0xC0, 0x0C,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x70, 0x00, 0x38, 0x00, 0x1F, 0x00,
|
||||
0x1F, 0x00, 0x38, 0x00, 0x70, 0x00, 0xFF, 0xFC, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x1C, 0x00, 0x0E, 0x00, 0x07, 0x00,
|
||||
0x03, 0x80, 0x01, 0xC0, 0x00, 0xE0, 0xFF, 0xFC, 0xFF, 0xFC,
|
||||
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C, 0x7F, 0xF8, 0x3F, 0xF0,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x00, 0xC3, 0x00,
|
||||
0xC3, 0x00, 0xC3, 0x00, 0xE7, 0x00, 0x7E, 0x00, 0x3C, 0x00,
|
||||
0x3F, 0xF0, 0x7F, 0xF8, 0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0xCC,
|
||||
0xC0, 0xEC, 0xC0, 0x7C, 0xE0, 0x38, 0x7F, 0xFC, 0x3F, 0xEC,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xC3, 0x00, 0xC3, 0x80, 0xC3, 0x80,
|
||||
0xC3, 0xC0, 0xC3, 0xC0, 0xE7, 0x70, 0x7E, 0x3C, 0x3C, 0x1C,
|
||||
0x3C, 0x18, 0x7E, 0x1C, 0xE7, 0x0C, 0xC3, 0x0C, 0xC3, 0x0C,
|
||||
0xC3, 0x0C, 0xC3, 0x0C, 0xC3, 0x9C, 0xE1, 0xF8, 0x60, 0xF0,
|
||||
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
|
||||
0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,
|
||||
0xFF, 0xC0, 0xFF, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,
|
||||
0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0xFF, 0xE0, 0xFF, 0xC0,
|
||||
0xFF, 0xF0, 0xFF, 0xF8, 0x00, 0x1C, 0x00, 0x3C, 0x00, 0xF8,
|
||||
0x00, 0xF8, 0x00, 0x3C, 0x00, 0x1C, 0xFF, 0xF8, 0xFF, 0xF0,
|
||||
0xF0, 0x3C, 0xF8, 0x7C, 0x1C, 0xE0, 0x0F, 0xC0, 0x07, 0x80,
|
||||
0x07, 0x80, 0x0F, 0xC0, 0x1C, 0xE0, 0xF8, 0x7C, 0xF0, 0x3C,
|
||||
0xFC, 0x00, 0xFE, 0x00, 0x07, 0x00, 0x03, 0x80, 0x01, 0xFC,
|
||||
0x01, 0xFC, 0x03, 0x80, 0x07, 0x00, 0xFE, 0x00, 0xFC, 0x00,
|
||||
0xC0, 0x3C, 0xC0, 0x7C, 0xC0, 0xEC, 0xC1, 0xCC, 0xC3, 0x8C,
|
||||
0xC7, 0x0C, 0xCE, 0x0C, 0xDC, 0x0C, 0xF8, 0x0C, 0xF0, 0x0C,
|
||||
0x00, 0x00, 0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0xC0, 0x0C,
|
||||
0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x30, 0x00, 0x30, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x03, 0x00,
|
||||
0x03, 0x00, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0x30, 0x00, 0x30,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0C, 0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x00, 0xE0, 0x00,
|
||||
0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C, 0x00,
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x0C,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0x00, 0xE0, 0x00, 0x70, 0x00,
|
||||
0x38, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x30, 0x06, 0x78, 0x0E, 0xFC, 0x0C, 0xCC, 0x0C, 0xCC,
|
||||
0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xCC, 0x07, 0xFC, 0x03, 0xF8,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C,
|
||||
0x03, 0x0C, 0x03, 0x0C, 0x03, 0x9C, 0x01, 0xF8, 0x00, 0xF0,
|
||||
0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0x30,
|
||||
0x00, 0xF0, 0x01, 0xF8, 0x03, 0x9C, 0x03, 0x0C, 0x03, 0x0C,
|
||||
0x03, 0x0C, 0x03, 0x0C, 0x03, 0x0C, 0xFF, 0xFC, 0xFF, 0xFC,
|
||||
0x03, 0xF0, 0x07, 0xF8, 0x0E, 0xDC, 0x0C, 0xCC, 0x0C, 0xCC,
|
||||
0x0C, 0xCC, 0x0C, 0xCC, 0x0E, 0xDC, 0x07, 0xD8, 0x03, 0x90,
|
||||
0x00, 0x00, 0x03, 0x00, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x00,
|
||||
0xE3, 0x00, 0x70, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,
|
||||
0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xDC, 0x0F, 0xF8, 0x07, 0xF0,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0x03, 0x00, 0x03, 0x00, 0x03, 0x00,
|
||||
0x03, 0x00, 0x03, 0x80, 0x01, 0xFC, 0x00, 0xFC, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0xFC,
|
||||
0x1B, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x30, 0x00, 0x38, 0x00, 0x1C, 0x00, 0x0C,
|
||||
0x00, 0x0C, 0x00, 0x1C, 0xCF, 0xF8, 0xCF, 0xF0, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0xFC, 0xFF, 0xFC, 0x00, 0xE0, 0x01, 0xE0,
|
||||
0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0x00, 0x00, 0x00,
|
||||
0x0F, 0xFC, 0x0F, 0xFC, 0x0E, 0x00, 0x07, 0x00, 0x03, 0xC0,
|
||||
0x03, 0xC0, 0x07, 0x00, 0x0E, 0x00, 0x0F, 0xFC, 0x0F, 0xFC,
|
||||
0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x00, 0x07, 0x00, 0x0E, 0x00,
|
||||
0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0xFC, 0x03, 0xFC,
|
||||
0x03, 0xF0, 0x07, 0xF8, 0x0E, 0x1C, 0x0C, 0x0C, 0x0C, 0x0C,
|
||||
0x0C, 0x0C, 0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0xF8, 0x03, 0xF0,
|
||||
0x0F, 0xFC, 0x0F, 0xFC, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
|
||||
0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xC0, 0x07, 0x80, 0x03, 0x00,
|
||||
0x03, 0x00, 0x07, 0x80, 0x0F, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0,
|
||||
0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0F, 0xFC, 0x0F, 0xFC,
|
||||
0x0F, 0xFC, 0x0F, 0xFC, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00,
|
||||
0x0C, 0x00, 0x0C, 0x00, 0x0E, 0x00, 0x07, 0x00, 0x03, 0x00,
|
||||
0x03, 0x18, 0x07, 0x9C, 0x0F, 0xCC, 0x0C, 0xCC, 0x0C, 0xCC,
|
||||
0x0C, 0xCC, 0x0C, 0xCC, 0x0C, 0xFC, 0x0E, 0x78, 0x06, 0x30,
|
||||
0x00, 0x00, 0x0C, 0x00, 0x0C, 0x00, 0xFF, 0xF0, 0xFF, 0xF8,
|
||||
0x0C, 0x1C, 0x0C, 0x1C, 0x0C, 0x38, 0x0C, 0x30, 0x00, 0x00,
|
||||
0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x0C, 0x00, 0x0C,
|
||||
0x00, 0x0C, 0x00, 0x0C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,
|
||||
0x0F, 0xC0, 0x0F, 0xE0, 0x00, 0x70, 0x00, 0x38, 0x00, 0x1C,
|
||||
0x00, 0x1C, 0x00, 0x38, 0x00, 0x70, 0x0F, 0xE0, 0x0F, 0xC0,
|
||||
0x0F, 0xF0, 0x0F, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x00, 0xF8,
|
||||
0x00, 0xF8, 0x00, 0x1C, 0x00, 0x1C, 0x0F, 0xF8, 0x0F, 0xF0,
|
||||
0x0C, 0x0C, 0x0E, 0x1C, 0x07, 0x38, 0x03, 0xF0, 0x01, 0xE0,
|
||||
0x01, 0xE0, 0x03, 0xF0, 0x07, 0x38, 0x0E, 0x1C, 0x0C, 0x0C,
|
||||
0x0C, 0x00, 0x0E, 0x00, 0x07, 0x0C, 0x03, 0x9C, 0x01, 0xF8,
|
||||
0x01, 0xF0, 0x03, 0x80, 0x07, 0x00, 0x0E, 0x00, 0x0C, 0x00,
|
||||
0x0C, 0x0C, 0x0C, 0x1C, 0x0C, 0x3C, 0x0C, 0x7C, 0x0C, 0xEC,
|
||||
0x0D, 0xCC, 0x0F, 0x8C, 0x0F, 0x0C, 0x0E, 0x0C, 0x0C, 0x0C,
|
||||
0x00, 0x00, 0x03, 0x00, 0x07, 0x80, 0x3F, 0xF0, 0x7C, 0xF8,
|
||||
0xE0, 0x1C, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0x00, 0x00,
|
||||
0x03, 0x0C, 0x03, 0x0C, 0x3F, 0xFC, 0x7F, 0xFC, 0xE3, 0x0C,
|
||||
0xC3, 0x0C, 0xC0, 0x0C, 0xE0, 0x0C, 0x70, 0x0C, 0x30, 0x0C,
|
||||
0x00, 0x00, 0xC0, 0x0C, 0xC0, 0x0C, 0xC0, 0x0C, 0xE0, 0x1C,
|
||||
0x7C, 0xF8, 0x3F, 0xF0, 0x07, 0x80, 0x03, 0x00, 0x00, 0x00,
|
||||
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
|
||||
0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00, 0xC0, 0x00,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC,
|
||||
0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC, 0xFF, 0xFC
|
||||
} ;
|
||||
@@ -0,0 +1,140 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of LCD driver, Include LCD initialization,
|
||||
* LCD on/off and LCD backlight control.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
#include "board.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Initializes the LCD controller.
|
||||
* Configure SMC to access LCD controller at 64MHz MCK.
|
||||
*/
|
||||
extern void LCDD_Initialize( void )
|
||||
{
|
||||
const Pin pPins[] = {BOARD_LCD_PINS};
|
||||
Smc *pSmc = SMC;
|
||||
|
||||
/* Enable pins */
|
||||
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
|
||||
|
||||
/* Enable peripheral clock */
|
||||
PMC_EnablePeripheral( ID_SMC ) ;
|
||||
|
||||
/* EBI SMC Configuration */
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_SETUP = SMC_SETUP_NWE_SETUP(2)
|
||||
| SMC_SETUP_NCS_WR_SETUP(2)
|
||||
| SMC_SETUP_NRD_SETUP(2)
|
||||
| SMC_SETUP_NCS_RD_SETUP(2);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_PULSE = SMC_PULSE_NWE_PULSE(4)
|
||||
| SMC_PULSE_NCS_WR_PULSE(4)
|
||||
| SMC_PULSE_NRD_PULSE(10)
|
||||
| SMC_PULSE_NCS_RD_PULSE(10);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_CYCLE = SMC_CYCLE_NWE_CYCLE(10)
|
||||
| SMC_CYCLE_NRD_CYCLE(22);
|
||||
|
||||
pSmc->SMC_CS_NUMBER[1].SMC_MODE = SMC_MODE_READ_MODE
|
||||
| SMC_MODE_WRITE_MODE
|
||||
| SMC_MODE_DBW_8_BIT;
|
||||
|
||||
/* Initialize LCD controller */
|
||||
LCD_Initialize() ;
|
||||
|
||||
/* Initialize LCD controller */
|
||||
LCD_SetDisplayPortrait( 0 ) ;
|
||||
|
||||
/* Set LCD backlight */
|
||||
LCDD_SetBacklight( 2 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn on the LCD.
|
||||
*/
|
||||
void LCDD_On(void)
|
||||
{
|
||||
LCD_On();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Turn off the LCD.
|
||||
*/
|
||||
void LCDD_Off(void)
|
||||
{
|
||||
LCD_Off();
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set the backlight of the LCD.
|
||||
*
|
||||
* \param level Backlight brightness level [1..16], 1 means maximum brightness.
|
||||
*/
|
||||
void LCDD_SetBacklight (uint32_t level)
|
||||
{
|
||||
uint32_t i;
|
||||
const Pin pPins[] = {BOARD_BACKLIGHT_PIN};
|
||||
|
||||
/* Ensure valid level */
|
||||
level = (level < 1) ? 1 : level;
|
||||
level = (level > 16) ? 16 : level;
|
||||
|
||||
/* Enable pins */
|
||||
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
|
||||
|
||||
/* Switch off backlight */
|
||||
PIO_Clear(pPins);
|
||||
i = 600 * (BOARD_MCK / 1000000); /* wait for at least 500us */
|
||||
while(i--);
|
||||
|
||||
/* Set new backlight level */
|
||||
for (i = 0; i < level; i++) {
|
||||
PIO_Clear(pPins);
|
||||
PIO_Clear(pPins);
|
||||
PIO_Clear(pPins);
|
||||
|
||||
PIO_Set(pPins);
|
||||
PIO_Set(pPins);
|
||||
PIO_Set(pPins);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Local Variables
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef PINS_LEDS
|
||||
static const Pin pinsLeds[] = { PINS_LEDS } ;
|
||||
static const uint32_t numLeds = PIO_LISTSIZE( pinsLeds ) ;
|
||||
#endif
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Global Functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Configures the pin associated with the given LED number. If the LED does
|
||||
* not exist on the board, the function does nothing.
|
||||
* \param led Number of the LED to configure.
|
||||
* \return 1 if the LED exists and has been configured; otherwise 0.
|
||||
*/
|
||||
extern uint32_t LED_Configure( uint32_t dwLed )
|
||||
{
|
||||
#ifdef PINS_LEDS
|
||||
// Check that LED exists
|
||||
if ( dwLed >= numLeds)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Configure LED
|
||||
return ( PIO_Configure( &pinsLeds[dwLed], 1 ) ) ;
|
||||
#else
|
||||
return 0 ;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns the given LED on if it exists; otherwise does nothing.
|
||||
* \param led Number of the LED to turn on.
|
||||
* \return 1 if the LED has been turned on; 0 otherwise.
|
||||
*/
|
||||
extern uint32_t LED_Set( uint32_t dwLed )
|
||||
{
|
||||
#ifdef PINS_LEDS
|
||||
/* Check if LED exists */
|
||||
if ( dwLed >= numLeds )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Turn LED on */
|
||||
if ( pinsLeds[dwLed].type == PIO_OUTPUT_0 )
|
||||
{
|
||||
|
||||
PIO_Set( &pinsLeds[dwLed] ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
PIO_Clear( &pinsLeds[dwLed] ) ;
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
#else
|
||||
return 0 ;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a LED off.
|
||||
*
|
||||
* \param led Number of the LED to turn off.
|
||||
* \return 1 if the LED has been turned off; 0 otherwise.
|
||||
*/
|
||||
extern uint32_t LED_Clear( uint32_t dwLed )
|
||||
{
|
||||
#ifdef PINS_LEDS
|
||||
/* Check if LED exists */
|
||||
if ( dwLed >= numLeds )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Turn LED off */
|
||||
if ( pinsLeds[dwLed].type == PIO_OUTPUT_0 )
|
||||
{
|
||||
PIO_Clear( &pinsLeds[dwLed] ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
PIO_Set( &pinsLeds[dwLed] ) ;
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
#else
|
||||
return 0 ;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggles the current state of a LED.
|
||||
*
|
||||
* \param led Number of the LED to toggle.
|
||||
* \return 1 if the LED has been toggled; otherwise 0.
|
||||
*/
|
||||
extern uint32_t LED_Toggle( uint32_t dwLed )
|
||||
{
|
||||
#ifdef PINS_LEDS
|
||||
/* Check if LED exists */
|
||||
if ( dwLed >= numLeds )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* Toggle LED */
|
||||
if ( PIO_GetOutputDataStatus( &pinsLeds[dwLed] ) )
|
||||
{
|
||||
PIO_Clear( &pinsLeds[dwLed] ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
PIO_Set( &pinsLeds[dwLed] ) ;
|
||||
}
|
||||
|
||||
return 1 ;
|
||||
#else
|
||||
return 0 ;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Returns the minimum value between two integers.
|
||||
*
|
||||
* \param a First integer to compare.
|
||||
* \param b Second integer to compare.
|
||||
*/
|
||||
extern uint32_t min( uint32_t dwA, uint32_t dwB )
|
||||
{
|
||||
if ( dwA < dwB )
|
||||
{
|
||||
return dwA ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return dwB ;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Returns the absolute value of an integer.
|
||||
*
|
||||
* \param value Integer value.
|
||||
*
|
||||
* \note Do not call this function "abs", problem with gcc !
|
||||
*/
|
||||
extern uint32_t absv( int32_t lValue )
|
||||
{
|
||||
if ( lValue < 0 )
|
||||
{
|
||||
return -lValue ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return lValue ;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Computes and returns x power of y.
|
||||
*
|
||||
* \param x Value.
|
||||
* \param y Power.
|
||||
*/
|
||||
extern uint32_t power( uint32_t dwX, uint32_t dwY )
|
||||
{
|
||||
uint32_t dwResult = 1 ;
|
||||
|
||||
while ( dwY > 0 )
|
||||
{
|
||||
dwResult *= dwX ;
|
||||
dwY-- ;
|
||||
}
|
||||
|
||||
return dwResult ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Global Variables
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
static uint32_t _dwRandNext=1 ;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Exported Functions
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Initialize the seed for rand generator.
|
||||
*
|
||||
* \param seed rand initiation seed
|
||||
*/
|
||||
extern void srand( uint32_t dwSeed )
|
||||
{
|
||||
_dwRandNext = dwSeed ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a random number, maxinum assumed to be 65536
|
||||
*/
|
||||
extern int rand( void )
|
||||
{
|
||||
_dwRandNext = _dwRandNext * 1103515245 + 12345 ;
|
||||
|
||||
return (uint32_t)(_dwRandNext/131072) % 65536 ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2010, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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 file Configures the target-dependent low level functions for character I/O.
|
||||
*/
|
||||
|
||||
#include "board.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/* Disable semihosting */
|
||||
#pragma import(__use_no_semihosting_swi)
|
||||
|
||||
struct __FILE { int handle;} ;
|
||||
FILE __stdout;
|
||||
FILE __stderr;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Outputs a character.
|
||||
*------------------------------------------------------------------------------*/
|
||||
int fputc(int ch, FILE *f)
|
||||
{
|
||||
if ((f == stdout) || (f == stderr))
|
||||
{
|
||||
UART_PutChar( ch ) ;
|
||||
return ch ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return EOF ;
|
||||
}
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Returns the error status accumulated during file I/O.
|
||||
*------------------------------------------------------------------------------*/
|
||||
int ferror( FILE *f )
|
||||
{
|
||||
return EOF ;
|
||||
}
|
||||
|
||||
|
||||
void _ttywrch( int ch )
|
||||
{
|
||||
UART_PutChar( (uint8_t)ch ) ;
|
||||
}
|
||||
|
||||
void _sys_exit(int return_code)
|
||||
{
|
||||
while ( 1 ) ; /* endless loop */
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Low level functions I/O for assert().
|
||||
*------------------------------------------------------------------------------*/
|
||||
void __assert_puts(const char *str)
|
||||
{
|
||||
printf("%s", str);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file syscalls.c
|
||||
*
|
||||
* Implementation of newlib syscall.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#undef errno
|
||||
extern int errno ;
|
||||
extern int _end ;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
extern void _exit( int status ) ;
|
||||
extern void _kill( int pid, int sig ) ;
|
||||
extern int _getpid ( void ) ;
|
||||
|
||||
extern caddr_t _sbrk ( int incr )
|
||||
{
|
||||
static unsigned char *heap = NULL ;
|
||||
unsigned char *prev_heap ;
|
||||
|
||||
if ( heap == NULL )
|
||||
{
|
||||
heap = (unsigned char *)&_end ;
|
||||
}
|
||||
prev_heap = heap;
|
||||
|
||||
heap += incr ;
|
||||
|
||||
return (caddr_t) prev_heap ;
|
||||
}
|
||||
|
||||
extern int link( char *old, char *new )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
extern int _close( int file )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
|
||||
extern int _fstat( int file, struct stat *st )
|
||||
{
|
||||
st->st_mode = S_IFCHR ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
extern int _isatty( int file )
|
||||
{
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
extern int _lseek( int file, int ptr, int dir )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
extern int _read(int file, char *ptr, int len)
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
extern int _write( int file, char *ptr, int len )
|
||||
{
|
||||
/*
|
||||
int iIndex ;
|
||||
|
||||
|
||||
// for ( ; *ptr != 0 ; ptr++ )
|
||||
for ( iIndex=0 ; iIndex < len ; iIndex++, ptr++ )
|
||||
{
|
||||
UART_PutChar( *ptr ) ;
|
||||
}
|
||||
return iIndex ;
|
||||
*/
|
||||
return -1;
|
||||
}
|
||||
|
||||
extern void _exit( int status )
|
||||
{
|
||||
printf( "Exiting with status %d.\n", status ) ;
|
||||
|
||||
for ( ; ; ) ;
|
||||
}
|
||||
|
||||
extern void _kill( int pid, int sig )
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
extern int _getpid ( void )
|
||||
{
|
||||
return -1 ;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Implement simple system tick usage.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Tick Counter united by ms */
|
||||
static volatile uint32_t _dwTickCount=0 ;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported Functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Handler for Sytem Tick interrupt.
|
||||
*/
|
||||
extern void TimeTick_Increment( void )
|
||||
{
|
||||
_dwTickCount++ ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configures the SAM3 SysTick & reset tickCount.
|
||||
* Systick interrupt handler will generates 1ms interrupt and increase a
|
||||
* tickCount.
|
||||
* \param new_mck Current master clock.
|
||||
*/
|
||||
extern uint32_t TimeTick_Configure( uint32_t new_mck )
|
||||
{
|
||||
_dwTickCount = 0 ;
|
||||
return SysTick_Config( new_mck/1000 ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Get current Tick Count, in ms.
|
||||
*/
|
||||
extern uint32_t GetTickCount( void )
|
||||
{
|
||||
return _dwTickCount ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sync Wait for several ms
|
||||
*/
|
||||
extern void Wait( volatile uint32_t dwMs )
|
||||
{
|
||||
uint32_t dwStart ;
|
||||
uint32_t dwCurrent ;
|
||||
|
||||
dwStart = _dwTickCount ;
|
||||
do
|
||||
{
|
||||
dwCurrent = _dwTickCount ;
|
||||
} while ( dwCurrent - dwStart < dwMs ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Sync Sleep for several ms
|
||||
*/
|
||||
extern void Sleep( volatile uint32_t dwMs )
|
||||
{
|
||||
uint32_t dwStart ;
|
||||
uint32_t dwCurrent ;
|
||||
|
||||
dwStart = _dwTickCount ;
|
||||
|
||||
do
|
||||
{
|
||||
dwCurrent = _dwTickCount ;
|
||||
|
||||
if ( dwCurrent - dwStart > dwMs )
|
||||
{
|
||||
break ;
|
||||
}
|
||||
|
||||
__WFI() ;
|
||||
} while( 1 ) ;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2008, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Headers
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
* Internal variables
|
||||
*------------------------------------------------------------------------------*/
|
||||
|
||||
/** Trace level can be set at applet initialization */
|
||||
#if !defined(NOTRACE) && (DYN_TRACES == 1)
|
||||
uint32_t dwTraceLevel = TRACE_LEVEL ;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initializes the U(S)ART Console
|
||||
*
|
||||
* \param dwBaudRate U(S)ART baudrate.
|
||||
* \param dwMCk Master clock frequency.
|
||||
*/
|
||||
extern void TRACE_CONFIGURE( uint32_t dwBaudRate, uint32_t dwMCk )
|
||||
{
|
||||
const Pin pinsUART0[] = { PINS_UART } ;
|
||||
|
||||
PIO_Configure( pinsUART0, PIO_LISTSIZE( pinsUART0 ) ) ;
|
||||
|
||||
UART_Configure( dwBaudRate, dwMCk ) ;
|
||||
}
|
||||
@@ -0,0 +1,317 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of ADS7843 driver.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef BOARD_TSC_ADS7843
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Delay for pushbutton debouncing (the time-base is 10 ms). */
|
||||
#define DEBOUNCE_TIME 6 /* 10 * 6 = 60 ms */
|
||||
|
||||
/** Color of calibration points. */
|
||||
#define POINTS_COLOR 0x0000FF
|
||||
|
||||
/** Size in pixels of calibration points. */
|
||||
#define POINTS_SIZE 4
|
||||
|
||||
/** Maximum difference in pixels between the test point and the measured point. */
|
||||
#define POINTS_MAX_ERROR 5
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Types
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** pen state */
|
||||
typedef enum {
|
||||
STATE_PEN_RELEASED = 0,
|
||||
STATE_PEN_PRESSED = 1,
|
||||
STATE_PEN_DEBOUNCE = 2
|
||||
} e_pen_state;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Pins used by Interrupt Signal for Touch Screen Controller */
|
||||
static const Pin pinPenIRQ = PIN_TSC_IRQ;
|
||||
|
||||
/** Global timestamp in milliseconds since start of application. */
|
||||
static volatile uint32_t timestamp = 0;
|
||||
|
||||
/** last time when the pen is pressed on the touchscreen */
|
||||
static volatile uint32_t timePress = 0;
|
||||
|
||||
/** last time when the pen is released */
|
||||
static volatile uint32_t timeRelease = 0;
|
||||
|
||||
/** pen state */
|
||||
static volatile e_pen_state penState = STATE_PEN_RELEASED;
|
||||
|
||||
/** Touch screen initiallized flag */
|
||||
static uint32_t tsInitFlag = 0;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Timer handler for touch screen. Increments the timestamp counter.
|
||||
* Determine the state "Pen Pressed" or "Pen Released". To change state,
|
||||
* the penIRQ has to keep the same value during DEBOUNCE_TIME.
|
||||
*
|
||||
* \note External timer interrupt should call it per 10ms.
|
||||
*/
|
||||
void TSD_TimerHandler( void )
|
||||
{
|
||||
uint32_t data[2];
|
||||
uint32_t timeKeep;
|
||||
static uint32_t point[2];
|
||||
|
||||
if (!tsInitFlag) return;
|
||||
|
||||
timestamp++;
|
||||
/* Get the current position of the pen if penIRQ has low value (pen pressed) */
|
||||
if ( PIO_Get(&pinPenIRQ) == 0 )
|
||||
{
|
||||
/* Get the current position of the pressed pen */
|
||||
if ( TSDCom_IsCalibrationOk() )
|
||||
{
|
||||
TSD_GetRawMeasurement(data);
|
||||
TSDCom_InterpolateMeasurement(data, point);
|
||||
}
|
||||
|
||||
/* call the callback function */
|
||||
if ( penState == STATE_PEN_PRESSED )
|
||||
{
|
||||
if(TSDCom_IsCalibrationOk())
|
||||
{
|
||||
TSD_PenMoved(point[0], point[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Determine the pen state */
|
||||
if ( PIO_Get( &pinPenIRQ ) == 0 )
|
||||
{
|
||||
/* reinit the last time when release */
|
||||
timeRelease = timestamp;
|
||||
|
||||
if ( penState == STATE_PEN_DEBOUNCE )
|
||||
{
|
||||
timeKeep = timestamp;
|
||||
timeKeep -= timePress;
|
||||
if(timeKeep > DEBOUNCE_TIME)
|
||||
{
|
||||
/* pen is pressed during an enough time : the state change */
|
||||
penState = STATE_PEN_PRESSED;
|
||||
/* call the callback function */
|
||||
if ( TSDCom_IsCalibrationOk() )
|
||||
{
|
||||
TSD_PenPressed(point[0], point[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* reinit the last time when release */
|
||||
timePress = timestamp;
|
||||
|
||||
if ( penState == STATE_PEN_DEBOUNCE )
|
||||
{
|
||||
timeKeep = timestamp;
|
||||
timeKeep -= timeRelease;
|
||||
if ( timeKeep > DEBOUNCE_TIME )
|
||||
{
|
||||
/* pen is released during an enough time : the state change */
|
||||
penState = STATE_PEN_RELEASED;
|
||||
/* call the callback function */
|
||||
if ( TSDCom_IsCalibrationOk() )
|
||||
{
|
||||
TSD_PenReleased(point[0], point[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \breif Interrupt handler for Touchscreen.
|
||||
*/
|
||||
static void ISR_PenIRQ( void )
|
||||
{
|
||||
/* Check if the pen has been pressed */
|
||||
if ( !PIO_Get( &pinPenIRQ ) )
|
||||
{
|
||||
if ( penState == STATE_PEN_RELEASED )
|
||||
{
|
||||
timePress = timestamp;
|
||||
penState = STATE_PEN_DEBOUNCE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( penState == STATE_PEN_PRESSED )
|
||||
{
|
||||
timeRelease = timestamp;
|
||||
penState = STATE_PEN_DEBOUNCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Configure PENIRQ for interrupt.
|
||||
*
|
||||
* \note Be sure the PIO interrupt management has been initialized by
|
||||
* PIO_InitializeInterrupts() before call this function.
|
||||
*/
|
||||
static void ConfigurePenIRQ( void )
|
||||
{
|
||||
/* Configure pios */
|
||||
PIO_Configure(&pinPenIRQ, PIO_LISTSIZE(pinPenIRQ));
|
||||
|
||||
/* Initialize interrupts */
|
||||
PIO_ConfigureIt(&pinPenIRQ, (void (*)(const Pin *)) ISR_PenIRQ);
|
||||
|
||||
/* Enable the interrupt */
|
||||
PIO_EnableIt(&pinPenIRQ);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Reads and store a touchscreen measurement in the provided array.
|
||||
*
|
||||
* \param pData Array where the measurements will be stored
|
||||
*/
|
||||
extern void TSD_GetRawMeasurement( uint32_t* pdwData )
|
||||
{
|
||||
/* Get the current position of the pressed pen */
|
||||
PIO_DisableIt( &pinPenIRQ ) ;
|
||||
ADS7843_GetPosition( &pdwData[0], &pdwData[1] ) ;
|
||||
PIO_EnableIt( &pinPenIRQ ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Wait pen pressed.
|
||||
*/
|
||||
extern void TSD_WaitPenPressed( void )
|
||||
{
|
||||
/* Wait for touch & end of conversion */
|
||||
while ( penState != STATE_PEN_RELEASED ) ;
|
||||
|
||||
/* while (penState != STATE_PEN_PRESSED); */
|
||||
while ( penState != STATE_PEN_PRESSED )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Wait pen released.
|
||||
*/
|
||||
extern void TSD_WaitPenReleased( void )
|
||||
{
|
||||
/* Wait for contact loss */
|
||||
while (penState != STATE_PEN_PRESSED);
|
||||
while (penState != STATE_PEN_RELEASED);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Do calibration.
|
||||
*
|
||||
* \return 1 if calibration is Ok, 0 else.
|
||||
*/
|
||||
extern uint8_t TSD_Calibrate( void )
|
||||
{
|
||||
uint8_t ret = 0 ;
|
||||
|
||||
/* Calibration is done only once */
|
||||
if ( TSDCom_IsCalibrationOk() )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do calibration */
|
||||
ret = TSDCom_Calibrate();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initializes the touchscreen driver and starts the calibration process. When
|
||||
* finished, the touchscreen is operational.
|
||||
*
|
||||
* \note Important: the LCD driver must have been initialized prior to calling this
|
||||
* function.
|
||||
*/
|
||||
extern void TSD_Initialize( int8_t calEn )
|
||||
{
|
||||
ADS7843_Initialize();
|
||||
ConfigurePenIRQ();
|
||||
|
||||
tsInitFlag = 1;
|
||||
|
||||
/* Calibration */
|
||||
if(calEn) {
|
||||
while (!TSD_Calibrate());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Stop the Touchscreen, disable interrupt.
|
||||
*/
|
||||
extern void TSD_Reset( void )
|
||||
{
|
||||
/* Disable SPI 0 */
|
||||
ADS7843_Reset() ;
|
||||
|
||||
/* Disable the interrupt */
|
||||
PIO_DisableIt( &pinPenIRQ ) ;
|
||||
}
|
||||
|
||||
#endif /* #ifdef BOARD_TSC_ADS7843 */
|
||||
@@ -0,0 +1,369 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation of touchscreen driver device irrelevance code.
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Size in pixels of calibration points. */
|
||||
#define POINTS_SIZE 4
|
||||
/** Maximum difference in pixels between the test point and the measured point. */
|
||||
#define POINTS_MAX_ERROR 8
|
||||
|
||||
/** Delay at the end of calibartion for result display */
|
||||
#define DELAY_RESULT_DISPLAY 4000000
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Types
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** \brief Point used during the touchscreen calibration process. */
|
||||
typedef struct _CalibrationPoint {
|
||||
|
||||
/** Coordinate of point along the X-axis of the screen. */
|
||||
uint32_t x;
|
||||
/** Coordinate of point along the Y-axis of the screen. */
|
||||
uint32_t y;
|
||||
/** Calibration data of point. */
|
||||
uint32_t data[2];
|
||||
|
||||
} CalibrationPoint;
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** indicates if the touch screen has been calibrated. */
|
||||
/** If not, Callback functions are not called. */
|
||||
static volatile uint8_t bCalibrationOk = 0;
|
||||
/** Slope for interpoling touchscreen measurements along the X-axis. */
|
||||
static int32_t xSlope;
|
||||
/** Slope for interpoling touchscreen measurements along the Y-axis. */
|
||||
static int32_t ySlope;
|
||||
|
||||
/** Calibration points. */
|
||||
static CalibrationPoint calibrationPoints[] = {
|
||||
|
||||
/* Top-left corner calibration point */
|
||||
{
|
||||
BOARD_LCD_WIDTH / 10,
|
||||
BOARD_LCD_HEIGHT / 10,
|
||||
{0, 0}
|
||||
},
|
||||
/* Top-right corner calibration point */
|
||||
{
|
||||
BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10,
|
||||
BOARD_LCD_HEIGHT / 10,
|
||||
{0, 0}
|
||||
},
|
||||
/* Bottom-right corner calibration point */
|
||||
{
|
||||
BOARD_LCD_WIDTH - BOARD_LCD_WIDTH / 10,
|
||||
BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10,
|
||||
{0, 0}
|
||||
},
|
||||
/* Bottom-left corner calibration point */
|
||||
{
|
||||
BOARD_LCD_WIDTH / 10,
|
||||
BOARD_LCD_HEIGHT - BOARD_LCD_HEIGHT / 10,
|
||||
{0, 0}
|
||||
}
|
||||
};
|
||||
|
||||
/** Test point */
|
||||
static const CalibrationPoint testPoint = {
|
||||
BOARD_LCD_WIDTH / 2,
|
||||
BOARD_LCD_HEIGHT / 2,
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Local functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Display a calibration point on the given buffer.
|
||||
*
|
||||
* \param pPoint Calibration point to display.
|
||||
*/
|
||||
static void DrawCalibrationPoint(const CalibrationPoint *pPoint)
|
||||
{
|
||||
LCDD_DrawRectangleWithFill(pPoint->x - POINTS_SIZE / 2,
|
||||
pPoint->y - POINTS_SIZE / 2,
|
||||
POINTS_SIZE,
|
||||
POINTS_SIZE,
|
||||
COLOR_RED);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clears a calibration point from the given buffer.
|
||||
*
|
||||
* \param pPoint Calibration point to clear.
|
||||
*/
|
||||
static void ClearCalibrationPoint(const CalibrationPoint *pPoint)
|
||||
{
|
||||
LCDD_DrawRectangleWithFill(pPoint->x - POINTS_SIZE / 2,
|
||||
pPoint->y - POINTS_SIZE / 2,
|
||||
POINTS_SIZE,
|
||||
POINTS_SIZE,
|
||||
COLOR_WHITE);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Indicates if the calibration of the touch screen is Ok.
|
||||
*
|
||||
* \return 1 calibration Ok, 0 if not.
|
||||
*/
|
||||
uint8_t TSDCom_IsCalibrationOk(void)
|
||||
{
|
||||
if (bCalibrationOk == 1) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Interpolates the provided raw measurements using the previously calculated
|
||||
* slope. The resulting x and y coordinates are stored in an array.
|
||||
*
|
||||
* \param pData Raw measurement data, as returned by TSD_GetRawMeasurement().
|
||||
* \param pPoint Array in which x and y will be stored.
|
||||
*/
|
||||
void TSDCom_InterpolateMeasurement(const uint32_t *pData, uint32_t *pPoint)
|
||||
{
|
||||
pPoint[0] = calibrationPoints[0].x
|
||||
- (((int32_t) calibrationPoints[0].data[0] - (int32_t) pData[0]) * 1024)
|
||||
/ xSlope;
|
||||
|
||||
pPoint[1] = calibrationPoints[0].y
|
||||
- (((int32_t) calibrationPoints[0].data[1] - (int32_t) pData[1]) * 1024)
|
||||
/ ySlope;
|
||||
|
||||
if(pPoint[0] & 0x80000000) /* Is pPoint[0] negative ? */
|
||||
{
|
||||
pPoint[0] = 0;
|
||||
}
|
||||
|
||||
if(pPoint[0] > BOARD_LCD_WIDTH) /* Is pPoint[0] bigger than the LCD width ? */
|
||||
{
|
||||
pPoint[0] = BOARD_LCD_WIDTH;
|
||||
}
|
||||
|
||||
if(pPoint[1] & 0x80000000) /* Is pPoint[1] negative ? */
|
||||
{
|
||||
pPoint[1] = 0;
|
||||
}
|
||||
|
||||
if(pPoint[1] > BOARD_LCD_HEIGHT) /* Is pPoint[1] bigger than the LCD width ? */
|
||||
{
|
||||
pPoint[1] = BOARD_LCD_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Performs the calibration process using the provided buffer to display
|
||||
* information.
|
||||
*
|
||||
* \return True if calibration was successful; otherwise false.
|
||||
*/
|
||||
uint8_t TSDCom_Calibrate(void)
|
||||
{
|
||||
volatile uint32_t i; /* to keep the tempo with gcc code optimisation */
|
||||
int32_t slope1, slope2;
|
||||
CalibrationPoint measuredPoint;
|
||||
uint8_t xOk, yOk;
|
||||
int32_t xDiff, yDiff;
|
||||
|
||||
/* Calibration setup */
|
||||
LCDD_Fill(COLOR_WHITE);
|
||||
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
|
||||
LCDD_DrawString(1, 140, (uint8_t *)"Touch the dots to\ncalibrate the screen", COLOR_DARKBLUE);
|
||||
|
||||
/* Calibration points */
|
||||
for (i=0; i < 4; i++) {
|
||||
|
||||
DrawCalibrationPoint(&calibrationPoints[i]);
|
||||
|
||||
/* Wait for touch & end of conversion */
|
||||
TSD_WaitPenPressed();
|
||||
TSD_GetRawMeasurement(calibrationPoints[i].data);
|
||||
ClearCalibrationPoint(&calibrationPoints[i]);
|
||||
|
||||
/* Wait for contact loss */
|
||||
TSD_WaitPenReleased();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate slopes using the calibration data
|
||||
* Theory behind those calculations:
|
||||
* - We suppose the touchscreen measurements are linear, so the following equations are true (simple
|
||||
* linear regression) for any two 'a' and 'b' points of the screen:
|
||||
* dx = (a.data[0] - b.data[0]) / (a.x - b.x)
|
||||
* dy = (a.data[1] - b.data[1]) / (a.y - b.y)
|
||||
*
|
||||
* - We calculate dx and dy (called xslope and yslope here) using the calibration points.
|
||||
*
|
||||
* - We can then use dx and dy to infer the position of a point 'p' given the measurements performed
|
||||
* by the touchscreen ('c' is any of the calibration points):
|
||||
* dx = (p.data[0] - c.data[0]) / (p.x - c.x)
|
||||
* dy = (p.data[1] - c.data[1]) / (p.y - c.y)
|
||||
* Thus:
|
||||
* p.x = c.x - (p.data[0] - c.data[0]) / dx
|
||||
* p.y = c.y - (p.data[1] - c.data[1]) / dy
|
||||
*
|
||||
* - Since there are four calibration points, dx and dy can be calculated twice, so we average
|
||||
* the two values.
|
||||
*/
|
||||
slope1 = ((int32_t) calibrationPoints[0].data[0]) - ((int32_t) calibrationPoints[1].data[0]);
|
||||
slope1 *= 1024;
|
||||
slope1 /= ((int32_t) calibrationPoints[0].x) - ((int32_t) calibrationPoints[1].x);
|
||||
slope2 = ((int32_t) calibrationPoints[2].data[0]) - ((int32_t) calibrationPoints[3].data[0]);
|
||||
slope2 *= 1024;
|
||||
slope2 /= ((int32_t) calibrationPoints[2].x) - ((int32_t) calibrationPoints[3].x);
|
||||
xSlope = (slope1 + slope2) / 2;
|
||||
|
||||
slope1 = ((int32_t) calibrationPoints[0].data[1]) - ((int32_t) calibrationPoints[2].data[1]);
|
||||
slope1 *= 1024;
|
||||
slope1 /= ((int32_t) calibrationPoints[0].y) - ((int32_t) calibrationPoints[2].y);
|
||||
slope2 = ((int32_t) calibrationPoints[1].data[1]) - ((int32_t) calibrationPoints[3].data[1]);
|
||||
slope2 *= 1024;
|
||||
slope2 /= ((int32_t) calibrationPoints[1].y) - ((int32_t) calibrationPoints[3].y);
|
||||
ySlope = (slope1 + slope2) / 2;
|
||||
|
||||
/* Test point */
|
||||
LCDD_Fill(0xFFFFFF);
|
||||
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
|
||||
LCDD_DrawString(1, 100, (uint8_t *)" Touch the point to\nvalidate calibration", COLOR_DARKBLUE);
|
||||
DrawCalibrationPoint(&testPoint);
|
||||
|
||||
/* Wait for touch & end of conversion */
|
||||
TSD_WaitPenPressed();
|
||||
|
||||
TSD_GetRawMeasurement(measuredPoint.data);
|
||||
TSDCom_InterpolateMeasurement(measuredPoint.data, (uint32_t *) &measuredPoint);
|
||||
DrawCalibrationPoint(&measuredPoint);
|
||||
|
||||
/* Check resulting x and y */
|
||||
xDiff = (int32_t) measuredPoint.x - (int32_t) testPoint.x;
|
||||
yDiff = (int32_t) measuredPoint.y - (int32_t) testPoint.y;
|
||||
xOk = (xDiff >= -POINTS_MAX_ERROR) && (xDiff <= POINTS_MAX_ERROR);
|
||||
yOk = (yDiff >= -POINTS_MAX_ERROR) && (yDiff <= POINTS_MAX_ERROR);
|
||||
|
||||
/* Wait for contact loss */
|
||||
TSD_WaitPenReleased();
|
||||
|
||||
/* Check calibration result */
|
||||
if (xOk && yOk) {
|
||||
|
||||
bCalibrationOk = 1;
|
||||
LCDD_Fill(COLOR_WHITE);
|
||||
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
|
||||
LCDD_DrawString(80, 140, (uint8_t *)"Success !", COLOR_GREEN);
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
bCalibrationOk = 0;
|
||||
LCDD_Fill(COLOR_WHITE);
|
||||
LCDD_DrawString(30, 50, (uint8_t *)"LCD calibration", COLOR_BLACK);
|
||||
LCDD_DrawString(40, 140, (uint8_t *)"Error too big", COLOR_RED);
|
||||
}
|
||||
|
||||
/* Slight delay */
|
||||
for (i = 0; i < DELAY_RESULT_DISPLAY; i++);
|
||||
|
||||
return (xOk && yOk);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Read calibrate data to buffer.
|
||||
*
|
||||
* \param pBuffer Data buffer.
|
||||
* \param size Size of data buffer in bytes.
|
||||
*/
|
||||
void TSDCom_ReadCalibrateData(void *pBuffer, uint32_t size)
|
||||
{
|
||||
uint8_t *pDest = (uint8_t *)pBuffer;
|
||||
|
||||
assert( (sizeof(bCalibrationOk) + sizeof(xSlope) +
|
||||
sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size ) ;
|
||||
|
||||
memcpy(pDest, (void const *)&bCalibrationOk, sizeof(bCalibrationOk));
|
||||
pDest += sizeof(bCalibrationOk);
|
||||
memcpy(pDest, &xSlope, sizeof(xSlope));
|
||||
pDest += sizeof(xSlope);
|
||||
memcpy(pDest, &ySlope, sizeof(ySlope));
|
||||
pDest += sizeof(ySlope);
|
||||
memcpy(pDest, &calibrationPoints[0].data, sizeof(calibrationPoints[0].data));
|
||||
pDest += sizeof(calibrationPoints[0].data);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Restore calibrate data with buffer data.
|
||||
*
|
||||
* \param pBuffer Data buffer.
|
||||
* \param size Size of data buffer in bytes.
|
||||
*/
|
||||
void TSDCom_RestoreCalibrateData(void *pBuffer, uint32_t size)
|
||||
{
|
||||
uint8_t *pSrc = (uint8_t *)pBuffer;
|
||||
|
||||
assert( (sizeof(bCalibrationOk) + sizeof(xSlope) +
|
||||
sizeof(ySlope) + sizeof(calibrationPoints[0].data)) < size ) ;
|
||||
|
||||
memcpy((void *)&bCalibrationOk, pSrc, sizeof(bCalibrationOk));
|
||||
pSrc += sizeof(bCalibrationOk);
|
||||
memcpy(&xSlope, pSrc, sizeof(xSlope));
|
||||
pSrc += sizeof(xSlope);
|
||||
memcpy(&ySlope, pSrc, sizeof(ySlope));
|
||||
pSrc += sizeof(ySlope);
|
||||
memcpy(&calibrationPoints[0].data, pSrc, sizeof(calibrationPoints[0].data));
|
||||
pSrc += sizeof(calibrationPoints[0].data);
|
||||
}
|
||||
@@ -0,0 +1,389 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implements UART console.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definitions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Console baudrate always using 115200. */
|
||||
#define CONSOLE_BAUDRATE 115200
|
||||
/** Usart Hw interface used by the console (UART0). */
|
||||
#define CONSOLE_USART UART0
|
||||
/** Usart Hw ID used by the console (UART0). */
|
||||
#define CONSOLE_ID ID_UART0
|
||||
/** Pins description corresponding to Rxd,Txd, (UART pins) */
|
||||
#define CONSOLE_PINS {PINS_UART}
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Variables
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/** Is Console Initialized. */
|
||||
static uint8_t _ucIsConsoleInitialized=0 ;
|
||||
|
||||
/**
|
||||
* \brief Configures an USART peripheral with the specified parameters.
|
||||
*
|
||||
* \param baudrate Baudrate at which the USART should operate (in Hz).
|
||||
* \param masterClock Frequency of the system master clock (in Hz).
|
||||
*/
|
||||
extern void UART_Configure( uint32_t baudrate, uint32_t masterClock)
|
||||
{
|
||||
const Pin pPins[] = CONSOLE_PINS;
|
||||
Uart *pUart = CONSOLE_USART;
|
||||
|
||||
/* Configure PIO */
|
||||
PIO_Configure(pPins, PIO_LISTSIZE(pPins));
|
||||
|
||||
/* Configure PMC */
|
||||
PMC->PMC_PCER0 = 1 << CONSOLE_ID;
|
||||
|
||||
/* Reset and disable receiver & transmitter */
|
||||
pUart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX
|
||||
| UART_CR_RXDIS | UART_CR_TXDIS;
|
||||
|
||||
/* Configure mode */
|
||||
pUart->UART_MR = UART_MR_PAR_NO;
|
||||
|
||||
/* Configure baudrate */
|
||||
/* Asynchronous, no oversampling */
|
||||
pUart->UART_BRGR = (masterClock / baudrate) / 16;
|
||||
|
||||
/* Disable PDC channel */
|
||||
pUart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
||||
|
||||
/* Enable receiver and transmitter */
|
||||
pUart->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
||||
|
||||
_ucIsConsoleInitialized=1 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Outputs a character on the UART line.
|
||||
*
|
||||
* \note This function is synchronous (i.e. uses polling).
|
||||
* \param c Character to send.
|
||||
*/
|
||||
extern void UART_PutChar( uint8_t c )
|
||||
{
|
||||
Uart *pUart=CONSOLE_USART ;
|
||||
|
||||
if ( !_ucIsConsoleInitialized )
|
||||
{
|
||||
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
||||
}
|
||||
|
||||
/* Wait for the transmitter to be ready */
|
||||
while ( (pUart->UART_SR & UART_SR_TXEMPTY) == 0 ) ;
|
||||
|
||||
/* Send character */
|
||||
pUart->UART_THR=c ;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Input a character from the UART line.
|
||||
*
|
||||
* \note This function is synchronous
|
||||
* \return character received.
|
||||
*/
|
||||
extern uint32_t UART_GetChar( void )
|
||||
{
|
||||
Uart *pUart=CONSOLE_USART ;
|
||||
|
||||
if ( !_ucIsConsoleInitialized )
|
||||
{
|
||||
UART_Configure(CONSOLE_BAUDRATE, BOARD_MCK);
|
||||
}
|
||||
|
||||
while ( (pUart->UART_SR & UART_SR_RXRDY) == 0 ) ;
|
||||
|
||||
return pUart->UART_RHR ;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Check if there is Input from UART line.
|
||||
*
|
||||
* \return true if there is Input.
|
||||
*/
|
||||
extern uint32_t UART_IsRxReady( void )
|
||||
{
|
||||
Uart *pUart=CONSOLE_USART ;
|
||||
|
||||
if ( !_ucIsConsoleInitialized )
|
||||
{
|
||||
UART_Configure( CONSOLE_BAUDRATE, BOARD_MCK ) ;
|
||||
}
|
||||
|
||||
return (pUart->UART_SR & UART_SR_RXRDY) > 0 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the content of the given frame on the UART0.
|
||||
*
|
||||
* \param pucFrame Pointer to the frame to dump.
|
||||
* \param dwSize Buffer size in bytes.
|
||||
*/
|
||||
extern void UART_DumpFrame( uint8_t* pucFrame, uint32_t dwSize )
|
||||
{
|
||||
uint32_t dw ;
|
||||
|
||||
for ( dw=0 ; dw < dwSize ; dw++ )
|
||||
{
|
||||
printf( "%02X ", pucFrame[dw] ) ;
|
||||
}
|
||||
|
||||
printf( "\n\r" ) ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the content of the given buffer on the UART0.
|
||||
*
|
||||
* \param pucBuffer Pointer to the buffer to dump.
|
||||
* \param dwSize Buffer size in bytes.
|
||||
* \param dwAddress Start address to display
|
||||
*/
|
||||
extern void UART_DumpMemory( uint8_t* pucBuffer, uint32_t dwSize, uint32_t dwAddress )
|
||||
{
|
||||
uint32_t i ;
|
||||
uint32_t j ;
|
||||
uint32_t dwLastLineStart ;
|
||||
uint8_t* pucTmp ;
|
||||
|
||||
for ( i=0 ; i < (dwSize / 16) ; i++ )
|
||||
{
|
||||
printf( "0x%08X: ", (unsigned int)(dwAddress + (i*16)) ) ;
|
||||
pucTmp = (uint8_t*)&pucBuffer[i*16] ;
|
||||
|
||||
for ( j=0 ; j < 4 ; j++ )
|
||||
{
|
||||
printf( "%02X%02X%02X%02X ", pucTmp[0], pucTmp[1], pucTmp[2], pucTmp[3] ) ;
|
||||
pucTmp += 4 ;
|
||||
}
|
||||
|
||||
pucTmp=(uint8_t*)&pucBuffer[i*16] ;
|
||||
|
||||
for ( j=0 ; j < 16 ; j++ )
|
||||
{
|
||||
UART_PutChar( *pucTmp++ ) ;
|
||||
}
|
||||
|
||||
printf( "\n\r" ) ;
|
||||
}
|
||||
|
||||
if ( (dwSize%16) != 0 )
|
||||
{
|
||||
dwLastLineStart=dwSize - (dwSize%16) ;
|
||||
|
||||
printf( "0x%08X: ", (unsigned int)(dwAddress + dwLastLineStart) ) ;
|
||||
for ( j=dwLastLineStart ; j < dwLastLineStart+16 ; j++ )
|
||||
{
|
||||
if ( (j!=dwLastLineStart) && (j%4 == 0) )
|
||||
{
|
||||
printf( " " ) ;
|
||||
}
|
||||
|
||||
if ( j < dwSize )
|
||||
{
|
||||
printf( "%02X", pucBuffer[j] ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" ") ;
|
||||
}
|
||||
}
|
||||
|
||||
printf( " " ) ;
|
||||
for ( j=dwLastLineStart ; j < dwSize ; j++ )
|
||||
{
|
||||
UART_PutChar( pucBuffer[j] ) ;
|
||||
}
|
||||
|
||||
printf( "\n\r" ) ;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an integer
|
||||
*
|
||||
* \param pdwValue Pointer to the uint32_t variable to contain the input value.
|
||||
*/
|
||||
extern uint32_t UART_GetInteger( uint32_t* pdwValue )
|
||||
{
|
||||
uint8_t ucKey ;
|
||||
uint8_t ucNbNb=0 ;
|
||||
uint32_t dwValue=0 ;
|
||||
|
||||
while ( 1 )
|
||||
{
|
||||
ucKey=UART_GetChar() ;
|
||||
UART_PutChar( ucKey ) ;
|
||||
|
||||
if ( ucKey >= '0' && ucKey <= '9' )
|
||||
{
|
||||
dwValue = (dwValue * 10) + (ucKey - '0');
|
||||
ucNbNb++ ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ucKey == 0x0D || ucKey == ' ' )
|
||||
{
|
||||
if ( ucNbNb == 0 )
|
||||
{
|
||||
printf( "\n\rWrite a number and press ENTER or SPACE!\n\r" ) ;
|
||||
return 0 ;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "\n\r" ) ;
|
||||
*pdwValue=dwValue ;
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "\n\r'%c' not a number!\n\r", ucKey ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an integer and check the value
|
||||
*
|
||||
* \param pdwValue Pointer to the uint32_t variable to contain the input value.
|
||||
* \param dwMin Minimum value
|
||||
* \param dwMax Maximum value
|
||||
*/
|
||||
extern uint32_t UART_GetIntegerMinMax( uint32_t* pdwValue, uint32_t dwMin, uint32_t dwMax )
|
||||
{
|
||||
uint32_t dwValue=0 ;
|
||||
|
||||
if ( UART_GetInteger( &dwValue ) == 0 )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
if ( dwValue < dwMin || dwValue > dwMax )
|
||||
{
|
||||
printf( "\n\rThe number have to be between %d and %d\n\r", (int)dwMin, (int)dwMax ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
printf( "\n\r" ) ;
|
||||
|
||||
*pdwValue = dwValue ;
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an hexadecimal number
|
||||
*
|
||||
* \param pdwValue Pointer to the uint32_t variable to contain the input value.
|
||||
*/
|
||||
extern uint32_t UART_GetHexa32( uint32_t* pdwValue )
|
||||
{
|
||||
uint8_t ucKey ;
|
||||
uint32_t dw = 0 ;
|
||||
uint32_t dwValue = 0 ;
|
||||
|
||||
for ( dw=0 ; dw < 8 ; dw++ )
|
||||
{
|
||||
ucKey = UART_GetChar() ;
|
||||
UART_PutChar( ucKey ) ;
|
||||
|
||||
if ( ucKey >= '0' && ucKey <= '9' )
|
||||
{
|
||||
dwValue = (dwValue * 16) + (ucKey - '0') ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ucKey >= 'A' && ucKey <= 'F' )
|
||||
{
|
||||
dwValue = (dwValue * 16) + (ucKey - 'A' + 10) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( ucKey >= 'a' && ucKey <= 'f' )
|
||||
{
|
||||
dwValue = (dwValue * 16) + (ucKey - 'a' + 10) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "\n\rIt is not a hexa character!\n\r" ) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("\n\r" ) ;
|
||||
*pdwValue = dwValue ;
|
||||
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
#if defined __ICCARM__ /* IAR Ewarm 5.41+ */
|
||||
/**
|
||||
* \brief Outputs a character on the UART.
|
||||
*
|
||||
* \param c Character to output.
|
||||
*
|
||||
* \return The character that was output.
|
||||
*/
|
||||
extern WEAK signed int putchar( signed int c )
|
||||
{
|
||||
UART_PutChar( c ) ;
|
||||
|
||||
return c ;
|
||||
}
|
||||
#endif // defined __ICCARM__
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Definiation
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/* WAV letters "RIFF" */
|
||||
#define WAV_CHUNKID 0x46464952
|
||||
/* WAV letters "WAVE"*/
|
||||
#define WAV_FORMAT 0x45564157
|
||||
/* WAV letters "fmt "*/
|
||||
#define WAV_SUBCHUNKID 0x20746D66
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Check if the header of a Wav file is valid ot not.
|
||||
*
|
||||
* \param file Buffer holding the file to examinate.
|
||||
* \return 1 if the header of a Wav file is valid; otherwise returns 0.
|
||||
*/
|
||||
unsigned char WAV_IsValid(const WavHeader *header)
|
||||
{
|
||||
return ((header->chunkID == WAV_CHUNKID)
|
||||
&& (header->format == WAV_FORMAT)
|
||||
&& (header->subchunk1Size == 0x10));
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Display the information of the WAV file (sample rate, stereo/mono
|
||||
* and frame size).
|
||||
*
|
||||
* \param header Wav head information.
|
||||
*/
|
||||
|
||||
void WAV_DisplayInfo(const WavHeader *header)
|
||||
{
|
||||
printf( "Wave file header information\n\r");
|
||||
printf( "--------------------------------\n\r");
|
||||
printf( " - Chunk ID = 0x%08X\n\r", header->chunkID);
|
||||
printf( " - Chunk Size = %u\n\r", header->chunkSize);
|
||||
printf( " - Format = 0x%08X\n\r", header->format);
|
||||
printf( " - SubChunk ID = 0x%08X\n\r", header->subchunk1ID);
|
||||
printf( " - Subchunk1 Size = %u\n\r", header->subchunk1Size);
|
||||
printf( " - Audio Format = 0x%04X\n\r", header->audioFormat);
|
||||
printf( " - Num. Channels = %d\n\r", header->numChannels);
|
||||
printf( " - Sample Rate = %u\n\r", header->sampleRate);
|
||||
printf( " - Byte Rate = %u\n\r", header->byteRate);
|
||||
printf( " - Block Align = %d\n\r", header->blockAlign);
|
||||
printf( " - Bits Per Sample = %d\n\r", header->bitsPerSample);
|
||||
printf( " - Subchunk2 ID = 0x%08X\n\r", header->subchunk2ID);
|
||||
printf( " - Subchunk2 Size = %u\n\r", header->subchunk2Size);
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
/* ----------------------------------------------------------------------------
|
||||
* ATMEL Microcontroller Software Support
|
||||
* ----------------------------------------------------------------------------
|
||||
* Copyright (c) 2009, Atmel Corporation
|
||||
*
|
||||
* All rights reserved.
|
||||
*
|
||||
* 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 disclaimer below.
|
||||
*
|
||||
* Atmel's name may not be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
|
||||
* ----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* Implementation WM8731 driver.
|
||||
*
|
||||
*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Headers
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
#include "board.h"
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Exported functions
|
||||
*----------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* \brief Read data from WM8731 Register.
|
||||
*
|
||||
* \param pTwid Pointer to twi driver structure
|
||||
* \param device Twi slave address.
|
||||
* \param regAddr Register address to read.
|
||||
* \return value in the given register.
|
||||
*/
|
||||
uint16_t WM8731_Read(Twid *pTwid,
|
||||
uint32_t device,
|
||||
uint32_t regAddr)
|
||||
{
|
||||
uint16_t bitsDataRegister;
|
||||
uint8_t Tdata[2]={0,0};
|
||||
|
||||
TWID_Read(pTwid, device, regAddr, 0, Tdata, 2, 0);
|
||||
bitsDataRegister = (Tdata[0] << 8) | Tdata[1];
|
||||
return bitsDataRegister;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write data to WM8731 Register.
|
||||
*
|
||||
* \param pTwid Pointer to twi driver structure
|
||||
* \param device Twi slave address.
|
||||
* \param regAddr Register address to read.
|
||||
* \param data Data to write
|
||||
*/
|
||||
void WM8731_Write(Twid *pTwid,
|
||||
uint32_t device,
|
||||
uint32_t regAddr,
|
||||
uint16_t data)
|
||||
{
|
||||
uint8_t tmpData[2];
|
||||
uint16_t tmp;
|
||||
tmp = ((regAddr & 0x7f) << 9) | (data & 0x1ff);
|
||||
|
||||
tmpData[0] = (tmp & 0xff00) >> 8;
|
||||
tmpData[1] = tmp & 0xff;
|
||||
TWID_Write(pTwid, device, regAddr, 0, tmpData, 2, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Init WM8731 to DAC mode.
|
||||
*
|
||||
* \param pTwid Pointer to twi driver structure
|
||||
* \param device Twi slave address.
|
||||
* \return 0.
|
||||
*/
|
||||
uint8_t WM8731_DAC_Init(Twid *pTwid,
|
||||
uint32_t device)
|
||||
{
|
||||
/* reset */
|
||||
WM8731_Write(pTwid, device, WM8731_REG_RESET, 0);
|
||||
|
||||
/* analogue audio path control */
|
||||
WM8731_Write(pTwid, device, WM8731_REG_ANALOGUE_PATH_CTRL, 0x12);
|
||||
|
||||
/* digital audio path control*/
|
||||
WM8731_Write(pTwid, device, WM8731_REG_DIGITAL_PATH_CTRL, 0x00);
|
||||
|
||||
/* power down control */
|
||||
WM8731_Write(pTwid, device, WM8731_REG_PWDOWN_CTRL, 0x7);
|
||||
|
||||
/* Active control*/
|
||||
WM8731_Write(pTwid, device, WM8731_REG_ACTIVE_CTRL, 0x01);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Set WM8731 volume
|
||||
*
|
||||
* \param pTwid Pointer to twi driver structure
|
||||
* \param device Twi slave address.
|
||||
* \param value Register value, valid value is between 0x30 to 0x7f
|
||||
* \return 0.
|
||||
*/
|
||||
uint8_t WM8731_VolumeSet(Twid *pTwid,
|
||||
uint32_t device,
|
||||
uint16_t value)
|
||||
{
|
||||
uint16_t regValue;
|
||||
|
||||
value &= WM8731_LHPVOL_BITS;
|
||||
regValue = WM8731_LRHPBOTH_BIT | WM8731_LZCEN_BIT | value;
|
||||
WM8731_Write(pTwid, device, WM8731_REG_LEFT_HPOUT, regValue);
|
||||
regValue = WM8731_RZCEN_BIT | WM8731_RLHPBOTH_BIT | value;
|
||||
WM8731_Write(pTwid, device, WM8731_REG_RIGHT_HPOUT, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user