TWI.rar

Re: ATxmega TWI - nie umiem obsłużyć tej magistrali po przesiadce z Mega

Witam Oto przykład Atmela. Niestety, nie mam czasu by go sprawdzić. Oraz sprawdzony (otrzymałem razem z płytką XMegi)

  • TWI.rar
    • twi_master_driver.h
    • twi_master_driver.c
    • twi_example.c
    • fram.aws
    • FRAM.aps
    • avr_compiler.h
    • Array


Download file - link to post

TWI.rar > twi_master_driver.h

/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief XMEGA TWI master driver header file.
*
* This file contains the function prototypes and enumerator definitions
* for various configuration parameters for the XMEGA TWI master driver.
*
* The driver is not intended for size and/or speed critical code, since
* most functions are just a few lines of code, and the function call
* overhead would decrease code performance. The driver is intended for
* rapid prototyping and documentation purposes for getting started with
* the XMEGA TWI master module.
*
* For size and/or speed critical code, it is recommended to copy the
* function contents directly into your application instead of making
* a function call.
*
* \par Application note:
* AVR1308: Using the XMEGA TWI
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1569 $
* $Date: 2008-04-22 13:03:43 +0200 (ti, 22 apr 2008) $ \n
*
* 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:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL " AS IS " AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY 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.
*****************************************************************************/
#ifndef TWI_MASTER_DRIVER_H
#define TWI_MASTER_DRIVER_H

#include " avr_compiler.h "

/*! Baud register setting calculation. Formula described in datasheet. */
#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)


/*! Transaction status defines. */
#define TWIM_STATUS_READY 0
#define TWIM_STATUS_BUSY 1


/*! Transaction result enumeration. */
typedef enum TWIM_RESULT_enum {
TWIM_RESULT_UNKNOWN = (0x00 & lt; & lt; 0),
TWIM_RESULT_OK = (0x01 & lt; & lt; 0),
TWIM_RESULT_BUFFER_OVERFLOW = (0x02 & lt; & lt; 0),
TWIM_RESULT_ARBITRATION_LOST = (0x03 & lt; & lt; 0),
TWIM_RESULT_BUS_ERROR = (0x04 & lt; & lt; 0),
TWIM_RESULT_NACK_RECEIVED = (0x05 & lt; & lt; 0),
TWIM_RESULT_FAIL = (0x06 & lt; & lt; 0),
} TWIM_RESULT_t;

/*! Buffer size defines */
#define TWIM_WRITE_BUFFER_SIZE 8
#define TWIM_READ_BUFFER_SIZE 8


/*! \brief TWI master driver struct
*
* TWI master struct. Holds pointer to TWI module,
* buffers and necessary varibles.
*/
typedef struct TWI_Master {
TWI_t *interface; /*! & lt; Pointer to what interface to use */
register8_t address; /*! & lt; Slave address */
register8_t writeData[TWIM_WRITE_BUFFER_SIZE]; /*! & lt; Data to write */
register8_t readData[TWIM_READ_BUFFER_SIZE]; /*! & lt; Read data */
register8_t bytesToWrite; /*! & lt; Number of bytes to write */
register8_t bytesToRead; /*! & lt; Number of bytes to read */
register8_t bytesWritten; /*! & lt; Number of bytes written */
register8_t bytesRead; /*! & lt; Number of bytes read */
register8_t status; /*! & lt; Status of transaction */
register8_t result; /*! & lt; Result of transaction */
}TWI_Master_t;



void TWI_MasterInit(TWI_Master_t *twi,
TWI_t *module,
TWI_MASTER_INTLVL_t intLevel,
uint8_t baudRateRegisterSetting);
TWI_MASTER_BUSSTATE_t TWI_MasterState(TWI_Master_t *twi);
bool TWI_MasterReady(TWI_Master_t *twi);
bool TWI_MasterWrite(TWI_Master_t *twi,
uint8_t address,
uint8_t * writeData,
uint8_t bytesToWrite);
bool TWI_MasterRead(TWI_Master_t *twi,
uint8_t address,
uint8_t bytesToRead);
bool TWI_MasterWriteRead(TWI_Master_t *twi,
uint8_t address,
uint8_t *writeData,
uint8_t bytesToWrite,
uint8_t bytesToRead);
void TWI_MasterInterruptHandler(TWI_Master_t *twi);
void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi);
void TWI_MasterWriteHandler(TWI_Master_t *twi);
void TWI_MasterReadHandler(TWI_Master_t *twi);
void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result);


