Makefile with libs and atmel source

This commit is contained in:
Christina Quast
2014-12-02 13:06:01 +01:00
parent a42c11f876
commit 8be71e4e99
63 changed files with 14441 additions and 2654 deletions

View File

@@ -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 ) ;
}

View File

@@ -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) ;
}

View File

@@ -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 ) ;
}

View File

@@ -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);
}
}
}

View File

@@ -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 ) ;
}

View File

@@ -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) ; );
}

View File

@@ -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 ;
}

View File

@@ -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;
}
}
}

View File

@@ -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 ;
}

View File

@@ -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 ;
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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 ) ;
}
}

View File

@@ -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 ) ;
}
}
}
}

View File

@@ -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
} ;

View File

@@ -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);
}
}

View File

@@ -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
}

View File

@@ -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 ;
}

View File

@@ -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 ;
}

View File

@@ -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);
}

View File

@@ -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 ;
}

View File

@@ -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 ) ;
}

View File

@@ -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 ) ;
}

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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__

View File

@@ -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);
}

View File

@@ -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;
}