/*! TWI master interrupt service routine.
*
* Interrupt service routine for the TWI master. Copy the needed vectors
* into your code.
*
ISR(TWIC_TWIM_vect)
{
TWI_MasterInterruptHandler( & twiMaster);
}

*
*/

#endif /* TWI_MASTER_DRIVER_H */


TWI.rar > twi_master_driver.c

/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief
* XMEGA TWI master driver source file.
*
* This file contains the function implementations the XMEGA master TWI
* driver.
*
* The driver is not intended for size and/or speed critical code, since
* most functions are just a few lines of code, and the function call
* overhead would decrease code performance. The driver is intended for
* rapid prototyping and documentation purposes for getting started with
* the XMEGA TWI master module.
*
* For size and/or speed critical code, it is recommended to copy the
* function contents directly into your application instead of making
* a function call.
*
* Several functions use the following construct:
* " some_register = ... | (some_parameter ? SOME_BIT_bm : 0) | ... "
* Although the use of the ternary operator ( if ? then : else ) is
* discouraged, in some occasions the operator makes it possible to write
* pretty clean and neat code. In this driver, the construct is used to
* set or not set a configuration bit based on a boolean input parameter,
* such as the " some_parameter " in the example above.
*
* \par Application note:
* AVR1308: Using the XMEGA TWI
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 1569 $
* $Date: 2008-04-22 13:03:43 +0200 (ti, 22 apr 2008) $ \n
*
* 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:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL " AS IS " AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY 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 " twi_master_driver.h "


/*! \brief Initialize the TWI module.
*
* TWI module initialization function.
* Enables master read and write interrupts.
* Remember to enable interrupts globally from the main application.
*
* \param twi The TWI_Master_t struct instance.
* \param module The TWI module to use.
* \param intLevel Master interrupt level.
* \param baudRateRegisterSetting The baud rate register value.
*/
void TWI_MasterInit(TWI_Master_t *twi,
TWI_t *module,
TWI_MASTER_INTLVL_t intLevel,
uint8_t baudRateRegisterSetting)
{
twi- & gt; interface = module;
twi- & gt; interface- & gt; MASTER.CTRLA = intLevel |
TWI_MASTER_RIEN_bm |
TWI_MASTER_WIEN_bm |
TWI_MASTER_ENABLE_bm;
twi- & gt; interface- & gt; MASTER.BAUD = baudRateRegisterSetting;
twi- & gt; interface- & gt; MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
}


/*! \brief Returns the TWI bus state.
*
* Returns the TWI bus state (type defined in device headerfile),
* unknown, idle, owner or busy.
*
* \param twi The TWI_Master_t struct instance.
*
* \retval TWI_MASTER_BUSSTATE_UNKNOWN_gc Bus state is unknown.
* \retval TWI_MASTER_BUSSTATE_IDLE_gc Bus state is idle.
* \retval TWI_MASTER_BUSSTATE_OWNER_gc Bus state is owned by the master.
* \retval TWI_MASTER_BUSSTATE_BUSY_gc Bus state is busy.
*/
TWI_MASTER_BUSSTATE_t TWI_MasterState(TWI_Master_t *twi)
{
TWI_MASTER_BUSSTATE_t twi_status;
twi_status = (TWI_MASTER_BUSSTATE_t) (twi- & gt; interface- & gt; MASTER.STATUS &
TWI_MASTER_BUSSTATE_gm);
return twi_status;
}


/*! \brief Returns true if transaction is ready.
*
* This function returns a boolean whether the TWI Master is ready
* for a new transaction.
*
* \param twi The TWI_Master_t struct instance.
*
* \retval true If transaction could be started.
* \retval false If transaction could not be started.
*/
bool TWI_MasterReady(TWI_Master_t *twi)
{
bool twi_status = (twi- & gt; status & TWIM_STATUS_READY);
return twi_status;
}


/*! \brief TWI write transaction.
*
* This function is TWI Master wrapper for a write-only transaction.
*
* \param twi The TWI_Master_t struct instance.
* \param address Slave address.
* \param writeData Pointer to data to write.
* \param bytesToWrite Number of data bytes to write.
*
* \retval true If transaction could be started.
* \retval false If transaction could not be started.
*/
bool TWI_MasterWrite(TWI_Master_t *twi,
uint8_t address,
uint8_t *writeData,
uint8_t bytesToWrite)
{
bool twi_status = TWI_MasterWriteRead(twi, address, writeData, bytesToWrite, 0);
return twi_status;
}


/*! \brief TWI read transaction.
*
* This function is a TWI Maste wrapper for read-only transaction.
*
* \param twi The TWI_Master_t struct instance.
* \param address The slave address.
* \param bytesToRead The number of bytes to read.
*
* \retval true If transaction could be started.
* \retval false If transaction could not be started.
*/
bool TWI_MasterRead(TWI_Master_t *twi,
uint8_t address,
uint8_t bytesToRead)
{
bool twi_status = TWI_MasterWriteRead(twi, address, 0, 0, bytesToRead);
return twi_status;
}


/*! \brief TWI write and/or read transaction.
*
* This function is a TWI Master write and/or read transaction. The function
* can be used to both write and/or read bytes to/from the TWI Slave in one
* transaction.
*
* \param twi The TWI_Master_t struct instance.
* \param address The slave address.
* \param writeData Pointer to data to write.
* \param bytesToWrite Number of bytes to write.
* \param bytesToRead Number of bytes to read.
*
* \retval true If transaction could be started.
* \retval false If transaction could not be started.
*/
bool TWI_MasterWriteRead(TWI_Master_t *twi,
uint8_t address,
uint8_t *writeData,
uint8_t bytesToWrite,
uint8_t bytesToRead)
{
/*Parameter sanity check. */
if (bytesToWrite & gt; TWIM_WRITE_BUFFER_SIZE) {
return false;
}
if (bytesToRead & gt; TWIM_READ_BUFFER_SIZE) {
return false;
}

/*Initiate transaction if bus is ready. */
if (twi- & gt; status == TWIM_STATUS_READY) {

twi- & gt; status = TWIM_STATUS_BUSY;
twi- & gt; result = TWIM_RESULT_UNKNOWN;

twi- & gt; address = address & lt; & lt; 1;

/* Fill write data buffer. */
for (uint8_t bufferIndex=0; bufferIndex & lt; bytesToWrite; bufferIndex++) {
twi- & gt; writeData[bufferIndex] = writeData[bufferIndex];
}

twi- & gt; bytesToWrite = bytesToWrite;
twi- & gt; bytesToRead = bytesToRead;
twi- & gt; bytesWritten = 0;
twi- & gt; bytesRead = 0;

/* If write command, send the START condition + Address +
* 'R/_W = 0'
*/
if (twi- & gt; bytesToWrite & gt; 0) {
uint8_t writeAddress = twi- & gt; address & ~0x01;
twi- & gt; interface- & gt; MASTER.ADDR = writeAddress;
}

/* If read command, send the START condition + Address +
* 'R/_W = 1'
*/
else if (twi- & gt; bytesToRead & gt; 0) {
uint8_t readAddress = twi- & gt; address | 0x01;
twi- & gt; interface- & gt; MASTER.ADDR = readAddress;
}
return true;
} else {
return false;
}
}


/*! \brief Common TWI master interrupt service routine.
*
* Check current status and calls the appropriate handler.
*
* \param twi The TWI_Master_t struct instance.
*/
void TWI_MasterInterruptHandler(TWI_Master_t *twi)
{
uint8_t currentStatus = twi- & gt; interface- & gt; MASTER.STATUS;

/* If arbitration lost or bus error. */
if ((currentStatus & TWI_MASTER_ARBLOST_bm) ||
(currentStatus & TWI_MASTER_BUSERR_bm)) {

TWI_MasterArbitrationLostBusErrorHandler(twi);
}

/* If master write interrupt. */
else if (currentStatus & TWI_MASTER_WIF_bm) {
TWI_MasterWriteHandler(twi);
}

/* If master read interrupt. */
else if (currentStatus & TWI_MASTER_RIF_bm) {
TWI_MasterReadHandler(twi);
}

/* If unexpected state. */
else {
TWI_MasterTransactionFinished(twi, TWIM_RESULT_FAIL);
}
}


/*! \brief TWI master arbitration lost and bus error interrupt handler.
*
* Handles TWI responses to lost arbitration and bus error.
*
* \param twi The TWI_Master_t struct instance.
*/
void TWI_MasterArbitrationLostBusErrorHandler(TWI_Master_t *twi)
{
uint8_t currentStatus = twi- & gt; interface- & gt; MASTER.STATUS;

/* If bus error. */
if (currentStatus & TWI_MASTER_BUSERR_bm) {
twi- & gt; result = TWIM_RESULT_BUS_ERROR;
}
/* If arbitration lost. */
else {
twi- & gt; result = TWIM_RESULT_ARBITRATION_LOST;
}

/* Clear interrupt flag. */
twi- & gt; interface- & gt; MASTER.STATUS = currentStatus | TWI_MASTER_ARBLOST_bm;

twi- & gt; status = TWIM_STATUS_READY;
}


/*! \brief TWI master write interrupt handler.
*
* Handles TWI transactions (master write) and responses to (N)ACK.
*
* \param twi The TWI_Master_t struct instance.
*/
void TWI_MasterWriteHandler(TWI_Master_t *twi)
{
/* Local variables used in if tests to avoid compiler warning. */
uint8_t bytesToWrite = twi- & gt; bytesToWrite;
uint8_t bytesToRead = twi- & gt; bytesToRead;

/* If NOT acknowledged (NACK) by slave cancel the transaction. */
if (twi- & gt; interface- & gt; MASTER.STATUS & TWI_MASTER_RXACK_bm) {
twi- & gt; interface- & gt; MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
twi- & gt; result = TWIM_RESULT_NACK_RECEIVED;
twi- & gt; status = TWIM_STATUS_READY;
}

/* If more bytes to write, send data. */
else if (twi- & gt; bytesWritten & lt; bytesToWrite) {
uint8_t data = twi- & gt; writeData[twi- & gt; bytesWritten];
twi- & gt; interface- & gt; MASTER.DATA = data;
++twi- & gt; bytesWritten;
}

/* If bytes to read, send repeated START condition + Address +
* 'R/_W = 1'
*/
else if (twi- & gt; bytesRead & lt; bytesToRead) {
uint8_t readAddress = twi- & gt; address | 0x01;
twi- & gt; interface- & gt; MASTER.ADDR = readAddress;
}

/* If transaction finished, send STOP condition and set RESULT OK. */
else {
twi- & gt; interface- & gt; MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK);
}
}


/*! \brief TWI master read interrupt handler.
*
* This is the master read interrupt handler that takes care of
* reading bytes from the TWI slave.
*
* \param twi The TWI_Master_t struct instance.
*/
void TWI_MasterReadHandler(TWI_Master_t *twi)
{
/* Fetch data if bytes to be read. */
if (twi- & gt; bytesRead & lt; TWIM_READ_BUFFER_SIZE) {
uint8_t data = twi- & gt; interface- & gt; MASTER.DATA;
twi- & gt; readData[twi- & gt; bytesRead] = data;
twi- & gt; bytesRead++;
}

/* If buffer overflow, issue STOP and BUFFER_OVERFLOW condition. */
else {
twi- & gt; interface- & gt; MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
TWI_MasterTransactionFinished(twi, TWIM_RESULT_BUFFER_OVERFLOW);
}

/* Local variable used in if test to avoid compiler warning. */
uint8_t bytesToRead = twi- & gt; bytesToRead;

/* If more bytes to read, issue ACK and start a byte read. */
if (twi- & gt; bytesRead & lt; bytesToRead) {
twi- & gt; interface- & gt; MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
}

/* If transaction finished, issue NACK and STOP condition. */
else {
twi- & gt; interface- & gt; MASTER.CTRLC = TWI_MASTER_ACKACT_bm |
TWI_MASTER_CMD_STOP_gc;
TWI_MasterTransactionFinished(twi, TWIM_RESULT_OK);
}
}


/*! \brief TWI transaction finished handler.
*
* Prepares module for new transaction.
*
* \param twi The TWI_Master_t struct instance.
* \param result The result of the operation.
*/
void TWI_MasterTransactionFinished(TWI_Master_t *twi, uint8_t result)
{
twi- & gt; result = result;
twi- & gt; status = TWIM_STATUS_READY;
}


TWI.rar > twi_example.c

/********************************************************************************************************
*********************************************************************************************************
*
* File : twi_example.c
* Hardware Environment: EVK XA1
* Build Environment : AVR Studio 4.18 sp1 + Winavr 20100110
* Version : V1.0
* By : Wu Ze
* DATE : 20100320
*
* (c) Copyright 2005-2010, WaveShare
* http://www.waveShare.net
* All Rights Reserved
*
*********************************************************************************************************
********************************************************************************************************/

#include " avr_compiler.h "
#include " twi_master_driver.h "
#include & lt; util/delay.h & gt;

#define FM24C_ADDR (0xA0 & gt; & gt; 1)

/*! Defining number of bytes in buffer. */
#define NUM_BYTES 8

/*! CPU speed 2MHz, BAUDRATE 100KHz and Baudrate Register Settings */
#define CPU_SPEED 2000000
#define BAUDRATE 100000
#define TWI_BAUDSETTING TWI_BAUD(CPU_SPEED, BAUDRATE)


/* Global variables */
TWI_Master_t twiMaster; /*! & lt; TWI master module. */

/*! Buffer with test data to send.*/
uint8_t sendBuffer[NUM_BYTES] = {0, //data address
1, 2, 3, 4, 5, 6, 7}; //data
uint8_t address=0;
/*! /brief Example code
*
* Example code that reads the key pressed and show a value from the buffer,
* sends the value to the slave and read back the processed value which will
* be inverted and displayed after key release.
*/
int main(void)
{

/* Initialize TWI master. */
TWI_MasterInit( & twiMaster,
& TWIF,
TWI_MASTER_INTLVL_LO_gc,
TWI_BAUDSETTING);


/* Enable LO interrupt level. */
PMIC.CTRL |= PMIC_LOLVLEN_bm;
sei();

TWI_MasterWriteRead( & twiMaster,
FM24C_ADDR,
sendBuffer,
NUM_BYTES,
0);

while (twiMaster.status != TWIM_STATUS_READY) {
/* Wait until transaction is complete. */
}


TWI_MasterWriteRead( & twiMaster,
FM24C_ADDR,
& address,
1,
7);
while (twiMaster.status != TWIM_STATUS_READY) {
/* Wait until transaction is complete. */
}

PORTC.DIR = 0xFF;
for(uint8_t n=0;n & lt; 7;n++)
{
PORTC.OUT = ~twiMaster.readData[n];
_delay_ms(1000);
}
while(1);
}

/*! TWIF Master Interrupt vector. */
ISR(TWIF_TWIM_vect)
{
TWI_MasterInterruptHandler( & twiMaster);
}


TWI.rar > avr_compiler.h

/* This file has been prepared for Doxygen automatic documentation generation.*/
/*! \file *********************************************************************
*
* \brief This file implements some macros that makes the IAR C-compiler and
* avr-gcc work with the same code base for the AVR architecture.
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* \author
* Atmel Corporation: http://www.atmel.com \n
* Support email: avr@atmel.com
*
* $Revision: 613 $
* $Date: 2006-04-07 14:40:07 +0200 (fr, 07 apr 2006) $ \n
*
* 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:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The name of ATMEL may not be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY ATMEL " AS IS " AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE EXPRESSLY AND
* SPECIFICALLY 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.
******************************************************************************/

#ifndef COMPILER_AVR_H
#define COMPILER_AVR_H

#ifndef F_CPU
/*! \brief Define default CPU frequency, if this is not already defined. */
#define F_CPU 2000000UL
#endif

#include & lt; stdint.h & gt;
#include & lt; stdbool.h & gt;
#include & lt; stdlib.h & gt;

/*! \brief This macro will protect the following code from interrupts. */
#define AVR_ENTER_CRITICAL_REGION( ) uint8_t volatile saved_sreg = SREG; \
cli();

/*! \brief This macro must always be used in conjunction with AVR_ENTER_CRITICAL_REGION
* so the interrupts are enabled again.
*/
#define AVR_LEAVE_CRITICAL_REGION( ) SREG = saved_sreg;

#if defined( __ICCAVR__ )

#include & lt; inavr.h & gt;
#include & lt; ioavr.h & gt;
#include & lt; intrinsics.h & gt;
#include & lt; pgmspace.h & gt;

#ifndef __HAS_ELPM__
#define _MEMATTR __flash
#else /* __HAS_ELPM__ */
#define _MEMATTR __farflash
#endif /* __HAS_ELPM__ */

/*! \brief Perform a delay of \c us microseconds.
*
* The macro F_CPU is supposed to be defined to a constant defining the CPU
* clock frequency (in Hertz).
*
* The maximal possible delay is 262.14 ms / F_CPU in MHz.
*
* \note For the IAR compiler, currently F_CPU must be a
* multiple of 1000000UL (1 MHz).
*/
#define delay_us( us ) ( __delay_cycles( ( F_CPU / 1000000UL ) * ( us ) ) )

/*! \brief Preprocessor magic.
*
* Some preprocessor magic to allow for a header file abstraction of
* interrupt service routine declarations for the IAR compiler. This
* requires the use of the C99 _Pragma() directive (rather than the
* old #pragma one that could not be used as a macro replacement), as
* well as two different levels of preprocessor concetanations in
* order to do both, assign the correct interrupt vector name, as well
* as construct a unique function name for the ISR.
*
* \note Do *NOT* try to reorder the macros below, as this will only
* work in the given order.
*/
#define PRAGMA(x) _Pragma( #x )
#define ISR(vec) PRAGMA( vector=vec ) __interrupt void handler_##vec(void)
#define sei( ) (__enable_interrupt( ))
#define cli( ) (__disable_interrupt( ))

/*! \brief Define the no operation macro. */
#define nop( ) (__no_operation())

/*! \brief Define the watchdog reset macro. */
#define watchdog_reset( ) (__watchdog_reset( ))


#define INLINE PRAGMA( inline=forced ) static

#define FLASH_DECLARE(x) _MEMATTR x
#define FLASH_STRING(x) ((_MEMATTR const char *)(x))
#define FLASH_STRING_T char const _MEMATTR *
#define FLASH_BYTE_ARRAY_T uint8_t const _MEMATTR *
#define PGM_READ_BYTE(x) *(x)
#define PGM_READ_WORD(x) *(x)

#define SHORTENUM /**/

#elif defined( __GNUC__ )

#include & lt; avr/io.h & gt;
#include & lt; avr/interrupt.h & gt;
#include & lt; avr/pgmspace.h & gt;
#include & lt; util/delay.h & gt;

/*! \brief Define the delay_us macro for GCC. */
#define delay_us( us ) (_delay_us( us ))

#define INLINE static inline

/*! \brief Define the no operation macro. */
#define nop() do { __asm__ __volatile__ ( " nop " ); } while (0)

#define MAIN_TASK_PROLOGUE int


#define MAIN_TASK_EPILOGUE() return -1;

#define SHORTENUM __attribute__ ((packed))

#else
#error Compiler not supported.
#endif

#endif