Fixed line endings and SVN props with fixup.sh script

This commit is contained in:
skarg
2016-09-08 15:56:11 +00:00
parent 27a3c1ff0f
commit 10aa414351
258 changed files with 93175 additions and 93175 deletions
@@ -1,333 +1,333 @@
/**
* \file
*
* \brief Standard board header file.
*
* This file includes the appropriate board header file according to the
* defined board (parameter BOARD).
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/**
* \defgroup group_common_boards Generic board support
*
* The generic board support module includes board-specific definitions
* and function prototypes, such as the board initialization function.
*
* \{
*/
#include "compiler.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*! \name Base Boards
*/
//! @{
#define EVK1100 1 //!< AT32UC3A EVK1100 board.
#define EVK1101 2 //!< AT32UC3B EVK1101 board.
#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board.
#define EVK1104 4 //!< AT32UC3A3 EVK1104 board.
#define EVK1105 5 //!< AT32UC3A EVK1105 board.
#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board.
#define UC3L_EK 7 //!< AT32UC3L-EK board.
#define XPLAIN 8 //!< ATxmega128A1 Xplain board.
#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board.
#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board.
#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board.
#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board.
#define STK600_RCUC3D 16 //!< STK600 RCUC3D board.
#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board.
#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board.
#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board.
#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board
#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board
#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board
#define STK600_RC044X 24 //!< STK600 with RC044X routing card board.
#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board.
#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board.
#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board.
#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board.
#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board.
#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards
#define RZ600 31 //!< AT32UC3A RZ600 MCU board
#define SAM3S_EK 32 //!< SAM3S-EK board.
#define SAM3U_EK 33 //!< SAM3U-EK board.
#define SAM3X_EK 34 //!< SAM3X-EK board.
#define SAM3N_EK 35 //!< SAM3N-EK board.
#define SAM3S_EK2 36 //!< SAM3S-EK2 board.
#define SAM4S_EK 37 //!< SAM4S-EK board.
#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board.
#define STK600_MEGA 39 //!< STK600 MEGA board.
#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board.
#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board.
#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board.
#define ARDUINO_DUE_X 43 //!< Arduino Due/X board.
#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board
#define SAM4L_EK 45 //!< SAM4L-EK board.
#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board.
#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board.
#define STK600_RC032X 48 //!< STK600 with RC032X routing card board.
#define SAM4S_EK2 49 //!< SAM4S-EK2 board.
#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board.
#define SAM4E_EK 51 //!< SAM4E-EK board.
#define ATMEGA256RFR2_XPLAINED_PRO 52 //!< ATmega256RFR2 Xplained Pro board.
#define SAM4S_XPLAINED_PRO 53 //!< SAM4S Xplained Pro board.
#define SAM4L_XPLAINED_PRO 54 //!< SAM4L Xplained Pro board.
#define ATMEGA256RFR2_ZIGBIT 55 //!< ATmega256RFR2 zigbit
#define XMEGA_RF233_ZIGBIT 56 //!< ATxmega256A3U with AT86RF233 zigbit
#define XMEGA_RF212B_ZIGBIT 57 //!< ATxmega256A3U with AT86RF212B zigbit
#define SAM4S_WPIR_RD 58 //!< SAM4S-WPIR-RD board.
#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices
#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family.
#define USER_BOARD 99 //!< User-reserved board (if any).
#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader)
//! @}
/*! \name Extension Boards
*/
//! @{
#define EXT1102 1 //!< AT32UC3B EXT1102 board
#define MC300 2 //!< AT32UC3 MC300 board
#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1
#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2
#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board
#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board
#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A"
#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600
#define RZ600_AT86RF230B 9 //!< AT86RF230B RF board in RZ600
#define RZ600_AT86RF212 10 //!< AT86RF212 RF board in RZ600
#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard
#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board
#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any).
//! @}
#if BOARD == EVK1100
# include "evk1100/evk1100.h"
#elif BOARD == EVK1101
# include "evk1101/evk1101.h"
#elif BOARD == UC3C_EK
# include "uc3c_ek/uc3c_ek.h"
#elif BOARD == EVK1104
# include "evk1104/evk1104.h"
#elif BOARD == EVK1105
# include "evk1105/evk1105.h"
#elif BOARD == STK600_RCUC3L0
# include "stk600/rcuc3l0/stk600_rcuc3l0.h"
#elif BOARD == UC3L_EK
# include "uc3l_ek/uc3l_ek.h"
#elif BOARD == STK600_RCUC3L4
# include "stk600/rcuc3l4/stk600_rcuc3l4.h"
#elif BOARD == XPLAIN
# include "xplain/xplain.h"
#elif BOARD == STK600_MEGA
/*No header-file to include */
#elif BOARD == STK600_MEGA_RF
# include "stk600.h"
#elif BOARD == ATMEGA256RFR2_XPLAINED_PRO
# include "atmega256rfr2_xplained_pro/atmega256rfr2_xplained_pro.h"
#elif BOARD == ATMEGA256RFR2_ZIGBIT
# include "atmega256rfr2_zigbit/atmega256rfr2_zigbit.h"
#elif BOARD == STK600_RC032X
# include "stk600/rc032x/stk600_rc032x.h"
#elif BOARD == STK600_RC044X
# include "stk600/rc044x/stk600_rc044x.h"
#elif BOARD == STK600_RC064X
# include "stk600/rc064x/stk600_rc064x.h"
#elif BOARD == STK600_RC100X
# include "stk600/rc100x/stk600_rc100x.h"
#elif BOARD == UC3_A3_XPLAINED
# include "uc3_a3_xplained/uc3_a3_xplained.h"
#elif BOARD == UC3_L0_XPLAINED
# include "uc3_l0_xplained/uc3_l0_xplained.h"
#elif BOARD == STK600_RCUC3B0
# include "stk600/rcuc3b0/stk600_rcuc3b0.h"
#elif BOARD == STK600_RCUC3D
# include "stk600/rcuc3d/stk600_rcuc3d.h"
#elif BOARD == STK600_RCUC3C0
# include "stk600/rcuc3c0/stk600_rcuc3c0.h"
#elif BOARD == XMEGA_B1_XPLAINED
# include "xmega_b1_xplained/xmega_b1_xplained.h"
#elif BOARD == STK600_RC064X_LCDX
# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h"
#elif BOARD == STK600_RC100X_LCDX
# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h"
#elif BOARD == XMEGA_A1_XPLAINED
# include "xmega_a1_xplained/xmega_a1_xplained.h"
#elif BOARD == UC3_L0_XPLAINED_BC
# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h"
#elif BOARD == SAM3S_EK
# include "sam3s_ek/sam3s_ek.h"
# include "system_sam3s.h"
#elif BOARD == SAM3S_EK2
# include "sam3s_ek2/sam3s_ek2.h"
# include "system_sam3sd8.h"
#elif BOARD == SAM3U_EK
# include "sam3u_ek/sam3u_ek.h"
# include "system_sam3u.h"
#elif BOARD == SAM3X_EK
# include "sam3x_ek/sam3x_ek.h"
# include "system_sam3x.h"
#elif BOARD == SAM3N_EK
# include "sam3n_ek/sam3n_ek.h"
# include "system_sam3n.h"
#elif BOARD == SAM4S_EK
# include "sam4s_ek/sam4s_ek.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_WPIR_RD
# include "sam4s_wpir_rd/sam4s_wpir_rd.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_XPLAINED
# include "sam4s_xplained/sam4s_xplained.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_EK2
# include "sam4s_ek2/sam4s_ek2.h"
# include "system_sam4s.h"
#elif BOARD == MEGA_1284P_XPLAINED
/*No header-file to include */
#elif BOARD == ARDUINO_DUE_X
# include "arduino_due_x/arduino_due_x.h"
# include "system_sam3x.h"
#elif BOARD == SAM4L_EK
# include "sam4l_ek/sam4l_ek.h"
#elif BOARD == SAM4E_EK
# include "sam4e_ek/sam4e_ek.h"
#elif BOARD == MEGA1284P_XPLAINED_BC
# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h"
#elif BOARD == UC3_L0_QT600
# include "uc3_l0_qt600/uc3_l0_qt600.h"
#elif BOARD == XMEGA_A3BU_XPLAINED
# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h"
#elif BOARD == XMEGA_E5_XPLAINED
# include "xmega_e5_xplained/xmega_e5_xplained.h"
#elif BOARD == UC3B_BOARD_CONTROLLER
# include "uc3b_board_controller/uc3b_board_controller.h"
#elif BOARD == RZ600
# include "rz600/rz600.h"
#elif BOARD == STK600_RCUC3A0
# include "stk600/rcuc3a0/stk600_rcuc3a0.h"
#elif BOARD == ATXMEGA128A1_QT600
# include "atxmega128a1_qt600/atxmega128a1_qt600.h"
#elif BOARD == STK600_RCUC3L3
# include "stk600/rcuc3l3/stk600_rcuc3l3.h"
#elif BOARD == SAM4S_XPLAINED_PRO
# include "sam4s_xplained_pro/sam4s_xplained_pro.h"
#elif BOARD == SAM4L_XPLAINED_PRO
# include "sam4l_xplained_pro/sam4l_xplained_pro.h"
#elif BOARD == SIMULATOR_XMEGA_A1
# include "simulator/xmega_a1/simulator_xmega_a1.h"
#elif BOARD == XMEGA_C3_XPLAINED
# include "xmega_c3_xplained/xmega_c3_xplained.h"
#elif BOARD == XMEGA_RF233_ZIGBIT
# include "xmega_rf233_zigbit/xmega_rf233_zigbit.h"
#elif BOARD == XMEGA_RF212B_ZIGBIT
# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h"
#elif BOARD == AVR_SIMULATOR_UC3
# include "avr_simulator_uc3/avr_simulator_uc3.h"
#elif BOARD == USER_BOARD
// User-reserved area: #include the header file of your board here (if any).
# include "user_board.h"
#elif BOARD == DUMMY_BOARD
# include "dummy/dummy_board.h"
#else
//# error No known Atmel board defined
#endif
#if (defined EXT_BOARD)
# if EXT_BOARD == MC300
# include "mc300/mc300.h"
# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \
(EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \
(EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \
(EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
# include "sensors_xplained/sensors_xplained.h"
# elif EXT_BOARD == RZ600_AT86RF231
# include "at86rf231/at86rf231.h"
# elif EXT_BOARD == RZ600_AT86RF230B
# include "at86rf230b/at86rf230b.h"
# elif EXT_BOARD == RZ600_AT86RF212
# include "at86rf212/at86rf212.h"
# elif EXT_BOARD == SECURITY_XPLAINED
# include "security_xplained.h"
# elif EXT_BOARD == USER_EXT_BOARD
// User-reserved area: #include the header file of your extension board here
// (if any).
# endif
#endif
#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__))
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
/*! \brief This function initializes the board target resources
*
* This function should be called to ensure proper initialization of the target
* board hardware connected to the part.
*/
extern void board_init (void);
#endif // #ifdef __AVR32_ABI_COMPILER__
#else
/*! \brief This function initializes the board target resources
*
* This function should be called to ensure proper initialization of the target
* board hardware connected to the part.
*/
extern void board_init (void);
#endif
#ifdef __cplusplus
}
#endif
/**
* \}
*/
#endif // _BOARD_H_
/**
* \file
*
* \brief Standard board header file.
*
* This file includes the appropriate board header file according to the
* defined board (parameter BOARD).
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _BOARD_H_
#define _BOARD_H_
/**
* \defgroup group_common_boards Generic board support
*
* The generic board support module includes board-specific definitions
* and function prototypes, such as the board initialization function.
*
* \{
*/
#include "compiler.h"
#ifdef __cplusplus
extern "C"
{
#endif
/*! \name Base Boards
*/
//! @{
#define EVK1100 1 //!< AT32UC3A EVK1100 board.
#define EVK1101 2 //!< AT32UC3B EVK1101 board.
#define UC3C_EK 3 //!< AT32UC3C UC3C_EK board.
#define EVK1104 4 //!< AT32UC3A3 EVK1104 board.
#define EVK1105 5 //!< AT32UC3A EVK1105 board.
#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board.
#define UC3L_EK 7 //!< AT32UC3L-EK board.
#define XPLAIN 8 //!< ATxmega128A1 Xplain board.
#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board.
#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board.
#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board.
#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board.
#define STK600_RCUC3D 16 //!< STK600 RCUC3D board.
#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board.
#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board.
#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board.
#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board
#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board
#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board
#define STK600_RC044X 24 //!< STK600 with RC044X routing card board.
#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board.
#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board.
#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board.
#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board.
#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board.
#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards
#define RZ600 31 //!< AT32UC3A RZ600 MCU board
#define SAM3S_EK 32 //!< SAM3S-EK board.
#define SAM3U_EK 33 //!< SAM3U-EK board.
#define SAM3X_EK 34 //!< SAM3X-EK board.
#define SAM3N_EK 35 //!< SAM3N-EK board.
#define SAM3S_EK2 36 //!< SAM3S-EK2 board.
#define SAM4S_EK 37 //!< SAM4S-EK board.
#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board.
#define STK600_MEGA 39 //!< STK600 MEGA board.
#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board.
#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board.
#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board.
#define ARDUINO_DUE_X 43 //!< Arduino Due/X board.
#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board
#define SAM4L_EK 45 //!< SAM4L-EK board.
#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board.
#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board.
#define STK600_RC032X 48 //!< STK600 with RC032X routing card board.
#define SAM4S_EK2 49 //!< SAM4S-EK2 board.
#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board.
#define SAM4E_EK 51 //!< SAM4E-EK board.
#define ATMEGA256RFR2_XPLAINED_PRO 52 //!< ATmega256RFR2 Xplained Pro board.
#define SAM4S_XPLAINED_PRO 53 //!< SAM4S Xplained Pro board.
#define SAM4L_XPLAINED_PRO 54 //!< SAM4L Xplained Pro board.
#define ATMEGA256RFR2_ZIGBIT 55 //!< ATmega256RFR2 zigbit
#define XMEGA_RF233_ZIGBIT 56 //!< ATxmega256A3U with AT86RF233 zigbit
#define XMEGA_RF212B_ZIGBIT 57 //!< ATxmega256A3U with AT86RF212B zigbit
#define SAM4S_WPIR_RD 58 //!< SAM4S-WPIR-RD board.
#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices
#define AVR_SIMULATOR_UC3 98 //!< AVR SIMULATOR for AVR UC3 device family.
#define USER_BOARD 99 //!< User-reserved board (if any).
#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader)
//! @}
/*! \name Extension Boards
*/
//! @{
#define EXT1102 1 //!< AT32UC3B EXT1102 board
#define MC300 2 //!< AT32UC3 MC300 board
#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1
#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2
#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board
#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board
#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A"
#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600
#define RZ600_AT86RF230B 9 //!< AT86RF230B RF board in RZ600
#define RZ600_AT86RF212 10 //!< AT86RF212 RF board in RZ600
#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard
#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board
#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any).
//! @}
#if BOARD == EVK1100
# include "evk1100/evk1100.h"
#elif BOARD == EVK1101
# include "evk1101/evk1101.h"
#elif BOARD == UC3C_EK
# include "uc3c_ek/uc3c_ek.h"
#elif BOARD == EVK1104
# include "evk1104/evk1104.h"
#elif BOARD == EVK1105
# include "evk1105/evk1105.h"
#elif BOARD == STK600_RCUC3L0
# include "stk600/rcuc3l0/stk600_rcuc3l0.h"
#elif BOARD == UC3L_EK
# include "uc3l_ek/uc3l_ek.h"
#elif BOARD == STK600_RCUC3L4
# include "stk600/rcuc3l4/stk600_rcuc3l4.h"
#elif BOARD == XPLAIN
# include "xplain/xplain.h"
#elif BOARD == STK600_MEGA
/*No header-file to include */
#elif BOARD == STK600_MEGA_RF
# include "stk600.h"
#elif BOARD == ATMEGA256RFR2_XPLAINED_PRO
# include "atmega256rfr2_xplained_pro/atmega256rfr2_xplained_pro.h"
#elif BOARD == ATMEGA256RFR2_ZIGBIT
# include "atmega256rfr2_zigbit/atmega256rfr2_zigbit.h"
#elif BOARD == STK600_RC032X
# include "stk600/rc032x/stk600_rc032x.h"
#elif BOARD == STK600_RC044X
# include "stk600/rc044x/stk600_rc044x.h"
#elif BOARD == STK600_RC064X
# include "stk600/rc064x/stk600_rc064x.h"
#elif BOARD == STK600_RC100X
# include "stk600/rc100x/stk600_rc100x.h"
#elif BOARD == UC3_A3_XPLAINED
# include "uc3_a3_xplained/uc3_a3_xplained.h"
#elif BOARD == UC3_L0_XPLAINED
# include "uc3_l0_xplained/uc3_l0_xplained.h"
#elif BOARD == STK600_RCUC3B0
# include "stk600/rcuc3b0/stk600_rcuc3b0.h"
#elif BOARD == STK600_RCUC3D
# include "stk600/rcuc3d/stk600_rcuc3d.h"
#elif BOARD == STK600_RCUC3C0
# include "stk600/rcuc3c0/stk600_rcuc3c0.h"
#elif BOARD == XMEGA_B1_XPLAINED
# include "xmega_b1_xplained/xmega_b1_xplained.h"
#elif BOARD == STK600_RC064X_LCDX
# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h"
#elif BOARD == STK600_RC100X_LCDX
# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h"
#elif BOARD == XMEGA_A1_XPLAINED
# include "xmega_a1_xplained/xmega_a1_xplained.h"
#elif BOARD == UC3_L0_XPLAINED_BC
# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h"
#elif BOARD == SAM3S_EK
# include "sam3s_ek/sam3s_ek.h"
# include "system_sam3s.h"
#elif BOARD == SAM3S_EK2
# include "sam3s_ek2/sam3s_ek2.h"
# include "system_sam3sd8.h"
#elif BOARD == SAM3U_EK
# include "sam3u_ek/sam3u_ek.h"
# include "system_sam3u.h"
#elif BOARD == SAM3X_EK
# include "sam3x_ek/sam3x_ek.h"
# include "system_sam3x.h"
#elif BOARD == SAM3N_EK
# include "sam3n_ek/sam3n_ek.h"
# include "system_sam3n.h"
#elif BOARD == SAM4S_EK
# include "sam4s_ek/sam4s_ek.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_WPIR_RD
# include "sam4s_wpir_rd/sam4s_wpir_rd.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_XPLAINED
# include "sam4s_xplained/sam4s_xplained.h"
# include "system_sam4s.h"
#elif BOARD == SAM4S_EK2
# include "sam4s_ek2/sam4s_ek2.h"
# include "system_sam4s.h"
#elif BOARD == MEGA_1284P_XPLAINED
/*No header-file to include */
#elif BOARD == ARDUINO_DUE_X
# include "arduino_due_x/arduino_due_x.h"
# include "system_sam3x.h"
#elif BOARD == SAM4L_EK
# include "sam4l_ek/sam4l_ek.h"
#elif BOARD == SAM4E_EK
# include "sam4e_ek/sam4e_ek.h"
#elif BOARD == MEGA1284P_XPLAINED_BC
# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h"
#elif BOARD == UC3_L0_QT600
# include "uc3_l0_qt600/uc3_l0_qt600.h"
#elif BOARD == XMEGA_A3BU_XPLAINED
# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h"
#elif BOARD == XMEGA_E5_XPLAINED
# include "xmega_e5_xplained/xmega_e5_xplained.h"
#elif BOARD == UC3B_BOARD_CONTROLLER
# include "uc3b_board_controller/uc3b_board_controller.h"
#elif BOARD == RZ600
# include "rz600/rz600.h"
#elif BOARD == STK600_RCUC3A0
# include "stk600/rcuc3a0/stk600_rcuc3a0.h"
#elif BOARD == ATXMEGA128A1_QT600
# include "atxmega128a1_qt600/atxmega128a1_qt600.h"
#elif BOARD == STK600_RCUC3L3
# include "stk600/rcuc3l3/stk600_rcuc3l3.h"
#elif BOARD == SAM4S_XPLAINED_PRO
# include "sam4s_xplained_pro/sam4s_xplained_pro.h"
#elif BOARD == SAM4L_XPLAINED_PRO
# include "sam4l_xplained_pro/sam4l_xplained_pro.h"
#elif BOARD == SIMULATOR_XMEGA_A1
# include "simulator/xmega_a1/simulator_xmega_a1.h"
#elif BOARD == XMEGA_C3_XPLAINED
# include "xmega_c3_xplained/xmega_c3_xplained.h"
#elif BOARD == XMEGA_RF233_ZIGBIT
# include "xmega_rf233_zigbit/xmega_rf233_zigbit.h"
#elif BOARD == XMEGA_RF212B_ZIGBIT
# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h"
#elif BOARD == AVR_SIMULATOR_UC3
# include "avr_simulator_uc3/avr_simulator_uc3.h"
#elif BOARD == USER_BOARD
// User-reserved area: #include the header file of your board here (if any).
# include "user_board.h"
#elif BOARD == DUMMY_BOARD
# include "dummy/dummy_board.h"
#else
//# error No known Atmel board defined
#endif
#if (defined EXT_BOARD)
# if EXT_BOARD == MC300
# include "mc300/mc300.h"
# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \
(EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \
(EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \
(EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \
(EXT_BOARD == SENSORS_XPLAINED_BREADBOARD)
# include "sensors_xplained/sensors_xplained.h"
# elif EXT_BOARD == RZ600_AT86RF231
# include "at86rf231/at86rf231.h"
# elif EXT_BOARD == RZ600_AT86RF230B
# include "at86rf230b/at86rf230b.h"
# elif EXT_BOARD == RZ600_AT86RF212
# include "at86rf212/at86rf212.h"
# elif EXT_BOARD == SECURITY_XPLAINED
# include "security_xplained.h"
# elif EXT_BOARD == USER_EXT_BOARD
// User-reserved area: #include the header file of your extension board here
// (if any).
# endif
#endif
#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__))
#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling.
/*! \brief This function initializes the board target resources
*
* This function should be called to ensure proper initialization of the target
* board hardware connected to the part.
*/
extern void board_init (void);
#endif // #ifdef __AVR32_ABI_COMPILER__
#else
/*! \brief This function initializes the board target resources
*
* This function should be called to ensure proper initialization of the target
* board hardware connected to the part.
*/
extern void board_init (void);
#endif
#ifdef __cplusplus
}
#endif
/**
* \}
*/
#endif // _BOARD_H_
@@ -1,318 +1,318 @@
/**
* \file
*
* \brief Non volatile memories management
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef COMMON_NVM_H_INCLUDED
#define COMMON_NVM_H_INCLUDED
#include "compiler.h"
#include "conf_board.h"
#include "parts.h"
#include "status_codes.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
#include "at45dbx.h"
#endif
/* ! \name Non volatile memory types */
/* ! @{ */
typedef enum {
INT_FLASH /* !< Internal Flash */
#if (XMEGA || UC3 || SAM4S)
, INT_USERPAGE /* !< Userpage/User signature */
#endif
#if XMEGA
, INT_EEPROM /* !< Internal EEPROM */
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
, AT45DBX /* !< External AT45DBX dataflash */
#endif
} mem_type_t;
/* ! @} */
#if SAM
# ifndef IFLASH_PAGE_SIZE
# define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
# endif
# ifndef IFLASH_ADDR
# define IFLASH_ADDR IFLASH0_ADDR
# endif
#endif
/**
* \defgroup nvm_group NVM service
*
* See \ref common_nvm_quickstart.
*
* This is the common API for non volatile memories. Additional features are
* available
* in the documentation of the specific modules.
*
*/
/**
* \brief Initialize the non volatile memory specified.
*
* \param mem Type of non volatile memory to initialize
*/
status_code_t nvm_init(mem_type_t mem);
/**
* \brief Read single byte of data.
*
* \param mem Type of non volatile memory to read
* \param address Address to read
* \param data Pointer to where to store the read data
*/
status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data);
/**
* \brief Write single byte of data.
*
* \param mem Type of non volatile memory to write
* \param address Address to write
* \param data Data to be written
*/
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data);
/**
* \brief Read \a len number of bytes from address \a address in non volatile
* memory \a mem and store it in the buffer \a buffer
*
* \param mem Type of non volatile memory to read
* \param address Address to read
* \param buffer Pointer to destination buffer
* \param len Number of bytes to read
*/
status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len);
/**
* \brief Write \a len number of bytes at address \a address in non volatile
* memory \a mem from the buffer \a buffer
*
* \param mem Type of non volatile memory to write
* \param address Address to write
* \param buffer Pointer to source buffer
* \param len Number of bytes to write
*/
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len);
/**
* \brief Erase a page in the non volatile memory.
*
* \param mem Type of non volatile memory to erase
* \param page_number Page number to erase
*/
status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number);
/**
* \brief Get the size of whole non volatile memory specified.
*
* \param mem Type of non volatile memory
* \param size Pointer to where to store the size
*/
status_code_t nvm_get_size(mem_type_t mem, uint32_t *size);
/**
* \brief Get the size of a page in the non volatile memory specified.
*
* \param mem Type of non volatile memory
* \param size Pointer to where to store the size
*/
status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size);
/**
* \brief Get the page number from the byte address \a address.
*
* \param mem Type of non volatile memory
* \param address Byte address of the non volatile memory
* \param num Pointer to where to store the page number
*/
status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
uint32_t *num);
/**
* \brief Enable security bit which blocks external read and write access
* to the device.
*
*/
status_code_t nvm_set_security_bit(void);
/**
* \page common_nvm_quickstart Quick Start quide for common NVM driver
*
* This is the quick start quide for the \ref nvm_group "Common NVM driver",
* with step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section nvm_basic_use_case Basic use case
* In this basic use case, NVM driver is configured for Internal Flash
*
* \section nvm_basic_use_case_setup Setup steps
*
* \subsection nvm_basic_use_case_setup_code Example code
* Add to you application C-file:
* \code
* if(nvm_init(INT_FLASH) == STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_setup_flow Workflow
* -# Ensure that board_init() has configured selected I/Os for TWI function
* when using external AT45DBX dataflash
* -# Ensure that \ref conf_nvm.h is present for the driver.
* - \note This file is only for the driver and should not be included by the
* user.
* -# Call nvm_init \code nvm_init(INT_FLASH); \endcode
* and optionally check its return code
*
* \section nvm_basic_use_case_usage Usage steps
* \subsection nvm_basic_use_case_usage_code_writing Example code: Writing to
* non volatile memory
* Use in the application C-file:
* \code
* uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
*
* if(nvm_write(INT_FLASH, test_address, (void *)buffer, sizeof(buffer)) ==
* STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare the data you want to send to the non volatile memory
* \code uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; \endcode
* -# Call nvm_write \code nvm_write(INT_FLASH, test_address, (void *)buffer,
* sizeof(buffer)) \endcode
* and optionally check its return value for STATUS_OK.
*
* \subsection nvm_basic_use_case_usage_code_reading Example code: Reading from
* non volatile memory
* Use in application C-file:
* \code
* uint8_t data_read[8];
*
* if(nvm_read(INT_FLASH, test_address, (void *)data_read, sizeof(data_read))
* == STATUS_OK) {
* //Check read content
* if(data_read[0] == 0xAA)
* do_something();
* }
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare a data buffer that will read data from non volatile memory
* \code uint8_t data_read[8]; \endcode
* -# Call nvm_read \code nvm_read(INT_FLASH, test_address, (void *)data_read,
* sizeof(data_read)); \endcode
* and optionally check its return value for STATUS_OK.
* The data read from the non volatile memory are in data_read.
*
* \subsection nvm_basic_use_case_usage_code_erasing Example code: Erasing a
* page of non volatile memory
* Use in the application C-file:
* \code
* if(nvm_page_erase(INT_FLASH, test_page) == STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Call nvm_page_erase \code nvm_page_erase(INT_FLASH, test_page) \endcode
* and optionally check its return value for STATUS_OK.
*
* \subsection nvm_basic_use_case_usage_code_config Example code: Reading
*configuration of non volatile memory
* Use in application C-file:
* \code
* uint8_t mem_size, page_size, page_num;
*
* nvm_get_size(INT_FLASH, &mem_size);
* nvm_get_page_size(INT_FLASH, &page_size);
* nvm_get_pagenumber(INT_FLASH, test_address, &page_num);
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare a buffer to store configuration of non volatile memory
* \code uint8_t mem_size, page_size, page_num; \endcode
* -# Call nvm_get_size \code nvm_get_size(INT_FLASH, &mem_size); \endcode
* and optionally check its return value for STATUS_OK.
* The memory size of the non volatile memory is in mem_size.
* -# Call nvm_get_page_size \code nvm_get_page_size(INT_FLASH, &page_size);
* \endcode
* and optionally check its return value for STATUS_OK.
* The page size of the non volatile memory is in page_size.
* -# Call nvm_get_pagenumber \code nvm_get_page_number(INT_FLASH, test_address,
* &page_num); \endcode
* and optionally check its return value for STATUS_OK.
* The page number of given address in the non volatile memory is in page_num.
*
* \subsection nvm_basic_use_case_usage_code_locking Example code: Enabling
* security bit
* Use in the application C-file:
* \code
* if(nvm_set_security_bit() == STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Call nvm_set_security_bit \code nvm_set_security_bit() \endcode
* and optionally check its return value for STATUS_OK.
*/
#ifdef __cplusplus
}
#endif
#endif /* COMMON_NVM_H_INCLUDED */
/**
* \file
*
* \brief Non volatile memories management
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef COMMON_NVM_H_INCLUDED
#define COMMON_NVM_H_INCLUDED
#include "compiler.h"
#include "conf_board.h"
#include "parts.h"
#include "status_codes.h"
#ifdef __cplusplus
extern "C" {
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
#include "at45dbx.h"
#endif
/* ! \name Non volatile memory types */
/* ! @{ */
typedef enum {
INT_FLASH /* !< Internal Flash */
#if (XMEGA || UC3 || SAM4S)
, INT_USERPAGE /* !< Userpage/User signature */
#endif
#if XMEGA
, INT_EEPROM /* !< Internal EEPROM */
#endif
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
, AT45DBX /* !< External AT45DBX dataflash */
#endif
} mem_type_t;
/* ! @} */
#if SAM
# ifndef IFLASH_PAGE_SIZE
# define IFLASH_PAGE_SIZE IFLASH0_PAGE_SIZE
# endif
# ifndef IFLASH_ADDR
# define IFLASH_ADDR IFLASH0_ADDR
# endif
#endif
/**
* \defgroup nvm_group NVM service
*
* See \ref common_nvm_quickstart.
*
* This is the common API for non volatile memories. Additional features are
* available
* in the documentation of the specific modules.
*
*/
/**
* \brief Initialize the non volatile memory specified.
*
* \param mem Type of non volatile memory to initialize
*/
status_code_t nvm_init(mem_type_t mem);
/**
* \brief Read single byte of data.
*
* \param mem Type of non volatile memory to read
* \param address Address to read
* \param data Pointer to where to store the read data
*/
status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data);
/**
* \brief Write single byte of data.
*
* \param mem Type of non volatile memory to write
* \param address Address to write
* \param data Data to be written
*/
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data);
/**
* \brief Read \a len number of bytes from address \a address in non volatile
* memory \a mem and store it in the buffer \a buffer
*
* \param mem Type of non volatile memory to read
* \param address Address to read
* \param buffer Pointer to destination buffer
* \param len Number of bytes to read
*/
status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len);
/**
* \brief Write \a len number of bytes at address \a address in non volatile
* memory \a mem from the buffer \a buffer
*
* \param mem Type of non volatile memory to write
* \param address Address to write
* \param buffer Pointer to source buffer
* \param len Number of bytes to write
*/
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len);
/**
* \brief Erase a page in the non volatile memory.
*
* \param mem Type of non volatile memory to erase
* \param page_number Page number to erase
*/
status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number);
/**
* \brief Get the size of whole non volatile memory specified.
*
* \param mem Type of non volatile memory
* \param size Pointer to where to store the size
*/
status_code_t nvm_get_size(mem_type_t mem, uint32_t *size);
/**
* \brief Get the size of a page in the non volatile memory specified.
*
* \param mem Type of non volatile memory
* \param size Pointer to where to store the size
*/
status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size);
/**
* \brief Get the page number from the byte address \a address.
*
* \param mem Type of non volatile memory
* \param address Byte address of the non volatile memory
* \param num Pointer to where to store the page number
*/
status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
uint32_t *num);
/**
* \brief Enable security bit which blocks external read and write access
* to the device.
*
*/
status_code_t nvm_set_security_bit(void);
/**
* \page common_nvm_quickstart Quick Start quide for common NVM driver
*
* This is the quick start quide for the \ref nvm_group "Common NVM driver",
* with step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section nvm_basic_use_case Basic use case
* In this basic use case, NVM driver is configured for Internal Flash
*
* \section nvm_basic_use_case_setup Setup steps
*
* \subsection nvm_basic_use_case_setup_code Example code
* Add to you application C-file:
* \code
* if(nvm_init(INT_FLASH) == STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_setup_flow Workflow
* -# Ensure that board_init() has configured selected I/Os for TWI function
* when using external AT45DBX dataflash
* -# Ensure that \ref conf_nvm.h is present for the driver.
* - \note This file is only for the driver and should not be included by the
* user.
* -# Call nvm_init \code nvm_init(INT_FLASH); \endcode
* and optionally check its return code
*
* \section nvm_basic_use_case_usage Usage steps
* \subsection nvm_basic_use_case_usage_code_writing Example code: Writing to
* non volatile memory
* Use in the application C-file:
* \code
* uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE};
*
* if(nvm_write(INT_FLASH, test_address, (void *)buffer, sizeof(buffer)) ==
* STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare the data you want to send to the non volatile memory
* \code uint8_t buffer[] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE}; \endcode
* -# Call nvm_write \code nvm_write(INT_FLASH, test_address, (void *)buffer,
* sizeof(buffer)) \endcode
* and optionally check its return value for STATUS_OK.
*
* \subsection nvm_basic_use_case_usage_code_reading Example code: Reading from
* non volatile memory
* Use in application C-file:
* \code
* uint8_t data_read[8];
*
* if(nvm_read(INT_FLASH, test_address, (void *)data_read, sizeof(data_read))
* == STATUS_OK) {
* //Check read content
* if(data_read[0] == 0xAA)
* do_something();
* }
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare a data buffer that will read data from non volatile memory
* \code uint8_t data_read[8]; \endcode
* -# Call nvm_read \code nvm_read(INT_FLASH, test_address, (void *)data_read,
* sizeof(data_read)); \endcode
* and optionally check its return value for STATUS_OK.
* The data read from the non volatile memory are in data_read.
*
* \subsection nvm_basic_use_case_usage_code_erasing Example code: Erasing a
* page of non volatile memory
* Use in the application C-file:
* \code
* if(nvm_page_erase(INT_FLASH, test_page) == STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Call nvm_page_erase \code nvm_page_erase(INT_FLASH, test_page) \endcode
* and optionally check its return value for STATUS_OK.
*
* \subsection nvm_basic_use_case_usage_code_config Example code: Reading
*configuration of non volatile memory
* Use in application C-file:
* \code
* uint8_t mem_size, page_size, page_num;
*
* nvm_get_size(INT_FLASH, &mem_size);
* nvm_get_page_size(INT_FLASH, &page_size);
* nvm_get_pagenumber(INT_FLASH, test_address, &page_num);
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Prepare a buffer to store configuration of non volatile memory
* \code uint8_t mem_size, page_size, page_num; \endcode
* -# Call nvm_get_size \code nvm_get_size(INT_FLASH, &mem_size); \endcode
* and optionally check its return value for STATUS_OK.
* The memory size of the non volatile memory is in mem_size.
* -# Call nvm_get_page_size \code nvm_get_page_size(INT_FLASH, &page_size);
* \endcode
* and optionally check its return value for STATUS_OK.
* The page size of the non volatile memory is in page_size.
* -# Call nvm_get_pagenumber \code nvm_get_page_number(INT_FLASH, test_address,
* &page_num); \endcode
* and optionally check its return value for STATUS_OK.
* The page number of given address in the non volatile memory is in page_num.
*
* \subsection nvm_basic_use_case_usage_code_locking Example code: Enabling
* security bit
* Use in the application C-file:
* \code
* if(nvm_set_security_bit() == STATUS_OK)
* do_something();
* \endcode
*
* \subsection nvm_basic_use_case_usage_flow Workflow
* -# Call nvm_set_security_bit \code nvm_set_security_bit() \endcode
* and optionally check its return value for STATUS_OK.
*/
#ifdef __cplusplus
}
#endif
#endif /* COMMON_NVM_H_INCLUDED */
@@ -1,331 +1,331 @@
/**
* \file
*
* \brief Non volatile memories management for XMEGA devices
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "common_nvm.h"
#include "conf_nvm.h"
#include "nvm.h"
status_code_t nvm_init(mem_type_t mem)
{
switch (mem) {
case INT_FLASH:
case INT_USERPAGE:
case INT_EEPROM:
/* No initialization required for internal memory */
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
/* Initialize dataflash */
at45dbx_init();
/* Perform memory check */
if (!at45dbx_mem_check()) {
return ERR_NO_MEMORY;
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data)
{
switch (mem) {
case INT_FLASH:
*data = nvm_flash_read_byte((flash_addr_t)address);
break;
case INT_USERPAGE:
nvm_user_sig_read_buffer((flash_addr_t)address, (void *)data,
1);
break;
case INT_EEPROM:
*data = nvm_eeprom_read_byte((eeprom_addr_t)address);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
if (!at45dbx_read_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
*data = at45dbx_read_byte();
at45dbx_read_close();
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data)
{
switch (mem) {
case INT_FLASH:
nvm_flash_erase_and_write_buffer((flash_addr_t)address,
(const void *)&data, 1, true);
break;
case INT_USERPAGE:
nvm_user_sig_write_buffer((flash_addr_t)address,
(const void *)&data, 1, true);
break;
case INT_EEPROM:
nvm_eeprom_write_byte((eeprom_addr_t)address, data);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
if (!at45dbx_write_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
at45dbx_write_byte(data);
at45dbx_write_close();
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len)
{
switch (mem) {
case INT_FLASH:
nvm_flash_read_buffer((flash_addr_t)address, buffer,
(uint16_t)len);
break;
case INT_USERPAGE:
nvm_user_sig_read_buffer((flash_addr_t)address, buffer,
(uint16_t)len);
break;
case INT_EEPROM:
nvm_eeprom_read_buffer((eeprom_addr_t)address, buffer,
(uint16_t)len);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
{
uint32_t sector = address / AT45DBX_SECTOR_SIZE;
if (!at45dbx_read_sector_open(sector)) {
return ERR_BAD_ADDRESS;
}
at45dbx_read_sector_to_ram(buffer);
at45dbx_read_close();
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len)
{
switch (mem) {
case INT_FLASH:
nvm_flash_erase_and_write_buffer((flash_addr_t)address,
(const void *)buffer, len, true);
break;
case INT_USERPAGE:
nvm_user_sig_write_buffer((flash_addr_t)address,
(const void *)buffer, len, true);
break;
case INT_EEPROM:
nvm_eeprom_erase_and_write_buffer((eeprom_addr_t)address,
(const void *)buffer, len);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
{
uint32_t sector = address / AT45DBX_SECTOR_SIZE;
if (!at45dbx_write_sector_open(sector)) {
return ERR_BAD_ADDRESS;
}
at45dbx_write_sector_from_ram((const void *)buffer);
at45dbx_write_close();
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number)
{
switch (mem) {
case INT_FLASH:
if ((page_number >= 0) &&
(page_number <
(BOOT_SECTION_START / FLASH_PAGE_SIZE))) {
nvm_flash_erase_app_page((flash_addr_t)(page_number *
FLASH_PAGE_SIZE));
} else if ((page_number >= 0) &&
(page_number <
(BOOT_SECTION_END / FLASH_PAGE_SIZE))) {
nvm_flash_erase_boot_page((flash_addr_t)(page_number *
FLASH_PAGE_SIZE));
} else {
return ERR_INVALID_ARG;
}
break;
case INT_USERPAGE:
nvm_flash_erase_user_section();
break;
case INT_EEPROM:
nvm_eeprom_erase_page((uint8_t)page_number);
break;
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_size(mem_type_t mem, uint32_t *size)
{
switch (mem) {
case INT_FLASH:
*size = (uint32_t)FLASH_SIZE;
break;
case INT_USERPAGE:
*size = (uint32_t)FLASH_PAGE_SIZE;
break;
case INT_EEPROM:
*size = (uint32_t)EEPROM_SIZE;
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
*size = (uint32_t)AT45DBX_MEM_SIZE;
break;
#endif
default:
/* Other memories not supported */
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size)
{
switch (mem) {
case INT_FLASH:
case INT_USERPAGE:
*size = (uint32_t)FLASH_PAGE_SIZE;
break;
case INT_EEPROM:
*size = (uint32_t)EEPROM_PAGE_SIZE;
break;
default:
/* Other memories not supported */
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
uint32_t *num)
{
switch (mem) {
case INT_FLASH:
*num = (uint32_t)(address / FLASH_PAGE_SIZE);
break;
case INT_EEPROM:
*num = (uint32_t)(address / EEPROM_PAGE_SIZE);
break;
default:
/* Other memories not supported */
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_set_security_bit(void)
{
/* Block external programming access to the device */
nvm_lb_lock_bits_write(NVM_LB_RWLOCK_gc);
return STATUS_OK;
}
/**
* \file
*
* \brief Non volatile memories management for XMEGA devices
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "common_nvm.h"
#include "conf_nvm.h"
#include "nvm.h"
status_code_t nvm_init(mem_type_t mem)
{
switch (mem) {
case INT_FLASH:
case INT_USERPAGE:
case INT_EEPROM:
/* No initialization required for internal memory */
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
/* Initialize dataflash */
at45dbx_init();
/* Perform memory check */
if (!at45dbx_mem_check()) {
return ERR_NO_MEMORY;
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_read_char(mem_type_t mem, uint32_t address, uint8_t *data)
{
switch (mem) {
case INT_FLASH:
*data = nvm_flash_read_byte((flash_addr_t)address);
break;
case INT_USERPAGE:
nvm_user_sig_read_buffer((flash_addr_t)address, (void *)data,
1);
break;
case INT_EEPROM:
*data = nvm_eeprom_read_byte((eeprom_addr_t)address);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
if (!at45dbx_read_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
*data = at45dbx_read_byte();
at45dbx_read_close();
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_write_char(mem_type_t mem, uint32_t address, uint8_t data)
{
switch (mem) {
case INT_FLASH:
nvm_flash_erase_and_write_buffer((flash_addr_t)address,
(const void *)&data, 1, true);
break;
case INT_USERPAGE:
nvm_user_sig_write_buffer((flash_addr_t)address,
(const void *)&data, 1, true);
break;
case INT_EEPROM:
nvm_eeprom_write_byte((eeprom_addr_t)address, data);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
if (!at45dbx_write_byte_open(address)) {
return ERR_BAD_ADDRESS;
}
at45dbx_write_byte(data);
at45dbx_write_close();
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_read(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len)
{
switch (mem) {
case INT_FLASH:
nvm_flash_read_buffer((flash_addr_t)address, buffer,
(uint16_t)len);
break;
case INT_USERPAGE:
nvm_user_sig_read_buffer((flash_addr_t)address, buffer,
(uint16_t)len);
break;
case INT_EEPROM:
nvm_eeprom_read_buffer((eeprom_addr_t)address, buffer,
(uint16_t)len);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
{
uint32_t sector = address / AT45DBX_SECTOR_SIZE;
if (!at45dbx_read_sector_open(sector)) {
return ERR_BAD_ADDRESS;
}
at45dbx_read_sector_to_ram(buffer);
at45dbx_read_close();
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_write(mem_type_t mem, uint32_t address, void *buffer,
uint32_t len)
{
switch (mem) {
case INT_FLASH:
nvm_flash_erase_and_write_buffer((flash_addr_t)address,
(const void *)buffer, len, true);
break;
case INT_USERPAGE:
nvm_user_sig_write_buffer((flash_addr_t)address,
(const void *)buffer, len, true);
break;
case INT_EEPROM:
nvm_eeprom_erase_and_write_buffer((eeprom_addr_t)address,
(const void *)buffer, len);
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
{
uint32_t sector = address / AT45DBX_SECTOR_SIZE;
if (!at45dbx_write_sector_open(sector)) {
return ERR_BAD_ADDRESS;
}
at45dbx_write_sector_from_ram((const void *)buffer);
at45dbx_write_close();
}
break;
#endif
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_page_erase(mem_type_t mem, uint32_t page_number)
{
switch (mem) {
case INT_FLASH:
if ((page_number >= 0) &&
(page_number <
(BOOT_SECTION_START / FLASH_PAGE_SIZE))) {
nvm_flash_erase_app_page((flash_addr_t)(page_number *
FLASH_PAGE_SIZE));
} else if ((page_number >= 0) &&
(page_number <
(BOOT_SECTION_END / FLASH_PAGE_SIZE))) {
nvm_flash_erase_boot_page((flash_addr_t)(page_number *
FLASH_PAGE_SIZE));
} else {
return ERR_INVALID_ARG;
}
break;
case INT_USERPAGE:
nvm_flash_erase_user_section();
break;
case INT_EEPROM:
nvm_eeprom_erase_page((uint8_t)page_number);
break;
default:
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_size(mem_type_t mem, uint32_t *size)
{
switch (mem) {
case INT_FLASH:
*size = (uint32_t)FLASH_SIZE;
break;
case INT_USERPAGE:
*size = (uint32_t)FLASH_PAGE_SIZE;
break;
case INT_EEPROM:
*size = (uint32_t)EEPROM_SIZE;
break;
#if defined(USE_EXTMEM) && defined(CONF_BOARD_AT45DBX)
case AT45DBX:
*size = (uint32_t)AT45DBX_MEM_SIZE;
break;
#endif
default:
/* Other memories not supported */
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_page_size(mem_type_t mem, uint32_t *size)
{
switch (mem) {
case INT_FLASH:
case INT_USERPAGE:
*size = (uint32_t)FLASH_PAGE_SIZE;
break;
case INT_EEPROM:
*size = (uint32_t)EEPROM_PAGE_SIZE;
break;
default:
/* Other memories not supported */
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_get_pagenumber(mem_type_t mem, uint32_t address,
uint32_t *num)
{
switch (mem) {
case INT_FLASH:
*num = (uint32_t)(address / FLASH_PAGE_SIZE);
break;
case INT_EEPROM:
*num = (uint32_t)(address / EEPROM_PAGE_SIZE);
break;
default:
/* Other memories not supported */
return ERR_INVALID_ARG;
}
return STATUS_OK;
}
status_code_t nvm_set_security_bit(void)
{
/* Block external programming access to the device */
nvm_lb_lock_bits_write(NVM_LB_RWLOCK_gc);
return STATUS_OK;
}
@@ -1,180 +1,180 @@
/**
* \file
*
* \brief Generic clock management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CLK_GENCLK_H_INCLUDED
#define CLK_GENCLK_H_INCLUDED
#include "parts.h"
#if SAM3S
# include "sam3s/genclk.h"
#elif SAM3U
# include "sam3u/genclk.h"
#elif SAM3N
# include "sam3n/genclk.h"
#elif SAM3XA
# include "sam3x/genclk.h"
#elif SAM4S
# include "sam4s/genclk.h"
#elif SAM4L
# include "sam4l/genclk.h"
#elif SAM4E
# include "sam4e/genclk.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/genclk.h"
#elif UC3A3
# include "uc3a3_a4/genclk.h"
#elif UC3B
# include "uc3b0_b1/genclk.h"
#elif UC3C
# include "uc3c/genclk.h"
#elif UC3D
# include "uc3d/genclk.h"
#elif UC3L
# include "uc3l/genclk.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup genclk_group Generic Clock Management
*
* Generic clocks are configurable clocks which run outside the system
* clock domain. They are often connected to peripherals which have an
* asynchronous component running independently of the bus clock, e.g.
* USB controllers, low-power timers and RTCs, etc.
*
* Note that not all platforms have support for generic clocks; on such
* platforms, this API will not be available.
*
* @{
*/
/**
* \def GENCLK_DIV_MAX
* \brief Maximum divider supported by the generic clock implementation
*/
/**
* \enum genclk_source
* \brief Generic clock source ID
*
* Each generic clock may be generated from a different clock source.
* These are the available alternatives provided by the chip.
*/
//! \name Generic clock configuration
//@{
/**
* \struct genclk_config
* \brief Hardware representation of a set of generic clock parameters
*/
/**
* \fn void genclk_config_defaults(struct genclk_config *cfg,
* unsigned int id)
* \brief Initialize \a cfg to the default configuration for the clock
* identified by \a id.
*/
/**
* \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id)
* \brief Read the currently active configuration of the clock
* identified by \a id into \a cfg.
*/
/**
* \fn void genclk_config_write(const struct genclk_config *cfg,
* unsigned int id)
* \brief Activate the configuration \a cfg on the clock identified by
* \a id.
*/
/**
* \fn void genclk_config_set_source(struct genclk_config *cfg,
* enum genclk_source src)
* \brief Select a new source clock \a src in configuration \a cfg.
*/
/**
* \fn void genclk_config_set_divider(struct genclk_config *cfg,
* unsigned int divider)
* \brief Set a new \a divider in configuration \a cfg.
*/
/**
* \fn void genclk_enable_source(enum genclk_source src)
* \brief Enable the source clock \a src used by a generic clock.
*/
//@}
//! \name Enabling and disabling Generic Clocks
//@{
/**
* \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id)
* \brief Activate the configuration \a cfg on the clock identified by
* \a id and enable it.
*/
/**
* \fn void genclk_disable(unsigned int id)
* \brief Disable the generic clock identified by \a id.
*/
//@}
/**
* \brief Enable the configuration defined by \a src and \a divider
* for the generic clock identified by \a id.
*
* \param id The ID of the generic clock.
* \param src The source clock of the generic clock.
* \param divider The divider used to generate the generic clock.
*/
static inline void
genclk_enable_config (unsigned int id, enum genclk_source src,
unsigned int divider)
{
struct genclk_config gcfg;
genclk_config_defaults (&gcfg, id);
genclk_enable_source (src);
genclk_config_set_source (&gcfg, src);
genclk_config_set_divider (&gcfg, divider);
genclk_enable (&gcfg, id);
}
//! @}
#endif /* CLK_GENCLK_H_INCLUDED */
/**
* \file
*
* \brief Generic clock management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CLK_GENCLK_H_INCLUDED
#define CLK_GENCLK_H_INCLUDED
#include "parts.h"
#if SAM3S
# include "sam3s/genclk.h"
#elif SAM3U
# include "sam3u/genclk.h"
#elif SAM3N
# include "sam3n/genclk.h"
#elif SAM3XA
# include "sam3x/genclk.h"
#elif SAM4S
# include "sam4s/genclk.h"
#elif SAM4L
# include "sam4l/genclk.h"
#elif SAM4E
# include "sam4e/genclk.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/genclk.h"
#elif UC3A3
# include "uc3a3_a4/genclk.h"
#elif UC3B
# include "uc3b0_b1/genclk.h"
#elif UC3C
# include "uc3c/genclk.h"
#elif UC3D
# include "uc3d/genclk.h"
#elif UC3L
# include "uc3l/genclk.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup genclk_group Generic Clock Management
*
* Generic clocks are configurable clocks which run outside the system
* clock domain. They are often connected to peripherals which have an
* asynchronous component running independently of the bus clock, e.g.
* USB controllers, low-power timers and RTCs, etc.
*
* Note that not all platforms have support for generic clocks; on such
* platforms, this API will not be available.
*
* @{
*/
/**
* \def GENCLK_DIV_MAX
* \brief Maximum divider supported by the generic clock implementation
*/
/**
* \enum genclk_source
* \brief Generic clock source ID
*
* Each generic clock may be generated from a different clock source.
* These are the available alternatives provided by the chip.
*/
//! \name Generic clock configuration
//@{
/**
* \struct genclk_config
* \brief Hardware representation of a set of generic clock parameters
*/
/**
* \fn void genclk_config_defaults(struct genclk_config *cfg,
* unsigned int id)
* \brief Initialize \a cfg to the default configuration for the clock
* identified by \a id.
*/
/**
* \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id)
* \brief Read the currently active configuration of the clock
* identified by \a id into \a cfg.
*/
/**
* \fn void genclk_config_write(const struct genclk_config *cfg,
* unsigned int id)
* \brief Activate the configuration \a cfg on the clock identified by
* \a id.
*/
/**
* \fn void genclk_config_set_source(struct genclk_config *cfg,
* enum genclk_source src)
* \brief Select a new source clock \a src in configuration \a cfg.
*/
/**
* \fn void genclk_config_set_divider(struct genclk_config *cfg,
* unsigned int divider)
* \brief Set a new \a divider in configuration \a cfg.
*/
/**
* \fn void genclk_enable_source(enum genclk_source src)
* \brief Enable the source clock \a src used by a generic clock.
*/
//@}
//! \name Enabling and disabling Generic Clocks
//@{
/**
* \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id)
* \brief Activate the configuration \a cfg on the clock identified by
* \a id and enable it.
*/
/**
* \fn void genclk_disable(unsigned int id)
* \brief Disable the generic clock identified by \a id.
*/
//@}
/**
* \brief Enable the configuration defined by \a src and \a divider
* for the generic clock identified by \a id.
*
* \param id The ID of the generic clock.
* \param src The source clock of the generic clock.
* \param divider The divider used to generate the generic clock.
*/
static inline void
genclk_enable_config (unsigned int id, enum genclk_source src,
unsigned int divider)
{
struct genclk_config gcfg;
genclk_config_defaults (&gcfg, id);
genclk_enable_source (src);
genclk_config_set_source (&gcfg, src);
genclk_config_set_divider (&gcfg, divider);
genclk_enable (&gcfg, id);
}
//! @}
#endif /* CLK_GENCLK_H_INCLUDED */
@@ -1,166 +1,166 @@
/**
* \file
*
* \brief Oscillator management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef OSC_H_INCLUDED
#define OSC_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/osc.h"
#elif SAM3XA
# include "sam3x/osc.h"
#elif SAM3U
# include "sam3u/osc.h"
#elif SAM3N
# include "sam3n/osc.h"
#elif SAM4S
# include "sam4s/osc.h"
#elif SAM4E
# include "sam4e/osc.h"
#elif SAM4L
# include "sam4l/osc.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/osc.h"
#elif UC3A3
# include "uc3a3_a4/osc.h"
#elif UC3B
# include "uc3b0_b1/osc.h"
#elif UC3C
# include "uc3c/osc.h"
#elif UC3D
# include "uc3d/osc.h"
#elif UC3L
# include "uc3l/osc.h"
#elif XMEGA
# include "xmega/osc.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup osc_group Oscillator Management
*
* This group contains functions and definitions related to configuring
* and enabling/disabling on-chip oscillators. Internal RC-oscillators,
* external crystal oscillators and external clock generators are
* supported by this module. What all of these have in common is that
* they swing at a fixed, nominal frequency which is normally not
* adjustable.
*
* \par Example: Enabling an oscillator
*
* The following example demonstrates how to enable the external
* oscillator on XMEGA A and wait for it to be ready to use. The
* oscillator identifiers are platform-specific, so while the same
* procedure is used on all platforms, the parameter to osc_enable()
* will be different from device to device.
* \code
osc_enable(OSC_ID_XOSC);
osc_wait_ready(OSC_ID_XOSC); \endcode
*
* \section osc_group_board Board-specific Definitions
* If external oscillators are used, the board code must provide the
* following definitions for each of those:
* - \b BOARD_<osc name>_HZ: The nominal frequency of the oscillator.
* - \b BOARD_<osc name>_STARTUP_US: The startup time of the
* oscillator in microseconds.
* - \b BOARD_<osc name>_TYPE: The type of oscillator connected, i.e.
* whether it's a crystal or external clock, and sometimes what kind
* of crystal it is. The meaning of this value is platform-specific.
*
* @{
*/
//! \name Oscillator Management
//@{
/**
* \fn void osc_enable(uint8_t id)
* \brief Enable oscillator \a id
*
* The startup time and mode value is automatically determined based on
* definitions in the board code.
*/
/**
* \fn void osc_disable(uint8_t id)
* \brief Disable oscillator \a id
*/
/**
* \fn osc_is_ready(uint8_t id)
* \brief Determine whether oscillator \a id is ready.
* \retval true Oscillator \a id is running and ready to use as a clock
* source.
* \retval false Oscillator \a id is not running.
*/
/**
* \fn uint32_t osc_get_rate(uint8_t id)
* \brief Return the frequency of oscillator \a id in Hz
*/
#ifndef __ASSEMBLY__
/**
* \brief Wait until the oscillator identified by \a id is ready
*
* This function will busy-wait for the oscillator identified by \a id
* to become stable and ready to use as a clock source.
*
* \param id A number identifying the oscillator to wait for.
*/
static inline void
osc_wait_ready (uint8_t id)
{
while (!osc_is_ready (id))
{
/* Do nothing */
}
}
#endif /* __ASSEMBLY__ */
//@}
//! @}
#endif /* OSC_H_INCLUDED */
/**
* \file
*
* \brief Oscillator management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef OSC_H_INCLUDED
#define OSC_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/osc.h"
#elif SAM3XA
# include "sam3x/osc.h"
#elif SAM3U
# include "sam3u/osc.h"
#elif SAM3N
# include "sam3n/osc.h"
#elif SAM4S
# include "sam4s/osc.h"
#elif SAM4E
# include "sam4e/osc.h"
#elif SAM4L
# include "sam4l/osc.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/osc.h"
#elif UC3A3
# include "uc3a3_a4/osc.h"
#elif UC3B
# include "uc3b0_b1/osc.h"
#elif UC3C
# include "uc3c/osc.h"
#elif UC3D
# include "uc3d/osc.h"
#elif UC3L
# include "uc3l/osc.h"
#elif XMEGA
# include "xmega/osc.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup osc_group Oscillator Management
*
* This group contains functions and definitions related to configuring
* and enabling/disabling on-chip oscillators. Internal RC-oscillators,
* external crystal oscillators and external clock generators are
* supported by this module. What all of these have in common is that
* they swing at a fixed, nominal frequency which is normally not
* adjustable.
*
* \par Example: Enabling an oscillator
*
* The following example demonstrates how to enable the external
* oscillator on XMEGA A and wait for it to be ready to use. The
* oscillator identifiers are platform-specific, so while the same
* procedure is used on all platforms, the parameter to osc_enable()
* will be different from device to device.
* \code
osc_enable(OSC_ID_XOSC);
osc_wait_ready(OSC_ID_XOSC); \endcode
*
* \section osc_group_board Board-specific Definitions
* If external oscillators are used, the board code must provide the
* following definitions for each of those:
* - \b BOARD_<osc name>_HZ: The nominal frequency of the oscillator.
* - \b BOARD_<osc name>_STARTUP_US: The startup time of the
* oscillator in microseconds.
* - \b BOARD_<osc name>_TYPE: The type of oscillator connected, i.e.
* whether it's a crystal or external clock, and sometimes what kind
* of crystal it is. The meaning of this value is platform-specific.
*
* @{
*/
//! \name Oscillator Management
//@{
/**
* \fn void osc_enable(uint8_t id)
* \brief Enable oscillator \a id
*
* The startup time and mode value is automatically determined based on
* definitions in the board code.
*/
/**
* \fn void osc_disable(uint8_t id)
* \brief Disable oscillator \a id
*/
/**
* \fn osc_is_ready(uint8_t id)
* \brief Determine whether oscillator \a id is ready.
* \retval true Oscillator \a id is running and ready to use as a clock
* source.
* \retval false Oscillator \a id is not running.
*/
/**
* \fn uint32_t osc_get_rate(uint8_t id)
* \brief Return the frequency of oscillator \a id in Hz
*/
#ifndef __ASSEMBLY__
/**
* \brief Wait until the oscillator identified by \a id is ready
*
* This function will busy-wait for the oscillator identified by \a id
* to become stable and ready to use as a clock source.
*
* \param id A number identifying the oscillator to wait for.
*/
static inline void
osc_wait_ready (uint8_t id)
{
while (!osc_is_ready (id))
{
/* Do nothing */
}
}
#endif /* __ASSEMBLY__ */
//@}
//! @}
#endif /* OSC_H_INCLUDED */
@@ -1,322 +1,322 @@
/**
* \file
*
* \brief PLL management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CLK_PLL_H_INCLUDED
#define CLK_PLL_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/pll.h"
#elif SAM3XA
# include "sam3x/pll.h"
#elif SAM3U
# include "sam3u/pll.h"
#elif SAM3N
# include "sam3n/pll.h"
#elif SAM4S
# include "sam4s/pll.h"
#elif SAM4E
# include "sam4e/pll.h"
#elif SAM4L
# include "sam4l/pll.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/pll.h"
#elif UC3A3
# include "uc3a3_a4/pll.h"
#elif UC3B
# include "uc3b0_b1/pll.h"
#elif UC3C
# include "uc3c/pll.h"
#elif UC3D
# include "uc3d/pll.h"
#elif (UC3L0128 || UC3L0256 || UC3L3_L4)
# include "uc3l/pll.h"
#elif XMEGA
# include "xmega/pll.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup pll_group PLL Management
*
* This group contains functions and definitions related to configuring
* and enabling/disabling on-chip PLLs. A PLL will take an input signal
* (the \em source), optionally divide the frequency by a configurable
* \em divider, and then multiply the frequency by a configurable \em
* multiplier.
*
* Some devices don't support input dividers; specifying any other
* divisor than 1 on these devices will result in an assertion failure.
* Other devices may have various restrictions to the frequency range of
* the input and output signals.
*
* \par Example: Setting up PLL0 with default parameters
*
* The following example shows how to configure and enable PLL0 using
* the default parameters specified using the configuration symbols
* listed above.
* \code
pll_enable_config_defaults(0); \endcode
*
* To configure, enable PLL0 using the default parameters and to disable
* a specific feature like Wide Bandwidth Mode (a UC3A3-specific
* PLL option.), you can use this initialization process.
* \code
struct pll_config pllcfg;
if (pll_is_locked(pll_id)) {
return; // Pll already running
}
pll_enable_source(CONFIG_PLL0_SOURCE);
pll_config_defaults(&pllcfg, 0);
pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE);
pll_enable(&pllcfg, 0);
pll_wait_for_lock(0); \endcode
*
* When the last function call returns, PLL0 is ready to be used as the
* main system clock source.
*
* \section pll_group_config Configuration Symbols
*
* Each PLL has a set of default parameters determined by the following
* configuration symbols in the application's configuration file:
* - \b CONFIG_PLLn_SOURCE: The default clock source connected to the
* input of PLL \a n. Must be one of the values defined by the
* #pll_source enum.
* - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL
* \a n.
* - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n.
*
* These configuration symbols determine the result of calling
* pll_config_defaults() and pll_get_default_rate().
*
* @{
*/
//! \name Chip-specific PLL characteristics
//@{
/**
* \def PLL_MAX_STARTUP_CYCLES
* \brief Maximum PLL startup time in number of slow clock cycles
*/
/**
* \def NR_PLLS
* \brief Number of on-chip PLLs
*/
/**
* \def PLL_MIN_HZ
* \brief Minimum frequency that the PLL can generate
*/
/**
* \def PLL_MAX_HZ
* \brief Maximum frequency that the PLL can generate
*/
/**
* \def PLL_NR_OPTIONS
* \brief Number of PLL option bits
*/
//@}
/**
* \enum pll_source
* \brief PLL clock source
*/
//! \name PLL configuration
//@{
/**
* \struct pll_config
* \brief Hardware-specific representation of PLL configuration.
*
* This structure contains one or more device-specific values
* representing the current PLL configuration. The contents of this
* structure is typically different from platform to platform, and the
* user should not access any fields except through the PLL
* configuration API.
*/
/**
* \fn void pll_config_init(struct pll_config *cfg,
* enum pll_source src, unsigned int div, unsigned int mul)
* \brief Initialize PLL configuration from standard parameters.
*
* \note This function may be defined inline because it is assumed to be
* called very few times, and usually with constant parameters. Inlining
* it will in such cases reduce the code size significantly.
*
* \param cfg The PLL configuration to be initialized.
* \param src The oscillator to be used as input to the PLL.
* \param div PLL input divider.
* \param mul PLL loop divider (i.e. multiplier).
*
* \return A configuration which will make the PLL run at
* (\a mul / \a div) times the frequency of \a src
*/
/**
* \def pll_config_defaults(cfg, pll_id)
* \brief Initialize PLL configuration using default parameters.
*
* After this function returns, \a cfg will contain a configuration
* which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV)
* times the frequency of CONFIG_PLLx_SOURCE.
*
* \param cfg The PLL configuration to be initialized.
* \param pll_id Use defaults for this PLL.
*/
/**
* \def pll_get_default_rate(pll_id)
* \brief Get the default rate in Hz of \a pll_id
*/
/**
* \fn void pll_config_set_option(struct pll_config *cfg,
* unsigned int option)
* \brief Set the PLL option bit \a option in the configuration \a cfg.
*
* \param cfg The PLL configuration to be changed.
* \param option The PLL option bit to be set.
*/
/**
* \fn void pll_config_clear_option(struct pll_config *cfg,
* unsigned int option)
* \brief Clear the PLL option bit \a option in the configuration \a cfg.
*
* \param cfg The PLL configuration to be changed.
* \param option The PLL option bit to be cleared.
*/
/**
* \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id)
* \brief Read the currently active configuration of \a pll_id.
*
* \param cfg The configuration object into which to store the currently
* active configuration.
* \param pll_id The ID of the PLL to be accessed.
*/
/**
* \fn void pll_config_write(const struct pll_config *cfg,
* unsigned int pll_id)
* \brief Activate the configuration \a cfg on \a pll_id
*
* \param cfg The configuration object representing the PLL
* configuration to be activated.
* \param pll_id The ID of the PLL to be updated.
*/
//@}
//! \name Interaction with the PLL hardware
//@{
/**
* \fn void pll_enable(const struct pll_config *cfg,
* unsigned int pll_id)
* \brief Activate the configuration \a cfg and enable PLL \a pll_id.
*
* \param cfg The PLL configuration to be activated.
* \param pll_id The ID of the PLL to be enabled.
*/
/**
* \fn void pll_disable(unsigned int pll_id)
* \brief Disable the PLL identified by \a pll_id.
*
* After this function is called, the PLL identified by \a pll_id will
* be disabled. The PLL configuration stored in hardware may be affected
* by this, so if the caller needs to restore the same configuration
* later, it should either do a pll_config_read() before disabling the
* PLL, or remember the last configuration written to the PLL.
*
* \param pll_id The ID of the PLL to be disabled.
*/
/**
* \fn bool pll_is_locked(unsigned int pll_id)
* \brief Determine whether the PLL is locked or not.
*
* \param pll_id The ID of the PLL to check.
*
* \retval true The PLL is locked and ready to use as a clock source
* \retval false The PLL is not yet locked, or has not been enabled.
*/
/**
* \fn void pll_enable_source(enum pll_source src)
* \brief Enable the source of the pll.
* The source is enabled, if the source is not already running.
*
* \param src The ID of the PLL source to enable.
*/
/**
* \fn void pll_enable_config_defaults(unsigned int pll_id)
* \brief Enable the pll with the default configuration.
* PLL is enabled, if the PLL is not already locked.
*
* \param pll_id The ID of the PLL to enable.
*/
/**
* \brief Wait for PLL \a pll_id to become locked
*
* \todo Use a timeout to avoid waiting forever and hanging the system
*
* \param pll_id The ID of the PLL to wait for.
*
* \retval STATUS_OK The PLL is now locked.
* \retval ERR_TIMEOUT Timed out waiting for PLL to become locked.
*/
static inline int
pll_wait_for_lock (unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
while (!pll_is_locked (pll_id))
{
/* Do nothing */
}
return 0;
}
//@}
//! @}
#endif /* CLK_PLL_H_INCLUDED */
/**
* \file
*
* \brief PLL management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CLK_PLL_H_INCLUDED
#define CLK_PLL_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/pll.h"
#elif SAM3XA
# include "sam3x/pll.h"
#elif SAM3U
# include "sam3u/pll.h"
#elif SAM3N
# include "sam3n/pll.h"
#elif SAM4S
# include "sam4s/pll.h"
#elif SAM4E
# include "sam4e/pll.h"
#elif SAM4L
# include "sam4l/pll.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/pll.h"
#elif UC3A3
# include "uc3a3_a4/pll.h"
#elif UC3B
# include "uc3b0_b1/pll.h"
#elif UC3C
# include "uc3c/pll.h"
#elif UC3D
# include "uc3d/pll.h"
#elif (UC3L0128 || UC3L0256 || UC3L3_L4)
# include "uc3l/pll.h"
#elif XMEGA
# include "xmega/pll.h"
#else
# error Unsupported chip type
#endif
/**
* \ingroup clk_group
* \defgroup pll_group PLL Management
*
* This group contains functions and definitions related to configuring
* and enabling/disabling on-chip PLLs. A PLL will take an input signal
* (the \em source), optionally divide the frequency by a configurable
* \em divider, and then multiply the frequency by a configurable \em
* multiplier.
*
* Some devices don't support input dividers; specifying any other
* divisor than 1 on these devices will result in an assertion failure.
* Other devices may have various restrictions to the frequency range of
* the input and output signals.
*
* \par Example: Setting up PLL0 with default parameters
*
* The following example shows how to configure and enable PLL0 using
* the default parameters specified using the configuration symbols
* listed above.
* \code
pll_enable_config_defaults(0); \endcode
*
* To configure, enable PLL0 using the default parameters and to disable
* a specific feature like Wide Bandwidth Mode (a UC3A3-specific
* PLL option.), you can use this initialization process.
* \code
struct pll_config pllcfg;
if (pll_is_locked(pll_id)) {
return; // Pll already running
}
pll_enable_source(CONFIG_PLL0_SOURCE);
pll_config_defaults(&pllcfg, 0);
pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE);
pll_enable(&pllcfg, 0);
pll_wait_for_lock(0); \endcode
*
* When the last function call returns, PLL0 is ready to be used as the
* main system clock source.
*
* \section pll_group_config Configuration Symbols
*
* Each PLL has a set of default parameters determined by the following
* configuration symbols in the application's configuration file:
* - \b CONFIG_PLLn_SOURCE: The default clock source connected to the
* input of PLL \a n. Must be one of the values defined by the
* #pll_source enum.
* - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL
* \a n.
* - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n.
*
* These configuration symbols determine the result of calling
* pll_config_defaults() and pll_get_default_rate().
*
* @{
*/
//! \name Chip-specific PLL characteristics
//@{
/**
* \def PLL_MAX_STARTUP_CYCLES
* \brief Maximum PLL startup time in number of slow clock cycles
*/
/**
* \def NR_PLLS
* \brief Number of on-chip PLLs
*/
/**
* \def PLL_MIN_HZ
* \brief Minimum frequency that the PLL can generate
*/
/**
* \def PLL_MAX_HZ
* \brief Maximum frequency that the PLL can generate
*/
/**
* \def PLL_NR_OPTIONS
* \brief Number of PLL option bits
*/
//@}
/**
* \enum pll_source
* \brief PLL clock source
*/
//! \name PLL configuration
//@{
/**
* \struct pll_config
* \brief Hardware-specific representation of PLL configuration.
*
* This structure contains one or more device-specific values
* representing the current PLL configuration. The contents of this
* structure is typically different from platform to platform, and the
* user should not access any fields except through the PLL
* configuration API.
*/
/**
* \fn void pll_config_init(struct pll_config *cfg,
* enum pll_source src, unsigned int div, unsigned int mul)
* \brief Initialize PLL configuration from standard parameters.
*
* \note This function may be defined inline because it is assumed to be
* called very few times, and usually with constant parameters. Inlining
* it will in such cases reduce the code size significantly.
*
* \param cfg The PLL configuration to be initialized.
* \param src The oscillator to be used as input to the PLL.
* \param div PLL input divider.
* \param mul PLL loop divider (i.e. multiplier).
*
* \return A configuration which will make the PLL run at
* (\a mul / \a div) times the frequency of \a src
*/
/**
* \def pll_config_defaults(cfg, pll_id)
* \brief Initialize PLL configuration using default parameters.
*
* After this function returns, \a cfg will contain a configuration
* which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV)
* times the frequency of CONFIG_PLLx_SOURCE.
*
* \param cfg The PLL configuration to be initialized.
* \param pll_id Use defaults for this PLL.
*/
/**
* \def pll_get_default_rate(pll_id)
* \brief Get the default rate in Hz of \a pll_id
*/
/**
* \fn void pll_config_set_option(struct pll_config *cfg,
* unsigned int option)
* \brief Set the PLL option bit \a option in the configuration \a cfg.
*
* \param cfg The PLL configuration to be changed.
* \param option The PLL option bit to be set.
*/
/**
* \fn void pll_config_clear_option(struct pll_config *cfg,
* unsigned int option)
* \brief Clear the PLL option bit \a option in the configuration \a cfg.
*
* \param cfg The PLL configuration to be changed.
* \param option The PLL option bit to be cleared.
*/
/**
* \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id)
* \brief Read the currently active configuration of \a pll_id.
*
* \param cfg The configuration object into which to store the currently
* active configuration.
* \param pll_id The ID of the PLL to be accessed.
*/
/**
* \fn void pll_config_write(const struct pll_config *cfg,
* unsigned int pll_id)
* \brief Activate the configuration \a cfg on \a pll_id
*
* \param cfg The configuration object representing the PLL
* configuration to be activated.
* \param pll_id The ID of the PLL to be updated.
*/
//@}
//! \name Interaction with the PLL hardware
//@{
/**
* \fn void pll_enable(const struct pll_config *cfg,
* unsigned int pll_id)
* \brief Activate the configuration \a cfg and enable PLL \a pll_id.
*
* \param cfg The PLL configuration to be activated.
* \param pll_id The ID of the PLL to be enabled.
*/
/**
* \fn void pll_disable(unsigned int pll_id)
* \brief Disable the PLL identified by \a pll_id.
*
* After this function is called, the PLL identified by \a pll_id will
* be disabled. The PLL configuration stored in hardware may be affected
* by this, so if the caller needs to restore the same configuration
* later, it should either do a pll_config_read() before disabling the
* PLL, or remember the last configuration written to the PLL.
*
* \param pll_id The ID of the PLL to be disabled.
*/
/**
* \fn bool pll_is_locked(unsigned int pll_id)
* \brief Determine whether the PLL is locked or not.
*
* \param pll_id The ID of the PLL to check.
*
* \retval true The PLL is locked and ready to use as a clock source
* \retval false The PLL is not yet locked, or has not been enabled.
*/
/**
* \fn void pll_enable_source(enum pll_source src)
* \brief Enable the source of the pll.
* The source is enabled, if the source is not already running.
*
* \param src The ID of the PLL source to enable.
*/
/**
* \fn void pll_enable_config_defaults(unsigned int pll_id)
* \brief Enable the pll with the default configuration.
* PLL is enabled, if the PLL is not already locked.
*
* \param pll_id The ID of the PLL to enable.
*/
/**
* \brief Wait for PLL \a pll_id to become locked
*
* \todo Use a timeout to avoid waiting forever and hanging the system
*
* \param pll_id The ID of the PLL to wait for.
*
* \retval STATUS_OK The PLL is now locked.
* \retval ERR_TIMEOUT Timed out waiting for PLL to become locked.
*/
static inline int
pll_wait_for_lock (unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
while (!pll_is_locked (pll_id))
{
/* Do nothing */
}
return 0;
}
//@}
//! @}
#endif /* CLK_PLL_H_INCLUDED */
@@ -1,173 +1,173 @@
/**
* \file
*
* \brief System clock management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SYSCLK_H_INCLUDED
#define SYSCLK_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/sysclk.h"
#elif SAM3U
# include "sam3u/sysclk.h"
#elif SAM3N
# include "sam3n/sysclk.h"
#elif SAM3XA
# include "sam3x/sysclk.h"
#elif SAM4S
# include "sam4s/sysclk.h"
#elif SAM4E
# include "sam4e/sysclk.h"
#elif SAM4L
# include "sam4l/sysclk.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/sysclk.h"
#elif UC3A3
# include "uc3a3_a4/sysclk.h"
#elif UC3B
# include "uc3b0_b1/sysclk.h"
#elif UC3C
# include "uc3c/sysclk.h"
#elif UC3D
# include "uc3d/sysclk.h"
#elif UC3L
# include "uc3l/sysclk.h"
#elif XMEGA
# include "xmega/sysclk.h"
#elif MEGA
# include "mega/sysclk.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup clk_group Clock Management
*/
/**
* \ingroup clk_group
* \defgroup sysclk_group System Clock Management
*
* See \ref sysclk_quickstart.
*
* The <em>sysclk</em> API covers the <em>system clock</em> and all
* clocks derived from it. The system clock is a chip-internal clock on
* which all <em>synchronous clocks</em>, i.e. CPU and bus/peripheral
* clocks, are based. The system clock is typically generated from one
* of a variety of sources, which may include crystal and RC oscillators
* as well as PLLs. The clocks derived from the system clock are
* sometimes also known as <em>synchronous clocks</em>, since they
* always run synchronously with respect to each other, as opposed to
* <em>generic clocks</em> which may run from different oscillators or
* PLLs.
*
* Most applications should simply call sysclk_init() to initialize
* everything related to the system clock and its source (oscillator,
* PLL or DFLL), and leave it at that. More advanced applications, and
* platform-specific drivers, may require additional services from the
* clock system, some of which may be platform-specific.
*
* \section sysclk_group_platform Platform Dependencies
*
* The sysclk API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms with the same
* parameters and functionality. These functions may be called freely by
* portable applications, drivers and services:
* - sysclk_init()
* - sysclk_set_source()
* - sysclk_get_main_hz()
* - sysclk_get_cpu_hz()
* - sysclk_get_peripheral_bus_hz()
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behavior. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - sysclk_enable_peripheral_clock()
* - sysclk_disable_peripheral_clock()
* - sysclk_enable_module()
* - sysclk_disable_module()
* - sysclk_module_is_enabled()
* - sysclk_set_prescalers()
*
* All other functions should be considered platform-specific.
* Enabling/disabling clocks to specific peripherals as well as
* determining the speed of these clocks should be done by calling
* functions provided by the driver for that peripheral.
*
* @{
*/
//! \name System Clock Initialization
//@{
/**
* \fn void sysclk_init(void)
* \brief Initialize the synchronous clock system.
*
* This function will initialize the system clock and its source. This
* includes:
* - Mask all synchronous clocks except for any clocks which are
* essential for normal operation (for example internal memory
* clocks).
* - Set up the system clock prescalers as specified by the
* application's configuration file.
* - Enable the clock source specified by the application's
* configuration file (oscillator or PLL) and wait for it to become
* stable.
* - Set the main system clock source to the clock specified by the
* application's configuration file.
*
* Since all non-essential peripheral clocks are initially disabled, it
* is the responsibility of the peripheral driver to re-enable any
* clocks that are needed for normal operation.
*/
//@}
//! @}
#endif /* SYSCLK_H_INCLUDED */
/**
* \file
*
* \brief System clock management
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SYSCLK_H_INCLUDED
#define SYSCLK_H_INCLUDED
#include "parts.h"
#include "conf_clock.h"
#if SAM3S
# include "sam3s/sysclk.h"
#elif SAM3U
# include "sam3u/sysclk.h"
#elif SAM3N
# include "sam3n/sysclk.h"
#elif SAM3XA
# include "sam3x/sysclk.h"
#elif SAM4S
# include "sam4s/sysclk.h"
#elif SAM4E
# include "sam4e/sysclk.h"
#elif SAM4L
# include "sam4l/sysclk.h"
#elif (UC3A0 || UC3A1)
# include "uc3a0_a1/sysclk.h"
#elif UC3A3
# include "uc3a3_a4/sysclk.h"
#elif UC3B
# include "uc3b0_b1/sysclk.h"
#elif UC3C
# include "uc3c/sysclk.h"
#elif UC3D
# include "uc3d/sysclk.h"
#elif UC3L
# include "uc3l/sysclk.h"
#elif XMEGA
# include "xmega/sysclk.h"
#elif MEGA
# include "mega/sysclk.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup clk_group Clock Management
*/
/**
* \ingroup clk_group
* \defgroup sysclk_group System Clock Management
*
* See \ref sysclk_quickstart.
*
* The <em>sysclk</em> API covers the <em>system clock</em> and all
* clocks derived from it. The system clock is a chip-internal clock on
* which all <em>synchronous clocks</em>, i.e. CPU and bus/peripheral
* clocks, are based. The system clock is typically generated from one
* of a variety of sources, which may include crystal and RC oscillators
* as well as PLLs. The clocks derived from the system clock are
* sometimes also known as <em>synchronous clocks</em>, since they
* always run synchronously with respect to each other, as opposed to
* <em>generic clocks</em> which may run from different oscillators or
* PLLs.
*
* Most applications should simply call sysclk_init() to initialize
* everything related to the system clock and its source (oscillator,
* PLL or DFLL), and leave it at that. More advanced applications, and
* platform-specific drivers, may require additional services from the
* clock system, some of which may be platform-specific.
*
* \section sysclk_group_platform Platform Dependencies
*
* The sysclk API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms with the same
* parameters and functionality. These functions may be called freely by
* portable applications, drivers and services:
* - sysclk_init()
* - sysclk_set_source()
* - sysclk_get_main_hz()
* - sysclk_get_cpu_hz()
* - sysclk_get_peripheral_bus_hz()
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behavior. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - sysclk_enable_peripheral_clock()
* - sysclk_disable_peripheral_clock()
* - sysclk_enable_module()
* - sysclk_disable_module()
* - sysclk_module_is_enabled()
* - sysclk_set_prescalers()
*
* All other functions should be considered platform-specific.
* Enabling/disabling clocks to specific peripherals as well as
* determining the speed of these clocks should be done by calling
* functions provided by the driver for that peripheral.
*
* @{
*/
//! \name System Clock Initialization
//@{
/**
* \fn void sysclk_init(void)
* \brief Initialize the synchronous clock system.
*
* This function will initialize the system clock and its source. This
* includes:
* - Mask all synchronous clocks except for any clocks which are
* essential for normal operation (for example internal memory
* clocks).
* - Set up the system clock prescalers as specified by the
* application's configuration file.
* - Enable the clock source specified by the application's
* configuration file (oscillator or PLL) and wait for it to become
* stable.
* - Set the main system clock source to the clock specified by the
* application's configuration file.
*
* Since all non-essential peripheral clocks are initially disabled, it
* is the responsibility of the peripheral driver to re-enable any
* clocks that are needed for normal operation.
*/
//@}
//! @}
#endif /* SYSCLK_H_INCLUDED */
File diff suppressed because it is too large Load Diff
@@ -1,287 +1,287 @@
/**
* \file
*
* \brief Chip-specific PLL management functions
*
* Copyright (c) 2010-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_PLL_H_INCLUDED
#define XMEGA_PLL_H_INCLUDED
#include <compiler.h>
/**
* \weakgroup pll_group
* @{
*/
#define NR_PLLS 1
#define PLL_MIN_HZ 10000000UL
#define PLL_MAX_HZ 200000000UL
#define PLL_NR_OPTIONS 0
enum pll_source
{
//! 2 MHz Internal RC Oscillator
PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc,
//! 32 MHz Internal RC Oscillator
PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc,
//! External Clock Source
PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc,
};
#define pll_get_default_rate(pll_id) \
pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \
CONFIG_PLL##pll_id##_MUL, \
CONFIG_PLL##pll_id##_DIV)
/**
* \internal
* \brief Return clock rate for specified PLL settings.
*
* \note Due to the hardware implementation of the PLL, \a div must be 4 if the
* 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must
* be above 440 kHz, and the output between 10 and 200 MHz.
*
* \param src ID of the PLL's reference source oscillator.
* \param mul Multiplier for the PLL.
* \param div Divisor for the PLL.
*
* \retval Output clock rate from PLL.
*/
static inline uint32_t
pll_get_default_rate_priv (enum pll_source src,
unsigned int mul, unsigned int div)
{
uint32_t rate;
switch (src)
{
case PLL_SRC_RC2MHZ:
rate = 2000000UL;
Assert (div == 1);
break;
case PLL_SRC_RC32MHZ:
#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency
rate = CONFIG_OSC_RC32_CAL / 4;
#else
rate = 8000000UL;
#endif
Assert (div == 4);
break;
case PLL_SRC_XOSC:
rate = osc_get_rate (OSC_ID_XOSC);
Assert (div == 1);
break;
default:
break;
}
Assert (rate >= 440000UL);
rate *= mul;
Assert (rate >= PLL_MIN_HZ);
Assert (rate <= PLL_MAX_HZ);
return rate;
}
struct pll_config
{
uint8_t ctrl;
};
/**
* \note The XMEGA PLL hardware uses hard-wired input dividers, so the
* user must ensure that \a div is set as follows:
* - If \a src is PLL_SRC_32MHZ, \a div must be set to 4.
* - Otherwise, \a div must be set to 1.
*/
static inline void
pll_config_init (struct pll_config *cfg, enum pll_source src,
unsigned int div, unsigned int mul)
{
Assert (mul >= 1 && mul <= 31);
if (src == PLL_SRC_RC32MHZ)
{
Assert (div == 4);
}
else
{
Assert (div == 1);
}
/* Initialize the configuration */
cfg->ctrl = src | (mul << OSC_PLLFAC_gp);
}
#define pll_config_defaults(cfg, pll_id) \
pll_config_init(cfg, \
CONFIG_PLL##pll_id##_SOURCE, \
CONFIG_PLL##pll_id##_DIV, \
CONFIG_PLL##pll_id##_MUL)
static inline void
pll_config_read (struct pll_config *cfg, unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
cfg->ctrl = OSC.PLLCTRL;
}
static inline void
pll_config_write (const struct pll_config *cfg, unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
OSC.PLLCTRL = cfg->ctrl;
}
/**
* \note If a different PLL reference oscillator than those enabled by
* \ref sysclk_init() is used, the user must ensure that the desired reference
* is enabled prior to calling this function.
*/
static inline void
pll_enable (const struct pll_config *cfg, unsigned int pll_id)
{
irqflags_t flags;
Assert (pll_id < NR_PLLS);
flags = cpu_irq_save ();
pll_config_write (cfg, pll_id);
OSC.CTRL |= OSC_PLLEN_bm;
cpu_irq_restore (flags);
}
/*! \note This will not automatically disable the reference oscillator that is
* configured for the PLL.
*/
static inline void
pll_disable (unsigned int pll_id)
{
irqflags_t flags;
Assert (pll_id < NR_PLLS);
flags = cpu_irq_save ();
OSC.CTRL &= ~OSC_PLLEN_bm;
cpu_irq_restore (flags);
}
static inline bool
pll_is_locked (unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
return OSC.STATUS & OSC_PLLRDY_bm;
}
static inline void
pll_enable_source (enum pll_source src)
{
switch (src)
{
case PLL_SRC_RC2MHZ:
break;
case PLL_SRC_RC32MHZ:
if (!osc_is_ready (OSC_ID_RC32MHZ))
{
osc_enable (OSC_ID_RC32MHZ);
osc_wait_ready (OSC_ID_RC32MHZ);
#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF)
{
osc_enable (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
osc_wait_ready (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
}
osc_enable_autocalibration (OSC_ID_RC32MHZ,
CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
#endif
}
break;
case PLL_SRC_XOSC:
if (!osc_is_ready (OSC_ID_XOSC))
{
osc_enable (OSC_ID_XOSC);
osc_wait_ready (OSC_ID_XOSC);
}
break;
default:
Assert (false);
break;
}
}
static inline void
pll_enable_config_defaults (unsigned int pll_id)
{
struct pll_config pllcfg;
if (pll_is_locked (pll_id))
{
return; // Pll already running
}
switch (pll_id)
{
#ifdef CONFIG_PLL0_SOURCE
case 0:
pll_enable_source (CONFIG_PLL0_SOURCE);
pll_config_init (&pllcfg,
CONFIG_PLL0_SOURCE, CONFIG_PLL0_DIV, CONFIG_PLL0_MUL);
break;
#endif
default:
Assert (false);
break;
}
pll_enable (&pllcfg, pll_id);
while (!pll_is_locked (pll_id));
}
//! @}
#endif /* XMEGA_PLL_H_INCLUDED */
/**
* \file
*
* \brief Chip-specific PLL management functions
*
* Copyright (c) 2010-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_PLL_H_INCLUDED
#define XMEGA_PLL_H_INCLUDED
#include <compiler.h>
/**
* \weakgroup pll_group
* @{
*/
#define NR_PLLS 1
#define PLL_MIN_HZ 10000000UL
#define PLL_MAX_HZ 200000000UL
#define PLL_NR_OPTIONS 0
enum pll_source
{
//! 2 MHz Internal RC Oscillator
PLL_SRC_RC2MHZ = OSC_PLLSRC_RC2M_gc,
//! 32 MHz Internal RC Oscillator
PLL_SRC_RC32MHZ = OSC_PLLSRC_RC32M_gc,
//! External Clock Source
PLL_SRC_XOSC = OSC_PLLSRC_XOSC_gc,
};
#define pll_get_default_rate(pll_id) \
pll_get_default_rate_priv(CONFIG_PLL##pll_id##_SOURCE, \
CONFIG_PLL##pll_id##_MUL, \
CONFIG_PLL##pll_id##_DIV)
/**
* \internal
* \brief Return clock rate for specified PLL settings.
*
* \note Due to the hardware implementation of the PLL, \a div must be 4 if the
* 32 MHz RC oscillator is used as reference and 1 otherwise. The reference must
* be above 440 kHz, and the output between 10 and 200 MHz.
*
* \param src ID of the PLL's reference source oscillator.
* \param mul Multiplier for the PLL.
* \param div Divisor for the PLL.
*
* \retval Output clock rate from PLL.
*/
static inline uint32_t
pll_get_default_rate_priv (enum pll_source src,
unsigned int mul, unsigned int div)
{
uint32_t rate;
switch (src)
{
case PLL_SRC_RC2MHZ:
rate = 2000000UL;
Assert (div == 1);
break;
case PLL_SRC_RC32MHZ:
#ifdef CONFIG_OSC_RC32_CAL //32MHz oscillator is calibrated to another frequency
rate = CONFIG_OSC_RC32_CAL / 4;
#else
rate = 8000000UL;
#endif
Assert (div == 4);
break;
case PLL_SRC_XOSC:
rate = osc_get_rate (OSC_ID_XOSC);
Assert (div == 1);
break;
default:
break;
}
Assert (rate >= 440000UL);
rate *= mul;
Assert (rate >= PLL_MIN_HZ);
Assert (rate <= PLL_MAX_HZ);
return rate;
}
struct pll_config
{
uint8_t ctrl;
};
/**
* \note The XMEGA PLL hardware uses hard-wired input dividers, so the
* user must ensure that \a div is set as follows:
* - If \a src is PLL_SRC_32MHZ, \a div must be set to 4.
* - Otherwise, \a div must be set to 1.
*/
static inline void
pll_config_init (struct pll_config *cfg, enum pll_source src,
unsigned int div, unsigned int mul)
{
Assert (mul >= 1 && mul <= 31);
if (src == PLL_SRC_RC32MHZ)
{
Assert (div == 4);
}
else
{
Assert (div == 1);
}
/* Initialize the configuration */
cfg->ctrl = src | (mul << OSC_PLLFAC_gp);
}
#define pll_config_defaults(cfg, pll_id) \
pll_config_init(cfg, \
CONFIG_PLL##pll_id##_SOURCE, \
CONFIG_PLL##pll_id##_DIV, \
CONFIG_PLL##pll_id##_MUL)
static inline void
pll_config_read (struct pll_config *cfg, unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
cfg->ctrl = OSC.PLLCTRL;
}
static inline void
pll_config_write (const struct pll_config *cfg, unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
OSC.PLLCTRL = cfg->ctrl;
}
/**
* \note If a different PLL reference oscillator than those enabled by
* \ref sysclk_init() is used, the user must ensure that the desired reference
* is enabled prior to calling this function.
*/
static inline void
pll_enable (const struct pll_config *cfg, unsigned int pll_id)
{
irqflags_t flags;
Assert (pll_id < NR_PLLS);
flags = cpu_irq_save ();
pll_config_write (cfg, pll_id);
OSC.CTRL |= OSC_PLLEN_bm;
cpu_irq_restore (flags);
}
/*! \note This will not automatically disable the reference oscillator that is
* configured for the PLL.
*/
static inline void
pll_disable (unsigned int pll_id)
{
irqflags_t flags;
Assert (pll_id < NR_PLLS);
flags = cpu_irq_save ();
OSC.CTRL &= ~OSC_PLLEN_bm;
cpu_irq_restore (flags);
}
static inline bool
pll_is_locked (unsigned int pll_id)
{
Assert (pll_id < NR_PLLS);
return OSC.STATUS & OSC_PLLRDY_bm;
}
static inline void
pll_enable_source (enum pll_source src)
{
switch (src)
{
case PLL_SRC_RC2MHZ:
break;
case PLL_SRC_RC32MHZ:
if (!osc_is_ready (OSC_ID_RC32MHZ))
{
osc_enable (OSC_ID_RC32MHZ);
osc_wait_ready (OSC_ID_RC32MHZ);
#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF)
{
osc_enable (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
osc_wait_ready (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
}
osc_enable_autocalibration (OSC_ID_RC32MHZ,
CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
#endif
}
break;
case PLL_SRC_XOSC:
if (!osc_is_ready (OSC_ID_XOSC))
{
osc_enable (OSC_ID_XOSC);
osc_wait_ready (OSC_ID_XOSC);
}
break;
default:
Assert (false);
break;
}
}
static inline void
pll_enable_config_defaults (unsigned int pll_id)
{
struct pll_config pllcfg;
if (pll_is_locked (pll_id))
{
return; // Pll already running
}
switch (pll_id)
{
#ifdef CONFIG_PLL0_SOURCE
case 0:
pll_enable_source (CONFIG_PLL0_SOURCE);
pll_config_init (&pllcfg,
CONFIG_PLL0_SOURCE, CONFIG_PLL0_DIV, CONFIG_PLL0_MUL);
break;
#endif
default:
Assert (false);
break;
}
pll_enable (&pllcfg, pll_id);
while (!pll_is_locked (pll_id));
}
//! @}
#endif /* XMEGA_PLL_H_INCLUDED */
@@ -1,255 +1,255 @@
/**
* \file
*
* \brief Chip-specific system clock management functions
*
* Copyright (c) 2010-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <sysclk.h>
#include <osc.h>
#include <pll.h>
#if XMEGA_AU || XMEGA_B || XMEGA_C
# include <nvm.h>
#endif
void sysclk_init(void)
{
uint8_t *reg = (uint8_t *) & PR.PRGEN;
uint8_t i;
#ifdef CONFIG_OSC_RC32_CAL
uint16_t cal;
/* avoid Cppcheck Warning */
UNUSED(cal);
#endif
bool need_rc2mhz = false;
/* Turn off all peripheral clocks that can be turned off. */
for (i = 0; i <= SYSCLK_PORT_F; i++) {
*(reg++) = 0xff;
}
/* Set up system clock prescalers if different from defaults */
if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1)
|| (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) {
sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, CONFIG_SYSCLK_PSBCDIV);
}
#if (CONFIG_OSC_RC32_CAL==48000000UL)
MSB(cal) =
nvm_read_production_signature_row
(nvm_get_production_signature_row_offset(USBRCOSC));
LSB(cal) =
nvm_read_production_signature_row
(nvm_get_production_signature_row_offset(USBRCOSCA));
/*
* If a device has an uncalibrated value in the
* production signature row (early sample part), load a
* sane default calibration value.
*/
if (cal == 0xFFFF) {
cal = 0x2340;
}
osc_user_calibration(OSC_ID_RC32MHZ, cal);
#endif
/*
* Switch to the selected initial system clock source, unless
* the default internal 2 MHz oscillator is selected.
*/
if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) {
need_rc2mhz = true;
} else {
switch (CONFIG_SYSCLK_SOURCE) {
case SYSCLK_SRC_RC32MHZ:
osc_enable(OSC_ID_RC32MHZ);
osc_wait_ready(OSC_ID_RC32MHZ);
#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) {
osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
}
osc_enable_autocalibration(OSC_ID_RC32MHZ,
CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
#endif
break;
case SYSCLK_SRC_RC32KHZ:
osc_enable(OSC_ID_RC32KHZ);
osc_wait_ready(OSC_ID_RC32KHZ);
break;
case SYSCLK_SRC_XOSC:
osc_enable(OSC_ID_XOSC);
osc_wait_ready(OSC_ID_XOSC);
break;
#ifdef CONFIG_PLL0_SOURCE
case SYSCLK_SRC_PLL:
if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) {
need_rc2mhz = true;
}
pll_enable_config_defaults(0);
break;
#endif
#if XMEGA_E
case SYSCLK_SRC_RC8MHZ:
osc_enable(OSC_ID_RC8MHZ);
osc_wait_ready(OSC_ID_RC8MHZ);
break;
#endif
default:
//unhandled_case(CONFIG_SYSCLK_SOURCE);
return;
}
ccp_write_io((uint8_t *) & CLK.CTRL, CONFIG_SYSCLK_SOURCE);
Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE);
}
if (need_rc2mhz) {
#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC
osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
osc_enable_autocalibration(OSC_ID_RC2MHZ,
CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
#endif
} else {
osc_disable(OSC_ID_RC2MHZ);
}
#ifdef CONFIG_RTC_SOURCE
sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE);
#endif
}
void sysclk_enable_module(enum sysclk_port_id port,
uint8_t id)
{
irqflags_t flags = cpu_irq_save();
*((uint8_t *) & PR.PRGEN + port) &= ~id;
cpu_irq_restore(flags);
}
void sysclk_disable_module(enum sysclk_port_id port,
uint8_t id)
{
irqflags_t flags = cpu_irq_save();
*((uint8_t *) & PR.PRGEN + port) |= id;
cpu_irq_restore(flags);
}
#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__)
/**
* \brief Enable clock for the USB module
*
* \pre CONFIG_USBCLK_SOURCE must be defined.
*
* \param frequency The required USB clock frequency in MHz:
* \arg \c 6 for 6 MHz
* \arg \c 48 for 48 MHz
*/
void sysclk_enable_usb(uint8_t frequency)
{
uint8_t prescaler;
Assert((frequency == 6) || (frequency == 48));
/*
* Enable or disable prescaler depending on if the USB frequency is 6
* MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling.
*/
if (frequency == 6) {
prescaler = CLK_USBPSDIV_8_gc;
} else {
prescaler = 0;
}
/*
* Switch to the system clock selected by the user.
*/
switch (CONFIG_USBCLK_SOURCE) {
case USBCLK_SRC_RCOSC:
if (!osc_is_ready(OSC_ID_RC32MHZ)) {
osc_enable(OSC_ID_RC32MHZ);
osc_wait_ready(OSC_ID_RC32MHZ);
#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) {
osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
}
osc_enable_autocalibration(OSC_ID_RC32MHZ,
CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
#endif
}
ccp_write_io((uint8_t *) & CLK.USBCTRL, (prescaler)
| CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm);
break;
#ifdef CONFIG_PLL0_SOURCE
case USBCLK_SRC_PLL:
pll_enable_config_defaults(0);
ccp_write_io((uint8_t *) & CLK.USBCTRL, (prescaler)
| CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);
break;
#endif
default:
Assert(false);
break;
}
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB);
}
/**
* \brief Disable clock for the USB module
*/
void sysclk_disable_usb(void)
{
sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB);
ccp_write_io((uint8_t *) & CLK.USBCTRL, 0);
}
#endif // XMEGA_AU || XMEGA_B || XMEGA_C
/**
* \file
*
* \brief Chip-specific system clock management functions
*
* Copyright (c) 2010-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <sysclk.h>
#include <osc.h>
#include <pll.h>
#if XMEGA_AU || XMEGA_B || XMEGA_C
# include <nvm.h>
#endif
void sysclk_init(void)
{
uint8_t *reg = (uint8_t *) & PR.PRGEN;
uint8_t i;
#ifdef CONFIG_OSC_RC32_CAL
uint16_t cal;
/* avoid Cppcheck Warning */
UNUSED(cal);
#endif
bool need_rc2mhz = false;
/* Turn off all peripheral clocks that can be turned off. */
for (i = 0; i <= SYSCLK_PORT_F; i++) {
*(reg++) = 0xff;
}
/* Set up system clock prescalers if different from defaults */
if ((CONFIG_SYSCLK_PSADIV != SYSCLK_PSADIV_1)
|| (CONFIG_SYSCLK_PSBCDIV != SYSCLK_PSBCDIV_1_1)) {
sysclk_set_prescalers(CONFIG_SYSCLK_PSADIV, CONFIG_SYSCLK_PSBCDIV);
}
#if (CONFIG_OSC_RC32_CAL==48000000UL)
MSB(cal) =
nvm_read_production_signature_row
(nvm_get_production_signature_row_offset(USBRCOSC));
LSB(cal) =
nvm_read_production_signature_row
(nvm_get_production_signature_row_offset(USBRCOSCA));
/*
* If a device has an uncalibrated value in the
* production signature row (early sample part), load a
* sane default calibration value.
*/
if (cal == 0xFFFF) {
cal = 0x2340;
}
osc_user_calibration(OSC_ID_RC32MHZ, cal);
#endif
/*
* Switch to the selected initial system clock source, unless
* the default internal 2 MHz oscillator is selected.
*/
if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_RC2MHZ) {
need_rc2mhz = true;
} else {
switch (CONFIG_SYSCLK_SOURCE) {
case SYSCLK_SRC_RC32MHZ:
osc_enable(OSC_ID_RC32MHZ);
osc_wait_ready(OSC_ID_RC32MHZ);
#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) {
osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
}
osc_enable_autocalibration(OSC_ID_RC32MHZ,
CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
#endif
break;
case SYSCLK_SRC_RC32KHZ:
osc_enable(OSC_ID_RC32KHZ);
osc_wait_ready(OSC_ID_RC32KHZ);
break;
case SYSCLK_SRC_XOSC:
osc_enable(OSC_ID_XOSC);
osc_wait_ready(OSC_ID_XOSC);
break;
#ifdef CONFIG_PLL0_SOURCE
case SYSCLK_SRC_PLL:
if (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) {
need_rc2mhz = true;
}
pll_enable_config_defaults(0);
break;
#endif
#if XMEGA_E
case SYSCLK_SRC_RC8MHZ:
osc_enable(OSC_ID_RC8MHZ);
osc_wait_ready(OSC_ID_RC8MHZ);
break;
#endif
default:
//unhandled_case(CONFIG_SYSCLK_SOURCE);
return;
}
ccp_write_io((uint8_t *) & CLK.CTRL, CONFIG_SYSCLK_SOURCE);
Assert(CLK.CTRL == CONFIG_SYSCLK_SOURCE);
}
if (need_rc2mhz) {
#ifdef CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC
osc_enable(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
osc_wait_ready(CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
osc_enable_autocalibration(OSC_ID_RC2MHZ,
CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC);
#endif
} else {
osc_disable(OSC_ID_RC2MHZ);
}
#ifdef CONFIG_RTC_SOURCE
sysclk_rtcsrc_enable(CONFIG_RTC_SOURCE);
#endif
}
void sysclk_enable_module(enum sysclk_port_id port,
uint8_t id)
{
irqflags_t flags = cpu_irq_save();
*((uint8_t *) & PR.PRGEN + port) &= ~id;
cpu_irq_restore(flags);
}
void sysclk_disable_module(enum sysclk_port_id port,
uint8_t id)
{
irqflags_t flags = cpu_irq_save();
*((uint8_t *) & PR.PRGEN + port) |= id;
cpu_irq_restore(flags);
}
#if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__)
/**
* \brief Enable clock for the USB module
*
* \pre CONFIG_USBCLK_SOURCE must be defined.
*
* \param frequency The required USB clock frequency in MHz:
* \arg \c 6 for 6 MHz
* \arg \c 48 for 48 MHz
*/
void sysclk_enable_usb(uint8_t frequency)
{
uint8_t prescaler;
Assert((frequency == 6) || (frequency == 48));
/*
* Enable or disable prescaler depending on if the USB frequency is 6
* MHz or 48 MHz. Only 6 MHz USB frequency requires prescaling.
*/
if (frequency == 6) {
prescaler = CLK_USBPSDIV_8_gc;
} else {
prescaler = 0;
}
/*
* Switch to the system clock selected by the user.
*/
switch (CONFIG_USBCLK_SOURCE) {
case USBCLK_SRC_RCOSC:
if (!osc_is_ready(OSC_ID_RC32MHZ)) {
osc_enable(OSC_ID_RC32MHZ);
osc_wait_ready(OSC_ID_RC32MHZ);
#ifdef CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC
if (CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC != OSC_ID_USBSOF) {
osc_enable(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
osc_wait_ready(CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
}
osc_enable_autocalibration(OSC_ID_RC32MHZ,
CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC);
#endif
}
ccp_write_io((uint8_t *) & CLK.USBCTRL, (prescaler)
| CLK_USBSRC_RC32M_gc | CLK_USBSEN_bm);
break;
#ifdef CONFIG_PLL0_SOURCE
case USBCLK_SRC_PLL:
pll_enable_config_defaults(0);
ccp_write_io((uint8_t *) & CLK.USBCTRL, (prescaler)
| CLK_USBSRC_PLL_gc | CLK_USBSEN_bm);
break;
#endif
default:
Assert(false);
break;
}
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_USB);
}
/**
* \brief Disable clock for the USB module
*/
void sysclk_disable_usb(void)
{
sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_USB);
ccp_write_io((uint8_t *) & CLK.USBCTRL, 0);
}
#endif // XMEGA_AU || XMEGA_B || XMEGA_C
File diff suppressed because it is too large Load Diff
@@ -1,137 +1,137 @@
/**
* \file
*
* \brief Common Delay Service
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _DELAY_H_
#define _DELAY_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <sysclk.h>
#if UC3
# include <cycle_counter.h>
#elif XMEGA
# include "xmega/cycle_counter.h"
#elif MEGA
# include "mega/cycle_counter.h"
#elif SAM
# include "sam/cycle_counter.h"
#endif
/**
* @defgroup group_common_services_delay Busy-Wait Delay Routines
*
* This module provides simple loop-based delay routines for those
* applications requiring a brief wait during execution. Common API
* for UC3, XMEGA, and AVR MEGA.
*
* @{
*/
/**
* @def F_CPU
* @brief MCU Clock Frequency (Hertz)
*
* @deprecated
* The \ref F_CPU configuration constant is used for compatibility with the
* \ref group_common_services_delay routines. The common loop-based delay
* routines are designed to use the \ref clk_group modules while anticipating
* support for legacy applications assuming a statically defined clock
* frequency. Applications using a statically configured MCU clock frequency
* can define \ref F_CPU (Hertz), in which case the common delay routines will
* use this value rather than calling sysclk_get_cpu_hz() to get the current
* MCU clock frequency.
*/
#ifndef F_CPU
# define F_CPU sysclk_get_cpu_hz()
#endif
/**
* @def delay_init
*
* @brief Initialize the delay driver.
* @param fcpu_hz CPU frequency in Hz
*
* @deprecated
* This function is provided for compatibility with ASF applications that
* may not have been updated to configure the system clock via the common
* clock service; e.g. sysclk_init() and a configuration header file are
* used to configure clocks.
*
* The functions in this module call \ref sysclk_get_cpu_hz() function to
* obtain the system clock frequency.
*/
#define delay_init(fcpu_hz)
/**
* @def delay_s
* @brief Delay in seconds.
* @param delay Delay in seconds
*/
#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU)
/**
* @def delay_ms
* @brief Delay in milliseconds.
* @param delay Delay in milliseconds
*/
#define delay_ms(delay) cpu_delay_ms(delay, F_CPU)
/**
* @def delay_us
* @brief Delay in microseconds.
* @param delay Delay in microseconds
*/
#define delay_us(delay) cpu_delay_us(delay, F_CPU)
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* _DELAY_H_ */
/**
* \file
*
* \brief Common Delay Service
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _DELAY_H_
#define _DELAY_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <sysclk.h>
#if UC3
# include <cycle_counter.h>
#elif XMEGA
# include "xmega/cycle_counter.h"
#elif MEGA
# include "mega/cycle_counter.h"
#elif SAM
# include "sam/cycle_counter.h"
#endif
/**
* @defgroup group_common_services_delay Busy-Wait Delay Routines
*
* This module provides simple loop-based delay routines for those
* applications requiring a brief wait during execution. Common API
* for UC3, XMEGA, and AVR MEGA.
*
* @{
*/
/**
* @def F_CPU
* @brief MCU Clock Frequency (Hertz)
*
* @deprecated
* The \ref F_CPU configuration constant is used for compatibility with the
* \ref group_common_services_delay routines. The common loop-based delay
* routines are designed to use the \ref clk_group modules while anticipating
* support for legacy applications assuming a statically defined clock
* frequency. Applications using a statically configured MCU clock frequency
* can define \ref F_CPU (Hertz), in which case the common delay routines will
* use this value rather than calling sysclk_get_cpu_hz() to get the current
* MCU clock frequency.
*/
#ifndef F_CPU
# define F_CPU sysclk_get_cpu_hz()
#endif
/**
* @def delay_init
*
* @brief Initialize the delay driver.
* @param fcpu_hz CPU frequency in Hz
*
* @deprecated
* This function is provided for compatibility with ASF applications that
* may not have been updated to configure the system clock via the common
* clock service; e.g. sysclk_init() and a configuration header file are
* used to configure clocks.
*
* The functions in this module call \ref sysclk_get_cpu_hz() function to
* obtain the system clock frequency.
*/
#define delay_init(fcpu_hz)
/**
* @def delay_s
* @brief Delay in seconds.
* @param delay Delay in seconds
*/
#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU)
/**
* @def delay_ms
* @brief Delay in milliseconds.
* @param delay Delay in milliseconds
*/
#define delay_ms(delay) cpu_delay_ms(delay, F_CPU)
/**
* @def delay_us
* @brief Delay in microseconds.
* @param delay Delay in microseconds
*/
#define delay_us(delay) cpu_delay_us(delay, F_CPU)
#ifdef __cplusplus
}
#endif
/**
* @}
*/
#endif /* _DELAY_H_ */
@@ -1,118 +1,118 @@
/**
* \file
*
* \brief AVR functions for busy-wait delay loops
*
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _CYCLE_COUNTER_H_
#define _CYCLE_COUNTER_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <compiler.h>
/**
* @name Convenience functions for busy-wait delay loops
*
* @def delay_cycles
* @brief Delay program execution for a specified number of CPU cycles.
* @param n number of CPU cycles to wait
*
* @def cpu_delay_ms
* @brief Delay program execution for a specified number of milliseconds.
* @param delay number of milliseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_delay_us
* @brief Delay program execution for a specified number of microseconds.
* @param delay number of microseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_ms_2_cy
* @brief Convert milli-seconds into CPU cycles.
* @param ms number of milliseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @def cpu_us_2_cy
* @brief Convert micro-seconds into CPU cycles.
* @param ms number of microseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @{
*/
__always_optimize
static inline void __portable_avr_delay_cycles (unsigned long n)
{
do
{
barrier ();
}
while (--n);
}
#if !defined(__DELAY_CYCLE_INTRINSICS__)
# define delay_cycles __portable_avr_delay_cycles
# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3)
# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6)
#else
# if defined(__GNUC__)
# define delay_cycles __builtin_avr_delay_cycles
# elif defined(__ICCAVR__)
# define delay_cycles __delay_cycles
# endif
# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3)
# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6)
#endif
#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu))
#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu))
//! @}
#ifdef __cplusplus
}
#endif
#endif /* _CYCLE_COUNTER_H_ */
/**
* \file
*
* \brief AVR functions for busy-wait delay loops
*
* Copyright (c) 2011 - 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _CYCLE_COUNTER_H_
#define _CYCLE_COUNTER_H_
#ifdef __cplusplus
extern "C"
{
#endif
#include <compiler.h>
/**
* @name Convenience functions for busy-wait delay loops
*
* @def delay_cycles
* @brief Delay program execution for a specified number of CPU cycles.
* @param n number of CPU cycles to wait
*
* @def cpu_delay_ms
* @brief Delay program execution for a specified number of milliseconds.
* @param delay number of milliseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_delay_us
* @brief Delay program execution for a specified number of microseconds.
* @param delay number of microseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_ms_2_cy
* @brief Convert milli-seconds into CPU cycles.
* @param ms number of milliseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @def cpu_us_2_cy
* @brief Convert micro-seconds into CPU cycles.
* @param ms number of microseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @{
*/
__always_optimize
static inline void __portable_avr_delay_cycles (unsigned long n)
{
do
{
barrier ();
}
while (--n);
}
#if !defined(__DELAY_CYCLE_INTRINSICS__)
# define delay_cycles __portable_avr_delay_cycles
# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 6e3)
# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 6e6)
#else
# if defined(__GNUC__)
# define delay_cycles __builtin_avr_delay_cycles
# elif defined(__ICCAVR__)
# define delay_cycles __delay_cycles
# endif
# define cpu_ms_2_cy(ms, f_cpu) (((uint64_t)(ms) * (f_cpu) + 999) / 1e3)
# define cpu_us_2_cy(us, f_cpu) (((uint64_t)(us) * (f_cpu) + 999999ul) / 1e6)
#endif
#define cpu_delay_ms(delay, f_cpu) delay_cycles((uint64_t)cpu_ms_2_cy(delay, f_cpu))
#define cpu_delay_us(delay, f_cpu) delay_cycles((uint64_t)cpu_us_2_cy(delay, f_cpu))
//! @}
#ifdef __cplusplus
}
#endif
#endif /* _CYCLE_COUNTER_H_ */
@@ -1,83 +1,83 @@
/**
* \file
*
* \brief Common GPIO API.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include <parts.h>
#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E)
# include "sam_gpio/sam_gpio.h"
#elif XMEGA
# include "xmega_gpio/xmega_gpio.h"
#elif MEGA || MEGA_RF
# include "mega_gpio/mega_gpio.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup gpio_group General Purpose Input/Output
*
* This is the common API for GPIO. Additional features are available
* in the documentation of the specific modules.
*
* \section io_group_platform Platform Dependencies
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - gpio_pin_is_low()
* - gpio_pin_is_high()
* - gpio_set_pin_high()
* - gpio_set_pin_group_high()
* - gpio_set_pin_low()
* - gpio_set_pin_group_low()
* - gpio_toggle_pin()
* - gpio_toggle_pin_group()
* - gpio_configure_pin()
* - gpio_configure_group()
*/
#endif /* _GPIO_H_ */
/**
* \file
*
* \brief Common GPIO API.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include <parts.h>
#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E)
# include "sam_gpio/sam_gpio.h"
#elif XMEGA
# include "xmega_gpio/xmega_gpio.h"
#elif MEGA || MEGA_RF
# include "mega_gpio/mega_gpio.h"
#else
# error Unsupported chip type
#endif
/**
* \defgroup gpio_group General Purpose Input/Output
*
* This is the common API for GPIO. Additional features are available
* in the documentation of the specific modules.
*
* \section io_group_platform Platform Dependencies
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - gpio_pin_is_low()
* - gpio_pin_is_high()
* - gpio_set_pin_high()
* - gpio_set_pin_group_high()
* - gpio_set_pin_low()
* - gpio_set_pin_group_low()
* - gpio_toggle_pin()
* - gpio_toggle_pin_group()
* - gpio_configure_pin()
* - gpio_configure_group()
*/
#endif /* _GPIO_H_ */
@@ -1,80 +1,80 @@
/**
* \file
*
* \brief Common gpio data/structure for all AVR XMEGA implementations.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _XMEGA_GPIO_H_
#define _XMEGA_GPIO_H_
#include "compiler.h"
#include "ioport.h"
#define gpio_pin_is_low(io_id) \
ioport_pin_is_low(io_id)
#define gpio_pin_is_high(io_id) \
ioport_pin_is_high(io_id)
#define gpio_set_pin_high(io_id) \
ioport_set_value(io_id,1)
#define gpio_set_pin_low(io_id) \
ioport_set_value(io_id,0)
#define gpio_toggle_pin(io_id) \
ioport_toggle_pin(io_id)
#define gpio_configure_pin(io_id,io_flags) \
ioport_configure_pin(io_id,io_flags)
#define gpio_configure_group(port_id,port_mask,io_flags) \
ioport_configure_group(port_id,port_mask,io_flags)
#define gpio_set_pin_group_high(port_id,mask) \
ioport_set_group_high(port_id,mask)
#define gpio_set_pin_group_low(port_id,mask) \
ioport_set_group_low(port_id,mask)
#define gpio_toggle_pin_group(port_id,mask) \
ioport_tgl_group(port_id,mask)
#endif // _XMEGA_GPIO_H_
/**
* \file
*
* \brief Common gpio data/structure for all AVR XMEGA implementations.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _XMEGA_GPIO_H_
#define _XMEGA_GPIO_H_
#include "compiler.h"
#include "ioport.h"
#define gpio_pin_is_low(io_id) \
ioport_pin_is_low(io_id)
#define gpio_pin_is_high(io_id) \
ioport_pin_is_high(io_id)
#define gpio_set_pin_high(io_id) \
ioport_set_value(io_id,1)
#define gpio_set_pin_low(io_id) \
ioport_set_value(io_id,0)
#define gpio_toggle_pin(io_id) \
ioport_toggle_pin(io_id)
#define gpio_configure_pin(io_id,io_flags) \
ioport_configure_pin(io_id,io_flags)
#define gpio_configure_group(port_id,port_mask,io_flags) \
ioport_configure_group(port_id,port_mask,io_flags)
#define gpio_set_pin_group_high(port_id,mask) \
ioport_set_group_high(port_id,mask)
#define gpio_set_pin_group_low(port_id,mask) \
ioport_set_group_low(port_id,mask)
#define gpio_toggle_pin_group(port_id,mask) \
ioport_tgl_group(port_id,mask)
#endif // _XMEGA_GPIO_H_
File diff suppressed because it is too large Load Diff
@@ -1,367 +1,367 @@
/**
* \file
*
* \brief XMEGA architecture specific IOPORT service implementation header file.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef IOPORT_XMEGA_H
#define IOPORT_XMEGA_H
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin))
#define IOPORT_BASE_ADDRESS 0x600
#define IOPORT_PORT_OFFSET 0x20
/** \name IOPORT port numbers */
/** @{ */
#if !XMEGA_B3
# define IOPORT_PORTA 0
#endif
#define IOPORT_PORTB 1
#define IOPORT_PORTC 2
#define IOPORT_PORTD 3
#if !XMEGA_B3
# define IOPORT_PORTE 4
#endif
#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\
XMEGA_C3 || XMEGA_D3
# define IOPORT_PORTF 5
#endif
#if XMEGA_B1 || XMEGA_B3
# define IOPORT_PORTG 6
#endif
#if XMEGA_A1 || XMEGA_A1U
# define IOPORT_PORTH 7
# define IOPORT_PORTJ 8
# define IOPORT_PORTK 9
#endif
#if XMEGA_B1 || XMEGA_B3
# define IOPORT_PORTM 11
#endif
#if XMEGA_A1 || XMEGA_A1U
# define IOPORT_PORTQ 14
#endif
#define IOPORT_PORTR 15
/** @} */
/**
* \weakgroup ioport_group
* \section ioport_modes IOPORT Modes
*
* For details on these please see the XMEGA Manual.
*
* @{
*/
/** \name IOPORT Mode bit definitions */
/** @{ */
#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */
#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */
#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */
#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */
#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */
#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */
#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */
#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */
#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */
#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */
/** @} */
/** @} */
typedef uint8_t ioport_mode_t;
typedef uint8_t ioport_pin_t;
typedef uint8_t ioport_port_t;
typedef uint8_t ioport_port_mask_t;
__always_inline static ioport_port_t
arch_ioport_pin_to_port_id (ioport_pin_t pin)
{
return pin >> 3;
}
__always_inline static PORT_t *
arch_ioport_port_to_base (ioport_port_t port)
{
return (PORT_t *) ((uintptr_t) IOPORT_BASE_ADDRESS +
(port * IOPORT_PORT_OFFSET));
}
__always_inline static PORT_t *
arch_ioport_pin_to_base (ioport_pin_t pin)
{
return arch_ioport_port_to_base (arch_ioport_pin_to_port_id (pin));
}
__always_inline static ioport_port_mask_t
arch_ioport_pin_to_mask (ioport_pin_t pin)
{
return 1U << (pin & 0x07);
}
__always_inline static ioport_port_mask_t
arch_ioport_pin_to_index (ioport_pin_t pin)
{
return (pin & 0x07);
}
__always_inline static void
arch_ioport_init (void)
{
}
__always_inline static void
arch_ioport_enable_port (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
volatile uint8_t *pin_ctrl = &base->PIN0CTRL;
uint8_t flags = cpu_irq_save ();
for (uint8_t i = 0; i < 8; i++)
{
if (mask & arch_ioport_pin_to_mask (i))
{
pin_ctrl[i] &= ~PORT_ISC_gm;
}
}
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_enable_pin (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
volatile uint8_t *pin_ctrl =
(&base->PIN0CTRL + arch_ioport_pin_to_index (pin));
uint8_t flags = cpu_irq_save ();
*pin_ctrl &= ~PORT_ISC_gm;
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_disable_port (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
volatile uint8_t *pin_ctrl = &base->PIN0CTRL;
uint8_t flags = cpu_irq_save ();
for (uint8_t i = 0; i < 8; i++)
{
if (mask & arch_ioport_pin_to_mask (i))
{
pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc;
}
}
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_disable_pin (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
volatile uint8_t *pin_ctrl =
(&base->PIN0CTRL + arch_ioport_pin_to_index (pin));
uint8_t flags = cpu_irq_save ();
*pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc;
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_set_port_mode (ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
PORT_t *base = arch_ioport_port_to_base (port);
PORTCFG.MPCMASK = mask;
base->PIN0CTRL = mode;
}
__always_inline static void
arch_ioport_set_pin_mode (ioport_pin_t pin, ioport_mode_t mode)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
PORTCFG.MPCMASK = arch_ioport_pin_to_mask (pin);
base->PIN0CTRL = mode;
}
__always_inline static void
arch_ioport_set_port_dir (ioport_port_t port,
ioport_port_mask_t mask, enum ioport_direction dir)
{
PORT_t *base = arch_ioport_port_to_base (port);
if (dir == IOPORT_DIR_OUTPUT)
{
base->DIRSET = mask;
}
else if (dir == IOPORT_DIR_INPUT)
{
base->DIRCLR = mask;
}
}
__always_inline static void
arch_ioport_set_pin_dir (ioport_pin_t pin, enum ioport_direction dir)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
if (dir == IOPORT_DIR_OUTPUT)
{
base->DIRSET = arch_ioport_pin_to_mask (pin);
}
else if (dir == IOPORT_DIR_INPUT)
{
base->DIRCLR = arch_ioport_pin_to_mask (pin);
}
}
__always_inline static void
arch_ioport_set_pin_level (ioport_pin_t pin, bool level)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
if (level)
{
base->OUTSET = arch_ioport_pin_to_mask (pin);
}
else
{
base->OUTCLR = arch_ioport_pin_to_mask (pin);
}
}
__always_inline static void
arch_ioport_set_port_level (ioport_port_t port,
ioport_port_mask_t mask, ioport_port_mask_t level)
{
PORT_t *base = arch_ioport_port_to_base (port);
base->OUTSET = mask & level;
base->OUTCLR = mask & ~level;
}
__always_inline static bool
arch_ioport_get_pin_level (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
return base->IN & arch_ioport_pin_to_mask (pin);
}
__always_inline static ioport_port_mask_t
arch_ioport_get_port_level (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
return base->IN & mask;
}
__always_inline static void
arch_ioport_toggle_pin_level (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
base->OUTTGL = arch_ioport_pin_to_mask (pin);
}
__always_inline static void
arch_ioport_toggle_port_level (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
base->OUTTGL = mask;
}
__always_inline static void
arch_ioport_set_pin_sense_mode (ioport_pin_t pin, enum ioport_sense pin_sense)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
volatile uint8_t *pin_ctrl =
(&base->PIN0CTRL + arch_ioport_pin_to_index (pin));
uint8_t flags = cpu_irq_save ();
*pin_ctrl &= ~PORT_ISC_gm;
*pin_ctrl |= (pin_sense & PORT_ISC_gm);
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_set_port_sense_mode (ioport_port_t port,
ioport_port_mask_t mask,
enum ioport_sense pin_sense)
{
PORT_t *base = arch_ioport_port_to_base (port);
volatile uint8_t *pin_ctrl = &base->PIN0CTRL;
uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm);
uint8_t flags = cpu_irq_save ();
for (uint8_t i = 0; i < 8; i++)
{
if (mask & arch_ioport_pin_to_mask (i))
{
pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits;
}
}
cpu_irq_restore (flags);
}
#endif /* IOPORT_XMEGA_H */
/**
* \file
*
* \brief XMEGA architecture specific IOPORT service implementation header file.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef IOPORT_XMEGA_H
#define IOPORT_XMEGA_H
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 8 + (pin))
#define IOPORT_BASE_ADDRESS 0x600
#define IOPORT_PORT_OFFSET 0x20
/** \name IOPORT port numbers */
/** @{ */
#if !XMEGA_B3
# define IOPORT_PORTA 0
#endif
#define IOPORT_PORTB 1
#define IOPORT_PORTC 2
#define IOPORT_PORTD 3
#if !XMEGA_B3
# define IOPORT_PORTE 4
#endif
#if XMEGA_A1 || XMEGA_A1U || XMEGA_A3 || XMEGA_A3U || XMEGA_A3B || XMEGA_A3BU ||\
XMEGA_C3 || XMEGA_D3
# define IOPORT_PORTF 5
#endif
#if XMEGA_B1 || XMEGA_B3
# define IOPORT_PORTG 6
#endif
#if XMEGA_A1 || XMEGA_A1U
# define IOPORT_PORTH 7
# define IOPORT_PORTJ 8
# define IOPORT_PORTK 9
#endif
#if XMEGA_B1 || XMEGA_B3
# define IOPORT_PORTM 11
#endif
#if XMEGA_A1 || XMEGA_A1U
# define IOPORT_PORTQ 14
#endif
#define IOPORT_PORTR 15
/** @} */
/**
* \weakgroup ioport_group
* \section ioport_modes IOPORT Modes
*
* For details on these please see the XMEGA Manual.
*
* @{
*/
/** \name IOPORT Mode bit definitions */
/** @{ */
#define IOPORT_MODE_TOTEM (0x00 << 3) /*!< Totem-pole */
#define IOPORT_MODE_BUSKEEPER (0x01 << 3) /*!< Buskeeper */
#define IOPORT_MODE_PULLDOWN (0x02 << 3) /*!< Pull-down */
#define IOPORT_MODE_PULLUP (0x03 << 3) /*!< Pull-up */
#define IOPORT_MODE_WIREDOR (0x04 << 3) /*!< Wired OR */
#define IOPORT_MODE_WIREDAND (0x05 << 3) /*!< Wired AND */
#define IOPORT_MODE_WIREDORPULL (0x06 << 3) /*!< Wired OR with pull-down */
#define IOPORT_MODE_WIREDANDPULL (0x07 << 3) /*!< Wired AND with pull-up */
#define IOPORT_MODE_INVERT_PIN (0x01 << 6) /*!< Invert output and input */
#define IOPORT_MODE_SLEW_RATE_LIMIT (0x01 << 7) /*!< Slew rate limiting */
/** @} */
/** @} */
typedef uint8_t ioport_mode_t;
typedef uint8_t ioport_pin_t;
typedef uint8_t ioport_port_t;
typedef uint8_t ioport_port_mask_t;
__always_inline static ioport_port_t
arch_ioport_pin_to_port_id (ioport_pin_t pin)
{
return pin >> 3;
}
__always_inline static PORT_t *
arch_ioport_port_to_base (ioport_port_t port)
{
return (PORT_t *) ((uintptr_t) IOPORT_BASE_ADDRESS +
(port * IOPORT_PORT_OFFSET));
}
__always_inline static PORT_t *
arch_ioport_pin_to_base (ioport_pin_t pin)
{
return arch_ioport_port_to_base (arch_ioport_pin_to_port_id (pin));
}
__always_inline static ioport_port_mask_t
arch_ioport_pin_to_mask (ioport_pin_t pin)
{
return 1U << (pin & 0x07);
}
__always_inline static ioport_port_mask_t
arch_ioport_pin_to_index (ioport_pin_t pin)
{
return (pin & 0x07);
}
__always_inline static void
arch_ioport_init (void)
{
}
__always_inline static void
arch_ioport_enable_port (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
volatile uint8_t *pin_ctrl = &base->PIN0CTRL;
uint8_t flags = cpu_irq_save ();
for (uint8_t i = 0; i < 8; i++)
{
if (mask & arch_ioport_pin_to_mask (i))
{
pin_ctrl[i] &= ~PORT_ISC_gm;
}
}
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_enable_pin (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
volatile uint8_t *pin_ctrl =
(&base->PIN0CTRL + arch_ioport_pin_to_index (pin));
uint8_t flags = cpu_irq_save ();
*pin_ctrl &= ~PORT_ISC_gm;
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_disable_port (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
volatile uint8_t *pin_ctrl = &base->PIN0CTRL;
uint8_t flags = cpu_irq_save ();
for (uint8_t i = 0; i < 8; i++)
{
if (mask & arch_ioport_pin_to_mask (i))
{
pin_ctrl[i] |= PORT_ISC_INPUT_DISABLE_gc;
}
}
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_disable_pin (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
volatile uint8_t *pin_ctrl =
(&base->PIN0CTRL + arch_ioport_pin_to_index (pin));
uint8_t flags = cpu_irq_save ();
*pin_ctrl |= PORT_ISC_INPUT_DISABLE_gc;
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_set_port_mode (ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
PORT_t *base = arch_ioport_port_to_base (port);
PORTCFG.MPCMASK = mask;
base->PIN0CTRL = mode;
}
__always_inline static void
arch_ioport_set_pin_mode (ioport_pin_t pin, ioport_mode_t mode)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
PORTCFG.MPCMASK = arch_ioport_pin_to_mask (pin);
base->PIN0CTRL = mode;
}
__always_inline static void
arch_ioport_set_port_dir (ioport_port_t port,
ioport_port_mask_t mask, enum ioport_direction dir)
{
PORT_t *base = arch_ioport_port_to_base (port);
if (dir == IOPORT_DIR_OUTPUT)
{
base->DIRSET = mask;
}
else if (dir == IOPORT_DIR_INPUT)
{
base->DIRCLR = mask;
}
}
__always_inline static void
arch_ioport_set_pin_dir (ioport_pin_t pin, enum ioport_direction dir)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
if (dir == IOPORT_DIR_OUTPUT)
{
base->DIRSET = arch_ioport_pin_to_mask (pin);
}
else if (dir == IOPORT_DIR_INPUT)
{
base->DIRCLR = arch_ioport_pin_to_mask (pin);
}
}
__always_inline static void
arch_ioport_set_pin_level (ioport_pin_t pin, bool level)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
if (level)
{
base->OUTSET = arch_ioport_pin_to_mask (pin);
}
else
{
base->OUTCLR = arch_ioport_pin_to_mask (pin);
}
}
__always_inline static void
arch_ioport_set_port_level (ioport_port_t port,
ioport_port_mask_t mask, ioport_port_mask_t level)
{
PORT_t *base = arch_ioport_port_to_base (port);
base->OUTSET = mask & level;
base->OUTCLR = mask & ~level;
}
__always_inline static bool
arch_ioport_get_pin_level (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
return base->IN & arch_ioport_pin_to_mask (pin);
}
__always_inline static ioport_port_mask_t
arch_ioport_get_port_level (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
return base->IN & mask;
}
__always_inline static void
arch_ioport_toggle_pin_level (ioport_pin_t pin)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
base->OUTTGL = arch_ioport_pin_to_mask (pin);
}
__always_inline static void
arch_ioport_toggle_port_level (ioport_port_t port, ioport_port_mask_t mask)
{
PORT_t *base = arch_ioport_port_to_base (port);
base->OUTTGL = mask;
}
__always_inline static void
arch_ioport_set_pin_sense_mode (ioport_pin_t pin, enum ioport_sense pin_sense)
{
PORT_t *base = arch_ioport_pin_to_base (pin);
volatile uint8_t *pin_ctrl =
(&base->PIN0CTRL + arch_ioport_pin_to_index (pin));
uint8_t flags = cpu_irq_save ();
*pin_ctrl &= ~PORT_ISC_gm;
*pin_ctrl |= (pin_sense & PORT_ISC_gm);
cpu_irq_restore (flags);
}
__always_inline static void
arch_ioport_set_port_sense_mode (ioport_port_t port,
ioport_port_mask_t mask,
enum ioport_sense pin_sense)
{
PORT_t *base = arch_ioport_port_to_base (port);
volatile uint8_t *pin_ctrl = &base->PIN0CTRL;
uint8_t new_sense_bits = (pin_sense & PORT_ISC_gm);
uint8_t flags = cpu_irq_save ();
for (uint8_t i = 0; i < 8; i++)
{
if (mask & arch_ioport_pin_to_mask (i))
{
pin_ctrl[i] = (pin_ctrl[i] & ~PORT_ISC_gm) | new_sense_bits;
}
}
cpu_irq_restore (flags);
}
#endif /* IOPORT_XMEGA_H */
@@ -1,71 +1,71 @@
/**
* \file
*
* \brief XMEGA legacy IOPORT software compatibility driver interface.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "ioport_compat.h"
#if defined(IOPORT_XMEGA_COMPAT)
void ioport_configure_port_pin(void *port,
pin_mask_t pin_mask,
port_pin_flags_t flags)
{
uint8_t pin;
for (pin = 0; pin < 8; pin++) {
if (pin_mask & (1 << pin)) {
*((uint8_t *) port + PORT_PIN0CTRL + pin) = flags >> 8;
}
}
/* Select direction and initial pin state */
if (flags & IOPORT_DIR_OUTPUT) {
if (flags & IOPORT_INIT_HIGH) {
*((uint8_t *) port + PORT_OUTSET) = pin_mask;
} else {
*((uint8_t *) port + PORT_OUTCLR) = pin_mask;
}
*((uint8_t *) port + PORT_DIRSET) = pin_mask;
} else {
*((uint8_t *) port + PORT_DIRCLR) = pin_mask;
}
}
#endif
/**
* \file
*
* \brief XMEGA legacy IOPORT software compatibility driver interface.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "ioport_compat.h"
#if defined(IOPORT_XMEGA_COMPAT)
void ioport_configure_port_pin(void *port,
pin_mask_t pin_mask,
port_pin_flags_t flags)
{
uint8_t pin;
for (pin = 0; pin < 8; pin++) {
if (pin_mask & (1 << pin)) {
*((uint8_t *) port + PORT_PIN0CTRL + pin) = flags >> 8;
}
}
/* Select direction and initial pin state */
if (flags & IOPORT_DIR_OUTPUT) {
if (flags & IOPORT_INIT_HIGH) {
*((uint8_t *) port + PORT_OUTSET) = pin_mask;
} else {
*((uint8_t *) port + PORT_OUTCLR) = pin_mask;
}
*((uint8_t *) port + PORT_DIRSET) = pin_mask;
} else {
*((uint8_t *) port + PORT_DIRCLR) = pin_mask;
}
}
#endif
@@ -1,332 +1,332 @@
/**
* \file
*
* \brief XMEGA legacy IOPORT software compatibility driver interface header
* file.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef IOPORT_XMEGA_COMPAT_H_
#define IOPORT_XMEGA_COMPAT_H_
#include "../ioport.h"
/**
* \brief A pin mask
*
* This type is used to describe the port pin mask on the part.
*/
typedef uint8_t pin_mask_t;
/**
* \brief A PORT pin
*
* This type is used to describe the PORT pins on the part.
*/
typedef uint8_t port_pin_t;
/**
* \brief Pin configuration flags
*
* This is a bitmask containing configuration flags for the pins that shall be
* configured.
*/
typedef uint16_t port_pin_flags_t;
/**
* \brief A port id
*
* This type is used to describe the port id on the part (0 is PORTA).
*/
typedef uint8_t port_id_t;
/** \name Initial Output State Flags */
/** @{ */
#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */
#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */
/** @} */
/** \name Input/Sense Configuration Flags */
/** @{ */
#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */
#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */
#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */
#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */
#if XMEGA_E
# define IOPORT_FORCE_ENABLE (6 << 8) /*!< Sense Force Input Enable Low Level */
#endif
#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */
/** @} */
/** \name Output and Pull Configuration Flags */
/** @{ */
#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */
#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */
#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */
#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */
#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */
#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */
#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */
#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */
/** @} */
/** \name Inverted I/O Configuration Flags */
/** @{ */
#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */
#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */
/** @} */
/** \name Slew Rate Limit Configuration Flags */
/** @{ */
#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */
#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */
/** @} */
/**
* \internal
* \name PORT fields structure offset
*
* These macros are used to compute the field offset number with the PORT_t
* structure.
*/
/** @{ */
#define PORT_DIR 0x00 /*!< Data Direction */
#define PORT_DIRSET 0x01 /*!< Data Direction Set */
#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */
#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */
#define PORT_OUT 0x04 /*!< Data Output Value */
#define PORT_OUTSET 0x05 /*!< Data Output Value Set */
#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */
#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */
#define PORT_IN 0x08 /*!< Data Input Value */
#define PORT_INTCTRL 0x09 /*!< Interrupt Control */
#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */
#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */
#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */
#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */
#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */
#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */
#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */
#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */
#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */
#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */
#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */
/** @} */
static inline PORT_t *
ioport_pin_to_port (port_pin_t pin)
{
return arch_ioport_pin_to_base (pin);
}
static inline PORT_t *
ioport_id_pin_to_port (port_id_t port)
{
return arch_ioport_port_to_base (port);
}
/**
* \brief Configure the IO PORT pin function for a set of pins on a port
*
* \param port Pointer to the port
* \param pin_mask Mask containing the pins that should be configured
* \param flags Bitmask of flags specifying additional configuration
* parameters.
*/
void ioport_configure_port_pin (void *port, pin_mask_t pin_mask,
port_pin_flags_t flags);
/**
* \brief Select the port function for a single pin
*
* \param pin The pin to configure
* \param flags Bitmask of flags specifying additional configuration
* parameters.
*/
static inline void
ioport_configure_pin (port_pin_t pin, port_pin_flags_t flags)
{
ioport_configure_port_pin (arch_ioport_pin_to_base (pin),
arch_ioport_pin_to_mask (pin), flags);
}
/**
* \brief Configure a group of I/O pins on a specified port number
*
* \param port The port number
* \param pin_mask The pin mask to configure
* \param flags Bitmask of flags specifying additional configuration
* parameters.
*/
static inline void
ioport_configure_group (port_id_t port, pin_mask_t pin_mask,
port_pin_flags_t flags)
{
ioport_configure_port_pin (arch_ioport_port_to_base (port), pin_mask,
flags);
}
/**
* \brief Drive a PORT pin to a given state
*
* This function will only have an effect if \a pin is configured as
* an output.
*
* \param pin A number identifying the pin to act on.
* \param value The desired state of the pin. \a true means drive the
* pin high (towards Vdd), while \a false means drive the pin low
* (towards Vss).
*/
static inline void
ioport_set_value (port_pin_t pin, bool value)
{
arch_ioport_set_pin_level (pin, value);
}
/**
* \brief Drive a PORT pin to a low level
*
* This function will only have an effect if \a pin is configured as
* an output.
*
* \param pin A number identifying the pin to act on.
*/
static inline void
ioport_set_pin_low (port_pin_t pin)
{
arch_ioport_set_pin_level (pin, false);
}
/**
* \brief Drive a PORT pin to a high level
*
* This function will only have an effect if \a pin is configured as
* an output.
*
* \param pin A number identifying the pin to act on.
*/
static inline void
ioport_set_pin_high (port_pin_t pin)
{
arch_ioport_set_pin_level (pin, true);
}
/**
* \brief Read the current state of a PORT pin
*
* \param pin A number identifying the pin to read.
* \retval true The pin is currently high (close to Vdd)
* \retval false The pin is currently low (close to Vss)
*/
static inline bool
ioport_get_value (port_pin_t pin)
{
return arch_ioport_get_pin_level (pin);
}
/**
* \brief Read the current state of a PORT pin and test high level
*
* \param pin A number identifying the pin to read.
* \retval true The pin is currently high (close to Vdd)
* \retval false The pin is currently low (close to Vss)
*/
static inline bool
ioport_pin_is_high (port_pin_t pin)
{
return (arch_ioport_get_pin_level (pin) == true);
}
/**
* \brief Read the current state of a PORT pin and test high level
*
* \param pin A number identifying the pin to read.
* \retval true The pin is currently high (close to Vdd)
* \retval false The pin is currently low (close to Vss)
*/
static inline bool
ioport_pin_is_low (port_pin_t pin)
{
return (arch_ioport_get_pin_level (pin) == false);
}
/**
* \brief Toggle the current state of a PORT pin
*
* \param pin A number identifying the pin to act on.
*/
static inline void
ioport_toggle_pin (port_pin_t pin)
{
arch_ioport_toggle_pin_level (pin);
}
/*! \brief Drives a group of I/O pin of a port to high level.
*
* \param port_id The port number.
* \param port_mask The mask.
*/
static inline void
ioport_set_group_high (port_id_t port_id, pin_mask_t port_mask)
{
arch_ioport_set_port_level (port_id, port_mask, port_mask);
}
/*! \brief Drives a group of I/O pin of a port to low level.
*
* \param port_id The port number.
* \param port_mask The mask.
*/
static inline void
ioport_set_group_low (port_id_t port_id, pin_mask_t port_mask)
{
arch_ioport_set_port_level (port_id, port_mask, 0);
}
/*! \brief Toggles a group of I/O pin of a port.
*
* \param port_id The port number.
* \param port_mask The mask.
*/
static inline void
ioport_tgl_group (port_id_t port_id, pin_mask_t port_mask)
{
arch_ioport_toggle_port_level (port_id, port_mask);
}
#endif /* IOPORT_COMPAT_H_ */
/**
* \file
*
* \brief XMEGA legacy IOPORT software compatibility driver interface header
* file.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef IOPORT_XMEGA_COMPAT_H_
#define IOPORT_XMEGA_COMPAT_H_
#include "../ioport.h"
/**
* \brief A pin mask
*
* This type is used to describe the port pin mask on the part.
*/
typedef uint8_t pin_mask_t;
/**
* \brief A PORT pin
*
* This type is used to describe the PORT pins on the part.
*/
typedef uint8_t port_pin_t;
/**
* \brief Pin configuration flags
*
* This is a bitmask containing configuration flags for the pins that shall be
* configured.
*/
typedef uint16_t port_pin_flags_t;
/**
* \brief A port id
*
* This type is used to describe the port id on the part (0 is PORTA).
*/
typedef uint8_t port_id_t;
/** \name Initial Output State Flags */
/** @{ */
#define IOPORT_INIT_LOW (0 << 1) /*!< Initial Output State Low */
#define IOPORT_INIT_HIGH (1 << 1) /*!< Initial Output State High */
/** @} */
/** \name Input/Sense Configuration Flags */
/** @{ */
#define IOPORT_BOTHEDGES (0 << 8) /*!< Sense Both Edges */
#define IOPORT_RISING (1 << 8) /*!< Sense Rising Edge */
#define IOPORT_FALLING (2 << 8) /*!< Sense Falling Edge */
#define IOPORT_LEVEL (3 << 8) /*!< Sense Low Level */
#if XMEGA_E
# define IOPORT_FORCE_ENABLE (6 << 8) /*!< Sense Force Input Enable Low Level */
#endif
#define IOPORT_INPUT_DISABLE (7 << 8) /*!< Input Buffer Disabled */
/** @} */
/** \name Output and Pull Configuration Flags */
/** @{ */
#define IOPORT_TOTEM (0 << 11) /*!< Normal push/pull output */
#define IOPORT_BUSKEEPER (1 << 11) /*!< Bus Keeper */
#define IOPORT_PULL_DOWN (2 << 11) /*!< Pull-Down (when input) */
#define IOPORT_PULL_UP (3 << 11) /*!< Pull-Up (when input) */
#define IOPORT_WIRED_OR (4 << 11) /*!< Wired OR */
#define IOPORT_WIRED_AND (5 << 11) /*!< Wired AND */
#define IOPORT_WIRED_OR_PULL_DOWN (6 << 11) /*!< Wired OR and Pull-Down */
#define IOPORT_WIRED_AND_PULL_UP (7 << 11) /*!< Wired AND and Pull-Up */
/** @} */
/** \name Inverted I/O Configuration Flags */
/** @{ */
#define IOPORT_INV_ENABLED (1 << 14) /*!< I/O is Inverted */
#define IOPORT_INV_DISABLE (0 << 14) /*!< I/O is Not Inverted */
/** @} */
/** \name Slew Rate Limit Configuration Flags */
/** @{ */
#define IOPORT_SRL_ENABLED (1 << 15) /*!< Slew Rate Limit Enabled */
#define IOPORT_SRL_DISABLED (0 << 15) /*!< Slew Rate Limit Disabled */
/** @} */
/**
* \internal
* \name PORT fields structure offset
*
* These macros are used to compute the field offset number with the PORT_t
* structure.
*/
/** @{ */
#define PORT_DIR 0x00 /*!< Data Direction */
#define PORT_DIRSET 0x01 /*!< Data Direction Set */
#define PORT_DIRCLR 0x02 /*!< Data Direction Clear */
#define PORT_DIRTGL 0x03 /*!< Data Direction Toggle */
#define PORT_OUT 0x04 /*!< Data Output Value */
#define PORT_OUTSET 0x05 /*!< Data Output Value Set */
#define PORT_OUTCLR 0x06 /*!< Data Output Value Clear */
#define PORT_OUTTGL 0x07 /*!< Data Output Value Toggle */
#define PORT_IN 0x08 /*!< Data Input Value */
#define PORT_INTCTRL 0x09 /*!< Interrupt Control */
#define PORT_INT0MASK 0x0A /*!< Interrupt 0 Mask */
#define PORT_INT1MASK 0x0B /*!< Interrupt 1 Mask */
#define PORT_INTFLAGS 0x0C /*!< Interrupt Flags */
#define PORT_PIN0CTRL 0x10 /*!< Pin 0 Configuration */
#define PORT_PIN1CTRL 0x11 /*!< Pin 1 Configuration */
#define PORT_PIN2CTRL 0x12 /*!< Pin 2 Configuration */
#define PORT_PIN3CTRL 0x13 /*!< Pin 3 Configuration */
#define PORT_PIN4CTRL 0x14 /*!< Pin 4 Configuration */
#define PORT_PIN5CTRL 0x15 /*!< Pin 5 Configuration */
#define PORT_PIN6CTRL 0x16 /*!< Pin 6 Configuration */
#define PORT_PIN7CTRL 0x17 /*!< Pin 7 Configuration */
/** @} */
static inline PORT_t *
ioport_pin_to_port (port_pin_t pin)
{
return arch_ioport_pin_to_base (pin);
}
static inline PORT_t *
ioport_id_pin_to_port (port_id_t port)
{
return arch_ioport_port_to_base (port);
}
/**
* \brief Configure the IO PORT pin function for a set of pins on a port
*
* \param port Pointer to the port
* \param pin_mask Mask containing the pins that should be configured
* \param flags Bitmask of flags specifying additional configuration
* parameters.
*/
void ioport_configure_port_pin (void *port, pin_mask_t pin_mask,
port_pin_flags_t flags);
/**
* \brief Select the port function for a single pin
*
* \param pin The pin to configure
* \param flags Bitmask of flags specifying additional configuration
* parameters.
*/
static inline void
ioport_configure_pin (port_pin_t pin, port_pin_flags_t flags)
{
ioport_configure_port_pin (arch_ioport_pin_to_base (pin),
arch_ioport_pin_to_mask (pin), flags);
}
/**
* \brief Configure a group of I/O pins on a specified port number
*
* \param port The port number
* \param pin_mask The pin mask to configure
* \param flags Bitmask of flags specifying additional configuration
* parameters.
*/
static inline void
ioport_configure_group (port_id_t port, pin_mask_t pin_mask,
port_pin_flags_t flags)
{
ioport_configure_port_pin (arch_ioport_port_to_base (port), pin_mask,
flags);
}
/**
* \brief Drive a PORT pin to a given state
*
* This function will only have an effect if \a pin is configured as
* an output.
*
* \param pin A number identifying the pin to act on.
* \param value The desired state of the pin. \a true means drive the
* pin high (towards Vdd), while \a false means drive the pin low
* (towards Vss).
*/
static inline void
ioport_set_value (port_pin_t pin, bool value)
{
arch_ioport_set_pin_level (pin, value);
}
/**
* \brief Drive a PORT pin to a low level
*
* This function will only have an effect if \a pin is configured as
* an output.
*
* \param pin A number identifying the pin to act on.
*/
static inline void
ioport_set_pin_low (port_pin_t pin)
{
arch_ioport_set_pin_level (pin, false);
}
/**
* \brief Drive a PORT pin to a high level
*
* This function will only have an effect if \a pin is configured as
* an output.
*
* \param pin A number identifying the pin to act on.
*/
static inline void
ioport_set_pin_high (port_pin_t pin)
{
arch_ioport_set_pin_level (pin, true);
}
/**
* \brief Read the current state of a PORT pin
*
* \param pin A number identifying the pin to read.
* \retval true The pin is currently high (close to Vdd)
* \retval false The pin is currently low (close to Vss)
*/
static inline bool
ioport_get_value (port_pin_t pin)
{
return arch_ioport_get_pin_level (pin);
}
/**
* \brief Read the current state of a PORT pin and test high level
*
* \param pin A number identifying the pin to read.
* \retval true The pin is currently high (close to Vdd)
* \retval false The pin is currently low (close to Vss)
*/
static inline bool
ioport_pin_is_high (port_pin_t pin)
{
return (arch_ioport_get_pin_level (pin) == true);
}
/**
* \brief Read the current state of a PORT pin and test high level
*
* \param pin A number identifying the pin to read.
* \retval true The pin is currently high (close to Vdd)
* \retval false The pin is currently low (close to Vss)
*/
static inline bool
ioport_pin_is_low (port_pin_t pin)
{
return (arch_ioport_get_pin_level (pin) == false);
}
/**
* \brief Toggle the current state of a PORT pin
*
* \param pin A number identifying the pin to act on.
*/
static inline void
ioport_toggle_pin (port_pin_t pin)
{
arch_ioport_toggle_pin_level (pin);
}
/*! \brief Drives a group of I/O pin of a port to high level.
*
* \param port_id The port number.
* \param port_mask The mask.
*/
static inline void
ioport_set_group_high (port_id_t port_id, pin_mask_t port_mask)
{
arch_ioport_set_port_level (port_id, port_mask, port_mask);
}
/*! \brief Drives a group of I/O pin of a port to low level.
*
* \param port_id The port number.
* \param port_mask The mask.
*/
static inline void
ioport_set_group_low (port_id_t port_id, pin_mask_t port_mask)
{
arch_ioport_set_port_level (port_id, port_mask, 0);
}
/*! \brief Toggles a group of I/O pin of a port.
*
* \param port_id The port number.
* \param port_mask The mask.
*/
static inline void
ioport_tgl_group (port_id_t port_id, pin_mask_t port_mask)
{
arch_ioport_toggle_port_level (port_id, port_mask);
}
#endif /* IOPORT_COMPAT_H_ */
@@ -1,264 +1,264 @@
/**
* \file
*
* \brief Serial Mode management
*
* Copyright (c) 2010 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SERIAL_H_INCLUDED
#define SERIAL_H_INCLUDED
#include <parts.h>
#include "status_codes.h"
/**
* \typedef usart_if
*
* This type can be used independently to refer to USART module for the
* architecture used. It refers to the correct type definition for the
* architecture, ie. USART_t* for XMEGA or avr32_usart_t* for UC3.
*/
#if XMEGA
# include "xmega_usart/usart_serial.h"
#elif MEGA_RF
# include "megarf_usart/usart_serial.h"
#elif UC3
# include "uc3_usart/usart_serial.h"
#elif SAM
# include "sam_uart/uart_serial.h"
#else
# error Unsupported chip type
#endif
/**
*
* \defgroup serial_group Serial Interface (Serial)
*
* See \ref serial_quickstart.
*
* This is the common API for serial interface. Additional features are available
* in the documentation of the specific modules.
*
* \section serial_group_platform Platform Dependencies
*
* The serial API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - usart_serial_init()
* - usart_serial_putchar()
* - usart_serial_getchar()
* - usart_serial_write_packet()
* - usart_serial_read_packet()
*
*
* @{
*/
//! @}
/**
* \page serial_quickstart Quick start guide for Serial Interface service
*
* This is the quick start guide for the \ref serial_group "Serial Interface module", with
* step-by-step instructions on how to configure and use the serial in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section serial_use_cases Serial use cases
* - \ref serial_basic_use_case
* - \subpage serial_use_case_1
*
* \section serial_basic_use_case Basic use case - transmit a character
* In this use case, the serial module is configured for:
* - Using USARTD0
* - Baudrate: 9600
* - Character length: 8 bit
* - Parity mode: Disabled
* - Stop bit: None
* - RS232 mode
*
* The use case waits for a received character on the configured USART and
* echoes the character back to the same USART.
*
* \section serial_basic_use_case_setup Setup steps
*
* \subsection serial_basic_use_case_setup_prereq Prerequisites
* -# \ref sysclk_group "System Clock Management (sysclk)"
*
* \subsection serial_basic_use_case_setup_code Example code
* The following configuration must be added to the project (typically to a
* conf_serial.h file, but it can also be added to your main application file.)
* \code
* #define USART_SERIAL &USARTD0
* #define USART_SERIAL_BAUDRATE 9600
* #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc
* #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc
* #define USART_SERIAL_STOP_BIT false
* \endcode
*
* A variable for the received byte must be added:
* \code uint8_t received_byte; \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
*
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
*
* usart_serial_init(USART_SERIAL, &usart_options);
* \endcode
*
* \subsection serial_basic_use_case_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Create serial USART options struct:
* - \code
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
* \endcode
* -# Initialize the serial service:
* - \code usart_serial_init(USART_SERIAL, &usart_options);\endcode
*
* \section serial_basic_use_case_usage Usage steps
*
* \subsection serial_basic_use_case_usage_code Example code
* Add to application C-file:
* \code
* usart_serial_getchar(USART_SERIAL, &received_byte);
* usart_serial_putchar(USART_SERIAL, received_byte);
* \endcode
*
* \subsection serial_basic_use_case_usage_flow Workflow
* -# Wait for reception of a character:
* - \code usart_serial_getchar(USART_SERIAL, &received_byte); \endcode
* -# Echo the character back:
* - \code usart_serial_putchar(USART_SERIAL, received_byte); \endcode
*/
/**
* \page serial_use_case_1 Advanced use case - Send a packet of serial data
*
* In this use case, the USART module is configured for:
* - Using USARTD0
* - Baudrate: 9600
* - Character length: 8 bit
* - Parity mode: Disabled
* - Stop bit: None
* - RS232 mode
*
* The use case sends a string of text through the USART.
*
* \section serial_use_case_1_setup Setup steps
*
* \subsection serial_use_case_1_setup_prereq Prerequisites
* -# \ref sysclk_group "System Clock Management (sysclk)"
*
* \subsection serial_use_case_1_setup_code Example code
* The following configuration must be added to the project (typically to a
* conf_serial.h file, but it can also be added to your main application file.):
* \code
* #define USART_SERIAL &USARTD0
* #define USART_SERIAL_BAUDRATE 9600
* #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc
* #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc
* #define USART_SERIAL_STOP_BIT false
* \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
*
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
*
* usart_serial_init(USART_SERIAL, &usart_options);
* \endcode
*
* \subsection serial_use_case_1_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Create USART options struct:
* - \code
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
* \endcode
* -# Initialize in RS232 mode:
* - \code usart_serial_init(USART_SERIAL_EXAMPLE, &usart_options); \endcode
*
* \section serial_use_case_1_usage Usage steps
*
* \subsection serial_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String"));
* \endcode
*
* \subsection serial_use_case_1_usage_flow Workflow
* -# Write a string of text to the USART:
* - \code usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); \endcode
*/
#endif /* SERIAL_H_INCLUDED */
/**
* \file
*
* \brief Serial Mode management
*
* Copyright (c) 2010 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SERIAL_H_INCLUDED
#define SERIAL_H_INCLUDED
#include <parts.h>
#include "status_codes.h"
/**
* \typedef usart_if
*
* This type can be used independently to refer to USART module for the
* architecture used. It refers to the correct type definition for the
* architecture, ie. USART_t* for XMEGA or avr32_usart_t* for UC3.
*/
#if XMEGA
# include "xmega_usart/usart_serial.h"
#elif MEGA_RF
# include "megarf_usart/usart_serial.h"
#elif UC3
# include "uc3_usart/usart_serial.h"
#elif SAM
# include "sam_uart/uart_serial.h"
#else
# error Unsupported chip type
#endif
/**
*
* \defgroup serial_group Serial Interface (Serial)
*
* See \ref serial_quickstart.
*
* This is the common API for serial interface. Additional features are available
* in the documentation of the specific modules.
*
* \section serial_group_platform Platform Dependencies
*
* The serial API is partially chip- or platform-specific. While all
* platforms provide mostly the same functionality, there are some
* variations around how different bus types and clock tree structures
* are handled.
*
* The following functions are available on all platforms, but there may
* be variations in the function signature (i.e. parameters) and
* behaviour. These functions are typically called by platform-specific
* parts of drivers, and applications that aren't intended to be
* portable:
* - usart_serial_init()
* - usart_serial_putchar()
* - usart_serial_getchar()
* - usart_serial_write_packet()
* - usart_serial_read_packet()
*
*
* @{
*/
//! @}
/**
* \page serial_quickstart Quick start guide for Serial Interface service
*
* This is the quick start guide for the \ref serial_group "Serial Interface module", with
* step-by-step instructions on how to configure and use the serial in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section serial_use_cases Serial use cases
* - \ref serial_basic_use_case
* - \subpage serial_use_case_1
*
* \section serial_basic_use_case Basic use case - transmit a character
* In this use case, the serial module is configured for:
* - Using USARTD0
* - Baudrate: 9600
* - Character length: 8 bit
* - Parity mode: Disabled
* - Stop bit: None
* - RS232 mode
*
* The use case waits for a received character on the configured USART and
* echoes the character back to the same USART.
*
* \section serial_basic_use_case_setup Setup steps
*
* \subsection serial_basic_use_case_setup_prereq Prerequisites
* -# \ref sysclk_group "System Clock Management (sysclk)"
*
* \subsection serial_basic_use_case_setup_code Example code
* The following configuration must be added to the project (typically to a
* conf_serial.h file, but it can also be added to your main application file.)
* \code
* #define USART_SERIAL &USARTD0
* #define USART_SERIAL_BAUDRATE 9600
* #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc
* #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc
* #define USART_SERIAL_STOP_BIT false
* \endcode
*
* A variable for the received byte must be added:
* \code uint8_t received_byte; \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
*
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
*
* usart_serial_init(USART_SERIAL, &usart_options);
* \endcode
*
* \subsection serial_basic_use_case_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Create serial USART options struct:
* - \code
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
* \endcode
* -# Initialize the serial service:
* - \code usart_serial_init(USART_SERIAL, &usart_options);\endcode
*
* \section serial_basic_use_case_usage Usage steps
*
* \subsection serial_basic_use_case_usage_code Example code
* Add to application C-file:
* \code
* usart_serial_getchar(USART_SERIAL, &received_byte);
* usart_serial_putchar(USART_SERIAL, received_byte);
* \endcode
*
* \subsection serial_basic_use_case_usage_flow Workflow
* -# Wait for reception of a character:
* - \code usart_serial_getchar(USART_SERIAL, &received_byte); \endcode
* -# Echo the character back:
* - \code usart_serial_putchar(USART_SERIAL, received_byte); \endcode
*/
/**
* \page serial_use_case_1 Advanced use case - Send a packet of serial data
*
* In this use case, the USART module is configured for:
* - Using USARTD0
* - Baudrate: 9600
* - Character length: 8 bit
* - Parity mode: Disabled
* - Stop bit: None
* - RS232 mode
*
* The use case sends a string of text through the USART.
*
* \section serial_use_case_1_setup Setup steps
*
* \subsection serial_use_case_1_setup_prereq Prerequisites
* -# \ref sysclk_group "System Clock Management (sysclk)"
*
* \subsection serial_use_case_1_setup_code Example code
* The following configuration must be added to the project (typically to a
* conf_serial.h file, but it can also be added to your main application file.):
* \code
* #define USART_SERIAL &USARTD0
* #define USART_SERIAL_BAUDRATE 9600
* #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc
* #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc
* #define USART_SERIAL_STOP_BIT false
* \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
*
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
*
* usart_serial_init(USART_SERIAL, &usart_options);
* \endcode
*
* \subsection serial_use_case_1_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Create USART options struct:
* - \code
* static usart_serial_options_t usart_options = {
* .baudrate = USART_SERIAL_BAUDRATE,
* .charlength = USART_SERIAL_CHAR_LENGTH,
* .paritytype = USART_SERIAL_PARITY,
* .stopbits = USART_SERIAL_STOP_BIT
* };
* \endcode
* -# Initialize in RS232 mode:
* - \code usart_serial_init(USART_SERIAL_EXAMPLE, &usart_options); \endcode
*
* \section serial_use_case_1_usage Usage steps
*
* \subsection serial_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String"));
* \endcode
*
* \subsection serial_use_case_1_usage_flow Workflow
* -# Write a string of text to the USART:
* - \code usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); \endcode
*/
#endif /* SERIAL_H_INCLUDED */
@@ -1,83 +1,83 @@
/**
*
* \file
*
* \brief USART Serial driver functions.
*
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "serial.h"
/**
* \brief Send a sequence of bytes to USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to read
* \param len Length of data
*
*/
status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data,
size_t len)
{
while (len) {
usart_serial_putchar(usart, *data);
len--;
data++;
}
return STATUS_OK;
}
/**
* \brief Receive a sequence of bytes from USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to write
* \param len Length of data
*
*/
status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data,
size_t len)
{
while (len) {
usart_serial_getchar(usart, data);
len--;
data++;
}
return STATUS_OK;
}
/**
*
* \file
*
* \brief USART Serial driver functions.
*
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "serial.h"
/**
* \brief Send a sequence of bytes to USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to read
* \param len Length of data
*
*/
status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data,
size_t len)
{
while (len) {
usart_serial_putchar(usart, *data);
len--;
data++;
}
return STATUS_OK;
}
/**
* \brief Receive a sequence of bytes from USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to write
* \param len Length of data
*
*/
status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data,
size_t len)
{
while (len) {
usart_serial_getchar(usart, data);
len--;
data++;
}
return STATUS_OK;
}
@@ -1,170 +1,170 @@
/**
* \file
*
* This file defines a useful set of functions for the Serial interface on AVR
* XMEGA devices.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _USART_SERIAL_H_
#define _USART_SERIAL_H_
#include "compiler.h"
#include "sysclk.h"
#include "status_codes.h"
#include "usart.h"
/*! \name Serial Management Configuration
*/
//! @{
#include "conf_usart_serial.h"
//! @}
typedef usart_rs232_options_t usart_serial_options_t;
typedef USART_t *usart_if;
/*! \brief Initializes the Usart in master mode.
*
* \param usart Base address of the USART instance.
* \param options Options needed to set up RS232 communication (see \ref usart_serial_options_t).
*
* \retval true if the initialization was successful
* \retval false if initialization failed (error in baud rate calculation)
*/
static inline bool usart_serial_init(usart_if usart, const
usart_serial_options_t *options)
{
// USART options.
usart_rs232_options_t usart_rs232_options;
usart_rs232_options.charlength = options->charlength;
usart_rs232_options.paritytype = options->paritytype;
usart_rs232_options.stopbits = options->stopbits;
usart_rs232_options.baudrate = options->baudrate;
#ifdef USARTC0
if((uint16_t)usart == (uint16_t)&USARTC0) {
sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm);
}
#endif
#ifdef USARTC1
if((uint16_t)usart == (uint16_t)&USARTC1) {
sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm);
}
#endif
#ifdef USARTD0
if((uint16_t)usart == (uint16_t)&USARTD0) {
sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm);
}
#endif
#ifdef USARTD1
if((uint16_t)usart == (uint16_t)&USARTD1) {
sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm);
}
#endif
#ifdef USARTE0
if((uint16_t)usart == (uint16_t)&USARTE0) {
sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm);
}
#endif
#ifdef USARTE1
if((uint16_t)usart == (uint16_t)&USARTE1) {
sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm);
}
#endif
#ifdef USARTF0
if((uint16_t)usart == (uint16_t)&USARTF0) {
sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm);
}
#endif
#ifdef USARTF1
if((uint16_t)usart == (uint16_t)&USARTF1) {
sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm);
}
#endif
if (usart_init_rs232(usart, &usart_rs232_options)) {
return true;
}
else {
return false;
}
}
/*! \brief Sends a character with the USART.
*
* \param usart Base address of the USART instance.
* \param c Character to write.
*
* \return Status code
*/
static inline enum status_code usart_serial_putchar(usart_if usart, uint8_t c)
{
return usart_putchar(usart, c);
}
/*! \brief Waits until a character is received, and returns it.
*
* \param usart Base address of the USART instance.
* \param data Data to read
*
*/
static inline void usart_serial_getchar(usart_if usart, uint8_t *data)
{
*data = usart_getchar(usart);
}
/**
* \brief Send a sequence of bytes to USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to read
* \param len Length of data
*
*/
extern status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, size_t len);
/**
* \brief Receive a sequence of bytes from USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to write
* \param len Length of data
*
*/
extern status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data, size_t len);
#endif // _USART_SERIAL_H_
/**
* \file
*
* This file defines a useful set of functions for the Serial interface on AVR
* XMEGA devices.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _USART_SERIAL_H_
#define _USART_SERIAL_H_
#include "compiler.h"
#include "sysclk.h"
#include "status_codes.h"
#include "usart.h"
/*! \name Serial Management Configuration
*/
//! @{
#include "conf_usart_serial.h"
//! @}
typedef usart_rs232_options_t usart_serial_options_t;
typedef USART_t *usart_if;
/*! \brief Initializes the Usart in master mode.
*
* \param usart Base address of the USART instance.
* \param options Options needed to set up RS232 communication (see \ref usart_serial_options_t).
*
* \retval true if the initialization was successful
* \retval false if initialization failed (error in baud rate calculation)
*/
static inline bool usart_serial_init(usart_if usart, const
usart_serial_options_t *options)
{
// USART options.
usart_rs232_options_t usart_rs232_options;
usart_rs232_options.charlength = options->charlength;
usart_rs232_options.paritytype = options->paritytype;
usart_rs232_options.stopbits = options->stopbits;
usart_rs232_options.baudrate = options->baudrate;
#ifdef USARTC0
if((uint16_t)usart == (uint16_t)&USARTC0) {
sysclk_enable_module(SYSCLK_PORT_C,PR_USART0_bm);
}
#endif
#ifdef USARTC1
if((uint16_t)usart == (uint16_t)&USARTC1) {
sysclk_enable_module(SYSCLK_PORT_C,PR_USART1_bm);
}
#endif
#ifdef USARTD0
if((uint16_t)usart == (uint16_t)&USARTD0) {
sysclk_enable_module(SYSCLK_PORT_D,PR_USART0_bm);
}
#endif
#ifdef USARTD1
if((uint16_t)usart == (uint16_t)&USARTD1) {
sysclk_enable_module(SYSCLK_PORT_D,PR_USART1_bm);
}
#endif
#ifdef USARTE0
if((uint16_t)usart == (uint16_t)&USARTE0) {
sysclk_enable_module(SYSCLK_PORT_E,PR_USART0_bm);
}
#endif
#ifdef USARTE1
if((uint16_t)usart == (uint16_t)&USARTE1) {
sysclk_enable_module(SYSCLK_PORT_E,PR_USART1_bm);
}
#endif
#ifdef USARTF0
if((uint16_t)usart == (uint16_t)&USARTF0) {
sysclk_enable_module(SYSCLK_PORT_F,PR_USART0_bm);
}
#endif
#ifdef USARTF1
if((uint16_t)usart == (uint16_t)&USARTF1) {
sysclk_enable_module(SYSCLK_PORT_F,PR_USART1_bm);
}
#endif
if (usart_init_rs232(usart, &usart_rs232_options)) {
return true;
}
else {
return false;
}
}
/*! \brief Sends a character with the USART.
*
* \param usart Base address of the USART instance.
* \param c Character to write.
*
* \return Status code
*/
static inline enum status_code usart_serial_putchar(usart_if usart, uint8_t c)
{
return usart_putchar(usart, c);
}
/*! \brief Waits until a character is received, and returns it.
*
* \param usart Base address of the USART instance.
* \param data Data to read
*
*/
static inline void usart_serial_getchar(usart_if usart, uint8_t *data)
{
*data = usart_getchar(usart);
}
/**
* \brief Send a sequence of bytes to USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to read
* \param len Length of data
*
*/
extern status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, size_t len);
/**
* \brief Receive a sequence of bytes from USART device
*
* \param usart Base address of the USART instance.
* \param data Data buffer to write
* \param len Length of data
*
*/
extern status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data, size_t len);
#endif // _USART_SERIAL_H_
@@ -1,252 +1,252 @@
/**
* \file
*
* \brief Sleep manager
*
* Copyright (c) 2010 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SLEEPMGR_H
#define SLEEPMGR_H
#include <compiler.h>
#include <parts.h>
#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E)
# include "sam/sleepmgr.h"
#elif XMEGA
# include "xmega/sleepmgr.h"
#elif UC3
# include "uc3/sleepmgr.h"
#elif SAM4L
# include "sam4l/sleepmgr.h"
#else
# error Unsupported device.
#endif
/**
* \defgroup sleepmgr_group Sleep manager
*
* The sleep manager is a service for ensuring that the device is not put to
* sleep in deeper sleep modes than the system (e.g., peripheral drivers,
* services or the application) allows at any given time.
*
* It is based on the use of lock counting for the individual sleep modes, and
* will put the device to sleep in the shallowest sleep mode that has a non-zero
* lock count. The drivers/services/application can change these counts by use
* of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode.
* Refer to \ref sleepmgr_mode for a list of the sleep modes available for
* locking, and the device datasheet for information on their effect.
*
* The application must supply the file \ref conf_sleepmgr.h.
*
* For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE
* must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not
* defined, the functions are replaced with dummy functions and no RAM is used.
*
* @{
*/
/**
* \def CONFIG_SLEEPMGR_ENABLE
* \brief Configuration symbol for enabling the sleep manager
*
* If this symbol is not defined, the functions of this service are replaced
* with dummy functions. This is useful for reducing code size and execution
* time if the sleep manager is not needed in the application.
*
* This symbol may be defined in \ref conf_sleepmgr.h.
*/
#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE)
# define CONFIG_SLEEPMGR_ENABLE
#endif
/**
* \enum sleepmgr_mode
* \brief Sleep mode locks
*
* Identifiers for the different sleep mode locks.
*/
/**
* \brief Initialize the lock counts
*
* Sets all lock counts to 0, except the very last one, which is set to 1. This
* is done to simplify the algorithm for finding the deepest allowable sleep
* mode in \ref sleepmgr_enter_sleep.
*/
static inline void
sleepmgr_init (void)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
uint8_t i;
for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++)
{
sleepmgr_locks[i] = 0;
}
sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1;
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
/**
* \brief Increase lock count for a sleep mode
*
* Increases the lock count for \a mode to ensure that the sleep manager does
* not put the device to sleep in the deeper sleep modes.
*
* \param mode Sleep mode to lock.
*/
static inline void
sleepmgr_lock_mode (enum sleepmgr_mode mode)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
irqflags_t flags;
Assert (sleepmgr_locks[mode] < 0xff);
// Enter a critical section
flags = cpu_irq_save ();
++sleepmgr_locks[mode];
// Leave the critical section
cpu_irq_restore (flags);
#else
UNUSED (mode);
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
/**
* \brief Decrease lock count for a sleep mode
*
* Decreases the lock count for \a mode. If the lock count reaches 0, the sleep
* manager can put the device to sleep in the deeper sleep modes.
*
* \param mode Sleep mode to unlock.
*/
static inline void
sleepmgr_unlock_mode (enum sleepmgr_mode mode)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
irqflags_t flags;
Assert (sleepmgr_locks[mode]);
// Enter a critical section
flags = cpu_irq_save ();
--sleepmgr_locks[mode];
// Leave the critical section
cpu_irq_restore (flags);
#else
UNUSED (mode);
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
/**
* \brief Retrieves the deepest allowable sleep mode
*
* Searches through the sleep mode lock counts, starting at the shallowest sleep
* mode, until the first non-zero lock count is found. The deepest allowable
* sleep mode is then returned.
*/
static inline enum sleepmgr_mode
sleepmgr_get_sleep_mode (void)
{
enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE;
#ifdef CONFIG_SLEEPMGR_ENABLE
uint8_t *lock_ptr = sleepmgr_locks;
// Find first non-zero lock count, starting with the shallowest modes.
while (!(*lock_ptr))
{
lock_ptr++;
sleep_mode++;
}
// Catch the case where one too many sleepmgr_unlock_mode() call has been
// performed on the deepest sleep mode.
Assert ((uintptr_t) (lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES);
#endif /* CONFIG_SLEEPMGR_ENABLE */
return sleep_mode;
}
/**
* \fn sleepmgr_enter_sleep
* \brief Go to sleep in the deepest allowed mode
*
* Searches through the sleep mode lock counts, starting at the shallowest sleep
* mode, until the first non-zero lock count is found. The device is then put to
* sleep in the sleep mode that corresponds to the lock.
*
* \note This function enables interrupts before going to sleep, and will leave
* them enabled upon return. This also applies if sleep is skipped due to ACTIVE
* mode being locked.
*/
static inline void
sleepmgr_enter_sleep (void)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
enum sleepmgr_mode sleep_mode;
cpu_irq_disable ();
// Find the deepest allowable sleep mode
sleep_mode = sleepmgr_get_sleep_mode ();
// Return right away if first mode (ACTIVE) is locked.
if (sleep_mode == SLEEPMGR_ACTIVE)
{
cpu_irq_enable ();
return;
}
// Enter the deepest allowable sleep mode with interrupts enabled
sleepmgr_sleep (sleep_mode);
#else
cpu_irq_enable ();
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
//! @}
#endif /* SLEEPMGR_H */
/**
* \file
*
* \brief Sleep manager
*
* Copyright (c) 2010 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SLEEPMGR_H
#define SLEEPMGR_H
#include <compiler.h>
#include <parts.h>
#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E)
# include "sam/sleepmgr.h"
#elif XMEGA
# include "xmega/sleepmgr.h"
#elif UC3
# include "uc3/sleepmgr.h"
#elif SAM4L
# include "sam4l/sleepmgr.h"
#else
# error Unsupported device.
#endif
/**
* \defgroup sleepmgr_group Sleep manager
*
* The sleep manager is a service for ensuring that the device is not put to
* sleep in deeper sleep modes than the system (e.g., peripheral drivers,
* services or the application) allows at any given time.
*
* It is based on the use of lock counting for the individual sleep modes, and
* will put the device to sleep in the shallowest sleep mode that has a non-zero
* lock count. The drivers/services/application can change these counts by use
* of \ref sleepmgr_lock_mode and \ref sleepmgr_unlock_mode.
* Refer to \ref sleepmgr_mode for a list of the sleep modes available for
* locking, and the device datasheet for information on their effect.
*
* The application must supply the file \ref conf_sleepmgr.h.
*
* For the sleep manager to be enabled, the symbol \ref CONFIG_SLEEPMGR_ENABLE
* must be defined, e.g., in \ref conf_sleepmgr.h. If this symbol is not
* defined, the functions are replaced with dummy functions and no RAM is used.
*
* @{
*/
/**
* \def CONFIG_SLEEPMGR_ENABLE
* \brief Configuration symbol for enabling the sleep manager
*
* If this symbol is not defined, the functions of this service are replaced
* with dummy functions. This is useful for reducing code size and execution
* time if the sleep manager is not needed in the application.
*
* This symbol may be defined in \ref conf_sleepmgr.h.
*/
#if defined(__DOXYGEN__) && !defined(CONFIG_SLEEPMGR_ENABLE)
# define CONFIG_SLEEPMGR_ENABLE
#endif
/**
* \enum sleepmgr_mode
* \brief Sleep mode locks
*
* Identifiers for the different sleep mode locks.
*/
/**
* \brief Initialize the lock counts
*
* Sets all lock counts to 0, except the very last one, which is set to 1. This
* is done to simplify the algorithm for finding the deepest allowable sleep
* mode in \ref sleepmgr_enter_sleep.
*/
static inline void
sleepmgr_init (void)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
uint8_t i;
for (i = 0; i < SLEEPMGR_NR_OF_MODES - 1; i++)
{
sleepmgr_locks[i] = 0;
}
sleepmgr_locks[SLEEPMGR_NR_OF_MODES - 1] = 1;
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
/**
* \brief Increase lock count for a sleep mode
*
* Increases the lock count for \a mode to ensure that the sleep manager does
* not put the device to sleep in the deeper sleep modes.
*
* \param mode Sleep mode to lock.
*/
static inline void
sleepmgr_lock_mode (enum sleepmgr_mode mode)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
irqflags_t flags;
Assert (sleepmgr_locks[mode] < 0xff);
// Enter a critical section
flags = cpu_irq_save ();
++sleepmgr_locks[mode];
// Leave the critical section
cpu_irq_restore (flags);
#else
UNUSED (mode);
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
/**
* \brief Decrease lock count for a sleep mode
*
* Decreases the lock count for \a mode. If the lock count reaches 0, the sleep
* manager can put the device to sleep in the deeper sleep modes.
*
* \param mode Sleep mode to unlock.
*/
static inline void
sleepmgr_unlock_mode (enum sleepmgr_mode mode)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
irqflags_t flags;
Assert (sleepmgr_locks[mode]);
// Enter a critical section
flags = cpu_irq_save ();
--sleepmgr_locks[mode];
// Leave the critical section
cpu_irq_restore (flags);
#else
UNUSED (mode);
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
/**
* \brief Retrieves the deepest allowable sleep mode
*
* Searches through the sleep mode lock counts, starting at the shallowest sleep
* mode, until the first non-zero lock count is found. The deepest allowable
* sleep mode is then returned.
*/
static inline enum sleepmgr_mode
sleepmgr_get_sleep_mode (void)
{
enum sleepmgr_mode sleep_mode = SLEEPMGR_ACTIVE;
#ifdef CONFIG_SLEEPMGR_ENABLE
uint8_t *lock_ptr = sleepmgr_locks;
// Find first non-zero lock count, starting with the shallowest modes.
while (!(*lock_ptr))
{
lock_ptr++;
sleep_mode++;
}
// Catch the case where one too many sleepmgr_unlock_mode() call has been
// performed on the deepest sleep mode.
Assert ((uintptr_t) (lock_ptr - sleepmgr_locks) < SLEEPMGR_NR_OF_MODES);
#endif /* CONFIG_SLEEPMGR_ENABLE */
return sleep_mode;
}
/**
* \fn sleepmgr_enter_sleep
* \brief Go to sleep in the deepest allowed mode
*
* Searches through the sleep mode lock counts, starting at the shallowest sleep
* mode, until the first non-zero lock count is found. The device is then put to
* sleep in the sleep mode that corresponds to the lock.
*
* \note This function enables interrupts before going to sleep, and will leave
* them enabled upon return. This also applies if sleep is skipped due to ACTIVE
* mode being locked.
*/
static inline void
sleepmgr_enter_sleep (void)
{
#ifdef CONFIG_SLEEPMGR_ENABLE
enum sleepmgr_mode sleep_mode;
cpu_irq_disable ();
// Find the deepest allowable sleep mode
sleep_mode = sleepmgr_get_sleep_mode ();
// Return right away if first mode (ACTIVE) is locked.
if (sleep_mode == SLEEPMGR_ACTIVE)
{
cpu_irq_enable ();
return;
}
// Enter the deepest allowable sleep mode with interrupts enabled
sleepmgr_sleep (sleep_mode);
#else
cpu_irq_enable ();
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
//! @}
#endif /* SLEEPMGR_H */
@@ -1,58 +1,58 @@
/**
* \file
*
* \brief Sleep manager
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <sleepmgr.h>
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES];
enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = {
SLEEP_SMODE_IDLE_gc,
SLEEP_SMODE_ESTDBY_gc,
SLEEP_SMODE_PSAVE_gc,
SLEEP_SMODE_STDBY_gc,
SLEEP_SMODE_PDOWN_gc,
};
#endif /* CONFIG_SLEEPMGR_ENABLE */
/**
* \file
*
* \brief Sleep manager
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <sleepmgr.h>
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
uint8_t sleepmgr_locks[SLEEPMGR_NR_OF_MODES];
enum SLEEP_SMODE_enum sleepmgr_configs[SLEEPMGR_NR_OF_MODES] = {
SLEEP_SMODE_IDLE_gc,
SLEEP_SMODE_ESTDBY_gc,
SLEEP_SMODE_PSAVE_gc,
SLEEP_SMODE_STDBY_gc,
SLEEP_SMODE_PDOWN_gc,
};
#endif /* CONFIG_SLEEPMGR_ENABLE */
@@ -1,116 +1,116 @@
/**
* \file
*
* \brief AVR XMEGA Sleep manager implementation
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_SLEEPMGR_H
#define XMEGA_SLEEPMGR_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <compiler.h>
#include <conf_sleepmgr.h>
#include <sleep.h>
/**
* \weakgroup sleepmgr_group
* @{
*/
enum sleepmgr_mode
{
//! Active mode.
SLEEPMGR_ACTIVE = 0,
//! Idle mode.
SLEEPMGR_IDLE,
//! Extended Standby mode.
SLEEPMGR_ESTDBY,
//! Power Save mode.
SLEEPMGR_PSAVE,
//! Standby mode.
SLEEPMGR_STDBY,
//! Power Down mode.
SLEEPMGR_PDOWN,
SLEEPMGR_NR_OF_MODES,
};
/**
* \internal
* \name Internal arrays
* @{
*/
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
//! Sleep mode lock counters
extern uint8_t sleepmgr_locks[];
/**
* \brief Look-up table with sleep mode configurations
* \note This is located in program memory (Flash) as it is constant.
*/
extern enum SLEEP_SMODE_enum sleepmgr_configs[];
#endif /* CONFIG_SLEEPMGR_ENABLE */
//! @}
static inline void sleepmgr_sleep (const enum sleepmgr_mode sleep_mode)
{
Assert (sleep_mode != SLEEPMGR_ACTIVE);
#ifdef CONFIG_SLEEPMGR_ENABLE
sleep_set_mode (sleepmgr_configs[sleep_mode - 1]);
sleep_enable ();
cpu_irq_enable ();
sleep_enter ();
sleep_disable ();
#else
cpu_irq_enable ();
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
//! @}
#ifdef __cplusplus
}
#endif
#endif /* XMEGA_SLEEPMGR_H */
/**
* \file
*
* \brief AVR XMEGA Sleep manager implementation
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_SLEEPMGR_H
#define XMEGA_SLEEPMGR_H
#ifdef __cplusplus
extern "C"
{
#endif
#include <compiler.h>
#include <conf_sleepmgr.h>
#include <sleep.h>
/**
* \weakgroup sleepmgr_group
* @{
*/
enum sleepmgr_mode
{
//! Active mode.
SLEEPMGR_ACTIVE = 0,
//! Idle mode.
SLEEPMGR_IDLE,
//! Extended Standby mode.
SLEEPMGR_ESTDBY,
//! Power Save mode.
SLEEPMGR_PSAVE,
//! Standby mode.
SLEEPMGR_STDBY,
//! Power Down mode.
SLEEPMGR_PDOWN,
SLEEPMGR_NR_OF_MODES,
};
/**
* \internal
* \name Internal arrays
* @{
*/
#if defined(CONFIG_SLEEPMGR_ENABLE) || defined(__DOXYGEN__)
//! Sleep mode lock counters
extern uint8_t sleepmgr_locks[];
/**
* \brief Look-up table with sleep mode configurations
* \note This is located in program memory (Flash) as it is constant.
*/
extern enum SLEEP_SMODE_enum sleepmgr_configs[];
#endif /* CONFIG_SLEEPMGR_ENABLE */
//! @}
static inline void sleepmgr_sleep (const enum sleepmgr_mode sleep_mode)
{
Assert (sleep_mode != SLEEPMGR_ACTIVE);
#ifdef CONFIG_SLEEPMGR_ENABLE
sleep_set_mode (sleepmgr_configs[sleep_mode - 1]);
sleep_enable ();
cpu_irq_enable ();
sleep_enter ();
sleep_disable ();
#else
cpu_irq_enable ();
#endif /* CONFIG_SLEEPMGR_ENABLE */
}
//! @}
#ifdef __cplusplus
}
#endif
#endif /* XMEGA_SLEEPMGR_H */
@@ -1,139 +1,139 @@
/**
* \file
*
* \brief Global interrupt management for 8- and 32-bit AVR
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef UTILS_INTERRUPT_H
#define UTILS_INTERRUPT_H
#include <parts.h>
#if XMEGA || MEGA || TINY
# include "interrupt/interrupt_avr8.h"
#elif UC3
# include "interrupt/interrupt_avr32.h"
#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E
# include "interrupt/interrupt_sam_nvic.h"
#else
# error Unsupported device.
#endif
/**
* \defgroup interrupt_group Global interrupt management
*
* This is a driver for global enabling and disabling of interrupts.
*
* @{
*/
#if defined(__DOXYGEN__)
/**
* \def CONFIG_INTERRUPT_FORCE_INTC
* \brief Force usage of the ASF INTC driver
*
* Predefine this symbol when preprocessing to force the use of the ASF INTC driver.
* This is useful to ensure compatibilty accross compilers and shall be used only when required
* by the application needs.
*/
# define CONFIG_INTERRUPT_FORCE_INTC
#endif
//! \name Global interrupt flags
//@{
/**
* \typedef irqflags_t
* \brief Type used for holding state of interrupt flag
*/
/**
* \def cpu_irq_enable
* \brief Enable interrupts globally
*/
/**
* \def cpu_irq_disable
* \brief Disable interrupts globally
*/
/**
* \fn irqflags_t cpu_irq_save(void)
* \brief Get and clear the global interrupt flags
*
* Use in conjunction with \ref cpu_irq_restore.
*
* \return Current state of interrupt flags.
*
* \note This function leaves interrupts disabled.
*/
/**
* \fn void cpu_irq_restore(irqflags_t flags)
* \brief Restore global interrupt flags
*
* Use in conjunction with \ref cpu_irq_save.
*
* \param flags State to set interrupt flag to.
*/
/**
* \fn bool cpu_irq_is_enabled_flags(irqflags_t flags)
* \brief Check if interrupts are globally enabled in supplied flags
*
* \param flags Currents state of interrupt flags.
*
* \return True if interrupts are enabled.
*/
/**
* \def cpu_irq_is_enabled
* \brief Check if interrupts are globally enabled
*
* \return True if interrupts are enabled.
*/
//@}
//! @}
/**
* \ingroup interrupt_group
* \defgroup interrupt_deprecated_group Deprecated interrupt definitions
*/
#endif /* UTILS_INTERRUPT_H */
/**
* \file
*
* \brief Global interrupt management for 8- and 32-bit AVR
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef UTILS_INTERRUPT_H
#define UTILS_INTERRUPT_H
#include <parts.h>
#if XMEGA || MEGA || TINY
# include "interrupt/interrupt_avr8.h"
#elif UC3
# include "interrupt/interrupt_avr32.h"
#elif SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4L || SAM4E
# include "interrupt/interrupt_sam_nvic.h"
#else
# error Unsupported device.
#endif
/**
* \defgroup interrupt_group Global interrupt management
*
* This is a driver for global enabling and disabling of interrupts.
*
* @{
*/
#if defined(__DOXYGEN__)
/**
* \def CONFIG_INTERRUPT_FORCE_INTC
* \brief Force usage of the ASF INTC driver
*
* Predefine this symbol when preprocessing to force the use of the ASF INTC driver.
* This is useful to ensure compatibilty accross compilers and shall be used only when required
* by the application needs.
*/
# define CONFIG_INTERRUPT_FORCE_INTC
#endif
//! \name Global interrupt flags
//@{
/**
* \typedef irqflags_t
* \brief Type used for holding state of interrupt flag
*/
/**
* \def cpu_irq_enable
* \brief Enable interrupts globally
*/
/**
* \def cpu_irq_disable
* \brief Disable interrupts globally
*/
/**
* \fn irqflags_t cpu_irq_save(void)
* \brief Get and clear the global interrupt flags
*
* Use in conjunction with \ref cpu_irq_restore.
*
* \return Current state of interrupt flags.
*
* \note This function leaves interrupts disabled.
*/
/**
* \fn void cpu_irq_restore(irqflags_t flags)
* \brief Restore global interrupt flags
*
* Use in conjunction with \ref cpu_irq_save.
*
* \param flags State to set interrupt flag to.
*/
/**
* \fn bool cpu_irq_is_enabled_flags(irqflags_t flags)
* \brief Check if interrupts are globally enabled in supplied flags
*
* \param flags Currents state of interrupt flags.
*
* \return True if interrupts are enabled.
*/
/**
* \def cpu_irq_is_enabled
* \brief Check if interrupts are globally enabled
*
* \return True if interrupts are enabled.
*/
//@}
//! @}
/**
* \ingroup interrupt_group
* \defgroup interrupt_deprecated_group Deprecated interrupt definitions
*/
#endif /* UTILS_INTERRUPT_H */
@@ -1,148 +1,148 @@
/**
* \file
*
* \brief Global interrupt management for 8-bit AVR
*
* Copyright (C) 2010-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef UTILS_INTERRUPT_INTERRUPT_H
#define UTILS_INTERRUPT_INTERRUPT_H
#include <compiler.h>
#include <parts.h>
/**
* \weakgroup interrupt_group
*
* @{
*/
#ifdef ISR_CUSTOM_H
# include ISR_CUSTOM_H
#else
/**
* \def ISR
* \brief Define service routine for specified interrupt vector
*
* Usage:
* \code
* ISR(FOO_vect)
* {
* ...
* }
* \endcode
*
* \param vect Interrupt vector name as found in the device header files.
*/
#if defined(__DOXYGEN__)
# define ISR(vect)
#elif defined(__GNUC__)
# include <avr/interrupt.h>
#elif defined(__ICCAVR__)
# define __ISR(x) _Pragma(#x)
# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void)
#endif
#endif // ISR_CUSTOM_H
#if XMEGA
/**
* \brief Initialize interrupt vectors
* Enables all interrupt levels, with vectors located in the application section
* and fixed priority scheduling.
*/
#define irq_initialize_vectors() \
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
#elif MEGA_RF
#define irq_initialize_vectors()
#endif
#ifdef __GNUC__
# define cpu_irq_enable() sei()
# define cpu_irq_disable() cli()
#else
# define cpu_irq_enable() __enable_interrupt()
# define cpu_irq_disable() __disable_interrupt()
#endif
typedef uint8_t irqflags_t;
static inline irqflags_t
cpu_irq_save (void)
{
irqflags_t flags = SREG;
cpu_irq_disable ();
return flags;
}
static inline void
cpu_irq_restore (irqflags_t flags)
{
barrier ();
SREG = flags;
}
static inline bool
cpu_irq_is_enabled_flags (irqflags_t flags)
{
#if XMEGA
# ifdef __GNUC__
return flags & CPU_I_bm;
# else
return flags & I_bm;
# endif
#elif MEGA || TINY
return flags & (1 << SREG_I);
#endif
}
#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG)
//! @}
/**
* \weakgroup interrupt_deprecated_group
* @{
*/
// Deprecated definitions.
#define Enable_global_interrupt() cpu_irq_enable()
#define Disable_global_interrupt() cpu_irq_disable()
#define Is_global_interrupt_enabled() cpu_irq_is_enabled()
//! @}
#endif /* UTILS_INTERRUPT_INTERRUPT_H */
/**
* \file
*
* \brief Global interrupt management for 8-bit AVR
*
* Copyright (C) 2010-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef UTILS_INTERRUPT_INTERRUPT_H
#define UTILS_INTERRUPT_INTERRUPT_H
#include <compiler.h>
#include <parts.h>
/**
* \weakgroup interrupt_group
*
* @{
*/
#ifdef ISR_CUSTOM_H
# include ISR_CUSTOM_H
#else
/**
* \def ISR
* \brief Define service routine for specified interrupt vector
*
* Usage:
* \code
* ISR(FOO_vect)
* {
* ...
* }
* \endcode
*
* \param vect Interrupt vector name as found in the device header files.
*/
#if defined(__DOXYGEN__)
# define ISR(vect)
#elif defined(__GNUC__)
# include <avr/interrupt.h>
#elif defined(__ICCAVR__)
# define __ISR(x) _Pragma(#x)
# define ISR(vect) __ISR(vector=vect) __interrupt void handler_##vect(void)
#endif
#endif // ISR_CUSTOM_H
#if XMEGA
/**
* \brief Initialize interrupt vectors
* Enables all interrupt levels, with vectors located in the application section
* and fixed priority scheduling.
*/
#define irq_initialize_vectors() \
PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
#elif MEGA_RF
#define irq_initialize_vectors()
#endif
#ifdef __GNUC__
# define cpu_irq_enable() sei()
# define cpu_irq_disable() cli()
#else
# define cpu_irq_enable() __enable_interrupt()
# define cpu_irq_disable() __disable_interrupt()
#endif
typedef uint8_t irqflags_t;
static inline irqflags_t
cpu_irq_save (void)
{
irqflags_t flags = SREG;
cpu_irq_disable ();
return flags;
}
static inline void
cpu_irq_restore (irqflags_t flags)
{
barrier ();
SREG = flags;
}
static inline bool
cpu_irq_is_enabled_flags (irqflags_t flags)
{
#if XMEGA
# ifdef __GNUC__
return flags & CPU_I_bm;
# else
return flags & I_bm;
# endif
#elif MEGA || TINY
return flags & (1 << SREG_I);
#endif
}
#define cpu_irq_is_enabled() cpu_irq_is_enabled_flags(SREG)
//! @}
/**
* \weakgroup interrupt_deprecated_group
* @{
*/
// Deprecated definitions.
#define Enable_global_interrupt() cpu_irq_enable()
#define Disable_global_interrupt() cpu_irq_disable()
#define Is_global_interrupt_enabled() cpu_irq_is_enabled()
//! @}
#endif /* UTILS_INTERRUPT_INTERRUPT_H */
File diff suppressed because it is too large Load Diff
@@ -1,164 +1,164 @@
/**
* \file
*
* \brief System-specific implementation of the \ref _read function used by
* the standard library.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "compiler.h"
/**
* \defgroup group_common_utils_stdio Standard I/O (stdio)
*
* Common standard I/O driver that implements the stdio
* read and write functions on AVR and SAM devices.
*
* \{
*/
extern volatile void *volatile stdio_base;
void (*ptr_get)(void volatile*, char*);
// IAR common implementation
#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) )
#include <yfuns.h>
_STD_BEGIN
#pragma module_name = "?__read"
/*! \brief Reads a number of bytes, at most \a size, into the memory area
* pointed to by \a buffer.
*
* \param handle File handle to read from.
* \param buffer Pointer to buffer to write read bytes to.
* \param size Number of bytes to read.
*
* \return The number of bytes read, \c 0 at the end of the file, or
* \c _LLIO_ERROR on failure.
*/
size_t __read(int handle, unsigned char *buffer, size_t size)
{
int nChars = 0;
// This implementation only reads from stdin.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDIN) {
return _LLIO_ERROR;
}
for (; size > 0; --size) {
ptr_get(stdio_base, (char*)buffer);
buffer++;
nChars++;
}
return nChars;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
int __close(int handle)
{
UNUSED(handle);
return 0;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
int remove(const char* val)
{
UNUSED(val);
return 0;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
long __lseek(int handle, long val, int val2)
{
UNUSED(handle);
UNUSED(val2);
return val;
}
_STD_END
// GCC AVR32 and SAM implementation
#elif (defined(__GNUC__) && !XMEGA && !MEGA)
int __attribute__((weak))
_read (int file, char * ptr, int len); // Remove GCC compiler warning
int __attribute__((weak))
_read (int file, char * ptr, int len)
{
int nChars = 0;
if (file != 0) {
return -1;
}
for (; len > 0; --len) {
ptr_get(stdio_base, ptr);
ptr++;
nChars++;
}
return nChars;
}
// GCC AVR implementation
#elif (defined(__GNUC__) && (XMEGA || MEGA) )
int _read (int *f); // Remove GCC compiler warning
int _read (int *f)
{
char c;
ptr_get(stdio_base,&c);
return c;
}
#endif
/**
* \}
*/
/**
* \file
*
* \brief System-specific implementation of the \ref _read function used by
* the standard library.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "compiler.h"
/**
* \defgroup group_common_utils_stdio Standard I/O (stdio)
*
* Common standard I/O driver that implements the stdio
* read and write functions on AVR and SAM devices.
*
* \{
*/
extern volatile void *volatile stdio_base;
void (*ptr_get)(void volatile*, char*);
// IAR common implementation
#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) )
#include <yfuns.h>
_STD_BEGIN
#pragma module_name = "?__read"
/*! \brief Reads a number of bytes, at most \a size, into the memory area
* pointed to by \a buffer.
*
* \param handle File handle to read from.
* \param buffer Pointer to buffer to write read bytes to.
* \param size Number of bytes to read.
*
* \return The number of bytes read, \c 0 at the end of the file, or
* \c _LLIO_ERROR on failure.
*/
size_t __read(int handle, unsigned char *buffer, size_t size)
{
int nChars = 0;
// This implementation only reads from stdin.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDIN) {
return _LLIO_ERROR;
}
for (; size > 0; --size) {
ptr_get(stdio_base, (char*)buffer);
buffer++;
nChars++;
}
return nChars;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
int __close(int handle)
{
UNUSED(handle);
return 0;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
int remove(const char* val)
{
UNUSED(val);
return 0;
}
/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10
* the implementation is empty to be compatible with old IAR version.
*/
long __lseek(int handle, long val, int val2)
{
UNUSED(handle);
UNUSED(val2);
return val;
}
_STD_END
// GCC AVR32 and SAM implementation
#elif (defined(__GNUC__) && !XMEGA && !MEGA)
int __attribute__((weak))
_read (int file, char * ptr, int len); // Remove GCC compiler warning
int __attribute__((weak))
_read (int file, char * ptr, int len)
{
int nChars = 0;
if (file != 0) {
return -1;
}
for (; len > 0; --len) {
ptr_get(stdio_base, ptr);
ptr++;
nChars++;
}
return nChars;
}
// GCC AVR implementation
#elif (defined(__GNUC__) && (XMEGA || MEGA) )
int _read (int *f); // Remove GCC compiler warning
int _read (int *f)
{
char c;
ptr_get(stdio_base,&c);
return c;
}
#endif
/**
* \}
*/
@@ -1,123 +1,123 @@
/**
*
* \file
*
* \brief Common Standard I/O Serial Management.
*
* This file defines a useful set of functions for the Stdio Serial interface on AVR
* and SAM devices.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
******************************************************************************/
#ifndef _STDIO_SERIAL_H_
#define _STDIO_SERIAL_H_
/**
* \defgroup group_common_utils_stdio_stdio_serial Standard serial I/O (stdio)
* \ingroup group_common_utils_stdio
*
* Common standard serial I/O management driver that
* implements a stdio serial interface on AVR and SAM devices.
*
* \{
*/
#include <stdio.h>
#include "compiler.h"
#include "sysclk.h"
#include "serial.h"
#if (XMEGA || MEGA_RF) && defined(__GNUC__)
extern int _write (char c, int *f);
extern int _read (int *f);
#endif
//! Pointer to the base of the USART module instance to use for stdio.
extern volatile void *volatile stdio_base;
//! Pointer to the external low level write function.
extern int (*ptr_put)(void volatile*, char);
//! Pointer to the external low level read function.
extern void (*ptr_get)(void volatile*, char*);
/*! \brief Initializes the stdio in Serial Mode.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
*
*/
static inline void stdio_serial_init(volatile void *usart, const usart_serial_options_t *opt)
{
stdio_base = (void *)usart;
ptr_put = (int (*)(void volatile*,char))&usart_serial_putchar;
ptr_get = (void (*)(void volatile*,char*))&usart_serial_getchar;
#if (XMEGA || MEGA_RF)
usart_serial_init((USART_t *)usart,opt);
#elif UC3
usart_serial_init(usart,(usart_serial_options_t *)opt);
#elif SAM
usart_serial_init((Usart *)usart,(usart_serial_options_t *)opt);
#else
# error Unsupported chip type
#endif
#if defined(__GNUC__)
# if (XMEGA || MEGA_RF)
// For AVR GCC libc print redirection uses fdevopen.
fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read));
# endif
# if UC3 || SAM
// For AVR32 and SAM GCC
// Specify that stdout and stdin should not be buffered.
setbuf(stdout, NULL);
setbuf(stdin, NULL);
// Note: Already the case in IAR's Normal DLIB default configuration
// and AVR GCC library:
// - printf() emits one character at a time.
// - getchar() requests only 1 byte to exit.
# endif
#endif
}
/**
* \}
*/
#endif // _STDIO_SERIAL_H_
/**
*
* \file
*
* \brief Common Standard I/O Serial Management.
*
* This file defines a useful set of functions for the Stdio Serial interface on AVR
* and SAM devices.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
******************************************************************************/
#ifndef _STDIO_SERIAL_H_
#define _STDIO_SERIAL_H_
/**
* \defgroup group_common_utils_stdio_stdio_serial Standard serial I/O (stdio)
* \ingroup group_common_utils_stdio
*
* Common standard serial I/O management driver that
* implements a stdio serial interface on AVR and SAM devices.
*
* \{
*/
#include <stdio.h>
#include "compiler.h"
#include "sysclk.h"
#include "serial.h"
#if (XMEGA || MEGA_RF) && defined(__GNUC__)
extern int _write (char c, int *f);
extern int _read (int *f);
#endif
//! Pointer to the base of the USART module instance to use for stdio.
extern volatile void *volatile stdio_base;
//! Pointer to the external low level write function.
extern int (*ptr_put)(void volatile*, char);
//! Pointer to the external low level read function.
extern void (*ptr_get)(void volatile*, char*);
/*! \brief Initializes the stdio in Serial Mode.
*
* \param usart Base address of the USART instance.
* \param opt Options needed to set up RS232 communication (see \ref usart_options_t).
*
*/
static inline void stdio_serial_init(volatile void *usart, const usart_serial_options_t *opt)
{
stdio_base = (void *)usart;
ptr_put = (int (*)(void volatile*,char))&usart_serial_putchar;
ptr_get = (void (*)(void volatile*,char*))&usart_serial_getchar;
#if (XMEGA || MEGA_RF)
usart_serial_init((USART_t *)usart,opt);
#elif UC3
usart_serial_init(usart,(usart_serial_options_t *)opt);
#elif SAM
usart_serial_init((Usart *)usart,(usart_serial_options_t *)opt);
#else
# error Unsupported chip type
#endif
#if defined(__GNUC__)
# if (XMEGA || MEGA_RF)
// For AVR GCC libc print redirection uses fdevopen.
fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read));
# endif
# if UC3 || SAM
// For AVR32 and SAM GCC
// Specify that stdout and stdin should not be buffered.
setbuf(stdout, NULL);
setbuf(stdin, NULL);
// Note: Already the case in IAR's Normal DLIB default configuration
// and AVR GCC library:
// - printf() emits one character at a time.
// - getchar() requests only 1 byte to exit.
# endif
#endif
}
/**
* \}
*/
#endif // _STDIO_SERIAL_H_
@@ -1,144 +1,144 @@
/**
* \file
*
* \brief System-specific implementation of the \ref _write function used by
* the standard library.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "compiler.h"
/**
* \addtogroup group_common_utils_stdio
*
* \{
*/
volatile void *volatile stdio_base;
int (*ptr_put)(void volatile*, char);
#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__))
#include <yfuns.h>
_STD_BEGIN
#pragma module_name = "?__write"
/*! \brief Writes a number of bytes, at most \a size, from the memory area
* pointed to by \a buffer.
*
* If \a buffer is zero then \ref __write performs flushing of internal buffers,
* if any. In this case, \a handle can be \c -1 to indicate that all handles
* should be flushed.
*
* \param handle File handle to write to.
* \param buffer Pointer to buffer to read bytes to write from.
* \param size Number of bytes to write.
*
* \return The number of bytes written, or \c _LLIO_ERROR on failure.
*/
size_t __write(int handle, const unsigned char *buffer, size_t size)
{
size_t nChars = 0;
if (buffer == 0) {
// This means that we should flush internal buffers.
return 0;
}
// This implementation only writes to stdout and stderr.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
return _LLIO_ERROR;
}
for (; size != 0; --size) {
if (ptr_put(stdio_base, *buffer++) < 0) {
return _LLIO_ERROR;
}
++nChars;
}
return nChars;
}
_STD_END
#elif (defined(__GNUC__) && !XMEGA && !MEGA)
int __attribute__((weak))
_write (int file, const char *ptr, int len);
int __attribute__((weak))
_write (int file, const char *ptr, int len)
{
int nChars = 0;
if ((file != 1) && (file != 2) && (file!=3)) {
return -1;
}
for (; len != 0; --len) {
if (ptr_put(stdio_base, *ptr++) < 0) {
return -1;
}
++nChars;
}
return nChars;
}
#elif (defined(__GNUC__) && (XMEGA || MEGA))
int _write (char c, int *f);
int _write (char c, int *f)
{
if (ptr_put(stdio_base, c) < 0) {
return -1;
}
return 1;
}
#endif
/**
* \}
*/
/**
* \file
*
* \brief System-specific implementation of the \ref _write function used by
* the standard library.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "compiler.h"
/**
* \addtogroup group_common_utils_stdio
*
* \{
*/
volatile void *volatile stdio_base;
int (*ptr_put)(void volatile*, char);
#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__))
#include <yfuns.h>
_STD_BEGIN
#pragma module_name = "?__write"
/*! \brief Writes a number of bytes, at most \a size, from the memory area
* pointed to by \a buffer.
*
* If \a buffer is zero then \ref __write performs flushing of internal buffers,
* if any. In this case, \a handle can be \c -1 to indicate that all handles
* should be flushed.
*
* \param handle File handle to write to.
* \param buffer Pointer to buffer to read bytes to write from.
* \param size Number of bytes to write.
*
* \return The number of bytes written, or \c _LLIO_ERROR on failure.
*/
size_t __write(int handle, const unsigned char *buffer, size_t size)
{
size_t nChars = 0;
if (buffer == 0) {
// This means that we should flush internal buffers.
return 0;
}
// This implementation only writes to stdout and stderr.
// For all other file handles, it returns failure.
if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) {
return _LLIO_ERROR;
}
for (; size != 0; --size) {
if (ptr_put(stdio_base, *buffer++) < 0) {
return _LLIO_ERROR;
}
++nChars;
}
return nChars;
}
_STD_END
#elif (defined(__GNUC__) && !XMEGA && !MEGA)
int __attribute__((weak))
_write (int file, const char *ptr, int len);
int __attribute__((weak))
_write (int file, const char *ptr, int len)
{
int nChars = 0;
if ((file != 1) && (file != 2) && (file!=3)) {
return -1;
}
for (; len != 0; --len) {
if (ptr_put(stdio_base, *ptr++) < 0) {
return -1;
}
++nChars;
}
return nChars;
}
#elif (defined(__GNUC__) && (XMEGA || MEGA))
int _write (char c, int *f);
int _write (char c, int *f)
{
if (ptr_put(stdio_base, c) < 0) {
return -1;
}
return 1;
}
#endif
/**
* \}
*/
@@ -1,164 +1,164 @@
/**
* \file
*
* \brief XMEGA-A3BU Xplained board init.
*
* This file contains board initialization function.
*
* Copyright (c) 2010 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <conf_board.h>
#include <board.h>
#include <ioport.h>
/**
* \addtogroup xmega_a3bu_xplained_group
* @{
*/
void board_init(void)
{
#if 0
ioport_configure_pin(LED0_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(LED1_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(LED2_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(LED3_GPIO,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW | IOPORT_INV_ENABLED);
ioport_configure_pin(GPIO_PUSH_BUTTON_0,
IOPORT_DIR_INPUT | IOPORT_LEVEL | IOPORT_PULL_UP);
ioport_configure_pin(GPIO_PUSH_BUTTON_1,
IOPORT_DIR_INPUT | IOPORT_LEVEL | IOPORT_PULL_UP);
ioport_configure_pin(GPIO_PUSH_BUTTON_2,
IOPORT_DIR_INPUT | IOPORT_LEVEL | IOPORT_PULL_UP);
#ifdef CONF_BOARD_C12832A1Z
ioport_configure_pin(NHD_C12832A1Z_SPI_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_SPI_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_CSN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_REGISTER_SELECT,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_RESETN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_BACKLIGHT,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#endif
#ifdef CONF_BOARD_AT45DBX
ioport_configure_pin(AT45DBX_MASTER_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT45DBX_MASTER_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT45DBX_MASTER_MISO, IOPORT_DIR_INPUT);
ioport_configure_pin(AT45DBX_CS, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
#endif
#ifdef CONF_BOARD_ENABLE_MXT143E_XPLAINED
ioport_configure_pin(MXT143E_XPLAINED_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(MXT143E_XPLAINED_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(MXT143E_XPLAINED_MISO, IOPORT_DIR_INPUT);
ioport_configure_pin(MXT143E_XPLAINED_CS,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(MXT143E_XPLAINED_CHG, IOPORT_DIR_INPUT);
ioport_configure_pin(MXT143E_XPLAINED_DC,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#ifndef MXT143E_XPLAINED_BACKLIGHT_DISABLE
ioport_configure_pin(MXT143E_XPLAINED_BACKLIGHT,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#endif
ioport_configure_pin(MXT143E_XPLAINED_LCD_RESET,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#endif
#ifdef CONF_BOARD_ENABLE_AC_PINS
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 0), IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2), IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1), IOPORT_DIR_INPUT);
#endif
#ifdef CONF_BOARD_ENABLE_USARTC0
ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 3),
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 2), IOPORT_DIR_INPUT);
#endif
#ifdef CONF_BOARD_ENABLE_USARTD0
ioport_configure_pin(IOPORT_CREATE_PIN(PORTD, 3),
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTD, 2), IOPORT_DIR_INPUT);
#endif
#ifdef CONF_BOARD_ENABLE_USARTE0
ioport_configure_pin(IOPORT_CREATE_PIN(PORTE, 3),
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTE, 2), IOPORT_DIR_INPUT);
#endif
#if defined (SENSORS_XPLAINED_BOARD)
/* Configure the Xplained Sensor extension board, if any, after
* the platform Xplained board has configured basic clock settings,
* GPIO pin mapping, interrupt controller options, etc.
*/
sensor_board_init();
#endif
#ifdef CONF_BOARD_AT86RFX
ioport_configure_pin(AT86RFX_SPI_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT86RFX_SPI_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT86RFX_SPI_MISO, IOPORT_DIR_INPUT);
ioport_configure_pin(AT86RFX_SPI_CS, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
/* Initialize TRX_RST and SLP_TR as GPIO. */
ioport_configure_pin(AT86RFX_RST_PIN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT86RFX_SLP_PIN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
#endif
#endif
}
/**
* @}
*/
/**
* \file
*
* \brief XMEGA-A3BU Xplained board init.
*
* This file contains board initialization function.
*
* Copyright (c) 2010 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <conf_board.h>
#include <board.h>
#include <ioport.h>
/**
* \addtogroup xmega_a3bu_xplained_group
* @{
*/
void board_init(void)
{
#if 0
ioport_configure_pin(LED0_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(LED1_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(LED2_GPIO, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(LED3_GPIO,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW | IOPORT_INV_ENABLED);
ioport_configure_pin(GPIO_PUSH_BUTTON_0,
IOPORT_DIR_INPUT | IOPORT_LEVEL | IOPORT_PULL_UP);
ioport_configure_pin(GPIO_PUSH_BUTTON_1,
IOPORT_DIR_INPUT | IOPORT_LEVEL | IOPORT_PULL_UP);
ioport_configure_pin(GPIO_PUSH_BUTTON_2,
IOPORT_DIR_INPUT | IOPORT_LEVEL | IOPORT_PULL_UP);
#ifdef CONF_BOARD_C12832A1Z
ioport_configure_pin(NHD_C12832A1Z_SPI_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_SPI_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_CSN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_REGISTER_SELECT,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_RESETN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(NHD_C12832A1Z_BACKLIGHT,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#endif
#ifdef CONF_BOARD_AT45DBX
ioport_configure_pin(AT45DBX_MASTER_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT45DBX_MASTER_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT45DBX_MASTER_MISO, IOPORT_DIR_INPUT);
ioport_configure_pin(AT45DBX_CS, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
#endif
#ifdef CONF_BOARD_ENABLE_MXT143E_XPLAINED
ioport_configure_pin(MXT143E_XPLAINED_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(MXT143E_XPLAINED_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(MXT143E_XPLAINED_MISO, IOPORT_DIR_INPUT);
ioport_configure_pin(MXT143E_XPLAINED_CS,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(MXT143E_XPLAINED_CHG, IOPORT_DIR_INPUT);
ioport_configure_pin(MXT143E_XPLAINED_DC,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#ifndef MXT143E_XPLAINED_BACKLIGHT_DISABLE
ioport_configure_pin(MXT143E_XPLAINED_BACKLIGHT,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#endif
ioport_configure_pin(MXT143E_XPLAINED_LCD_RESET,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
#endif
#ifdef CONF_BOARD_ENABLE_AC_PINS
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 0), IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2), IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1), IOPORT_DIR_INPUT);
#endif
#ifdef CONF_BOARD_ENABLE_USARTC0
ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 3),
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTC, 2), IOPORT_DIR_INPUT);
#endif
#ifdef CONF_BOARD_ENABLE_USARTD0
ioport_configure_pin(IOPORT_CREATE_PIN(PORTD, 3),
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTD, 2), IOPORT_DIR_INPUT);
#endif
#ifdef CONF_BOARD_ENABLE_USARTE0
ioport_configure_pin(IOPORT_CREATE_PIN(PORTE, 3),
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTE, 2), IOPORT_DIR_INPUT);
#endif
#if defined (SENSORS_XPLAINED_BOARD)
/* Configure the Xplained Sensor extension board, if any, after
* the platform Xplained board has configured basic clock settings,
* GPIO pin mapping, interrupt controller options, etc.
*/
sensor_board_init();
#endif
#ifdef CONF_BOARD_AT86RFX
ioport_configure_pin(AT86RFX_SPI_SCK,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT86RFX_SPI_MOSI,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT86RFX_SPI_MISO, IOPORT_DIR_INPUT);
ioport_configure_pin(AT86RFX_SPI_CS, IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
/* Initialize TRX_RST and SLP_TR as GPIO. */
ioport_configure_pin(AT86RFX_RST_PIN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
ioport_configure_pin(AT86RFX_SLP_PIN,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
#endif
#endif
}
/**
* @}
*/
@@ -1,80 +1,80 @@
/**
* \file
*
* \brief XMEGA-A3BU board LEDs support package.
*
* This file contains definitions and services related to the LED features of
* the XMEGA-A3BU Xplained board.
*
* To use this board, define BOARD=XMEGA_A3BU_XPLAINED.
*
* Copyright (c) 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _LED_H_
#define _LED_H_
#include "gpio.h"
/**
* \brief Turns off the specified LEDs.
*
* \param led_gpio LED to turn off (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_Off(led_gpio) gpio_set_pin_high(led_gpio)
/**
* \brief Turns on the specified LEDs.
*
* \param led_gpio LED to turn on (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_On(led_gpio) gpio_set_pin_low(led_gpio)
/**
* \brief Toggles the specified LEDs.
*
* \param led_gpio LED to toggle (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_Toggle(led_gpio) gpio_toggle_pin(led_gpio)
#endif /* _LED_H_ */
/**
* \file
*
* \brief XMEGA-A3BU board LEDs support package.
*
* This file contains definitions and services related to the LED features of
* the XMEGA-A3BU Xplained board.
*
* To use this board, define BOARD=XMEGA_A3BU_XPLAINED.
*
* Copyright (c) 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _LED_H_
#define _LED_H_
#include "gpio.h"
/**
* \brief Turns off the specified LEDs.
*
* \param led_gpio LED to turn off (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_Off(led_gpio) gpio_set_pin_high(led_gpio)
/**
* \brief Turns on the specified LEDs.
*
* \param led_gpio LED to turn on (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_On(led_gpio) gpio_set_pin_low(led_gpio)
/**
* \brief Toggles the specified LEDs.
*
* \param led_gpio LED to toggle (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_Toggle(led_gpio) gpio_toggle_pin(led_gpio)
#endif /* _LED_H_ */
@@ -1,414 +1,414 @@
/**
* \file
*
* \brief XMEGA-A3BU-XPLAINED board header file.
*
* This file contains definitions and services related to the features of the
* XMEGA-A3BU Xplained board.
*
* To use this board define BOARD=XMEGA_A3BU_XPLAINED.
*
* Copyright (c) 2011 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _XMEGA_A3BU_XPLAINED_H_
#define _XMEGA_A3BU_XPLAINED_H_
#include <compiler.h>
#define MCU_SOC_NAME "ATxmega256A3BU"
#define BOARD_NAME "XMEGA-A3BU-XPLAINED"
/**
* \defgroup xmega_a3bu_xplained_group XMEGA-A3BU Xplained board
* @{
*/
/**
* \defgroup xmega_a3bu_xplained_feature_group Feature definitions
* @{
*/
//! \name Miscellaneous data
//@{
//! Validate board support for the common sensor service.
#define COMMON_SENSOR_PLATFORM
//@}
/**
* \name LEDs
*
* LED0 and LED1 are single yellow LEDs that are active low..
* LED2 and LED3 are inside one package (Led red and green close
* to USB connector) but can be controlled individually.
* LED2 has a red color and is active low. This LED can be
* used for general purposes.
* LED3 has a green color and is active high. By default this
* LED is on since it shall indicate that power is applied to the
* board. By pulling the gate of a N-FET low it is possible to
* turn off the LED if needed.
*/
//@{
#define LED0_GPIO IOPORT_CREATE_PIN(PORTR, 0)
#define LED1_GPIO IOPORT_CREATE_PIN(PORTR, 1)
#define LED2_GPIO IOPORT_CREATE_PIN(PORTD, 4)
#define LED3_GPIO IOPORT_CREATE_PIN(PORTD, 5)
#define LED0 LED0_GPIO
#define LED1 LED1_GPIO
#define LED2 LED2_GPIO
#define LED3 LED3_GPIO
//! Number of LEDs.
#define LED_COUNT 4
//@}
//! \name Push buttons
//@{
#define GPIO_PUSH_BUTTON_0 IOPORT_CREATE_PIN(PORTE, 5)
#define GPIO_PUSH_BUTTON_1 IOPORT_CREATE_PIN(PORTF, 1)
#define GPIO_PUSH_BUTTON_2 IOPORT_CREATE_PIN(PORTF, 2)
//@}
//! \name QTouch button
//! This button requires the software QTouch library
//@{
#define QTOUCH_BUTTON_SNS IOPORT_CREATE_PIN(PORTF, 6)
#define QTOUCH_BUTTON_SNSK IOPORT_CREATE_PIN(PORTF, 7)
//@}
//! \name Light sensor
//@{
#define LIGHT_SENSOR_ADC_MODULE ADCA
#define LIGHT_SENSOR_ADC_INPUT ADCCH_POS_PIN0
#define LIGHT_SENSOR_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 0)
//@}
//! \name Temperature sensor (NTC)
//@{
#define TEMPERATURE_SENSOR_ADC_MODULE ADCA
#define TEMPERATURE_SENSOR_ADC_INPUT ADCCH_POS_PIN1
#define TEMPERATURE_SENSOR_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 1)
//@}
//! \name Analog filter (lowpass RC @ 159 Hz)
//@{
#define FILTER_INPUT_SIGNAL_PIN IOPORT_CREATE_PIN(PORTF, 0)
#define FILTER_OUTPUT_ADC_MODULE ADCA
#define FILTER_OUTPUT_ADC_INPUT ADCCH_POS_PIN2
#define FILTER_OUTPUT_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 2)
//@}
//! \name LCD backlight
//@{
#define LCD_BACKLIGHT_ENABLE_PIN IOPORT_CREATE_PIN(PORTE, 4)
#define LCD_BACKLIGHT_ENABLE_LEVEL true
//@}
//! \name LCD controller (NHD-C12832A1Z-FSW-FBW-3V3)
//@{
#define NHD_C12832A1Z_SPI &USARTD0
#define NHD_C12832A1Z_SPI_SCK IOPORT_CREATE_PIN(PORTD, 1)
#define NHD_C12832A1Z_SPI_MOSI IOPORT_CREATE_PIN(PORTD, 3)
#define NHD_C12832A1Z_CSN IOPORT_CREATE_PIN(PORTF, 3)
//! If this signal is set high display data is sent otherwise commands
#define NHD_C12832A1Z_REGISTER_SELECT IOPORT_CREATE_PIN(PORTD, 0)
#define NHD_C12832A1Z_RESETN IOPORT_CREATE_PIN(PORTA, 3)
//! The backlight is active high
#define NHD_C12832A1Z_BACKLIGHT IOPORT_CREATE_PIN(PORTE, 4)
//@}
//! \name LCD dimensions
//@{
#define LCD_WIDTH_PIXELS (128)
#define LCD_HEIGHT_PIXELS (32)
//@}
//! \name DataFlash memory (AT45DBX)
//@{
#define AT45DBX_SPI &USARTD0
#define AT45DBX_CS IOPORT_CREATE_PIN(PORTF, 4)
//! SCK pin
#define AT45DBX_MASTER_SCK IOPORT_CREATE_PIN(PORTD, 1)
//! MOSI pin
#define AT45DBX_MASTER_MOSI IOPORT_CREATE_PIN(PORTD, 3)
//! MISO pin
#define AT45DBX_MASTER_MISO IOPORT_CREATE_PIN(PORTD, 2)
//@}
//! \name MXT143E Xplained top module
//@{
#define MXT143E_XPLAINED_TWI &TWIC
#define MXT143E_XPLAINED_USART_SPI &USARTC1
#define MXT143E_XPLAINED_CS IOPORT_CREATE_PIN(PORTC, 4)
#define MXT143E_XPLAINED_SCK IOPORT_CREATE_PIN(PORTC, 7)
#define MXT143E_XPLAINED_MOSI IOPORT_CREATE_PIN(PORTC, 5)
#define MXT143E_XPLAINED_MISO IOPORT_CREATE_PIN(PORTC, 6)
#define MXT143E_XPLAINED_CHG IOPORT_CREATE_PIN(PORTC, 2)
#define MXT143E_XPLAINED_DC IOPORT_CREATE_PIN(PORTC, 3)
#define MXT143E_XPLAINED_BACKLIGHT IOPORT_CREATE_PIN(PORTA, 4)
#define MXT143E_XPLAINED_LCD_RESET IOPORT_CREATE_PIN(PORTA, 6)
//@}
/**
* \name External oscillator
*
* \todo Need to measure the actual startup time on the hardware.
*/
//@{
#define BOARD_XOSC_HZ 32768
#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ
#define BOARD_XOSC_STARTUP_US 1000000
//@}
//! \name Communication interfaces on header J1
//@{
#define TWIC_SDA IOPORT_CREATE_PIN(PORTC, 0)
#define TWIC_SCL IOPORT_CREATE_PIN(PORTC, 1)
#define USARTC0_RXD IOPORT_CREATE_PIN(PORTC, 2)
#define USARTC0_TXD IOPORT_CREATE_PIN(PORTC, 3)
#define SPIC_SS IOPORT_CREATE_PIN(PORTC, 4)
#define SPIC_MOSI IOPORT_CREATE_PIN(PORTC, 5)
#define SPIC_MISO IOPORT_CREATE_PIN(PORTC, 6)
#define SPIC_SCK IOPORT_CREATE_PIN(PORTC, 7)
//@}
/*! \name Connections of the AT86RFX transceiver
*/
//! @{
#define AT86RFX_SPI &SPIC
#define AT86RFX_RST_PIN IOPORT_CREATE_PIN(PORTC, 0)
#define AT86RFX_MISC_PIN IOPORT_CREATE_PIN(PORTC, 1)
#define AT86RFX_IRQ_PIN IOPORT_CREATE_PIN(PORTC, 2)
#define AT86RFX_SLP_PIN IOPORT_CREATE_PIN(PORTC, 3)
#define AT86RFX_SPI_CS IOPORT_CREATE_PIN(PORTC, 4)
#define AT86RFX_SPI_MOSI IOPORT_CREATE_PIN(PORTC, 5)
#define AT86RFX_SPI_MISO IOPORT_CREATE_PIN(PORTC, 6)
#define AT86RFX_SPI_SCK IOPORT_CREATE_PIN(PORTC, 7)
#define AT86RFX_INTC_INIT() ioport_configure_pin(AT86RFX_IRQ_PIN, IOPORT_DIR_INPUT); \
PORTC.PIN2CTRL = PORT_ISC0_bm; \
PORTC.INT0MASK = PIN2_bm; \
PORTC.INTFLAGS = PORT_INT0IF_bm;
#define AT86RFX_ISR() ISR(PORTC_INT0_vect)
/** Enables the transceiver main interrupt. */
#define ENABLE_TRX_IRQ() (PORTC.INTCTRL |= PORT_INT0LVL_gm)
/** Disables the transceiver main interrupt. */
#define DISABLE_TRX_IRQ() (PORTC.INTCTRL &= ~PORT_INT0LVL_gm)
/** Clears the transceiver main interrupt. */
#define CLEAR_TRX_IRQ() (PORTC.INTFLAGS = PORT_INT0IF_bm)
/*
* This macro saves the trx interrupt status and disables the trx interrupt.
*/
#define ENTER_TRX_REGION() { uint8_t irq_mask = PORTC.INTCTRL; PORTC.INTCTRL &= ~PORT_INT0LVL_gm
/*
* This macro restores the transceiver interrupt status
*/
#define LEAVE_TRX_REGION() PORTC.INTCTRL = irq_mask; }
//! @}
/**
* \name Pin connections on header J1
*
* The whole port C is directly connected to J1.
*
* \note For the TWI lines there are footprints for pull up resistors, which
* are by default not mounted on the board.
*/
//@{
#define J1_PIN0 IOPORT_CREATE_PIN(PORTC, 0)
#define J1_PIN1 IOPORT_CREATE_PIN(PORTC, 1)
#define J1_PIN2 IOPORT_CREATE_PIN(PORTC, 2)
#define J1_PIN3 IOPORT_CREATE_PIN(PORTC, 3)
#define J1_PIN4 IOPORT_CREATE_PIN(PORTC, 4)
#define J1_PIN5 IOPORT_CREATE_PIN(PORTC, 5)
#define J1_PIN6 IOPORT_CREATE_PIN(PORTC, 6)
#define J1_PIN7 IOPORT_CREATE_PIN(PORTC, 7)
//@}
/**
* \name Pin connections on header J2
*
* The lower half of port B is connected to the lower pins of J2 while the
* upper half of port A is connected to the upper pins of J2.
*
* The port pins are connected directly to this header and are not shared with
* any on-board functionality.
*/
//@{
#define J2_PIN0 IOPORT_CREATE_PIN(PORTB, 0)
#define J2_PIN1 IOPORT_CREATE_PIN(PORTB, 1)
#define J2_PIN2 IOPORT_CREATE_PIN(PORTB, 2)
#define J2_PIN3 IOPORT_CREATE_PIN(PORTB, 3)
#define J2_PIN4 IOPORT_CREATE_PIN(PORTA, 4)
#define J2_PIN5 IOPORT_CREATE_PIN(PORTA, 5)
#define J2_PIN6 IOPORT_CREATE_PIN(PORTA, 6)
#define J2_PIN7 IOPORT_CREATE_PIN(PORTA, 7)
//@}
/**
* \name Pin connections on header J3
*
* The lower half of port A is connected to the lower pins of J3 while the
* upper half of port B is connected to the upper pins of J3.
*
* Following pins are shared with on-board functionality:
* - J3_PIN0 Light sensor output (can be disconnected via scratch pad)
* - J3_PIN1 NTC sensor output (can be disconnected via scratch pad)
* - J3_PIN2 Filter output (can be disconnected via scratch pad)
* - J3_PIN3 Display reset input (can't be used when display is in use)
* - J3_PIN4 JTAG TMS (pin can't be used while JTAG device connected)
* - J3_PIN5 JTAG TDI (pin can't be used while JTAG device connected)
* - J3_PIN6 JTAG TCK (pin can't be used while JTAG device connected)
* - J3_PIN7 JTAG TDO & PID DATA (pin can't be used while JTAG/PDI device is
* connected)
*/
//@{
#define J3_PIN0 IOPORT_CREATE_PIN(PORTA, 0)
#define J3_PIN1 IOPORT_CREATE_PIN(PORTA, 1)
#define J3_PIN2 IOPORT_CREATE_PIN(PORTA, 2)
#define J3_PIN3 IOPORT_CREATE_PIN(PORTA, 3)
#define J3_PIN4 IOPORT_CREATE_PIN(PORTB, 4)
#define J3_PIN5 IOPORT_CREATE_PIN(PORTB, 5)
#define J3_PIN6 IOPORT_CREATE_PIN(PORTB, 6)
#define J3_PIN7 IOPORT_CREATE_PIN(PORTB, 7)
//@}
/**
* \name Pin connections on header J4
*
* The lower half of port E is connected to the lower pins of J4 and the lower
* half of port D is connected to the upper pins of J4.
*/
//@{
#define J4_PIN0 IOPORT_CREATE_PIN(PORTE, 0)
#define J4_PIN1 IOPORT_CREATE_PIN(PORTE, 1)
#define J4_PIN2 IOPORT_CREATE_PIN(PORTE, 2)
#define J4_PIN3 IOPORT_CREATE_PIN(PORTE, 3)
#define J4_PIN4 IOPORT_CREATE_PIN(PORTD, 0)
#define J4_PIN5 IOPORT_CREATE_PIN(PORTD, 3)
#define J4_PIN6 IOPORT_CREATE_PIN(PORTD, 2)
#define J4_PIN7 IOPORT_CREATE_PIN(PORTD, 1)
//@}
/**
* @}
*/
/**
* \defgroup xmega_a3bu_xplained_config_group Configuration options
* @{
*/
#if defined(__DOXYGEN__)
/**
* \name Initialization
* \note Define these symbols in \ref conf_board.h to enable the corresponding
* features.
*/
//@{
/**
* \def CONF_BOARD_C12832A1Z
* \brief Initialize SPI and control pins for C12832A1Z LCD controller
*/
# if !defined(CONF_BOARD_C12832A1Z)
# define CONF_BOARD_C12832A1Z
# endif
/**
* \def CONF_BOARD_AT45DBX
* \brief Initialize SPI pins for AT45DBX DataFlash
*/
# if !defined(CONF_BOARD_AT45DBX)
# define CONF_BOARD_AT45DBX
# endif
/**
* \def CONF_BOARD_ENABLE_AC_PINS
* \brief Initialize IO pins for Analog Comparator
*
* \note This initializes pins PA0, PA2 and PB1 as inputs.
*/
# if !defined(CONF_BOARD_ENABLE_AC_PINS)
# define CONF_BOARD_ENABLE_AC_PINS
# endif
/**
* \def CONF_BOARD_ENABLE_USARTC0
* \brief Initialize IO pins for USART 0 on port C
*/
# if !defined(CONF_BOARD_ENABLE_USARTC0)
# define CONF_BOARD_ENABLE_USARTC0
# endif
/**
* \def CONF_BOARD_ENABLE_USARTD0
* \brief Initialize IO pins for USART 0 on port D
*/
# if !defined(CONF_BOARD_ENABLE_USARTD0)
# define CONF_BOARD_ENABLE_USARTD0
# endif
/**
* \def CONF_BOARD_ENABLE_USARTE0
* \brief Initialize IO pins for USART 0 on port E
*/
# if !defined(CONF_BOARD_ENABLE_USARTE0)
# define CONF_BOARD_ENABLE_USARTE0
# endif
//@}
#endif // __DOXYGEN__
/**
* @}
*/
/**
* @}
*/
#endif /* _XMEGA_A3BU_XPLAINED_H_ */
/**
* \file
*
* \brief XMEGA-A3BU-XPLAINED board header file.
*
* This file contains definitions and services related to the features of the
* XMEGA-A3BU Xplained board.
*
* To use this board define BOARD=XMEGA_A3BU_XPLAINED.
*
* Copyright (c) 2011 - 2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _XMEGA_A3BU_XPLAINED_H_
#define _XMEGA_A3BU_XPLAINED_H_
#include <compiler.h>
#define MCU_SOC_NAME "ATxmega256A3BU"
#define BOARD_NAME "XMEGA-A3BU-XPLAINED"
/**
* \defgroup xmega_a3bu_xplained_group XMEGA-A3BU Xplained board
* @{
*/
/**
* \defgroup xmega_a3bu_xplained_feature_group Feature definitions
* @{
*/
//! \name Miscellaneous data
//@{
//! Validate board support for the common sensor service.
#define COMMON_SENSOR_PLATFORM
//@}
/**
* \name LEDs
*
* LED0 and LED1 are single yellow LEDs that are active low..
* LED2 and LED3 are inside one package (Led red and green close
* to USB connector) but can be controlled individually.
* LED2 has a red color and is active low. This LED can be
* used for general purposes.
* LED3 has a green color and is active high. By default this
* LED is on since it shall indicate that power is applied to the
* board. By pulling the gate of a N-FET low it is possible to
* turn off the LED if needed.
*/
//@{
#define LED0_GPIO IOPORT_CREATE_PIN(PORTR, 0)
#define LED1_GPIO IOPORT_CREATE_PIN(PORTR, 1)
#define LED2_GPIO IOPORT_CREATE_PIN(PORTD, 4)
#define LED3_GPIO IOPORT_CREATE_PIN(PORTD, 5)
#define LED0 LED0_GPIO
#define LED1 LED1_GPIO
#define LED2 LED2_GPIO
#define LED3 LED3_GPIO
//! Number of LEDs.
#define LED_COUNT 4
//@}
//! \name Push buttons
//@{
#define GPIO_PUSH_BUTTON_0 IOPORT_CREATE_PIN(PORTE, 5)
#define GPIO_PUSH_BUTTON_1 IOPORT_CREATE_PIN(PORTF, 1)
#define GPIO_PUSH_BUTTON_2 IOPORT_CREATE_PIN(PORTF, 2)
//@}
//! \name QTouch button
//! This button requires the software QTouch library
//@{
#define QTOUCH_BUTTON_SNS IOPORT_CREATE_PIN(PORTF, 6)
#define QTOUCH_BUTTON_SNSK IOPORT_CREATE_PIN(PORTF, 7)
//@}
//! \name Light sensor
//@{
#define LIGHT_SENSOR_ADC_MODULE ADCA
#define LIGHT_SENSOR_ADC_INPUT ADCCH_POS_PIN0
#define LIGHT_SENSOR_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 0)
//@}
//! \name Temperature sensor (NTC)
//@{
#define TEMPERATURE_SENSOR_ADC_MODULE ADCA
#define TEMPERATURE_SENSOR_ADC_INPUT ADCCH_POS_PIN1
#define TEMPERATURE_SENSOR_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 1)
//@}
//! \name Analog filter (lowpass RC @ 159 Hz)
//@{
#define FILTER_INPUT_SIGNAL_PIN IOPORT_CREATE_PIN(PORTF, 0)
#define FILTER_OUTPUT_ADC_MODULE ADCA
#define FILTER_OUTPUT_ADC_INPUT ADCCH_POS_PIN2
#define FILTER_OUTPUT_SIGNAL_PIN IOPORT_CREATE_PIN(PORTA, 2)
//@}
//! \name LCD backlight
//@{
#define LCD_BACKLIGHT_ENABLE_PIN IOPORT_CREATE_PIN(PORTE, 4)
#define LCD_BACKLIGHT_ENABLE_LEVEL true
//@}
//! \name LCD controller (NHD-C12832A1Z-FSW-FBW-3V3)
//@{
#define NHD_C12832A1Z_SPI &USARTD0
#define NHD_C12832A1Z_SPI_SCK IOPORT_CREATE_PIN(PORTD, 1)
#define NHD_C12832A1Z_SPI_MOSI IOPORT_CREATE_PIN(PORTD, 3)
#define NHD_C12832A1Z_CSN IOPORT_CREATE_PIN(PORTF, 3)
//! If this signal is set high display data is sent otherwise commands
#define NHD_C12832A1Z_REGISTER_SELECT IOPORT_CREATE_PIN(PORTD, 0)
#define NHD_C12832A1Z_RESETN IOPORT_CREATE_PIN(PORTA, 3)
//! The backlight is active high
#define NHD_C12832A1Z_BACKLIGHT IOPORT_CREATE_PIN(PORTE, 4)
//@}
//! \name LCD dimensions
//@{
#define LCD_WIDTH_PIXELS (128)
#define LCD_HEIGHT_PIXELS (32)
//@}
//! \name DataFlash memory (AT45DBX)
//@{
#define AT45DBX_SPI &USARTD0
#define AT45DBX_CS IOPORT_CREATE_PIN(PORTF, 4)
//! SCK pin
#define AT45DBX_MASTER_SCK IOPORT_CREATE_PIN(PORTD, 1)
//! MOSI pin
#define AT45DBX_MASTER_MOSI IOPORT_CREATE_PIN(PORTD, 3)
//! MISO pin
#define AT45DBX_MASTER_MISO IOPORT_CREATE_PIN(PORTD, 2)
//@}
//! \name MXT143E Xplained top module
//@{
#define MXT143E_XPLAINED_TWI &TWIC
#define MXT143E_XPLAINED_USART_SPI &USARTC1
#define MXT143E_XPLAINED_CS IOPORT_CREATE_PIN(PORTC, 4)
#define MXT143E_XPLAINED_SCK IOPORT_CREATE_PIN(PORTC, 7)
#define MXT143E_XPLAINED_MOSI IOPORT_CREATE_PIN(PORTC, 5)
#define MXT143E_XPLAINED_MISO IOPORT_CREATE_PIN(PORTC, 6)
#define MXT143E_XPLAINED_CHG IOPORT_CREATE_PIN(PORTC, 2)
#define MXT143E_XPLAINED_DC IOPORT_CREATE_PIN(PORTC, 3)
#define MXT143E_XPLAINED_BACKLIGHT IOPORT_CREATE_PIN(PORTA, 4)
#define MXT143E_XPLAINED_LCD_RESET IOPORT_CREATE_PIN(PORTA, 6)
//@}
/**
* \name External oscillator
*
* \todo Need to measure the actual startup time on the hardware.
*/
//@{
#define BOARD_XOSC_HZ 32768
#define BOARD_XOSC_TYPE XOSC_TYPE_32KHZ
#define BOARD_XOSC_STARTUP_US 1000000
//@}
//! \name Communication interfaces on header J1
//@{
#define TWIC_SDA IOPORT_CREATE_PIN(PORTC, 0)
#define TWIC_SCL IOPORT_CREATE_PIN(PORTC, 1)
#define USARTC0_RXD IOPORT_CREATE_PIN(PORTC, 2)
#define USARTC0_TXD IOPORT_CREATE_PIN(PORTC, 3)
#define SPIC_SS IOPORT_CREATE_PIN(PORTC, 4)
#define SPIC_MOSI IOPORT_CREATE_PIN(PORTC, 5)
#define SPIC_MISO IOPORT_CREATE_PIN(PORTC, 6)
#define SPIC_SCK IOPORT_CREATE_PIN(PORTC, 7)
//@}
/*! \name Connections of the AT86RFX transceiver
*/
//! @{
#define AT86RFX_SPI &SPIC
#define AT86RFX_RST_PIN IOPORT_CREATE_PIN(PORTC, 0)
#define AT86RFX_MISC_PIN IOPORT_CREATE_PIN(PORTC, 1)
#define AT86RFX_IRQ_PIN IOPORT_CREATE_PIN(PORTC, 2)
#define AT86RFX_SLP_PIN IOPORT_CREATE_PIN(PORTC, 3)
#define AT86RFX_SPI_CS IOPORT_CREATE_PIN(PORTC, 4)
#define AT86RFX_SPI_MOSI IOPORT_CREATE_PIN(PORTC, 5)
#define AT86RFX_SPI_MISO IOPORT_CREATE_PIN(PORTC, 6)
#define AT86RFX_SPI_SCK IOPORT_CREATE_PIN(PORTC, 7)
#define AT86RFX_INTC_INIT() ioport_configure_pin(AT86RFX_IRQ_PIN, IOPORT_DIR_INPUT); \
PORTC.PIN2CTRL = PORT_ISC0_bm; \
PORTC.INT0MASK = PIN2_bm; \
PORTC.INTFLAGS = PORT_INT0IF_bm;
#define AT86RFX_ISR() ISR(PORTC_INT0_vect)
/** Enables the transceiver main interrupt. */
#define ENABLE_TRX_IRQ() (PORTC.INTCTRL |= PORT_INT0LVL_gm)
/** Disables the transceiver main interrupt. */
#define DISABLE_TRX_IRQ() (PORTC.INTCTRL &= ~PORT_INT0LVL_gm)
/** Clears the transceiver main interrupt. */
#define CLEAR_TRX_IRQ() (PORTC.INTFLAGS = PORT_INT0IF_bm)
/*
* This macro saves the trx interrupt status and disables the trx interrupt.
*/
#define ENTER_TRX_REGION() { uint8_t irq_mask = PORTC.INTCTRL; PORTC.INTCTRL &= ~PORT_INT0LVL_gm
/*
* This macro restores the transceiver interrupt status
*/
#define LEAVE_TRX_REGION() PORTC.INTCTRL = irq_mask; }
//! @}
/**
* \name Pin connections on header J1
*
* The whole port C is directly connected to J1.
*
* \note For the TWI lines there are footprints for pull up resistors, which
* are by default not mounted on the board.
*/
//@{
#define J1_PIN0 IOPORT_CREATE_PIN(PORTC, 0)
#define J1_PIN1 IOPORT_CREATE_PIN(PORTC, 1)
#define J1_PIN2 IOPORT_CREATE_PIN(PORTC, 2)
#define J1_PIN3 IOPORT_CREATE_PIN(PORTC, 3)
#define J1_PIN4 IOPORT_CREATE_PIN(PORTC, 4)
#define J1_PIN5 IOPORT_CREATE_PIN(PORTC, 5)
#define J1_PIN6 IOPORT_CREATE_PIN(PORTC, 6)
#define J1_PIN7 IOPORT_CREATE_PIN(PORTC, 7)
//@}
/**
* \name Pin connections on header J2
*
* The lower half of port B is connected to the lower pins of J2 while the
* upper half of port A is connected to the upper pins of J2.
*
* The port pins are connected directly to this header and are not shared with
* any on-board functionality.
*/
//@{
#define J2_PIN0 IOPORT_CREATE_PIN(PORTB, 0)
#define J2_PIN1 IOPORT_CREATE_PIN(PORTB, 1)
#define J2_PIN2 IOPORT_CREATE_PIN(PORTB, 2)
#define J2_PIN3 IOPORT_CREATE_PIN(PORTB, 3)
#define J2_PIN4 IOPORT_CREATE_PIN(PORTA, 4)
#define J2_PIN5 IOPORT_CREATE_PIN(PORTA, 5)
#define J2_PIN6 IOPORT_CREATE_PIN(PORTA, 6)
#define J2_PIN7 IOPORT_CREATE_PIN(PORTA, 7)
//@}
/**
* \name Pin connections on header J3
*
* The lower half of port A is connected to the lower pins of J3 while the
* upper half of port B is connected to the upper pins of J3.
*
* Following pins are shared with on-board functionality:
* - J3_PIN0 Light sensor output (can be disconnected via scratch pad)
* - J3_PIN1 NTC sensor output (can be disconnected via scratch pad)
* - J3_PIN2 Filter output (can be disconnected via scratch pad)
* - J3_PIN3 Display reset input (can't be used when display is in use)
* - J3_PIN4 JTAG TMS (pin can't be used while JTAG device connected)
* - J3_PIN5 JTAG TDI (pin can't be used while JTAG device connected)
* - J3_PIN6 JTAG TCK (pin can't be used while JTAG device connected)
* - J3_PIN7 JTAG TDO & PID DATA (pin can't be used while JTAG/PDI device is
* connected)
*/
//@{
#define J3_PIN0 IOPORT_CREATE_PIN(PORTA, 0)
#define J3_PIN1 IOPORT_CREATE_PIN(PORTA, 1)
#define J3_PIN2 IOPORT_CREATE_PIN(PORTA, 2)
#define J3_PIN3 IOPORT_CREATE_PIN(PORTA, 3)
#define J3_PIN4 IOPORT_CREATE_PIN(PORTB, 4)
#define J3_PIN5 IOPORT_CREATE_PIN(PORTB, 5)
#define J3_PIN6 IOPORT_CREATE_PIN(PORTB, 6)
#define J3_PIN7 IOPORT_CREATE_PIN(PORTB, 7)
//@}
/**
* \name Pin connections on header J4
*
* The lower half of port E is connected to the lower pins of J4 and the lower
* half of port D is connected to the upper pins of J4.
*/
//@{
#define J4_PIN0 IOPORT_CREATE_PIN(PORTE, 0)
#define J4_PIN1 IOPORT_CREATE_PIN(PORTE, 1)
#define J4_PIN2 IOPORT_CREATE_PIN(PORTE, 2)
#define J4_PIN3 IOPORT_CREATE_PIN(PORTE, 3)
#define J4_PIN4 IOPORT_CREATE_PIN(PORTD, 0)
#define J4_PIN5 IOPORT_CREATE_PIN(PORTD, 3)
#define J4_PIN6 IOPORT_CREATE_PIN(PORTD, 2)
#define J4_PIN7 IOPORT_CREATE_PIN(PORTD, 1)
//@}
/**
* @}
*/
/**
* \defgroup xmega_a3bu_xplained_config_group Configuration options
* @{
*/
#if defined(__DOXYGEN__)
/**
* \name Initialization
* \note Define these symbols in \ref conf_board.h to enable the corresponding
* features.
*/
//@{
/**
* \def CONF_BOARD_C12832A1Z
* \brief Initialize SPI and control pins for C12832A1Z LCD controller
*/
# if !defined(CONF_BOARD_C12832A1Z)
# define CONF_BOARD_C12832A1Z
# endif
/**
* \def CONF_BOARD_AT45DBX
* \brief Initialize SPI pins for AT45DBX DataFlash
*/
# if !defined(CONF_BOARD_AT45DBX)
# define CONF_BOARD_AT45DBX
# endif
/**
* \def CONF_BOARD_ENABLE_AC_PINS
* \brief Initialize IO pins for Analog Comparator
*
* \note This initializes pins PA0, PA2 and PB1 as inputs.
*/
# if !defined(CONF_BOARD_ENABLE_AC_PINS)
# define CONF_BOARD_ENABLE_AC_PINS
# endif
/**
* \def CONF_BOARD_ENABLE_USARTC0
* \brief Initialize IO pins for USART 0 on port C
*/
# if !defined(CONF_BOARD_ENABLE_USARTC0)
# define CONF_BOARD_ENABLE_USARTC0
# endif
/**
* \def CONF_BOARD_ENABLE_USARTD0
* \brief Initialize IO pins for USART 0 on port D
*/
# if !defined(CONF_BOARD_ENABLE_USARTD0)
# define CONF_BOARD_ENABLE_USARTD0
# endif
/**
* \def CONF_BOARD_ENABLE_USARTE0
* \brief Initialize IO pins for USART 0 on port E
*/
# if !defined(CONF_BOARD_ENABLE_USARTE0)
# define CONF_BOARD_ENABLE_USARTE0
# endif
//@}
#endif // __DOXYGEN__
/**
* @}
*/
/**
* @}
*/
#endif /* _XMEGA_A3BU_XPLAINED_H_ */
@@ -1,297 +1,297 @@
/**
* \file
*
* \brief AVR XMEGA Analog to Digital Converter driver
*
* Copyright (C) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <adc.h>
/**
* \ingroup adc_module_group
* @{
*/
/** \name ADC interrupt callback function */
/** @{ */
#ifdef ADCA
/**
* \internal
* \brief ADC A enable counter
*
* This is used to ensure that ADC A is not inadvertently disabled when its
* module or channel configurations are updated.
*/
static uint8_t adca_enable_count;
# ifdef CONFIG_ADC_CALLBACK_ENABLE
/**
* \internal
* \brief ADC A interrupt callback function pointer
*/
adc_callback_t adca_callback;
# endif
#endif
#ifdef ADCB
/**
* \internal
* \brief ADC B enable counter
*
* This is used to ensure that ADC B is not inadvertently disabled when its
* module or channel configurations are updated.
*/
static uint8_t adcb_enable_count;
# ifdef CONFIG_ADC_CALLBACK_ENABLE
/**
* \internal
* \brief ADC B interrupt callback function pointer
*/
adc_callback_t adcb_callback;
# endif
#endif
#if defined(CONFIG_ADC_CALLBACK_ENABLE) || defined(__DOXYGEN__)
/**
* \brief Set ADC interrupt callback function
*
* Sets a new callback function for interrupts on the specified ADC.
*
* \param adc Pointer to ADC module.
* \param callback Pointer to the callback function to set.
*/
void adc_set_callback(ADC_t * adc,
adc_callback_t callback)
{
irqflags_t flags;
Assert(callback);
flags = cpu_irq_save();
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
adca_callback = callback;
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
adcb_callback = callback;
} else
#endif
{
Assert(0);
}
cpu_irq_restore(flags);
}
#endif /* CONFIG_ADC_CALLBACK_ENABLE */
/** @} */
/** \name Internal functions for driver */
/** @{ */
/**
* \internal
* \brief Enable peripheral clock for ADC
*
* Checks if the enable count for the ADC is zero, then increments it. If the
* count was zero, the peripheral clock is enabled. Otherwise, it is already
* enabled.
*
* \param adc Pointer to ADC module.
*/
void adc_enable_clock(ADC_t * adc);
void adc_enable_clock(ADC_t * adc)
{
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) (&ADCA)) {
Assert(adca_enable_count < 0xff);
if (!adca_enable_count++) {
sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC);
}
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) (&ADCB)) {
Assert(adcb_enable_count < 0xff);
if (!adcb_enable_count++) {
sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC);
}
} else
#endif
{
Assert(0);
}
}
/**
* \internal
* \brief Disable peripheral clock for ADC
*
* Decrements the enable count for the ADC, then disables its peripheral clock
* if the count hit zero. If the count did not hit zero, it indicates the ADC is
* enabled.
*
* \param adc Pointer to ADC module
*/
void adc_disable_clock(ADC_t * adc);
void adc_disable_clock(ADC_t * adc)
{
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) (&ADCA)) {
Assert(adca_enable_count);
if (!--adca_enable_count) {
sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC);
}
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) (&ADCB)) {
Assert(adcb_enable_count);
if (!--adcb_enable_count) {
sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC);
}
} else
#endif
{
Assert(0);
}
}
/** @} */
/** \name ADC module management */
/** @{ */
/**
* \brief Enable ADC
*
* Enables the ADC and locks IDLE mode for the sleep manager.
*
* \param adc Pointer to ADC module
*
* \note To ensure accurate conversions, please wait for at least
* the specified start-up time between enabling the ADC module, and starting
* a conversion. For most XMEGA devices the start-up time is specified
* to be a maximum of 24 ADC clock cycles. Please verify the start-up time for
* the device in use.
*/
void adc_enable(ADC_t * adc)
{
irqflags_t flags = cpu_irq_save();
adc_enable_clock(adc);
adc->CTRLA |= ADC_ENABLE_bm;
cpu_irq_restore(flags);
sleepmgr_lock_mode(SLEEPMGR_IDLE);
}
/**
* \brief Disable ADC
*
* Disables the ADC and unlocks IDLE mode for the sleep manager.
*
* \param adc Pointer to ADC module
*/
void adc_disable(ADC_t * adc)
{
irqflags_t flags = cpu_irq_save();
adc->CTRLA &= ~ADC_ENABLE_bm;
adc_disable_clock(adc);
cpu_irq_restore(flags);
sleepmgr_unlock_mode(SLEEPMGR_IDLE);
}
/**
* \brief Check if the ADC is enabled
*
* \param adc Pointer to ADC module.
*
* \retval true if ADC is enabled.
* \retval false if ADC is disabled.
*/
bool adc_is_enabled(ADC_t * adc)
{
/* It is sufficient to return the state of the ADC enable counters
* since all driver functions that change the counts are protected
* against interrupts and only the enable/disable functions leave the
* counts incremented/decremented upon return.
*/
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
return adca_enable_count;
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
return adcb_enable_count;
} else
#endif
{
Assert(0);
return false;
}
}
/** @} */
/** @} */
/**
* \file
*
* \brief AVR XMEGA Analog to Digital Converter driver
*
* Copyright (C) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <adc.h>
/**
* \ingroup adc_module_group
* @{
*/
/** \name ADC interrupt callback function */
/** @{ */
#ifdef ADCA
/**
* \internal
* \brief ADC A enable counter
*
* This is used to ensure that ADC A is not inadvertently disabled when its
* module or channel configurations are updated.
*/
static uint8_t adca_enable_count;
# ifdef CONFIG_ADC_CALLBACK_ENABLE
/**
* \internal
* \brief ADC A interrupt callback function pointer
*/
adc_callback_t adca_callback;
# endif
#endif
#ifdef ADCB
/**
* \internal
* \brief ADC B enable counter
*
* This is used to ensure that ADC B is not inadvertently disabled when its
* module or channel configurations are updated.
*/
static uint8_t adcb_enable_count;
# ifdef CONFIG_ADC_CALLBACK_ENABLE
/**
* \internal
* \brief ADC B interrupt callback function pointer
*/
adc_callback_t adcb_callback;
# endif
#endif
#if defined(CONFIG_ADC_CALLBACK_ENABLE) || defined(__DOXYGEN__)
/**
* \brief Set ADC interrupt callback function
*
* Sets a new callback function for interrupts on the specified ADC.
*
* \param adc Pointer to ADC module.
* \param callback Pointer to the callback function to set.
*/
void adc_set_callback(ADC_t * adc,
adc_callback_t callback)
{
irqflags_t flags;
Assert(callback);
flags = cpu_irq_save();
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
adca_callback = callback;
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
adcb_callback = callback;
} else
#endif
{
Assert(0);
}
cpu_irq_restore(flags);
}
#endif /* CONFIG_ADC_CALLBACK_ENABLE */
/** @} */
/** \name Internal functions for driver */
/** @{ */
/**
* \internal
* \brief Enable peripheral clock for ADC
*
* Checks if the enable count for the ADC is zero, then increments it. If the
* count was zero, the peripheral clock is enabled. Otherwise, it is already
* enabled.
*
* \param adc Pointer to ADC module.
*/
void adc_enable_clock(ADC_t * adc);
void adc_enable_clock(ADC_t * adc)
{
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) (&ADCA)) {
Assert(adca_enable_count < 0xff);
if (!adca_enable_count++) {
sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC);
}
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) (&ADCB)) {
Assert(adcb_enable_count < 0xff);
if (!adcb_enable_count++) {
sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC);
}
} else
#endif
{
Assert(0);
}
}
/**
* \internal
* \brief Disable peripheral clock for ADC
*
* Decrements the enable count for the ADC, then disables its peripheral clock
* if the count hit zero. If the count did not hit zero, it indicates the ADC is
* enabled.
*
* \param adc Pointer to ADC module
*/
void adc_disable_clock(ADC_t * adc);
void adc_disable_clock(ADC_t * adc)
{
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) (&ADCA)) {
Assert(adca_enable_count);
if (!--adca_enable_count) {
sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC);
}
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) (&ADCB)) {
Assert(adcb_enable_count);
if (!--adcb_enable_count) {
sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC);
}
} else
#endif
{
Assert(0);
}
}
/** @} */
/** \name ADC module management */
/** @{ */
/**
* \brief Enable ADC
*
* Enables the ADC and locks IDLE mode for the sleep manager.
*
* \param adc Pointer to ADC module
*
* \note To ensure accurate conversions, please wait for at least
* the specified start-up time between enabling the ADC module, and starting
* a conversion. For most XMEGA devices the start-up time is specified
* to be a maximum of 24 ADC clock cycles. Please verify the start-up time for
* the device in use.
*/
void adc_enable(ADC_t * adc)
{
irqflags_t flags = cpu_irq_save();
adc_enable_clock(adc);
adc->CTRLA |= ADC_ENABLE_bm;
cpu_irq_restore(flags);
sleepmgr_lock_mode(SLEEPMGR_IDLE);
}
/**
* \brief Disable ADC
*
* Disables the ADC and unlocks IDLE mode for the sleep manager.
*
* \param adc Pointer to ADC module
*/
void adc_disable(ADC_t * adc)
{
irqflags_t flags = cpu_irq_save();
adc->CTRLA &= ~ADC_ENABLE_bm;
adc_disable_clock(adc);
cpu_irq_restore(flags);
sleepmgr_unlock_mode(SLEEPMGR_IDLE);
}
/**
* \brief Check if the ADC is enabled
*
* \param adc Pointer to ADC module.
*
* \retval true if ADC is enabled.
* \retval false if ADC is disabled.
*/
bool adc_is_enabled(ADC_t * adc)
{
/* It is sufficient to return the state of the ADC enable counters
* since all driver functions that change the counts are protected
* against interrupts and only the enable/disable functions leave the
* counts incremented/decremented upon return.
*/
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
return adca_enable_count;
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
return adcb_enable_count;
} else
#endif
{
Assert(0);
return false;
}
}
/** @} */
/** @} */
File diff suppressed because it is too large Load Diff
@@ -1,370 +1,370 @@
/**
* \file
*
* \brief AVR XMEGA A/AU specific ADC driver implementation
*
* Copyright (C) 2012-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "../adc.h"
/**
* \ingroup adc_module_group
* @{
*/
/** \name Internal functions for driver */
/** @{ */
extern void adc_enable_clock(ADC_t * adc);
extern void adc_disable_clock(ADC_t * adc);
/** @} */
/** \name ADC interrupt callback function */
/** @{ */
#ifdef ADCA
# ifdef CONFIG_ADC_CALLBACK_ENABLE
extern adc_callback_t adca_callback;
/**
* \internal
* \brief ISR for channel 0 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH0_vect)
{
adca_callback(&ADCA, ADC_CH0, adc_get_result(&ADCA, ADC_CH0));
}
/**
* \internal
* \brief ISR for channel 1 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH1_vect)
{
adca_callback(&ADCA, ADC_CH1, adc_get_result(&ADCA, ADC_CH1));
}
/**
* \internal
* \brief ISR for channel 2 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH2_vect)
{
adca_callback(&ADCA, ADC_CH2, adc_get_result(&ADCA, ADC_CH2));
}
/**
* \internal
* \brief ISR for channel 3 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH3_vect)
{
adca_callback(&ADCA, ADC_CH3, adc_get_result(&ADCA, ADC_CH3));
}
# endif
#endif
#ifdef ADCB
# ifdef CONFIG_ADC_CALLBACK_ENABLE
extern adc_callback_t adcb_callback;
/**
* \internal
* \brief ISR for channel 0 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH0_vect)
{
adcb_callback(&ADCB, ADC_CH0, adc_get_result(&ADCB, ADC_CH0));
}
/**
* \internal
* \brief ISR for channel 1 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH1_vect)
{
adcb_callback(&ADCB, ADC_CH1, adc_get_result(&ADCB, ADC_CH1));
}
/**
* \internal
* \brief ISR for channel 2 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH2_vect)
{
adcb_callback(&ADCB, ADC_CH2, adc_get_result(&ADCB, ADC_CH2));
}
/**
* \internal
* \brief ISR for channel 3 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH3_vect)
{
adcb_callback(&ADCB, ADC_CH3, adc_get_result(&ADCB, ADC_CH3));
}
# endif
#endif
/** @} */
/** \name ADC module configuration */
/** @{ */
/**
* \brief Write configuration to ADC module
*
* Disables the ADC and flushes its pipeline before writing the specified
* configuration and factory calibration value to it. If the ADC was enabled
* upon entry of the function, it is enabled upon function return.
*
* \param adc Pointer to ADC module.
* \param conf Pointer to ADC module configuration.
*/
void adc_write_configuration(ADC_t * adc,
const struct adc_config *conf)
{
uint16_t cal;
uint8_t enable;
irqflags_t flags;
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
cal = adc_get_calibration_data(ADC_CAL_ADCA);
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
cal = adc_get_calibration_data(ADC_CAL_ADCB);
} else
#endif
{
Assert(0);
return;
}
flags = cpu_irq_save();
adc_enable_clock(adc);
enable = adc->CTRLA & ADC_ENABLE_bm;
adc->CTRLA = ADC_FLUSH_bm;
adc->CAL = cal;
adc->CMP = conf->cmp;
adc->REFCTRL = conf->refctrl;
adc->PRESCALER = conf->prescaler;
adc->EVCTRL = conf->evctrl;
adc->CTRLB = conf->ctrlb;
adc->CTRLA = enable | conf->ctrla;
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/**
* \brief Read configuration from ADC module
*
* Reads out the current configuration of the ADC module to the specified
* buffer.
*
* \param adc Pointer to ADC module.
* \param conf Pointer to ADC module configuration.
*/
void adc_read_configuration(ADC_t * adc,
struct adc_config *conf)
{
irqflags_t flags = cpu_irq_save();
adc_enable_clock(adc);
conf->ctrla = adc->CTRLA & ADC_DMASEL_gm;
conf->cmp = adc->CMP;
conf->refctrl = adc->REFCTRL;
conf->prescaler = adc->PRESCALER;
conf->evctrl = adc->EVCTRL;
conf->ctrlb = adc->CTRLB;
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/** @} */
/** @} */
/**
* \ingroup adc_channel_group
* @{
*/
/** \name ADC channel configuration */
/** @{ */
/**
* \brief Write configuration to ADC channel
*
* Writes the specified configuration to the ADC channel.
*
* \param adc Pointer to ADC module.
* \param ch_mask Mask of ADC channel(s):
* \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel
* can be given in mask)
* \param ch_conf Pointer to ADC channel configuration.
*
* \note The specified ADC's callback function must be set before this function
* is called if callbacks are enabled and interrupts are enabled in the
* channel configuration.
*/
void adcch_write_configuration(ADC_t * adc,
uint8_t ch_mask,
const struct adc_channel_config *ch_conf)
{
ADC_CH_t *adc_ch;
irqflags_t flags;
adc_ch = adc_get_channel(adc, ch_mask);
flags = cpu_irq_save();
#if defined(CONFIG_ADC_CALLBACK_ENABLE) && defined(_ASSERT_ENABLE_)
if ((adc_ch->INTCTRL & ADC_CH_INTLVL_gm) != ADC_CH_INTLVL_OFF_gc) {
# ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
Assert(adca_callback);
} else
# endif
# ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
Assert(adcb_callback);
} else
# endif
{
Assert(0);
return;
}
}
#endif
adc_enable_clock(adc);
adc_ch->CTRL = ch_conf->ctrl;
adc_ch->INTCTRL = ch_conf->intctrl;
adc_ch->MUXCTRL = ch_conf->muxctrl;
if (ch_mask & ADC_CH0) {
/* USB devices has channel scan available on ADC channel 0 */
adc_ch->SCAN = ch_conf->scan;
}
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/**
* \brief Read configuration from ADC channel
*
* Reads out the current configuration from the ADC channel to the specified
* buffer.
*
* \param adc Pointer to ADC module.
* \param ch_mask Mask of ADC channel(s):
* \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel
* can be given in mask)
* \param ch_conf Pointer to ADC channel configuration.
*/
void adcch_read_configuration(ADC_t * adc,
uint8_t ch_mask,
struct adc_channel_config *ch_conf)
{
ADC_CH_t *adc_ch;
irqflags_t flags;
adc_ch = adc_get_channel(adc, ch_mask);
flags = cpu_irq_save();
adc_enable_clock(adc);
ch_conf->ctrl = adc_ch->CTRL;
ch_conf->intctrl = adc_ch->INTCTRL;
ch_conf->muxctrl = adc_ch->MUXCTRL;
if (ch_mask & ADC_CH0) {
/* USB devices has channel scan available on ADC channel 0 */
ch_conf->scan = adc_ch->SCAN;
}
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/** @} */
/** @} */
/**
* \file
*
* \brief AVR XMEGA A/AU specific ADC driver implementation
*
* Copyright (C) 2012-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "../adc.h"
/**
* \ingroup adc_module_group
* @{
*/
/** \name Internal functions for driver */
/** @{ */
extern void adc_enable_clock(ADC_t * adc);
extern void adc_disable_clock(ADC_t * adc);
/** @} */
/** \name ADC interrupt callback function */
/** @{ */
#ifdef ADCA
# ifdef CONFIG_ADC_CALLBACK_ENABLE
extern adc_callback_t adca_callback;
/**
* \internal
* \brief ISR for channel 0 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH0_vect)
{
adca_callback(&ADCA, ADC_CH0, adc_get_result(&ADCA, ADC_CH0));
}
/**
* \internal
* \brief ISR for channel 1 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH1_vect)
{
adca_callback(&ADCA, ADC_CH1, adc_get_result(&ADCA, ADC_CH1));
}
/**
* \internal
* \brief ISR for channel 2 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH2_vect)
{
adca_callback(&ADCA, ADC_CH2, adc_get_result(&ADCA, ADC_CH2));
}
/**
* \internal
* \brief ISR for channel 3 on ADC A
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCA_CH3_vect)
{
adca_callback(&ADCA, ADC_CH3, adc_get_result(&ADCA, ADC_CH3));
}
# endif
#endif
#ifdef ADCB
# ifdef CONFIG_ADC_CALLBACK_ENABLE
extern adc_callback_t adcb_callback;
/**
* \internal
* \brief ISR for channel 0 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH0_vect)
{
adcb_callback(&ADCB, ADC_CH0, adc_get_result(&ADCB, ADC_CH0));
}
/**
* \internal
* \brief ISR for channel 1 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH1_vect)
{
adcb_callback(&ADCB, ADC_CH1, adc_get_result(&ADCB, ADC_CH1));
}
/**
* \internal
* \brief ISR for channel 2 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH2_vect)
{
adcb_callback(&ADCB, ADC_CH2, adc_get_result(&ADCB, ADC_CH2));
}
/**
* \internal
* \brief ISR for channel 3 on ADC B
*
* Calls the callback function that has been set for the ADC when the channel's
* interrupt flag is set, if its interrupt has been enabled.
*/
ISR(ADCB_CH3_vect)
{
adcb_callback(&ADCB, ADC_CH3, adc_get_result(&ADCB, ADC_CH3));
}
# endif
#endif
/** @} */
/** \name ADC module configuration */
/** @{ */
/**
* \brief Write configuration to ADC module
*
* Disables the ADC and flushes its pipeline before writing the specified
* configuration and factory calibration value to it. If the ADC was enabled
* upon entry of the function, it is enabled upon function return.
*
* \param adc Pointer to ADC module.
* \param conf Pointer to ADC module configuration.
*/
void adc_write_configuration(ADC_t * adc,
const struct adc_config *conf)
{
uint16_t cal;
uint8_t enable;
irqflags_t flags;
#ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
cal = adc_get_calibration_data(ADC_CAL_ADCA);
} else
#endif
#ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
cal = adc_get_calibration_data(ADC_CAL_ADCB);
} else
#endif
{
Assert(0);
return;
}
flags = cpu_irq_save();
adc_enable_clock(adc);
enable = adc->CTRLA & ADC_ENABLE_bm;
adc->CTRLA = ADC_FLUSH_bm;
adc->CAL = cal;
adc->CMP = conf->cmp;
adc->REFCTRL = conf->refctrl;
adc->PRESCALER = conf->prescaler;
adc->EVCTRL = conf->evctrl;
adc->CTRLB = conf->ctrlb;
adc->CTRLA = enable | conf->ctrla;
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/**
* \brief Read configuration from ADC module
*
* Reads out the current configuration of the ADC module to the specified
* buffer.
*
* \param adc Pointer to ADC module.
* \param conf Pointer to ADC module configuration.
*/
void adc_read_configuration(ADC_t * adc,
struct adc_config *conf)
{
irqflags_t flags = cpu_irq_save();
adc_enable_clock(adc);
conf->ctrla = adc->CTRLA & ADC_DMASEL_gm;
conf->cmp = adc->CMP;
conf->refctrl = adc->REFCTRL;
conf->prescaler = adc->PRESCALER;
conf->evctrl = adc->EVCTRL;
conf->ctrlb = adc->CTRLB;
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/** @} */
/** @} */
/**
* \ingroup adc_channel_group
* @{
*/
/** \name ADC channel configuration */
/** @{ */
/**
* \brief Write configuration to ADC channel
*
* Writes the specified configuration to the ADC channel.
*
* \param adc Pointer to ADC module.
* \param ch_mask Mask of ADC channel(s):
* \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel
* can be given in mask)
* \param ch_conf Pointer to ADC channel configuration.
*
* \note The specified ADC's callback function must be set before this function
* is called if callbacks are enabled and interrupts are enabled in the
* channel configuration.
*/
void adcch_write_configuration(ADC_t * adc,
uint8_t ch_mask,
const struct adc_channel_config *ch_conf)
{
ADC_CH_t *adc_ch;
irqflags_t flags;
adc_ch = adc_get_channel(adc, ch_mask);
flags = cpu_irq_save();
#if defined(CONFIG_ADC_CALLBACK_ENABLE) && defined(_ASSERT_ENABLE_)
if ((adc_ch->INTCTRL & ADC_CH_INTLVL_gm) != ADC_CH_INTLVL_OFF_gc) {
# ifdef ADCA
if ((uintptr_t) adc == (uintptr_t) & ADCA) {
Assert(adca_callback);
} else
# endif
# ifdef ADCB
if ((uintptr_t) adc == (uintptr_t) & ADCB) {
Assert(adcb_callback);
} else
# endif
{
Assert(0);
return;
}
}
#endif
adc_enable_clock(adc);
adc_ch->CTRL = ch_conf->ctrl;
adc_ch->INTCTRL = ch_conf->intctrl;
adc_ch->MUXCTRL = ch_conf->muxctrl;
if (ch_mask & ADC_CH0) {
/* USB devices has channel scan available on ADC channel 0 */
adc_ch->SCAN = ch_conf->scan;
}
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/**
* \brief Read configuration from ADC channel
*
* Reads out the current configuration from the ADC channel to the specified
* buffer.
*
* \param adc Pointer to ADC module.
* \param ch_mask Mask of ADC channel(s):
* \arg \c ADC_CHn , where \c n specifies the channel. (Only a single channel
* can be given in mask)
* \param ch_conf Pointer to ADC channel configuration.
*/
void adcch_read_configuration(ADC_t * adc,
uint8_t ch_mask,
struct adc_channel_config *ch_conf)
{
ADC_CH_t *adc_ch;
irqflags_t flags;
adc_ch = adc_get_channel(adc, ch_mask);
flags = cpu_irq_save();
adc_enable_clock(adc);
ch_conf->ctrl = adc_ch->CTRL;
ch_conf->intctrl = adc_ch->INTCTRL;
ch_conf->muxctrl = adc_ch->MUXCTRL;
if (ch_mask & ADC_CH0) {
/* USB devices has channel scan available on ADC channel 0 */
ch_conf->scan = adc_ch->SCAN;
}
adc_disable_clock(adc);
cpu_irq_restore(flags);
}
/** @} */
/** @} */
@@ -1,120 +1,120 @@
/**
* \file
*
* \brief Configuration Change Protection write functions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CPU_CCP_H
#define CPU_CCP_H
#include <compiler.h>
/**
* \defgroup ccp_group Configuration Change Protection
*
* See \ref xmega_ccp_quickstart.
*
* Function for writing to protected IO registers.
* @{
*/
#if defined(__DOXYGEN__)
//! \name IAR Memory Model defines.
//@{
/**
* \def CONFIG_MEMORY_MODEL_TINY
* \brief Configuration symbol to enable 8 bit pointers.
*
*/
# define CONFIG_MEMORY_MODEL_TINY
/**
* \def CONFIG_MEMORY_MODEL_SMALL
* \brief Configuration symbol to enable 16 bit pointers.
* \note If no memory model is defined, SMALL is default.
*
*/
# define CONFIG_MEMORY_MODEL_SMALL
/**
* \def CONFIG_MEMORY_MODEL_LARGE
* \brief Configuration symbol to enable 24 bit pointers.
*
*/
# define CONFIG_MEMORY_MODEL_LARGE
//@}
#endif
/**
* \brief Write to a CCP-protected 8-bit I/O register
*
* \param addr Address of the I/O register
* \param value Value to be written
*
* \note Using IAR Embedded workbench, the choice of memory model has an impact
* on calling convention. The memory model is not visible to the
* preprocessor, so it must be defined in the Assembler preprocessor directives.
*/
extern void ccp_write_io (void *addr, uint8_t value);
/** @} */
/**
* \page xmega_ccp_quickstart Quick start guide for CCP driver
*
* This is the quick start guide for the \ref ccp_group
* "Configuration Change Protection (CCP) driver", with step-by-step
* instructions on how to use the driver.
*
* The use case contains a code fragment, and this can be copied into, e.g.,
* the main application function.
*
* \section ccp_basic_use_case Basic use case
* In this use case, the CCP is used to write to the protected XMEGA Clock
* Control register.
*
* \subsection ccp_basic_use_case_setup_flow Workflow
* -# call CCP write io to change system clock selection:
* - \code ccp_write_io((uint8_t *)&CLK.CTRL, CLK_SCLKSEL_RC32M_gc); \endcode
*/
#endif /* CPU_CCP_H */
/**
* \file
*
* \brief Configuration Change Protection write functions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CPU_CCP_H
#define CPU_CCP_H
#include <compiler.h>
/**
* \defgroup ccp_group Configuration Change Protection
*
* See \ref xmega_ccp_quickstart.
*
* Function for writing to protected IO registers.
* @{
*/
#if defined(__DOXYGEN__)
//! \name IAR Memory Model defines.
//@{
/**
* \def CONFIG_MEMORY_MODEL_TINY
* \brief Configuration symbol to enable 8 bit pointers.
*
*/
# define CONFIG_MEMORY_MODEL_TINY
/**
* \def CONFIG_MEMORY_MODEL_SMALL
* \brief Configuration symbol to enable 16 bit pointers.
* \note If no memory model is defined, SMALL is default.
*
*/
# define CONFIG_MEMORY_MODEL_SMALL
/**
* \def CONFIG_MEMORY_MODEL_LARGE
* \brief Configuration symbol to enable 24 bit pointers.
*
*/
# define CONFIG_MEMORY_MODEL_LARGE
//@}
#endif
/**
* \brief Write to a CCP-protected 8-bit I/O register
*
* \param addr Address of the I/O register
* \param value Value to be written
*
* \note Using IAR Embedded workbench, the choice of memory model has an impact
* on calling convention. The memory model is not visible to the
* preprocessor, so it must be defined in the Assembler preprocessor directives.
*/
extern void ccp_write_io (void *addr, uint8_t value);
/** @} */
/**
* \page xmega_ccp_quickstart Quick start guide for CCP driver
*
* This is the quick start guide for the \ref ccp_group
* "Configuration Change Protection (CCP) driver", with step-by-step
* instructions on how to use the driver.
*
* The use case contains a code fragment, and this can be copied into, e.g.,
* the main application function.
*
* \section ccp_basic_use_case Basic use case
* In this use case, the CCP is used to write to the protected XMEGA Clock
* Control register.
*
* \subsection ccp_basic_use_case_setup_flow Workflow
* -# call CCP write io to change system clock selection:
* - \code ccp_write_io((uint8_t *)&CLK.CTRL, CLK_SCLKSEL_RC32M_gc); \endcode
*/
#endif /* CPU_CCP_H */
@@ -1,109 +1,109 @@
/**
* \file
*
* \brief Chip-specific reset cause functions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_DRIVERS_CPU_RESET_CAUSE_H
#define XMEGA_DRIVERS_CPU_RESET_CAUSE_H
#include "compiler.h"
#include "ccp.h"
/**
* \ingroup reset_cause_group
* \defgroup xmega_reset_cause_group XMEGA reset cause
*
* See \ref reset_cause_quickstart
*
* @{
*/
/**
* \brief Chip-specific reset cause type capable of holding all chip reset
* causes. Typically reflects the size of the reset cause register.
*/
typedef uint8_t reset_cause_t;
//! \internal \name Chip-specific reset causes
//@{
//! \internal External reset cause
#define CHIP_RESET_CAUSE_EXTRST RST_EXTRF_bm
//! \internal brown-out detected reset cause, same as for CPU
#define CHIP_RESET_CAUSE_BOD_IO RST_BORF_bm
//! \internal Brown-out detected reset cause, same as for I/O
#define CHIP_RESET_CAUSE_BOD_CPU RST_BORF_bm
//! \internal On-chip debug system reset cause
#define CHIP_RESET_CAUSE_OCD RST_PDIRF_bm
//! \internal Power-on-reset reset cause
#define CHIP_RESET_CAUSE_POR RST_PORF_bm
//! \internal Software reset reset cause
#define CHIP_RESET_CAUSE_SOFT RST_SRF_bm
//! \internal Spike detected reset cause
#define CHIP_RESET_CAUSE_SPIKE RST_SDRF_bm
//! \internal Watchdog timeout reset cause
#define CHIP_RESET_CAUSE_WDT RST_WDRF_bm
//@}
static inline reset_cause_t
reset_cause_get_causes (void)
{
return (reset_cause_t) RST.STATUS;
}
static inline void
reset_cause_clear_causes (reset_cause_t causes)
{
RST.STATUS = causes;
}
static inline void
reset_do_soft_reset (void)
{
ccp_write_io ((void *) &RST.CTRL, RST_SWRST_bm);
while (1)
{
/* Intentionally empty. */
}
}
//! @}
#endif /* XMEGA_DRIVERS_CPU_RESET_CAUSE_H */
/**
* \file
*
* \brief Chip-specific reset cause functions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef XMEGA_DRIVERS_CPU_RESET_CAUSE_H
#define XMEGA_DRIVERS_CPU_RESET_CAUSE_H
#include "compiler.h"
#include "ccp.h"
/**
* \ingroup reset_cause_group
* \defgroup xmega_reset_cause_group XMEGA reset cause
*
* See \ref reset_cause_quickstart
*
* @{
*/
/**
* \brief Chip-specific reset cause type capable of holding all chip reset
* causes. Typically reflects the size of the reset cause register.
*/
typedef uint8_t reset_cause_t;
//! \internal \name Chip-specific reset causes
//@{
//! \internal External reset cause
#define CHIP_RESET_CAUSE_EXTRST RST_EXTRF_bm
//! \internal brown-out detected reset cause, same as for CPU
#define CHIP_RESET_CAUSE_BOD_IO RST_BORF_bm
//! \internal Brown-out detected reset cause, same as for I/O
#define CHIP_RESET_CAUSE_BOD_CPU RST_BORF_bm
//! \internal On-chip debug system reset cause
#define CHIP_RESET_CAUSE_OCD RST_PDIRF_bm
//! \internal Power-on-reset reset cause
#define CHIP_RESET_CAUSE_POR RST_PORF_bm
//! \internal Software reset reset cause
#define CHIP_RESET_CAUSE_SOFT RST_SRF_bm
//! \internal Spike detected reset cause
#define CHIP_RESET_CAUSE_SPIKE RST_SDRF_bm
//! \internal Watchdog timeout reset cause
#define CHIP_RESET_CAUSE_WDT RST_WDRF_bm
//@}
static inline reset_cause_t
reset_cause_get_causes (void)
{
return (reset_cause_t) RST.STATUS;
}
static inline void
reset_cause_clear_causes (reset_cause_t causes)
{
RST.STATUS = causes;
}
static inline void
reset_do_soft_reset (void)
{
ccp_write_io ((void *) &RST.CTRL, RST_SWRST_bm);
while (1)
{
/* Intentionally empty. */
}
}
//! @}
#endif /* XMEGA_DRIVERS_CPU_RESET_CAUSE_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,361 +1,361 @@
/**
* \file
*
* \brief Programmable Multilevel Interrupt Controller driver
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef PMIC_H
#define PMIC_H
#include <compiler.h>
#include <ccp.h>
/**
* \defgroup pmic_group Programmable Multilevel Interrupt Controller
*
* See \ref xmega_pmic_quickstart.
*
* This is a low-level driver implementation for the AVR XMEGA Programmable
* Multilevel Interrupt Controller.
*
* \note If these functions are used in interrupt service routines (ISRs), any
* non-ISR code or ISR code for lower level interrupts must ensure that the
* operations are atomic, i.e., by disabling interrupts during the function
* calls.
* @{
*/
/**
* \brief Interrupt level bitmasks
*
* \note These may be OR'ed, e.g., if multiple levels are to be enabled or
* disabled.
*/
enum pmic_level
{
PMIC_LVL_LOW = PMIC_LOLVLEN_bm, //!< Low-level interrupts
PMIC_LVL_MEDIUM = PMIC_MEDLVLEN_bm, //!< Medium-level interrupts
PMIC_LVL_HIGH = PMIC_HILVLEN_bm, //!< High-level interrupts
/**
* \brief Non-maskable interrupts
* \note These cannot be enabled nor disabled.
*/
PMIC_LVL_NMI = PMIC_NMIEX_bp,
};
//! Interrupt vector locations
enum pmic_vector
{
PMIC_VEC_APPLICATION, //!< Application section
PMIC_VEC_BOOT, //!< Boot section
PMIC_NR_OF_VECTORS, //!< Number of interrupt vector locations
};
//! Interrupt scheduling schemes
enum pmic_schedule
{
PMIC_SCH_FIXED_PRIORITY, //!< Default, fixed priority scheduling
PMIC_SCH_ROUND_ROBIN, //!< Round-robin scheduling
PMIC_NR_OF_SCHEDULES, //!< Number of interrupt scheduling schemes
};
/**
* \brief Initialize the PMIC
*
* Enables all interrupt levels, with vectors located in the application section
* and fixed priority scheduling.
*/
static inline void
pmic_init (void)
{
PMIC.CTRL = PMIC_LVL_LOW | PMIC_LVL_MEDIUM | PMIC_LVL_HIGH;
}
/**
* \brief Enable interrupts with specified \a level(s).
*
* \param level Interrupt level(s) to enable.
*/
static inline void
pmic_enable_level (enum pmic_level level)
{
Assert ((level & PMIC_LVL_NMI));
PMIC.CTRL |= level;
}
/**
* \brief Disable interrupts with specified \a level(s).
*
* \param level Interrupt level(s) to disable.
*/
static inline void
pmic_disable_level (enum pmic_level level)
{
Assert ((level & PMIC_LVL_NMI));
PMIC.CTRL &= ~level;
}
/**
* \brief Check if specified interrupt \a level(s) is enabled.
*
* \param level Interrupt level(s) to check.
*
* \return True if interrupt level(s) is enabled.
*/
static inline bool
pmic_level_is_enabled (enum pmic_level level)
{
Assert ((level & PMIC_LVL_NMI));
return PMIC.CTRL & level;
}
/**
* \brief Get currently enabled level(s)
*
* \return Bitmask with currently enabled levels.
*/
static inline enum pmic_level
pmic_get_enabled_levels (void)
{
return (enum pmic_level) (PMIC.CTRL & (PMIC_LVL_LOW | PMIC_LVL_MEDIUM
| PMIC_LVL_HIGH));
}
/**
* \brief Check if an interrupt level(s) is currently executing.
*
* \param level Interrupt level(s) to check.
*
* \return True if interrupt level(s) is currently executing.
*/
static inline bool
pmic_level_is_executing (enum pmic_level level)
{
return PMIC.STATUS & level;
}
/**
* \brief Set interrupt scheduling for low-level interrupts.
*
* \param schedule Interrupt scheduling method to set.
*
* \note The low-priority vector, INTPRI, must be set to 0 when round-robin
* scheduling is disabled to return to default interrupt priority order.
*/
static inline void
pmic_set_scheduling (enum pmic_schedule schedule)
{
Assert (schedule < PMIC_NR_OF_SCHEDULES);
switch (schedule)
{
case PMIC_SCH_FIXED_PRIORITY:
PMIC.CTRL &= ~PMIC_RREN_bm;
PMIC.INTPRI = 0;
break;
case PMIC_SCH_ROUND_ROBIN:
PMIC.CTRL |= PMIC_RREN_bm;
break;
default:
break;
};
}
/**
* \brief Set location of interrupt vectors.
*
* \param vector Location to use for interrupt vectors.
*/
static inline void
pmic_set_vector_location (enum pmic_vector vector)
{
uint8_t ctrl = PMIC.CTRL;
Assert (vector < PMIC_NR_OF_VECTORS);
switch (vector)
{
case PMIC_VEC_APPLICATION:
ctrl &= ~PMIC_IVSEL_bm;
break;
case PMIC_VEC_BOOT:
ctrl |= PMIC_IVSEL_bm;
break;
default:
break;
}
ccp_write_io ((uint8_t *) & PMIC.CTRL, ctrl);
}
//! @}
/**
* \page xmega_pmic_quickstart Quick start guide for PMIC driver
*
* This is the quick start guide for the \ref pmic_group "PMIC driver" and
* the closely related \ref interrupt_group "global interrupt driver", with
* step-by-step instructions on how to configure and use the drivers in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section pmic_basic_use_case Basic use case
* In this basic use case, the PMIC is configured for:
* - all interrupt levels enabled
* - round-robin scheduling
*
* This will allow for interrupts from other modules being used.
*
* \section pmic_basic_use_case_setup Setup steps
*
* \subsection pmic_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# Interrupts for the module requiring the PMIC module have to be
* enabled.
* -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be
* defined, where the interrupt vectors available are defined by toolchain and
* listed in the subsection 'Interrupt Vector Summary' in the data sheet.
* \code
* ISR(interrupt_vector){
* //Interrupt Service Routine
* }
* \endcode
*
* \subsection pmic_basic_use_case_setup_code Example code
* Add to the initialization code:
* \code
* pmic_init();
* pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN);
* cpu_irq_enable();
* \endcode
*
* \subsection pmic_basic_use_case_setup_flow Workflow
* -# call the PMIC driver's own init function to enable all interrupt levels:
* - \code pmic_init(); \endcode
* -# enable round-robin instead of fixed priority interrupt scheduling:
* - \code pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN); \endcode
* -# enable interrupts globally:
* - \code cpu_irq_enable(); \endcode
* - \attention Interrupts will not trigger without this step.
*
* \section pmic_use_cases Advanced use cases
* For more advanced use of the PMIC driver, see the following use cases:
* - \subpage pmic_use_case_1 : atomic operations
*/
/**
* \page pmic_use_case_1 Use case #1
*
* In this use case, the PMIC is configured for:
* - all interrupt levels enabled
*
* This will allow for interrupts from other modules being used.
*
* This use case shows how to make an operation which consists of multiple
* instructions uninterruptible, i.e., into an atomic operation. This is often
* necessary if there is a risk that data can be accessed by interrupt handlers
* while other code is accessing it, and at least one of them modifies it.
*
* \section pmic_use_case_1_setup Setup steps
*
* \subsection pmic_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# Interrupts for the module requiring the PMIC module have to be
* enabled.
* -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be
* defined, where the interrupt vectors available are defined by toolchain and
* listed in the subsection 'Interrupt Vector Summary' in the data sheet.
* \code
* ISR(interrupt_vector){
* //Interrupt Service Routine
* }
* \endcode
*
* \subsection pmic_use_case_1_setup_code Example code
* Add to application initialization:
* \code
* pmic_init();
* cpu_irq_enable();
* \endcode
*
* \subsection pmic_use_case_1_setup_flow Workflow
* -# call the PMIC driver's own init function to enable all interrupt levels:
* - \code pmic_init(); \endcode
* -# set global interrupt enable flag:
* - \code cpu_irq_enable(); \endcode
*
* \section pmic_use_case_1_usage Usage steps
*
* \subsection pmic_use_case_1_usage_code Example code
* \code
* Add to application:
* void atomic_operation(void)
* {
* irqflags_t flags;
*
* flags = cpu_irq_save();
*
* // Uninterruptible block of code
*
* cpu_irq_restore(flags);
* }
* \endcode
*
* \subsection pmic_use_case_1_usage_flow Workflow
* -# allocate temporary storage for interrupt enable:
* - \code irqflags_t flags; \endcode
* -# clear global interrupt enable flag while saving its previous state:
* - \code flags = cpu_irq_save(); \endcode
* -# restore the previous state of global interrupt flag after operation:
* - \code cpu_irq_restore(flags); \endcode
*/
#endif /* PMIC_H */
/**
* \file
*
* \brief Programmable Multilevel Interrupt Controller driver
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef PMIC_H
#define PMIC_H
#include <compiler.h>
#include <ccp.h>
/**
* \defgroup pmic_group Programmable Multilevel Interrupt Controller
*
* See \ref xmega_pmic_quickstart.
*
* This is a low-level driver implementation for the AVR XMEGA Programmable
* Multilevel Interrupt Controller.
*
* \note If these functions are used in interrupt service routines (ISRs), any
* non-ISR code or ISR code for lower level interrupts must ensure that the
* operations are atomic, i.e., by disabling interrupts during the function
* calls.
* @{
*/
/**
* \brief Interrupt level bitmasks
*
* \note These may be OR'ed, e.g., if multiple levels are to be enabled or
* disabled.
*/
enum pmic_level
{
PMIC_LVL_LOW = PMIC_LOLVLEN_bm, //!< Low-level interrupts
PMIC_LVL_MEDIUM = PMIC_MEDLVLEN_bm, //!< Medium-level interrupts
PMIC_LVL_HIGH = PMIC_HILVLEN_bm, //!< High-level interrupts
/**
* \brief Non-maskable interrupts
* \note These cannot be enabled nor disabled.
*/
PMIC_LVL_NMI = PMIC_NMIEX_bp,
};
//! Interrupt vector locations
enum pmic_vector
{
PMIC_VEC_APPLICATION, //!< Application section
PMIC_VEC_BOOT, //!< Boot section
PMIC_NR_OF_VECTORS, //!< Number of interrupt vector locations
};
//! Interrupt scheduling schemes
enum pmic_schedule
{
PMIC_SCH_FIXED_PRIORITY, //!< Default, fixed priority scheduling
PMIC_SCH_ROUND_ROBIN, //!< Round-robin scheduling
PMIC_NR_OF_SCHEDULES, //!< Number of interrupt scheduling schemes
};
/**
* \brief Initialize the PMIC
*
* Enables all interrupt levels, with vectors located in the application section
* and fixed priority scheduling.
*/
static inline void
pmic_init (void)
{
PMIC.CTRL = PMIC_LVL_LOW | PMIC_LVL_MEDIUM | PMIC_LVL_HIGH;
}
/**
* \brief Enable interrupts with specified \a level(s).
*
* \param level Interrupt level(s) to enable.
*/
static inline void
pmic_enable_level (enum pmic_level level)
{
Assert ((level & PMIC_LVL_NMI));
PMIC.CTRL |= level;
}
/**
* \brief Disable interrupts with specified \a level(s).
*
* \param level Interrupt level(s) to disable.
*/
static inline void
pmic_disable_level (enum pmic_level level)
{
Assert ((level & PMIC_LVL_NMI));
PMIC.CTRL &= ~level;
}
/**
* \brief Check if specified interrupt \a level(s) is enabled.
*
* \param level Interrupt level(s) to check.
*
* \return True if interrupt level(s) is enabled.
*/
static inline bool
pmic_level_is_enabled (enum pmic_level level)
{
Assert ((level & PMIC_LVL_NMI));
return PMIC.CTRL & level;
}
/**
* \brief Get currently enabled level(s)
*
* \return Bitmask with currently enabled levels.
*/
static inline enum pmic_level
pmic_get_enabled_levels (void)
{
return (enum pmic_level) (PMIC.CTRL & (PMIC_LVL_LOW | PMIC_LVL_MEDIUM
| PMIC_LVL_HIGH));
}
/**
* \brief Check if an interrupt level(s) is currently executing.
*
* \param level Interrupt level(s) to check.
*
* \return True if interrupt level(s) is currently executing.
*/
static inline bool
pmic_level_is_executing (enum pmic_level level)
{
return PMIC.STATUS & level;
}
/**
* \brief Set interrupt scheduling for low-level interrupts.
*
* \param schedule Interrupt scheduling method to set.
*
* \note The low-priority vector, INTPRI, must be set to 0 when round-robin
* scheduling is disabled to return to default interrupt priority order.
*/
static inline void
pmic_set_scheduling (enum pmic_schedule schedule)
{
Assert (schedule < PMIC_NR_OF_SCHEDULES);
switch (schedule)
{
case PMIC_SCH_FIXED_PRIORITY:
PMIC.CTRL &= ~PMIC_RREN_bm;
PMIC.INTPRI = 0;
break;
case PMIC_SCH_ROUND_ROBIN:
PMIC.CTRL |= PMIC_RREN_bm;
break;
default:
break;
};
}
/**
* \brief Set location of interrupt vectors.
*
* \param vector Location to use for interrupt vectors.
*/
static inline void
pmic_set_vector_location (enum pmic_vector vector)
{
uint8_t ctrl = PMIC.CTRL;
Assert (vector < PMIC_NR_OF_VECTORS);
switch (vector)
{
case PMIC_VEC_APPLICATION:
ctrl &= ~PMIC_IVSEL_bm;
break;
case PMIC_VEC_BOOT:
ctrl |= PMIC_IVSEL_bm;
break;
default:
break;
}
ccp_write_io ((uint8_t *) & PMIC.CTRL, ctrl);
}
//! @}
/**
* \page xmega_pmic_quickstart Quick start guide for PMIC driver
*
* This is the quick start guide for the \ref pmic_group "PMIC driver" and
* the closely related \ref interrupt_group "global interrupt driver", with
* step-by-step instructions on how to configure and use the drivers in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section pmic_basic_use_case Basic use case
* In this basic use case, the PMIC is configured for:
* - all interrupt levels enabled
* - round-robin scheduling
*
* This will allow for interrupts from other modules being used.
*
* \section pmic_basic_use_case_setup Setup steps
*
* \subsection pmic_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# Interrupts for the module requiring the PMIC module have to be
* enabled.
* -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be
* defined, where the interrupt vectors available are defined by toolchain and
* listed in the subsection 'Interrupt Vector Summary' in the data sheet.
* \code
* ISR(interrupt_vector){
* //Interrupt Service Routine
* }
* \endcode
*
* \subsection pmic_basic_use_case_setup_code Example code
* Add to the initialization code:
* \code
* pmic_init();
* pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN);
* cpu_irq_enable();
* \endcode
*
* \subsection pmic_basic_use_case_setup_flow Workflow
* -# call the PMIC driver's own init function to enable all interrupt levels:
* - \code pmic_init(); \endcode
* -# enable round-robin instead of fixed priority interrupt scheduling:
* - \code pmic_set_scheduling(PMIC_SCH_ROUND_ROBIN); \endcode
* -# enable interrupts globally:
* - \code cpu_irq_enable(); \endcode
* - \attention Interrupts will not trigger without this step.
*
* \section pmic_use_cases Advanced use cases
* For more advanced use of the PMIC driver, see the following use cases:
* - \subpage pmic_use_case_1 : atomic operations
*/
/**
* \page pmic_use_case_1 Use case #1
*
* In this use case, the PMIC is configured for:
* - all interrupt levels enabled
*
* This will allow for interrupts from other modules being used.
*
* This use case shows how to make an operation which consists of multiple
* instructions uninterruptible, i.e., into an atomic operation. This is often
* necessary if there is a risk that data can be accessed by interrupt handlers
* while other code is accessing it, and at least one of them modifies it.
*
* \section pmic_use_case_1_setup Setup steps
*
* \subsection pmic_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# Interrupts for the module requiring the PMIC module have to be
* enabled.
* -# An Interrupt Service Routine (ISR) for a given interrupt vector has to be
* defined, where the interrupt vectors available are defined by toolchain and
* listed in the subsection 'Interrupt Vector Summary' in the data sheet.
* \code
* ISR(interrupt_vector){
* //Interrupt Service Routine
* }
* \endcode
*
* \subsection pmic_use_case_1_setup_code Example code
* Add to application initialization:
* \code
* pmic_init();
* cpu_irq_enable();
* \endcode
*
* \subsection pmic_use_case_1_setup_flow Workflow
* -# call the PMIC driver's own init function to enable all interrupt levels:
* - \code pmic_init(); \endcode
* -# set global interrupt enable flag:
* - \code cpu_irq_enable(); \endcode
*
* \section pmic_use_case_1_usage Usage steps
*
* \subsection pmic_use_case_1_usage_code Example code
* \code
* Add to application:
* void atomic_operation(void)
* {
* irqflags_t flags;
*
* flags = cpu_irq_save();
*
* // Uninterruptible block of code
*
* cpu_irq_restore(flags);
* }
* \endcode
*
* \subsection pmic_use_case_1_usage_flow Workflow
* -# allocate temporary storage for interrupt enable:
* - \code irqflags_t flags; \endcode
* -# clear global interrupt enable flag while saving its previous state:
* - \code flags = cpu_irq_save(); \endcode
* -# restore the previous state of global interrupt flag after operation:
* - \code cpu_irq_restore(flags); \endcode
*/
#endif /* PMIC_H */
@@ -1,327 +1,327 @@
/**
* \file
*
* \brief AVR XMEGA 32-bit Real Time Counter driver
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <parts.h>
#include <sysclk.h>
#include <delay.h>
#include "rtc32.h"
#ifdef __ICCAVR__
# define _DWORDREGISTER DWORDREGISTER
#endif
/**
* \internal
* Workaround for missing CNT, PER and COMP in WinAVR header files
* \todo Remove when header files are fixed if WinAVR release
*/
typedef struct RTC32_struct2 {
register8_t CTRL;
register8_t SYNCCTRL;
register8_t INTCTRL;
register8_t INTFLAGS;
_DWORDREGISTER(CNT);
_DWORDREGISTER(PER);
_DWORDREGISTER(COMP);
} RTC32_t2;
#undef RTC32
/**
* \internal
* Workaround for missing CNT, PER and COMP in WinAVR header files
* \todo Remove when header files are fixed if WinAVR release
*/
#define RTC32 (*(RTC32_t2 *)0x0420)
#ifdef CONFIG_RTC32_COMPARE_INT_LEVEL
# define RTC32_COMPARE_INT_LEVEL CONFIG_RTC32_COMPARE_INT_LEVEL
#else
# define RTC32_COMPARE_INT_LEVEL RTC32_COMPINTLVL_LO_gc
#endif
#ifdef CONFIG_RTC32_CLOCK_1024HZ
# define RTC32_CLOCK VBAT_XOSCSEL_bm
#else
# define RTC32_CLOCK 0
#endif
/**
* \internal
* \brief Driver private struct
*/
struct rtc_data_struct {
//! Callback function to use on alarm
rtc_callback_t callback;
};
/**
* \internal
* \brief Driver private data
*/
struct rtc_data_struct rtc_data;
/**
* \internal
* \brief Check if RTC32 is busy synchronizing
*
* \retval true Is busy
* \retval false Is ready
*/
static __always_inline bool rtc_is_busy(void)
{
return RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm;
}
/**
* \internal
* \brief Get counter
*
* \return Counter value
*/
static inline uint32_t rtc_get_counter(void)
{
RTC32.SYNCCTRL = RTC32_SYNCCNT_bm;
while (RTC32.SYNCCTRL & RTC32_SYNCCNT_bm);
return RTC32.CNT;
}
/**
* \brief Set current time
*
* \param time Time value to set
*/
void rtc_set_time(uint32_t time)
{
RTC32.CTRL = 0;
while (rtc_is_busy());
RTC32.CNT = time;
RTC32.CTRL = RTC32_ENABLE_bm;
}
/**
* \brief Get current time
*
* \return Current time value
*/
uint32_t rtc_get_time(void)
{
return rtc_get_counter();
}
/**
* \brief Set alarm time
*
* Will set absolute time of the alarm that will call the callback function
* specified by \ref rtc_set_callback on expiration. Alternatively, you may
* use \ref rtc_alarm_has_triggered to check if the alarm has expired.
*
* Any pending alarm will be overwritten with this function.
*
* \param time Absolute time value. See also \ref rtc32_min_alarm_time
* \pre Needs interrupts disabled if used from several contexts
*/
void rtc_set_alarm(uint32_t time)
{
RTC32.INTCTRL = RTC32_COMPARE_INT_LEVEL;
RTC32.COMP = time;
RTC32.INTFLAGS = RTC32_COMPIF_bm;
}
/**
* \brief Check if pending alarm has triggered
*
* \retval true Alarm has triggered
* \retval false Alarm is pending
*/
bool rtc_alarm_has_triggered(void)
{
// Interrupt enable is used on pending alarm
return !(RTC32.INTCTRL & RTC32_COMPARE_INT_LEVEL);
}
/**
* \brief Set callback to call on alarm
*
* \param callback Callback function pointer
*/
void rtc_set_callback(rtc_callback_t callback)
{
rtc_data.callback = callback;
}
/**
* \brief Checks battery backup system status.
*
* This function should be called once after each reset of the device in order
* to determine the current battery backup status.
* This function can not be used to continuously poll the status of the backup
* system during normal operation since most status flags are only latched
* during the power up sequence of the device.
*
* \param first_time_startup Indicates whether or not the VBAT system has been
* started previously. This should be set to \c true upon the first call to this
* function, and \c false upon later calls. Typically, the value for this
* parameter should be stored in, e.g., EEPROM, in order to preserve the value
* when main system power is lost.
*
* \returns Battery backup system status.
*/
enum vbat_status_code rtc_vbat_system_check(bool first_time_startup)
{
enum vbat_status_code vbat_status;
uint8_t flags = VBAT.STATUS;
/* Ensure the module is clocked to be able to check the registers */
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
/*
* Check if a sufficient voltage was detected on the VBAT input.
* The brown-out detector (BBBOD) will be sampled once when the
* device starts up and the result is visible as the BBPWR flag.
*/
if (flags & VBAT_BBPWR_bm) {
vbat_status = VBAT_STATUS_NO_POWER;
} else {
/*
* We have sufficient power, now we check if a power-on-reset
* (BBPOR) was detected on VBAT. This is visible from the BBPORF
* flag which is also only updated once when the device starts.
*/
if (flags & VBAT_BBPORF_bm) {
if (first_time_startup) {
vbat_status = VBAT_STATUS_INIT;
} else {
vbat_status = VBAT_STATUS_BBPOR;
}
} else if (flags & VBAT_BBBORF_bm) {
vbat_status = VBAT_STATUS_BBBOD;
} else {
VBAT.CTRL = VBAT_ACCEN_bm;
if (flags & VBAT_XOSCFAIL_bm) {
vbat_status = VBAT_STATUS_XOSCFAIL;
} else {
vbat_status = VBAT_STATUS_OK;
}
}
}
return vbat_status;
}
/**
* \internal
* \brief Initialize VBAT and start 32kHz oscillator
*
* Enables access to the VBAT system, performs a reset, enables the failure
* detection, and starts the oscillator.
*
* The default clock rate to the RTC32 is 1Hz but this can be changed to 1024Hz
* by the user in the module configuration by defining
* \ref CONFIG_RTC32_CLOCK_1024HZ.
*/
static void vbat_init(void)
{
// Enable access to VBAT
VBAT.CTRL |= VBAT_ACCEN_bm;
ccp_write_io((void *) &VBAT.CTRL, VBAT_RESET_bm);
VBAT.CTRL |= VBAT_XOSCFDEN_bm;
/* This delay is needed to give the voltage in the backup system some
* time to stabilize before we turn on the oscillator. If we do not
* have this delay we may get a failure detection.
*/
delay_us(200);
VBAT.CTRL |= VBAT_XOSCEN_bm | RTC32_CLOCK;
while (!(VBAT.STATUS & VBAT_XOSCRDY_bm));
}
/**
* \brief Initialize the 32kHz oscillator and RTC32
*
* Starts up the 32kHz oscillator in the backup system and initializes the
* RTC32.
*
* \note When the backup system is used, the function \ref
* rtc_vbat_system_check should be called to determine if a re-initialization
* must be done.
*/
void rtc_init(void)
{
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
// Set up VBAT system and start oscillator
vbat_init();
// Disable the RTC32 module before setting it up
RTC32.CTRL = 0;
while (rtc_is_busy());
// Set up maximum period and start at 0
RTC32.PER = 0xffffffff;
RTC32.CNT = 0;
while (rtc_is_busy());
RTC32.INTCTRL = 0;
RTC32.CTRL = RTC32_ENABLE_bm;
// Make sure it's sync'ed before return
while (rtc_is_busy());
}
/**
* \internal
* \brief Compare interrupt used for alarm
*
* Disables the RTC32 interrupts, then calls the alarm callback function if one
* has been set.
*/
ISR(RTC32_COMP_vect)
{
RTC32.INTCTRL = 0;
if (rtc_data.callback)
rtc_data.callback(rtc_get_time());
}
/**
* \file
*
* \brief AVR XMEGA 32-bit Real Time Counter driver
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <compiler.h>
#include <parts.h>
#include <sysclk.h>
#include <delay.h>
#include "rtc32.h"
#ifdef __ICCAVR__
# define _DWORDREGISTER DWORDREGISTER
#endif
/**
* \internal
* Workaround for missing CNT, PER and COMP in WinAVR header files
* \todo Remove when header files are fixed if WinAVR release
*/
typedef struct RTC32_struct2 {
register8_t CTRL;
register8_t SYNCCTRL;
register8_t INTCTRL;
register8_t INTFLAGS;
_DWORDREGISTER(CNT);
_DWORDREGISTER(PER);
_DWORDREGISTER(COMP);
} RTC32_t2;
#undef RTC32
/**
* \internal
* Workaround for missing CNT, PER and COMP in WinAVR header files
* \todo Remove when header files are fixed if WinAVR release
*/
#define RTC32 (*(RTC32_t2 *)0x0420)
#ifdef CONFIG_RTC32_COMPARE_INT_LEVEL
# define RTC32_COMPARE_INT_LEVEL CONFIG_RTC32_COMPARE_INT_LEVEL
#else
# define RTC32_COMPARE_INT_LEVEL RTC32_COMPINTLVL_LO_gc
#endif
#ifdef CONFIG_RTC32_CLOCK_1024HZ
# define RTC32_CLOCK VBAT_XOSCSEL_bm
#else
# define RTC32_CLOCK 0
#endif
/**
* \internal
* \brief Driver private struct
*/
struct rtc_data_struct {
//! Callback function to use on alarm
rtc_callback_t callback;
};
/**
* \internal
* \brief Driver private data
*/
struct rtc_data_struct rtc_data;
/**
* \internal
* \brief Check if RTC32 is busy synchronizing
*
* \retval true Is busy
* \retval false Is ready
*/
static __always_inline bool rtc_is_busy(void)
{
return RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm;
}
/**
* \internal
* \brief Get counter
*
* \return Counter value
*/
static inline uint32_t rtc_get_counter(void)
{
RTC32.SYNCCTRL = RTC32_SYNCCNT_bm;
while (RTC32.SYNCCTRL & RTC32_SYNCCNT_bm);
return RTC32.CNT;
}
/**
* \brief Set current time
*
* \param time Time value to set
*/
void rtc_set_time(uint32_t time)
{
RTC32.CTRL = 0;
while (rtc_is_busy());
RTC32.CNT = time;
RTC32.CTRL = RTC32_ENABLE_bm;
}
/**
* \brief Get current time
*
* \return Current time value
*/
uint32_t rtc_get_time(void)
{
return rtc_get_counter();
}
/**
* \brief Set alarm time
*
* Will set absolute time of the alarm that will call the callback function
* specified by \ref rtc_set_callback on expiration. Alternatively, you may
* use \ref rtc_alarm_has_triggered to check if the alarm has expired.
*
* Any pending alarm will be overwritten with this function.
*
* \param time Absolute time value. See also \ref rtc32_min_alarm_time
* \pre Needs interrupts disabled if used from several contexts
*/
void rtc_set_alarm(uint32_t time)
{
RTC32.INTCTRL = RTC32_COMPARE_INT_LEVEL;
RTC32.COMP = time;
RTC32.INTFLAGS = RTC32_COMPIF_bm;
}
/**
* \brief Check if pending alarm has triggered
*
* \retval true Alarm has triggered
* \retval false Alarm is pending
*/
bool rtc_alarm_has_triggered(void)
{
// Interrupt enable is used on pending alarm
return !(RTC32.INTCTRL & RTC32_COMPARE_INT_LEVEL);
}
/**
* \brief Set callback to call on alarm
*
* \param callback Callback function pointer
*/
void rtc_set_callback(rtc_callback_t callback)
{
rtc_data.callback = callback;
}
/**
* \brief Checks battery backup system status.
*
* This function should be called once after each reset of the device in order
* to determine the current battery backup status.
* This function can not be used to continuously poll the status of the backup
* system during normal operation since most status flags are only latched
* during the power up sequence of the device.
*
* \param first_time_startup Indicates whether or not the VBAT system has been
* started previously. This should be set to \c true upon the first call to this
* function, and \c false upon later calls. Typically, the value for this
* parameter should be stored in, e.g., EEPROM, in order to preserve the value
* when main system power is lost.
*
* \returns Battery backup system status.
*/
enum vbat_status_code rtc_vbat_system_check(bool first_time_startup)
{
enum vbat_status_code vbat_status;
uint8_t flags = VBAT.STATUS;
/* Ensure the module is clocked to be able to check the registers */
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
/*
* Check if a sufficient voltage was detected on the VBAT input.
* The brown-out detector (BBBOD) will be sampled once when the
* device starts up and the result is visible as the BBPWR flag.
*/
if (flags & VBAT_BBPWR_bm) {
vbat_status = VBAT_STATUS_NO_POWER;
} else {
/*
* We have sufficient power, now we check if a power-on-reset
* (BBPOR) was detected on VBAT. This is visible from the BBPORF
* flag which is also only updated once when the device starts.
*/
if (flags & VBAT_BBPORF_bm) {
if (first_time_startup) {
vbat_status = VBAT_STATUS_INIT;
} else {
vbat_status = VBAT_STATUS_BBPOR;
}
} else if (flags & VBAT_BBBORF_bm) {
vbat_status = VBAT_STATUS_BBBOD;
} else {
VBAT.CTRL = VBAT_ACCEN_bm;
if (flags & VBAT_XOSCFAIL_bm) {
vbat_status = VBAT_STATUS_XOSCFAIL;
} else {
vbat_status = VBAT_STATUS_OK;
}
}
}
return vbat_status;
}
/**
* \internal
* \brief Initialize VBAT and start 32kHz oscillator
*
* Enables access to the VBAT system, performs a reset, enables the failure
* detection, and starts the oscillator.
*
* The default clock rate to the RTC32 is 1Hz but this can be changed to 1024Hz
* by the user in the module configuration by defining
* \ref CONFIG_RTC32_CLOCK_1024HZ.
*/
static void vbat_init(void)
{
// Enable access to VBAT
VBAT.CTRL |= VBAT_ACCEN_bm;
ccp_write_io((void *) &VBAT.CTRL, VBAT_RESET_bm);
VBAT.CTRL |= VBAT_XOSCFDEN_bm;
/* This delay is needed to give the voltage in the backup system some
* time to stabilize before we turn on the oscillator. If we do not
* have this delay we may get a failure detection.
*/
delay_us(200);
VBAT.CTRL |= VBAT_XOSCEN_bm | RTC32_CLOCK;
while (!(VBAT.STATUS & VBAT_XOSCRDY_bm));
}
/**
* \brief Initialize the 32kHz oscillator and RTC32
*
* Starts up the 32kHz oscillator in the backup system and initializes the
* RTC32.
*
* \note When the backup system is used, the function \ref
* rtc_vbat_system_check should be called to determine if a re-initialization
* must be done.
*/
void rtc_init(void)
{
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
// Set up VBAT system and start oscillator
vbat_init();
// Disable the RTC32 module before setting it up
RTC32.CTRL = 0;
while (rtc_is_busy());
// Set up maximum period and start at 0
RTC32.PER = 0xffffffff;
RTC32.CNT = 0;
while (rtc_is_busy());
RTC32.INTCTRL = 0;
RTC32.CTRL = RTC32_ENABLE_bm;
// Make sure it's sync'ed before return
while (rtc_is_busy());
}
/**
* \internal
* \brief Compare interrupt used for alarm
*
* Disables the RTC32 interrupts, then calls the alarm callback function if one
* has been set.
*/
ISR(RTC32_COMP_vect)
{
RTC32.INTCTRL = 0;
if (rtc_data.callback)
rtc_data.callback(rtc_get_time());
}
@@ -1,324 +1,324 @@
/**
* \file
*
* \brief AVR XMEGA 32-bit Real Time Counter driver definitions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef DRIVERS_RTC32_RTC32_H
#define DRIVERS_RTC32_RTC32_H
#include <compiler.h>
#include <conf_rtc32.h>
/**
* \defgroup rtc32_group 32-bit Real Time Counter (RTC32)
*
* See \ref xmega_rtc32_quickstart.
*
* This is a driver implementation for the XMEGA RTC32.
*
* This driver can be used to keep track of time; setting alarms, with or
* without function callbacks; initializing and checking the battery backup
* system.
*
* \section rtc32_min_alarm_time Minimum allowed alarm time
*
* Due to the RTC32 clock synchronization, there is a minimum alarm time that
* will generate a interrupt. This minimum time is 2 RTC32 clock cycles.
*
* Also, if a new RTC32 clock cycle is imminent at the time of setting the
* alarm, there is a risk that it will be missed even with the value 2. If there
* is a risk that this may occur, it is recommended to use a minimum alarm time
* of 3.
*
* @{
*/
/**
* \def CONFIG_RTC32_COMPARE_INT_LEVEL
* \brief Configuration symbol for interrupt level to use on alarm
*
* Define this in \ref conf_rtc32.h as the desired interrupt level, or leave it
* undefined to use the default.
*/
#ifdef __DOXYGEN__
# define CONFIG_RTC32_COMPARE_INT_LEVEL
#endif
/**
* \def CONFIG_RTC32_CLOCK_1024HZ
* \brief Configuration symbol for selecting 1024Hz clock instead of 1Hz
*
* Define this in \ref conf_rtc32.h if 1024Hz clock is desired. Otherwise, leave
* it undefined.
*/
#ifdef __DOXYGEN__
# define CONFIG_RTC32_CLOCK_1024HZ
#endif
//! \brief Battery backup system status codes
enum vbat_status_code
{
/**
* \brief Backup system is operating and no errors were detected.
*
* The backup system is configured and had no issues while main power was
* lost. Hence, all data stored in the backup domain is valid.
*/
VBAT_STATUS_OK,
/**
* \brief No power detected on VBAT.
*
* No power was detected on the VBAT pin and therefore all data within the
* backup system is invalid.
*
* The voltage on the VBAT pin is only sampled after a POR of the device,
* therefore it is not possible to detect any voltage loss on the VBAT pin
* during normal operation of the device.
*/
VBAT_STATUS_NO_POWER,
/**
* \brief The backup system must be initialized.
*
* A POR was detected on VBAT input, indicating that a supply was connected to
* the VBAT pin. Since this is also the first start-up of the device, it is
* necessary to initialize the RTC32.
*/
VBAT_STATUS_INIT,
/**
* \brief A POR was detected on the VBAT input.
*
* POR detection also works while the VBAT system is powered from main power,
* but the detection flag is only latched after a POR of the main system.
* A POR can happen when the power is lost and restored again on the VBAT pin
* while main power was also not present, or even when main power was present,
* but in this case the flag will only be latched after the next POR of the main
* system.
* If a POR is detected on VBAT, it should always be treated as if the backup
* system is in an unknown state, i.e., that all data is invalid.
*/
VBAT_STATUS_BBPOR,
/**
* \brief A brown-out was detected on the VBAT input.
*
* The backup system is in an unknown state and therefore the time in the RTC32
* is invalid. This can happen when the voltage on VBAT drops below the
* brown-out detection level while main power is absent.
*/
VBAT_STATUS_BBBOD,
/**
* \brief A failure was detected on the oscillator.
*
* The oscillator stopped for at least TBD period of time and because of that
* we can not rely on the RTC time any more.
*
* \todo Determine minimum period for detection of oscillator outage.
*/
VBAT_STATUS_XOSCFAIL,
};
enum vbat_status_code rtc_vbat_system_check (bool first_time_init);
/**
* \brief Callback definition for alarm callback
*
* \param time The time of the alarm
*/
typedef void (*rtc_callback_t) (uint32_t time);
void rtc_set_callback (rtc_callback_t callback);
void rtc_set_time (uint32_t time);
uint32_t rtc_get_time (void);
void rtc_set_alarm (uint32_t time);
bool rtc_alarm_has_triggered (void);
/**
* \brief Set alarm relative to current time
*
* \param offset Offset to current time. This is minimum value, so the alarm
* might happen at up to one time unit later. See also \ref
* rtc32_min_alarm_time
*/
static inline void
rtc_set_alarm_relative (uint32_t offset)
{
Assert (offset >= 2);
rtc_set_alarm (rtc_get_time () + offset);
}
void rtc_init (void);
//! @}
/**
* \page xmega_rtc32_quickstart Quick start guide for RTC32 driver
*
* This is the quick start guide for the \ref rtc32_group "RTC32 driver", with
* step-by-step instructions on how to configure and use the drivers in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section rtc32_basic_use_case Basic use case
*
* \section rtc32_basic_use_case_setup Setup steps
*
* \subsection rtc32_basic_use_case_setup_code Example code
* Add to the initialization code:
* \code
* sysclk_init();
* rtc_init();
* \endcode
*
* \subsection rtc32_basic_use_case_setup_flow Workflow
* -# Ensure that conf_rtc.h is present for the driver.
* - \note This configuration file is used by the driver and
* should not be included by the user.
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Call RTC32 driver's own init function to initialize the 32kHz oscillator
* and RTC32:
* - \code rtc_init(); \endcode
*
* \section rtc32_basic_use_case_usage Usage steps
*
* \subsection rtc32_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* rtc_get_time();
* \endcode
*
* \subsection rtc32_basic_use_case_usage_flow Workflow
* -# Get current time of the RTC32:
* - \code rtc_get_time(); \endcode
*
* \section rtc32_use_cases Advanced use cases
* For more advanced use of the RTC32 driver, see the following use cases:
* - \subpage rtc32_use_case_1 :
*/
/**
* \page rtc32_use_case_1 Use case #1
*
* This use case shows how to set an alarm for the RTC32.
*
* \section rtc32_use_case_1_setup Setup steps
*
* \subsection rtc32_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# PMIC for interrupt handling.
* -# Sleep Manager.
* -# A \ref rtc_callback_t "callback" function, called alarm, that
* reschedules the alarm must be provided
* by the user.
* \code
* static void alarm(uint32_t time)
* {
* rtc_set_alarm(2);
* }
* \endcode
* \note Since the next alarm will be rounded up to the next second pass, this
* will actually happen in 3 seconds.
*
* \subsection rtc32_use_case_1_setup_code Example code
* Add to application initialization:
* \code
* pmic_init();
* sysclk_init();
* sleepmgr_init();
* rtc_init();
* rtc_set_callback(alarm);
* cpu_irq_enable();
* \endcode
*
* \subsection rtc32_use_case_1_setup_flow Workflow
* -# Ensure that conf_rtc32.h is present for the driver.
* - \note This configuration file is used by the driver and
* should not be included by the user.
* -# Call the init function of the PMIC driver to enable all interrupt levels:
* - \code pmic_init(); \endcode
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Call the init function of the sleep manager driver to be able to sleep
* waiting for alarm:
* - \code sleepmgr_init(); \endcode
* -# Call RTC32 driver's own init function to initialize the 32kHz oscillator
* and RTC32:
* - \code rtc_init(); \endcode
* -# Set callback function to call on alarm:
* - \code rtc_set_callback(alarm); \endcode
* - \note The callback function alarm must be defined by the user.
* -# Enable interrupts globally:
* - \code cpu_irq_enable(); \endcode
*
* \section rtc32_use_case_1_usage Usage steps
*
* \subsection rtc32_use_case_1_usage_code Example code
* \code
* rtc_set_alarm_relative(3);
* while (true) {
* sleepmgr_enter_sleep();
* }
* \endcode
*
* \subsection rtc32_use_case_1_usage_flow Workflow
* -# Set the alarm to trigger on next time unit roll over:
* - \code rtc_set_alarm_relative(3); \endcode
* \note The lowest value which is safe to use is 3. The use of 2 could
* happen in a second change, and we would not get an interrupt. A
* value of 3 causes the alarm to be set of in 3-4 seconds.
* -# Sleep between each triggered alarm:
* - \code
* while (true) {
* sleepmgr_enter_sleep();
* }
* \endcode
*/
#endif /* DRIVERS_RTC32_RTC32_H */
/**
* \file
*
* \brief AVR XMEGA 32-bit Real Time Counter driver definitions
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef DRIVERS_RTC32_RTC32_H
#define DRIVERS_RTC32_RTC32_H
#include <compiler.h>
#include <conf_rtc32.h>
/**
* \defgroup rtc32_group 32-bit Real Time Counter (RTC32)
*
* See \ref xmega_rtc32_quickstart.
*
* This is a driver implementation for the XMEGA RTC32.
*
* This driver can be used to keep track of time; setting alarms, with or
* without function callbacks; initializing and checking the battery backup
* system.
*
* \section rtc32_min_alarm_time Minimum allowed alarm time
*
* Due to the RTC32 clock synchronization, there is a minimum alarm time that
* will generate a interrupt. This minimum time is 2 RTC32 clock cycles.
*
* Also, if a new RTC32 clock cycle is imminent at the time of setting the
* alarm, there is a risk that it will be missed even with the value 2. If there
* is a risk that this may occur, it is recommended to use a minimum alarm time
* of 3.
*
* @{
*/
/**
* \def CONFIG_RTC32_COMPARE_INT_LEVEL
* \brief Configuration symbol for interrupt level to use on alarm
*
* Define this in \ref conf_rtc32.h as the desired interrupt level, or leave it
* undefined to use the default.
*/
#ifdef __DOXYGEN__
# define CONFIG_RTC32_COMPARE_INT_LEVEL
#endif
/**
* \def CONFIG_RTC32_CLOCK_1024HZ
* \brief Configuration symbol for selecting 1024Hz clock instead of 1Hz
*
* Define this in \ref conf_rtc32.h if 1024Hz clock is desired. Otherwise, leave
* it undefined.
*/
#ifdef __DOXYGEN__
# define CONFIG_RTC32_CLOCK_1024HZ
#endif
//! \brief Battery backup system status codes
enum vbat_status_code
{
/**
* \brief Backup system is operating and no errors were detected.
*
* The backup system is configured and had no issues while main power was
* lost. Hence, all data stored in the backup domain is valid.
*/
VBAT_STATUS_OK,
/**
* \brief No power detected on VBAT.
*
* No power was detected on the VBAT pin and therefore all data within the
* backup system is invalid.
*
* The voltage on the VBAT pin is only sampled after a POR of the device,
* therefore it is not possible to detect any voltage loss on the VBAT pin
* during normal operation of the device.
*/
VBAT_STATUS_NO_POWER,
/**
* \brief The backup system must be initialized.
*
* A POR was detected on VBAT input, indicating that a supply was connected to
* the VBAT pin. Since this is also the first start-up of the device, it is
* necessary to initialize the RTC32.
*/
VBAT_STATUS_INIT,
/**
* \brief A POR was detected on the VBAT input.
*
* POR detection also works while the VBAT system is powered from main power,
* but the detection flag is only latched after a POR of the main system.
* A POR can happen when the power is lost and restored again on the VBAT pin
* while main power was also not present, or even when main power was present,
* but in this case the flag will only be latched after the next POR of the main
* system.
* If a POR is detected on VBAT, it should always be treated as if the backup
* system is in an unknown state, i.e., that all data is invalid.
*/
VBAT_STATUS_BBPOR,
/**
* \brief A brown-out was detected on the VBAT input.
*
* The backup system is in an unknown state and therefore the time in the RTC32
* is invalid. This can happen when the voltage on VBAT drops below the
* brown-out detection level while main power is absent.
*/
VBAT_STATUS_BBBOD,
/**
* \brief A failure was detected on the oscillator.
*
* The oscillator stopped for at least TBD period of time and because of that
* we can not rely on the RTC time any more.
*
* \todo Determine minimum period for detection of oscillator outage.
*/
VBAT_STATUS_XOSCFAIL,
};
enum vbat_status_code rtc_vbat_system_check (bool first_time_init);
/**
* \brief Callback definition for alarm callback
*
* \param time The time of the alarm
*/
typedef void (*rtc_callback_t) (uint32_t time);
void rtc_set_callback (rtc_callback_t callback);
void rtc_set_time (uint32_t time);
uint32_t rtc_get_time (void);
void rtc_set_alarm (uint32_t time);
bool rtc_alarm_has_triggered (void);
/**
* \brief Set alarm relative to current time
*
* \param offset Offset to current time. This is minimum value, so the alarm
* might happen at up to one time unit later. See also \ref
* rtc32_min_alarm_time
*/
static inline void
rtc_set_alarm_relative (uint32_t offset)
{
Assert (offset >= 2);
rtc_set_alarm (rtc_get_time () + offset);
}
void rtc_init (void);
//! @}
/**
* \page xmega_rtc32_quickstart Quick start guide for RTC32 driver
*
* This is the quick start guide for the \ref rtc32_group "RTC32 driver", with
* step-by-step instructions on how to configure and use the drivers in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section rtc32_basic_use_case Basic use case
*
* \section rtc32_basic_use_case_setup Setup steps
*
* \subsection rtc32_basic_use_case_setup_code Example code
* Add to the initialization code:
* \code
* sysclk_init();
* rtc_init();
* \endcode
*
* \subsection rtc32_basic_use_case_setup_flow Workflow
* -# Ensure that conf_rtc.h is present for the driver.
* - \note This configuration file is used by the driver and
* should not be included by the user.
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Call RTC32 driver's own init function to initialize the 32kHz oscillator
* and RTC32:
* - \code rtc_init(); \endcode
*
* \section rtc32_basic_use_case_usage Usage steps
*
* \subsection rtc32_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* rtc_get_time();
* \endcode
*
* \subsection rtc32_basic_use_case_usage_flow Workflow
* -# Get current time of the RTC32:
* - \code rtc_get_time(); \endcode
*
* \section rtc32_use_cases Advanced use cases
* For more advanced use of the RTC32 driver, see the following use cases:
* - \subpage rtc32_use_case_1 :
*/
/**
* \page rtc32_use_case_1 Use case #1
*
* This use case shows how to set an alarm for the RTC32.
*
* \section rtc32_use_case_1_setup Setup steps
*
* \subsection rtc32_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# PMIC for interrupt handling.
* -# Sleep Manager.
* -# A \ref rtc_callback_t "callback" function, called alarm, that
* reschedules the alarm must be provided
* by the user.
* \code
* static void alarm(uint32_t time)
* {
* rtc_set_alarm(2);
* }
* \endcode
* \note Since the next alarm will be rounded up to the next second pass, this
* will actually happen in 3 seconds.
*
* \subsection rtc32_use_case_1_setup_code Example code
* Add to application initialization:
* \code
* pmic_init();
* sysclk_init();
* sleepmgr_init();
* rtc_init();
* rtc_set_callback(alarm);
* cpu_irq_enable();
* \endcode
*
* \subsection rtc32_use_case_1_setup_flow Workflow
* -# Ensure that conf_rtc32.h is present for the driver.
* - \note This configuration file is used by the driver and
* should not be included by the user.
* -# Call the init function of the PMIC driver to enable all interrupt levels:
* - \code pmic_init(); \endcode
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Call the init function of the sleep manager driver to be able to sleep
* waiting for alarm:
* - \code sleepmgr_init(); \endcode
* -# Call RTC32 driver's own init function to initialize the 32kHz oscillator
* and RTC32:
* - \code rtc_init(); \endcode
* -# Set callback function to call on alarm:
* - \code rtc_set_callback(alarm); \endcode
* - \note The callback function alarm must be defined by the user.
* -# Enable interrupts globally:
* - \code cpu_irq_enable(); \endcode
*
* \section rtc32_use_case_1_usage Usage steps
*
* \subsection rtc32_use_case_1_usage_code Example code
* \code
* rtc_set_alarm_relative(3);
* while (true) {
* sleepmgr_enter_sleep();
* }
* \endcode
*
* \subsection rtc32_use_case_1_usage_flow Workflow
* -# Set the alarm to trigger on next time unit roll over:
* - \code rtc_set_alarm_relative(3); \endcode
* \note The lowest value which is safe to use is 3. The use of 2 could
* happen in a second change, and we would not get an interrupt. A
* value of 3 causes the alarm to be set of in 3-4 seconds.
* -# Sleep between each triggered alarm:
* - \code
* while (true) {
* sleepmgr_enter_sleep();
* }
* \endcode
*/
#endif /* DRIVERS_RTC32_RTC32_H */
@@ -1,169 +1,169 @@
/**
* \file
*
* \brief Sleep controller driver
*
* Copyright (c) 2010 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SLEEP_H
#define SLEEP_H
#include <compiler.h>
/**
* \defgroup sleep_group Sleep controller driver
*
* This is a low-level driver implementation for the AVR XMEGA sleep controller.
*
* \note To minimize the code overhead, these functions do not feature
* interrupt-protected access since they are likely to be called inside
* interrupt handlers or in applications where such protection is not
* necessary. If such protection is needed, it must be ensured by the calling
* code.
*
* \section xmega_sleep_quickstart_section Quick Start Guide
* See \ref xmega_sleep_quickstart
* @{
*/
#if defined(__ICCAVR__) || defined(__DOXYGEN__)
# include <intrinsics.h>
//! Macro for issuing the sleep instruction.
# define sleep_enter() __sleep()
/**
* \brief Enable sleep
*/
static inline void
sleep_enable (void)
{
SLEEP.CTRL |= SLEEP_SEN_bm;
}
/**
* \brief Disable sleep
*/
static inline void
sleep_disable (void)
{
SLEEP.CTRL &= ~SLEEP_SEN_bm;
}
#elif defined(__GNUC__)
# include <avr/sleep.h>
# define sleep_enter() sleep_cpu()
#else
# error Unsupported compiler.
#endif
/**
* \brief Set new sleep mode
*
* \param mode Sleep mode, from the device IO header file.
*/
static inline void
sleep_set_mode (enum SLEEP_SMODE_enum mode)
{
SLEEP.CTRL = mode | (SLEEP.CTRL & ~SLEEP_SMODE_gm);
}
//! @}
/**
* \page xmega_sleep_quickstart Quick Start Guide for the XMEGA Sleep Driver
*
* This is the quick start guide for the \ref sleep_group "Sleep Driver", with
* step-by-step instructions on how to configure and use the driver for a
* specific use case.
*
* The section described below can be copied into, e.g. the main application
* loop or any other function that will need to control and execute different
* sleep modes on the device.
*
* \section xmega_sleep_quickstart_basic Basic usage of the sleep driver
* This use case will prepare the device to enter the Power Down sleep mode and
* then enter the sleep mode. After waking up it will disable sleep.
*
* \section xmega_sleep_basic_usage Usage steps
* \subsection xmega_sleep_basic_usage_code Example code
* Add to, e.g., the main loop in the application C-file:
* \code
* sleep_set_mode(SLEEP_SMODE_PDOWN_gc);
* sleep_enable();
* sleep_enter();
* sleep_disable();
* \endcode
*
* \subsection xmega_sleep_basic_usage Workflow
* -# Set what sleep mode to use, the different sleep modes can be found in the
* device header file under the enum definition SLEEP_SMODE_enum:
* - \code sleep_set_mode(SLEEP_SMODE_PDOWN_gc); \endcode
* -# Enable that the device are allowed to go to sleep:
* - \code sleep_enable(); \endcode
* - \note This function has to be called in order for the device to go to
* sleep. This is a safety feature to stop the device to go to sleep
* unintentionally, even though it is possible to have this enabled at all times
* it is recommended to enable sleep mode only when you intend to go to sleep
* within a few clock cycles.
* -# Enter sleep mode:
* - \code sleep_enter(); \endcode
* - \attention Make sure to enable global interrupt and the interrupt you
* plan to use as wake-up source for your device, do also pay special
* attention to what wake-up sources are available for the different sleep
* modes. Failing to enable interrupts may result in indefinite sleep until
* power is cycled!
* -# When the device is woken from sleep it will execute the interrupt handler
* related to the wakeup-source (interrupt source) and continue on the next line
* of code after the \ref sleep_enter() call. Make sure to disable sleep when
* waking up.
* - \code sleep_disable(); \endcode
*
* \subsection xmega_sleep_basic_sleep_modes Sleep Modes
* Possible sleep modes depend on the device that is used. Please refer to the
* device datasheet and header file to find these definitions.
*
* As an example the ATxmega32A4U device has the following sleep modes:
* - Idle sleep: SLEEP_SMODE_IDLE_gc
* - Power Down: SLEEP_SMODE_PDOWN_gc
* - Power Save: SLEEP_SMODE_PSAVE_gc
* - Standby: SLEEP_SMODE_STDBY_gc
* - Extended standby: SLEEP_SMODE_ESTDBY_gc
*/
#endif /* SLEEP_H */
/**
* \file
*
* \brief Sleep controller driver
*
* Copyright (c) 2010 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef SLEEP_H
#define SLEEP_H
#include <compiler.h>
/**
* \defgroup sleep_group Sleep controller driver
*
* This is a low-level driver implementation for the AVR XMEGA sleep controller.
*
* \note To minimize the code overhead, these functions do not feature
* interrupt-protected access since they are likely to be called inside
* interrupt handlers or in applications where such protection is not
* necessary. If such protection is needed, it must be ensured by the calling
* code.
*
* \section xmega_sleep_quickstart_section Quick Start Guide
* See \ref xmega_sleep_quickstart
* @{
*/
#if defined(__ICCAVR__) || defined(__DOXYGEN__)
# include <intrinsics.h>
//! Macro for issuing the sleep instruction.
# define sleep_enter() __sleep()
/**
* \brief Enable sleep
*/
static inline void
sleep_enable (void)
{
SLEEP.CTRL |= SLEEP_SEN_bm;
}
/**
* \brief Disable sleep
*/
static inline void
sleep_disable (void)
{
SLEEP.CTRL &= ~SLEEP_SEN_bm;
}
#elif defined(__GNUC__)
# include <avr/sleep.h>
# define sleep_enter() sleep_cpu()
#else
# error Unsupported compiler.
#endif
/**
* \brief Set new sleep mode
*
* \param mode Sleep mode, from the device IO header file.
*/
static inline void
sleep_set_mode (enum SLEEP_SMODE_enum mode)
{
SLEEP.CTRL = mode | (SLEEP.CTRL & ~SLEEP_SMODE_gm);
}
//! @}
/**
* \page xmega_sleep_quickstart Quick Start Guide for the XMEGA Sleep Driver
*
* This is the quick start guide for the \ref sleep_group "Sleep Driver", with
* step-by-step instructions on how to configure and use the driver for a
* specific use case.
*
* The section described below can be copied into, e.g. the main application
* loop or any other function that will need to control and execute different
* sleep modes on the device.
*
* \section xmega_sleep_quickstart_basic Basic usage of the sleep driver
* This use case will prepare the device to enter the Power Down sleep mode and
* then enter the sleep mode. After waking up it will disable sleep.
*
* \section xmega_sleep_basic_usage Usage steps
* \subsection xmega_sleep_basic_usage_code Example code
* Add to, e.g., the main loop in the application C-file:
* \code
* sleep_set_mode(SLEEP_SMODE_PDOWN_gc);
* sleep_enable();
* sleep_enter();
* sleep_disable();
* \endcode
*
* \subsection xmega_sleep_basic_usage Workflow
* -# Set what sleep mode to use, the different sleep modes can be found in the
* device header file under the enum definition SLEEP_SMODE_enum:
* - \code sleep_set_mode(SLEEP_SMODE_PDOWN_gc); \endcode
* -# Enable that the device are allowed to go to sleep:
* - \code sleep_enable(); \endcode
* - \note This function has to be called in order for the device to go to
* sleep. This is a safety feature to stop the device to go to sleep
* unintentionally, even though it is possible to have this enabled at all times
* it is recommended to enable sleep mode only when you intend to go to sleep
* within a few clock cycles.
* -# Enter sleep mode:
* - \code sleep_enter(); \endcode
* - \attention Make sure to enable global interrupt and the interrupt you
* plan to use as wake-up source for your device, do also pay special
* attention to what wake-up sources are available for the different sleep
* modes. Failing to enable interrupts may result in indefinite sleep until
* power is cycled!
* -# When the device is woken from sleep it will execute the interrupt handler
* related to the wakeup-source (interrupt source) and continue on the next line
* of code after the \ref sleep_enter() call. Make sure to disable sleep when
* waking up.
* - \code sleep_disable(); \endcode
*
* \subsection xmega_sleep_basic_sleep_modes Sleep Modes
* Possible sleep modes depend on the device that is used. Please refer to the
* device datasheet and header file to find these definitions.
*
* As an example the ATxmega32A4U device has the following sleep modes:
* - Idle sleep: SLEEP_SMODE_IDLE_gc
* - Power Down: SLEEP_SMODE_PDOWN_gc
* - Power Save: SLEEP_SMODE_PSAVE_gc
* - Standby: SLEEP_SMODE_STDBY_gc
* - Extended standby: SLEEP_SMODE_ESTDBY_gc
*/
#endif /* SLEEP_H */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -1,389 +1,389 @@
/**
* \file
*
* \brief XMEGA TWI master source file.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "twim.h"
/* Master Transfer Descriptor */
static struct {
TWI_t *bus; // Bus register interface
twi_package_t *pkg; // Bus message descriptor
int addr_count; // Bus transfer address data counter
unsigned int data_count; // Bus transfer payload data counter
bool read; // Bus transfer direction
bool locked; // Bus busy or unavailable
volatile status_code_t status; // Transfer status
} transfer;
/**
* \internal
*
* \brief TWI Master Interrupt Vectors
*
* The TWI master interrupt request entry points are conditionally compiled
* for the TWI interfaces supported by the XMEGA MCU variant. All of these
* entry points call a common service function, twim_interrupt_handler(),
* to handle bus events. This handler uses the bus interface and message
* parameters specified in the global \c transfer structure.
*/
static void twim_interrupt_handler(void);
#ifdef TWIC
ISR(TWIC_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
#ifdef TWID
ISR(TWID_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
#ifdef TWIE
ISR(TWIE_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
#ifdef TWIF
ISR(TWIF_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
/**
* \internal
*
* \brief Test for an idle bus state.
*
* Software can determine the TWI master bus state (unknown, idle, owner, or
* busy) by reading the bus master status register:
*
* TWI_MASTER_BUSSTATE_UNKNOWN_gc Bus state is unknown.
* TWI_MASTER_BUSSTATE_IDLE_gc Bus state is idle.
* TWI_MASTER_BUSSTATE_OWNER_gc Bus state is owned by the master.
* TWI_MASTER_BUSSTATE_BUSY_gc Bus state is busy.
*
* \param twi Base address of the TWI (i.e. &TWI_t).
*
* \retval true The bus is currently idle.
* \retval false The bus is currently busy.
*/
static inline bool twim_idle(const TWI_t * twi)
{
return ((twi->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm)
== TWI_MASTER_BUSSTATE_IDLE_gc);
}
/**
* \internal
*
* \brief Get exclusive access to global TWI resources.
*
* Wait to acquire bus hardware interface and ISR variables.
*
* \param no_wait Set \c true to return instead of doing busy-wait (spin-lock).
*
* \return STATUS_OK if the bus is acquired, else ERR_BUSY.
*/
static inline status_code_t twim_acquire(bool no_wait)
{
while (transfer.locked) {
if (no_wait) {
return ERR_BUSY;
}
}
irqflags_t const flags = cpu_irq_save();
transfer.locked = true;
transfer.status = OPERATION_IN_PROGRESS;
cpu_irq_restore(flags);
return STATUS_OK;
}
/**
* \internal
*
* \brief Release exclusive access to global TWI resources.
*
* Release bus hardware interface and ISR variables previously locked by
* a call to \ref twim_acquire(). This function will busy-wait for
* pending driver operations to complete.
*
* \return status_code_t
* - STATUS_OK if the transfer completes
* - ERR_BUSY to indicate an unavailable bus
* - ERR_IO_ERROR to indicate a bus transaction error
* - ERR_NO_MEMORY to indicate buffer errors
* - ERR_PROTOCOL to indicate an unexpected bus state
*/
static inline status_code_t twim_release(void)
{
/* First wait for the driver event handler to indicate something
* other than a transfer in-progress, then test the bus interface
* for an Idle bus state.
*/
while (OPERATION_IN_PROGRESS == transfer.status);
while (!twim_idle(transfer.bus)) {
barrier();
}
status_code_t const status = transfer.status;
transfer.locked = false;
return status;
}
/**
* \internal
*
* \brief TWI master write interrupt handler.
*
* Handles TWI transactions (master write) and responses to (N)ACK.
*/
static inline void twim_write_handler(void)
{
TWI_t *const bus = transfer.bus;
twi_package_t *const pkg = transfer.pkg;
if (transfer.addr_count < pkg->addr_length) {
const uint8_t *const data = pkg->addr;
bus->MASTER.DATA = data[transfer.addr_count++];
} else if (transfer.data_count < pkg->length) {
if (transfer.read) {
/* Send repeated START condition (Address|R/W=1). */
bus->MASTER.ADDR |= 0x01;
} else {
const uint8_t *const data = pkg->buffer;
bus->MASTER.DATA = data[transfer.data_count++];
}
} else {
/* Send STOP condition to complete the transaction. */
bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = STATUS_OK;
}
}
/**
* \internal
*
* \brief TWI master read interrupt handler.
*
* This is the master read interrupt handler that takes care of
* reading bytes from the TWI slave.
*/
static inline void twim_read_handler(void)
{
TWI_t *const bus = transfer.bus;
twi_package_t *const pkg = transfer.pkg;
if (transfer.data_count < pkg->length) {
uint8_t *const data = pkg->buffer;
data[transfer.data_count++] = bus->MASTER.DATA;
/* If there is more to read, issue ACK and start a byte read.
* Otherwise, issue NACK and STOP to complete the transaction.
*/
if (transfer.data_count < pkg->length) {
bus->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
} else {
bus->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
transfer.status = STATUS_OK;
}
} else {
/* Issue STOP and buffer overflow condition. */
bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = ERR_NO_MEMORY;
}
}
/**
* \internal
*
* \brief Common TWI master interrupt service routine.
*
* Check current status and calls the appropriate handler.
*/
static void twim_interrupt_handler(void)
{
uint8_t const master_status = transfer.bus->MASTER.STATUS;
if (master_status & TWI_MASTER_ARBLOST_bm) {
transfer.bus->MASTER.STATUS = master_status | TWI_MASTER_ARBLOST_bm;
transfer.bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = ERR_BUSY;
} else if ((master_status & TWI_MASTER_BUSERR_bm) ||
(master_status & TWI_MASTER_RXACK_bm)) {
transfer.bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = ERR_IO_ERROR;
} else if (master_status & TWI_MASTER_WIF_bm) {
twim_write_handler();
} else if (master_status & TWI_MASTER_RIF_bm) {
twim_read_handler();
} else {
transfer.status = ERR_PROTOCOL;
}
}
/**
* \brief Initialize the twi master module
*
* \param twi Base address of the TWI (i.e. &TWIC).
* \param *opt Options for initializing the twi module
* (see \ref twi_options_t)
* \retval STATUS_OK Transaction is successful
* \retval ERR_INVALID_ARG Invalid arguments in \c opt.
*/
status_code_t twi_master_init(TWI_t * twi,
const twi_options_t * opt)
{
uint8_t const ctrla =
CONF_TWIM_INTLVL | TWI_MASTER_RIEN_bm | TWI_MASTER_WIEN_bm |
TWI_MASTER_ENABLE_bm;
twi->MASTER.BAUD = opt->speed_reg;
twi->MASTER.CTRLA = ctrla;
twi->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
transfer.locked = false;
transfer.status = STATUS_OK;
/* Enable configured PMIC interrupt level. */
PMIC.CTRL |= CONF_PMIC_INTLVL;
cpu_irq_enable();
return STATUS_OK;
}
/**
* \brief Perform a TWI master write or read transfer.
*
* This function is a TWI Master write or read transaction.
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \param read Selects the transfer direction
*
* \return status_code_t
* - STATUS_OK if the transfer completes
* - ERR_BUSY to indicate an unavailable bus
* - ERR_IO_ERROR to indicate a bus transaction error
* - ERR_NO_MEMORY to indicate buffer errors
* - ERR_PROTOCOL to indicate an unexpected bus state
* - ERR_INVALID_ARG to indicate invalid arguments.
*/
status_code_t twi_master_transfer(TWI_t * twi,
const twi_package_t * package,
bool read)
{
/* Do a sanity check on the arguments. */
if ((twi == NULL) || (package == NULL)) {
return ERR_INVALID_ARG;
}
/* Initiate a transaction when the bus is ready. */
status_code_t status = twim_acquire(package->no_wait);
if (STATUS_OK == status) {
transfer.bus = (TWI_t *) twi;
transfer.pkg = (twi_package_t *) package;
transfer.addr_count = 0;
transfer.data_count = 0;
transfer.read = read;
uint8_t const chip = (package->chip) << 1;
if (package->addr_length || (false == read)) {
transfer.bus->MASTER.ADDR = chip;
} else if (read) {
transfer.bus->MASTER.ADDR = chip | 0x01;
}
status = twim_release();
}
return status;
}
/**
* \file
*
* \brief XMEGA TWI master source file.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "twim.h"
/* Master Transfer Descriptor */
static struct {
TWI_t *bus; // Bus register interface
twi_package_t *pkg; // Bus message descriptor
int addr_count; // Bus transfer address data counter
unsigned int data_count; // Bus transfer payload data counter
bool read; // Bus transfer direction
bool locked; // Bus busy or unavailable
volatile status_code_t status; // Transfer status
} transfer;
/**
* \internal
*
* \brief TWI Master Interrupt Vectors
*
* The TWI master interrupt request entry points are conditionally compiled
* for the TWI interfaces supported by the XMEGA MCU variant. All of these
* entry points call a common service function, twim_interrupt_handler(),
* to handle bus events. This handler uses the bus interface and message
* parameters specified in the global \c transfer structure.
*/
static void twim_interrupt_handler(void);
#ifdef TWIC
ISR(TWIC_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
#ifdef TWID
ISR(TWID_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
#ifdef TWIE
ISR(TWIE_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
#ifdef TWIF
ISR(TWIF_TWIM_vect)
{
twim_interrupt_handler();
}
#endif
/**
* \internal
*
* \brief Test for an idle bus state.
*
* Software can determine the TWI master bus state (unknown, idle, owner, or
* busy) by reading the bus master status register:
*
* TWI_MASTER_BUSSTATE_UNKNOWN_gc Bus state is unknown.
* TWI_MASTER_BUSSTATE_IDLE_gc Bus state is idle.
* TWI_MASTER_BUSSTATE_OWNER_gc Bus state is owned by the master.
* TWI_MASTER_BUSSTATE_BUSY_gc Bus state is busy.
*
* \param twi Base address of the TWI (i.e. &TWI_t).
*
* \retval true The bus is currently idle.
* \retval false The bus is currently busy.
*/
static inline bool twim_idle(const TWI_t * twi)
{
return ((twi->MASTER.STATUS & TWI_MASTER_BUSSTATE_gm)
== TWI_MASTER_BUSSTATE_IDLE_gc);
}
/**
* \internal
*
* \brief Get exclusive access to global TWI resources.
*
* Wait to acquire bus hardware interface and ISR variables.
*
* \param no_wait Set \c true to return instead of doing busy-wait (spin-lock).
*
* \return STATUS_OK if the bus is acquired, else ERR_BUSY.
*/
static inline status_code_t twim_acquire(bool no_wait)
{
while (transfer.locked) {
if (no_wait) {
return ERR_BUSY;
}
}
irqflags_t const flags = cpu_irq_save();
transfer.locked = true;
transfer.status = OPERATION_IN_PROGRESS;
cpu_irq_restore(flags);
return STATUS_OK;
}
/**
* \internal
*
* \brief Release exclusive access to global TWI resources.
*
* Release bus hardware interface and ISR variables previously locked by
* a call to \ref twim_acquire(). This function will busy-wait for
* pending driver operations to complete.
*
* \return status_code_t
* - STATUS_OK if the transfer completes
* - ERR_BUSY to indicate an unavailable bus
* - ERR_IO_ERROR to indicate a bus transaction error
* - ERR_NO_MEMORY to indicate buffer errors
* - ERR_PROTOCOL to indicate an unexpected bus state
*/
static inline status_code_t twim_release(void)
{
/* First wait for the driver event handler to indicate something
* other than a transfer in-progress, then test the bus interface
* for an Idle bus state.
*/
while (OPERATION_IN_PROGRESS == transfer.status);
while (!twim_idle(transfer.bus)) {
barrier();
}
status_code_t const status = transfer.status;
transfer.locked = false;
return status;
}
/**
* \internal
*
* \brief TWI master write interrupt handler.
*
* Handles TWI transactions (master write) and responses to (N)ACK.
*/
static inline void twim_write_handler(void)
{
TWI_t *const bus = transfer.bus;
twi_package_t *const pkg = transfer.pkg;
if (transfer.addr_count < pkg->addr_length) {
const uint8_t *const data = pkg->addr;
bus->MASTER.DATA = data[transfer.addr_count++];
} else if (transfer.data_count < pkg->length) {
if (transfer.read) {
/* Send repeated START condition (Address|R/W=1). */
bus->MASTER.ADDR |= 0x01;
} else {
const uint8_t *const data = pkg->buffer;
bus->MASTER.DATA = data[transfer.data_count++];
}
} else {
/* Send STOP condition to complete the transaction. */
bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = STATUS_OK;
}
}
/**
* \internal
*
* \brief TWI master read interrupt handler.
*
* This is the master read interrupt handler that takes care of
* reading bytes from the TWI slave.
*/
static inline void twim_read_handler(void)
{
TWI_t *const bus = transfer.bus;
twi_package_t *const pkg = transfer.pkg;
if (transfer.data_count < pkg->length) {
uint8_t *const data = pkg->buffer;
data[transfer.data_count++] = bus->MASTER.DATA;
/* If there is more to read, issue ACK and start a byte read.
* Otherwise, issue NACK and STOP to complete the transaction.
*/
if (transfer.data_count < pkg->length) {
bus->MASTER.CTRLC = TWI_MASTER_CMD_RECVTRANS_gc;
} else {
bus->MASTER.CTRLC = TWI_MASTER_ACKACT_bm | TWI_MASTER_CMD_STOP_gc;
transfer.status = STATUS_OK;
}
} else {
/* Issue STOP and buffer overflow condition. */
bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = ERR_NO_MEMORY;
}
}
/**
* \internal
*
* \brief Common TWI master interrupt service routine.
*
* Check current status and calls the appropriate handler.
*/
static void twim_interrupt_handler(void)
{
uint8_t const master_status = transfer.bus->MASTER.STATUS;
if (master_status & TWI_MASTER_ARBLOST_bm) {
transfer.bus->MASTER.STATUS = master_status | TWI_MASTER_ARBLOST_bm;
transfer.bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = ERR_BUSY;
} else if ((master_status & TWI_MASTER_BUSERR_bm) ||
(master_status & TWI_MASTER_RXACK_bm)) {
transfer.bus->MASTER.CTRLC = TWI_MASTER_CMD_STOP_gc;
transfer.status = ERR_IO_ERROR;
} else if (master_status & TWI_MASTER_WIF_bm) {
twim_write_handler();
} else if (master_status & TWI_MASTER_RIF_bm) {
twim_read_handler();
} else {
transfer.status = ERR_PROTOCOL;
}
}
/**
* \brief Initialize the twi master module
*
* \param twi Base address of the TWI (i.e. &TWIC).
* \param *opt Options for initializing the twi module
* (see \ref twi_options_t)
* \retval STATUS_OK Transaction is successful
* \retval ERR_INVALID_ARG Invalid arguments in \c opt.
*/
status_code_t twi_master_init(TWI_t * twi,
const twi_options_t * opt)
{
uint8_t const ctrla =
CONF_TWIM_INTLVL | TWI_MASTER_RIEN_bm | TWI_MASTER_WIEN_bm |
TWI_MASTER_ENABLE_bm;
twi->MASTER.BAUD = opt->speed_reg;
twi->MASTER.CTRLA = ctrla;
twi->MASTER.STATUS = TWI_MASTER_BUSSTATE_IDLE_gc;
transfer.locked = false;
transfer.status = STATUS_OK;
/* Enable configured PMIC interrupt level. */
PMIC.CTRL |= CONF_PMIC_INTLVL;
cpu_irq_enable();
return STATUS_OK;
}
/**
* \brief Perform a TWI master write or read transfer.
*
* This function is a TWI Master write or read transaction.
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \param read Selects the transfer direction
*
* \return status_code_t
* - STATUS_OK if the transfer completes
* - ERR_BUSY to indicate an unavailable bus
* - ERR_IO_ERROR to indicate a bus transaction error
* - ERR_NO_MEMORY to indicate buffer errors
* - ERR_PROTOCOL to indicate an unexpected bus state
* - ERR_INVALID_ARG to indicate invalid arguments.
*/
status_code_t twi_master_transfer(TWI_t * twi,
const twi_package_t * package,
bool read)
{
/* Do a sanity check on the arguments. */
if ((twi == NULL) || (package == NULL)) {
return ERR_INVALID_ARG;
}
/* Initiate a transaction when the bus is ready. */
status_code_t status = twim_acquire(package->no_wait);
if (STATUS_OK == status) {
transfer.bus = (TWI_t *) twi;
transfer.pkg = (twi_package_t *) package;
transfer.addr_count = 0;
transfer.data_count = 0;
transfer.read = read;
uint8_t const chip = (package->chip) << 1;
if (package->addr_length || (false == read)) {
transfer.bus->MASTER.ADDR = chip;
} else if (read) {
transfer.bus->MASTER.ADDR = chip | 0x01;
}
status = twim_release();
}
return status;
}
@@ -1,168 +1,168 @@
/**
* \file
*
* \brief TWI driver for AVR.
*
* This file defines a useful set of functions for the TWI interface on AVR
* devices.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _TWIM_H_
#define _TWIM_H_
/**
* \defgroup group_xmega_drivers_twi_twim TWI Master
*
* \ingroup group_xmega_drivers_twi
*
* \{
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include <compiler.h>
#include <status_codes.h>
#include "conf_twim.h"
#include "twi_common.h"
/*! \brief Error Codes for the Module
*
* \deprecated
* This definition is provided for compatibility with existing ASF example
* applications. This module uses the \ref status_code_t values that will
* replace module-specific error codes in ASF drivers.
*/
#define TWI_SUCCESS (STATUS_OK)
/*! Baud register setting calculation. Formula described in datasheet. */
#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
/*! \brief Initialize the twi master module
*
* \param twi Base address of the TWI (i.e. &TWIC).
* \param *opt Options for initializing the twi module
* (see \ref twi_options_t)
* \retval STATUS_OK Transaction is successful
* \retval ERR_INVALID_ARG Invalid arguments in \c opt.
*/
status_code_t twi_master_init (TWI_t * twi, const twi_options_t * opt);
/*! \brief Perform a TWI master write or read transfer.
*
* This function is a TWI Master write or read transaction.
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \param read Selects the transfer direction
*
* \return status_code_t
* - STATUS_OK if the transfer completes
* - ERR_BUSY to indicate an unavailable bus
* - ERR_IO_ERROR to indicate a bus transaction error
* - ERR_NO_MEMORY to indicate buffer errors
* - ERR_PROTOCOL to indicate an unexpected bus state
* - ERR_INVALID_ARG to indicate invalid arguments.
*/
status_code_t twi_master_transfer (TWI_t * twi,
const twi_package_t * package,
bool read);
/*! \brief Read multiple bytes from a TWI compatible slave device
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \return STATUS_OK If all bytes were read, error code otherwise
*/
static inline status_code_t twi_master_read (TWI_t * twi,
const twi_package_t * package)
{
return twi_master_transfer (twi, package, true);
}
/*! \brief Write multiple bytes to a TWI compatible slave device
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \return STATUS_OK If all bytes were written, error code otherwise
*/
static inline status_code_t twi_master_write (TWI_t * twi,
const twi_package_t * package)
{
return twi_master_transfer (twi, package, false);
}
/*! \brief Enable Master Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void twi_master_enable (TWI_t * twi)
{
twi->MASTER.CTRLA |= TWI_MASTER_ENABLE_bm;
}
/*! \brief Disable Master Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void twi_master_disable (TWI_t * twi)
{
twi->MASTER.CTRLA &= (~TWI_MASTER_ENABLE_bm);
}
#ifdef __cplusplus
}
#endif
/**
* \}
*/
#endif // _TWIM_H_
/**
* \file
*
* \brief TWI driver for AVR.
*
* This file defines a useful set of functions for the TWI interface on AVR
* devices.
*
* Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _TWIM_H_
#define _TWIM_H_
/**
* \defgroup group_xmega_drivers_twi_twim TWI Master
*
* \ingroup group_xmega_drivers_twi
*
* \{
*/
#ifdef __cplusplus
extern "C"
{
#endif
#include <compiler.h>
#include <status_codes.h>
#include "conf_twim.h"
#include "twi_common.h"
/*! \brief Error Codes for the Module
*
* \deprecated
* This definition is provided for compatibility with existing ASF example
* applications. This module uses the \ref status_code_t values that will
* replace module-specific error codes in ASF drivers.
*/
#define TWI_SUCCESS (STATUS_OK)
/*! Baud register setting calculation. Formula described in datasheet. */
#define TWI_BAUD(F_SYS, F_TWI) ((F_SYS / (2 * F_TWI)) - 5)
/*! \brief Initialize the twi master module
*
* \param twi Base address of the TWI (i.e. &TWIC).
* \param *opt Options for initializing the twi module
* (see \ref twi_options_t)
* \retval STATUS_OK Transaction is successful
* \retval ERR_INVALID_ARG Invalid arguments in \c opt.
*/
status_code_t twi_master_init (TWI_t * twi, const twi_options_t * opt);
/*! \brief Perform a TWI master write or read transfer.
*
* This function is a TWI Master write or read transaction.
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \param read Selects the transfer direction
*
* \return status_code_t
* - STATUS_OK if the transfer completes
* - ERR_BUSY to indicate an unavailable bus
* - ERR_IO_ERROR to indicate a bus transaction error
* - ERR_NO_MEMORY to indicate buffer errors
* - ERR_PROTOCOL to indicate an unexpected bus state
* - ERR_INVALID_ARG to indicate invalid arguments.
*/
status_code_t twi_master_transfer (TWI_t * twi,
const twi_package_t * package,
bool read);
/*! \brief Read multiple bytes from a TWI compatible slave device
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \return STATUS_OK If all bytes were read, error code otherwise
*/
static inline status_code_t twi_master_read (TWI_t * twi,
const twi_package_t * package)
{
return twi_master_transfer (twi, package, true);
}
/*! \brief Write multiple bytes to a TWI compatible slave device
*
* \param twi Base address of the TWI (i.e. &TWI_t).
* \param package Package information and data
* (see \ref twi_package_t)
* \return STATUS_OK If all bytes were written, error code otherwise
*/
static inline status_code_t twi_master_write (TWI_t * twi,
const twi_package_t * package)
{
return twi_master_transfer (twi, package, false);
}
/*! \brief Enable Master Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void twi_master_enable (TWI_t * twi)
{
twi->MASTER.CTRLA |= TWI_MASTER_ENABLE_bm;
}
/*! \brief Disable Master Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void twi_master_disable (TWI_t * twi)
{
twi->MASTER.CTRLA &= (~TWI_MASTER_ENABLE_bm);
}
#ifdef __cplusplus
}
#endif
/**
* \}
*/
#endif // _TWIM_H_
@@ -1,330 +1,330 @@
/**
* \file *********************************************************************
*
* \brief
* XMEGA TWI slave driver source file.
*
* This file contains the function implementations the XMEGA TWI slave
* 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 slave 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
*
* Atmel Corporation: http://www.atmel.com \n
*
* $Revision: 2660 $
* $Date: 2009-08-11 12:28:58 +0200 (Tue, 11 Aug 2009) $ \n
*
* Copyright (c) 2008 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*****************************************************************************/
#include "twis.h"
/*! \brief Initalizes TWI slave driver structure.
*
* Initialize the instance of the TWI Slave and set the appropriate values.
*
* \param twi The TWI_Slave_t struct instance.
* \param module Pointer to the TWI module.
* \param processDataFunction Pointer to the function that handles incoming data.
*/
void TWI_SlaveInitializeDriver(TWI_Slave_t * twi,
TWI_t * module,
void (*processDataFunction) (void))
{
twi->interface = module;
twi->Process_Data = processDataFunction;
twi->bytesReceived = 0;
twi->bytesSent = 0;
twi->status = TWIS_STATUS_READY;
twi->result = TWIS_RESULT_UNKNOWN;
twi->abort = false;
}
/*! \brief Initialize the TWI module.
*
* Enables interrupts on address recognition and data available.
* Remember to enable interrupts globally from the main application.
*
* \param twi The TWI_Slave_t struct instance.
* \param address Slave address for this module.
* \param intLevel Interrupt level for the TWI slave interrupt handler.
*/
void TWI_SlaveInitializeModule(TWI_Slave_t * twi,
uint8_t address,
TWI_SLAVE_INTLVL_t intLevel)
{
twi->interface->SLAVE.CTRLA =
intLevel | TWI_SLAVE_DIEN_bm | TWI_SLAVE_APIEN_bm |
TWI_SLAVE_ENABLE_bm;
twi->interface->SLAVE.ADDR = (address << 1);
}
/*! \brief Common TWI slave interrupt service routine.
*
* Handles all TWI transactions and responses to address match, data reception,
* data transmission, bus error and data collision.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveInterruptHandler(TWI_Slave_t * twi)
{
uint8_t currentStatus = twi->interface->SLAVE.STATUS;
/* If bus error. */
if (currentStatus & TWI_SLAVE_BUSERR_bm) {
twi->bytesReceived = 0;
twi->bytesSent = 0;
twi->result = TWIS_RESULT_BUS_ERROR;
twi->status = TWIS_STATUS_READY;
}
/* If transmit collision. */
else if (currentStatus & TWI_SLAVE_COLL_bm) {
twi->bytesReceived = 0;
twi->bytesSent = 0;
twi->result = TWIS_RESULT_TRANSMIT_COLLISION;
twi->status = TWIS_STATUS_READY;
}
/* If address match. */
else if ((currentStatus & TWI_SLAVE_APIF_bm) &&
(currentStatus & TWI_SLAVE_AP_bm)) {
TWI_SlaveAddressMatchHandler(twi);
}
/* If stop (only enabled through slave read transaction). */
else if (currentStatus & TWI_SLAVE_APIF_bm) {
TWI_SlaveStopHandler(twi);
}
/* If data interrupt. */
else if (currentStatus & TWI_SLAVE_DIF_bm) {
TWI_SlaveDataHandler(twi);
}
/* If unexpected state. */
else {
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL);
}
}
/*! \brief TWI address match interrupt handler.
*
* Prepares TWI module for transaction when an address match occurs.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveAddressMatchHandler(TWI_Slave_t * twi)
{
/* If application signalling need to abort (error occured). */
if (twi->abort) {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
twi->abort = false;
} else {
twi->status = TWIS_STATUS_BUSY;
twi->result = TWIS_RESULT_UNKNOWN;
/* Disable stop interrupt. */
uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
twi->bytesReceived = 0;
twi->bytesSent = 0;
/* Send ACK, wait for data interrupt. */
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
}
}
/*! \brief TWI stop condition interrupt handler.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveStopHandler(TWI_Slave_t * twi)
{
/* Disable stop interrupt. */
uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
/* Clear APIF, according to flowchart don't ACK or NACK */
uint8_t currentStatus = twi->interface->SLAVE.STATUS;
twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
}
/*! \brief TWI data interrupt handler.
*
* Calls the appropriate slave read or write handler.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveDataHandler(TWI_Slave_t * twi)
{
if (twi->interface->SLAVE.STATUS & TWI_SLAVE_DIR_bm) {
TWI_SlaveWriteHandler(twi);
} else {
TWI_SlaveReadHandler(twi);
}
}
/*! \brief TWI slave read interrupt handler.
*
* Handles TWI slave read transactions and responses.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveReadHandler(TWI_Slave_t * twi)
{
/* Enable stop interrupt. */
uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm;
/* If free space in buffer. */
if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) {
/* Fetch data */
uint8_t data = twi->interface->SLAVE.DATA;
twi->receivedData[twi->bytesReceived] = data;
/* Process data. */
twi->Process_Data();
twi->bytesReceived++;
/* If application signalling need to abort (error occured),
* complete transaction and wait for next START. Otherwise
* send ACK and wait for data interrupt.
*/
if (twi->abort) {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
twi->abort = false;
} else {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
}
}
/* If buffer overflow, send NACK and wait for next START. Set
* result buffer overflow.
*/
else {
twi->interface->SLAVE.CTRLB =
TWI_SLAVE_ACKACT_bm | TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
}
}
/*! \brief TWI slave write interrupt handler.
*
* Handles TWI slave write transactions and responses.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveWriteHandler(TWI_Slave_t * twi)
{
/* If NACK, slave write transaction finished. */
if ((twi->bytesSent > 0) &&
(twi->interface->SLAVE.STATUS & TWI_SLAVE_RXACK_bm)) {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
}
/* If ACK, master expects more data. */
else {
if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) {
uint8_t data = twi->sendData[twi->bytesSent];
twi->interface->SLAVE.DATA = data;
twi->bytesSent++;
/* Send data, wait for data interrupt. */
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
}
/* If buffer overflow. */
else {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
}
}
}
/*! \brief TWI transaction finished function.
*
* Prepares module for new transaction.
*
* \param twi The TWI_Slave_t struct instance.
* \param result The result of the transaction.
*/
void TWI_SlaveTransactionFinished(TWI_Slave_t * twi,
uint8_t result)
{
twi->result = result;
twi->status = TWIS_STATUS_READY;
}
/**
* \file *********************************************************************
*
* \brief
* XMEGA TWI slave driver source file.
*
* This file contains the function implementations the XMEGA TWI slave
* 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 slave 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
*
* Atmel Corporation: http://www.atmel.com \n
*
* $Revision: 2660 $
* $Date: 2009-08-11 12:28:58 +0200 (Tue, 11 Aug 2009) $ \n
*
* Copyright (c) 2008 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*****************************************************************************/
#include "twis.h"
/*! \brief Initalizes TWI slave driver structure.
*
* Initialize the instance of the TWI Slave and set the appropriate values.
*
* \param twi The TWI_Slave_t struct instance.
* \param module Pointer to the TWI module.
* \param processDataFunction Pointer to the function that handles incoming data.
*/
void TWI_SlaveInitializeDriver(TWI_Slave_t * twi,
TWI_t * module,
void (*processDataFunction) (void))
{
twi->interface = module;
twi->Process_Data = processDataFunction;
twi->bytesReceived = 0;
twi->bytesSent = 0;
twi->status = TWIS_STATUS_READY;
twi->result = TWIS_RESULT_UNKNOWN;
twi->abort = false;
}
/*! \brief Initialize the TWI module.
*
* Enables interrupts on address recognition and data available.
* Remember to enable interrupts globally from the main application.
*
* \param twi The TWI_Slave_t struct instance.
* \param address Slave address for this module.
* \param intLevel Interrupt level for the TWI slave interrupt handler.
*/
void TWI_SlaveInitializeModule(TWI_Slave_t * twi,
uint8_t address,
TWI_SLAVE_INTLVL_t intLevel)
{
twi->interface->SLAVE.CTRLA =
intLevel | TWI_SLAVE_DIEN_bm | TWI_SLAVE_APIEN_bm |
TWI_SLAVE_ENABLE_bm;
twi->interface->SLAVE.ADDR = (address << 1);
}
/*! \brief Common TWI slave interrupt service routine.
*
* Handles all TWI transactions and responses to address match, data reception,
* data transmission, bus error and data collision.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveInterruptHandler(TWI_Slave_t * twi)
{
uint8_t currentStatus = twi->interface->SLAVE.STATUS;
/* If bus error. */
if (currentStatus & TWI_SLAVE_BUSERR_bm) {
twi->bytesReceived = 0;
twi->bytesSent = 0;
twi->result = TWIS_RESULT_BUS_ERROR;
twi->status = TWIS_STATUS_READY;
}
/* If transmit collision. */
else if (currentStatus & TWI_SLAVE_COLL_bm) {
twi->bytesReceived = 0;
twi->bytesSent = 0;
twi->result = TWIS_RESULT_TRANSMIT_COLLISION;
twi->status = TWIS_STATUS_READY;
}
/* If address match. */
else if ((currentStatus & TWI_SLAVE_APIF_bm) &&
(currentStatus & TWI_SLAVE_AP_bm)) {
TWI_SlaveAddressMatchHandler(twi);
}
/* If stop (only enabled through slave read transaction). */
else if (currentStatus & TWI_SLAVE_APIF_bm) {
TWI_SlaveStopHandler(twi);
}
/* If data interrupt. */
else if (currentStatus & TWI_SLAVE_DIF_bm) {
TWI_SlaveDataHandler(twi);
}
/* If unexpected state. */
else {
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_FAIL);
}
}
/*! \brief TWI address match interrupt handler.
*
* Prepares TWI module for transaction when an address match occurs.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveAddressMatchHandler(TWI_Slave_t * twi)
{
/* If application signalling need to abort (error occured). */
if (twi->abort) {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
twi->abort = false;
} else {
twi->status = TWIS_STATUS_BUSY;
twi->result = TWIS_RESULT_UNKNOWN;
/* Disable stop interrupt. */
uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
twi->bytesReceived = 0;
twi->bytesSent = 0;
/* Send ACK, wait for data interrupt. */
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
}
}
/*! \brief TWI stop condition interrupt handler.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveStopHandler(TWI_Slave_t * twi)
{
/* Disable stop interrupt. */
uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
twi->interface->SLAVE.CTRLA = currentCtrlA & ~TWI_SLAVE_PIEN_bm;
/* Clear APIF, according to flowchart don't ACK or NACK */
uint8_t currentStatus = twi->interface->SLAVE.STATUS;
twi->interface->SLAVE.STATUS = currentStatus | TWI_SLAVE_APIF_bm;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
}
/*! \brief TWI data interrupt handler.
*
* Calls the appropriate slave read or write handler.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveDataHandler(TWI_Slave_t * twi)
{
if (twi->interface->SLAVE.STATUS & TWI_SLAVE_DIR_bm) {
TWI_SlaveWriteHandler(twi);
} else {
TWI_SlaveReadHandler(twi);
}
}
/*! \brief TWI slave read interrupt handler.
*
* Handles TWI slave read transactions and responses.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveReadHandler(TWI_Slave_t * twi)
{
/* Enable stop interrupt. */
uint8_t currentCtrlA = twi->interface->SLAVE.CTRLA;
twi->interface->SLAVE.CTRLA = currentCtrlA | TWI_SLAVE_PIEN_bm;
/* If free space in buffer. */
if (twi->bytesReceived < TWIS_RECEIVE_BUFFER_SIZE) {
/* Fetch data */
uint8_t data = twi->interface->SLAVE.DATA;
twi->receivedData[twi->bytesReceived] = data;
/* Process data. */
twi->Process_Data();
twi->bytesReceived++;
/* If application signalling need to abort (error occured),
* complete transaction and wait for next START. Otherwise
* send ACK and wait for data interrupt.
*/
if (twi->abort) {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_ABORTED);
twi->abort = false;
} else {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
}
}
/* If buffer overflow, send NACK and wait for next START. Set
* result buffer overflow.
*/
else {
twi->interface->SLAVE.CTRLB =
TWI_SLAVE_ACKACT_bm | TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
}
}
/*! \brief TWI slave write interrupt handler.
*
* Handles TWI slave write transactions and responses.
*
* \param twi The TWI_Slave_t struct instance.
*/
void TWI_SlaveWriteHandler(TWI_Slave_t * twi)
{
/* If NACK, slave write transaction finished. */
if ((twi->bytesSent > 0) &&
(twi->interface->SLAVE.STATUS & TWI_SLAVE_RXACK_bm)) {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_OK);
}
/* If ACK, master expects more data. */
else {
if (twi->bytesSent < TWIS_SEND_BUFFER_SIZE) {
uint8_t data = twi->sendData[twi->bytesSent];
twi->interface->SLAVE.DATA = data;
twi->bytesSent++;
/* Send data, wait for data interrupt. */
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_RESPONSE_gc;
}
/* If buffer overflow. */
else {
twi->interface->SLAVE.CTRLB = TWI_SLAVE_CMD_COMPTRANS_gc;
TWI_SlaveTransactionFinished(twi, TWIS_RESULT_BUFFER_OVERFLOW);
}
}
}
/*! \brief TWI transaction finished function.
*
* Prepares module for new transaction.
*
* \param twi The TWI_Slave_t struct instance.
* \param result The result of the transaction.
*/
void TWI_SlaveTransactionFinished(TWI_Slave_t * twi,
uint8_t result)
{
twi->result = result;
twi->status = TWIS_STATUS_READY;
}
@@ -1,179 +1,179 @@
/**
* \file *********************************************************************
*
* \brief XMEGA TWI slave driver header file.
*
* This file contains the function prototypes and enumerator definitions
* for various configuration parameters for the XMEGA TWI slave 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 slave 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:
* AVR1307: Using the XMEGA TWI
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* Atmel Corporation: http://www.atmel.com \n
*
* $Revision: 1569 $
* $Date: 2008-04-22 13:03:43 +0200 (Tue, 22 Apr 2008) $ \n
*
* Copyright (c) 2008 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*****************************************************************************/
#ifndef TWIS_H
#define TWIS_H
/**
* \defgroup group_xmega_drivers_twi_twis TWI Slave
*
* \ingroup group_xmega_drivers_twi
*
* \{
*/
#include "compiler.h"
#include "twi_common.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 TWIS_STATUS_READY 0
#define TWIS_STATUS_BUSY 1
/* Transaction result enumeration */
typedef enum TWIS_RESULT_enum
{
TWIS_RESULT_UNKNOWN = (0x00 << 0),
TWIS_RESULT_OK = (0x01 << 0),
TWIS_RESULT_BUFFER_OVERFLOW = (0x02 << 0),
TWIS_RESULT_TRANSMIT_COLLISION = (0x03 << 0),
TWIS_RESULT_BUS_ERROR = (0x04 << 0),
TWIS_RESULT_FAIL = (0x05 << 0),
TWIS_RESULT_ABORTED = (0x06 << 0),
}
TWIS_RESULT_t;
/* Buffer size defines. */
#define TWIS_RECEIVE_BUFFER_SIZE 8
#define TWIS_SEND_BUFFER_SIZE 8
/*! \brief TWI slave driver struct.
*
* TWI slave struct. Holds pointer to TWI module and data processing routine,
* buffers and necessary variables.
*/
typedef struct TWI_Slave
{
TWI_t *interface; /*!< Pointer to what interface to use */
void (*Process_Data) (void); /*!< Pointer to process data function */
register8_t receivedData[TWIS_RECEIVE_BUFFER_SIZE]; /*!< Read data */
register8_t sendData[TWIS_SEND_BUFFER_SIZE]; /*!< Data to write */
register8_t bytesReceived; /*!< Number of bytes received */
register8_t bytesSent; /*!< Number of bytes sent */
register8_t status; /*!< Status of transaction */
register8_t result; /*!< Result of transaction */
bool abort; /*!< Strobe to abort */
}
TWI_Slave_t;
void TWI_SlaveInitializeDriver (TWI_Slave_t * twi,
TWI_t * module,
void (*processDataFunction) (void));
void TWI_SlaveInitializeModule (TWI_Slave_t * twi,
uint8_t address, TWI_SLAVE_INTLVL_t intLevel);
void TWI_SlaveInterruptHandler (TWI_Slave_t * twi);
void TWI_SlaveAddressMatchHandler (TWI_Slave_t * twi);
void TWI_SlaveStopHandler (TWI_Slave_t * twi);
void TWI_SlaveDataHandler (TWI_Slave_t * twi);
void TWI_SlaveReadHandler (TWI_Slave_t * twi);
void TWI_SlaveWriteHandler (TWI_Slave_t * twi);
void TWI_SlaveTransactionFinished (TWI_Slave_t * twi, uint8_t result);
/*! TWI slave interrupt service routine.
*
* Interrupt service routine for the TWI slave. Copy the interrupt vector
* into your code if needed.
*
ISR(TWIC_TWIS_vect)
{
TWI_SlaveInterruptHandler(&twiSlaveC);
}
*
*/
/*! \brief Enable Slave Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void
twi_slave_enable (TWI_t * twi)
{
twi->SLAVE.CTRLA |= TWI_SLAVE_ENABLE_bm;
}
/*! \brief Disable Slave Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void
twi_slave_disable (TWI_t * twi)
{
twi->SLAVE.CTRLA &= (~TWI_SLAVE_ENABLE_bm);
}
/**
* \}
*/
#endif /* TWIS_H */
/**
* \file *********************************************************************
*
* \brief XMEGA TWI slave driver header file.
*
* This file contains the function prototypes and enumerator definitions
* for various configuration parameters for the XMEGA TWI slave 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 slave 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:
* AVR1307: Using the XMEGA TWI
*
* \par Documentation
* For comprehensive code documentation, supported compilers, compiler
* settings and supported devices see readme.html
*
* Atmel Corporation: http://www.atmel.com \n
*
* $Revision: 1569 $
* $Date: 2008-04-22 13:03:43 +0200 (Tue, 22 Apr 2008) $ \n
*
* Copyright (c) 2008 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*****************************************************************************/
#ifndef TWIS_H
#define TWIS_H
/**
* \defgroup group_xmega_drivers_twi_twis TWI Slave
*
* \ingroup group_xmega_drivers_twi
*
* \{
*/
#include "compiler.h"
#include "twi_common.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 TWIS_STATUS_READY 0
#define TWIS_STATUS_BUSY 1
/* Transaction result enumeration */
typedef enum TWIS_RESULT_enum
{
TWIS_RESULT_UNKNOWN = (0x00 << 0),
TWIS_RESULT_OK = (0x01 << 0),
TWIS_RESULT_BUFFER_OVERFLOW = (0x02 << 0),
TWIS_RESULT_TRANSMIT_COLLISION = (0x03 << 0),
TWIS_RESULT_BUS_ERROR = (0x04 << 0),
TWIS_RESULT_FAIL = (0x05 << 0),
TWIS_RESULT_ABORTED = (0x06 << 0),
}
TWIS_RESULT_t;
/* Buffer size defines. */
#define TWIS_RECEIVE_BUFFER_SIZE 8
#define TWIS_SEND_BUFFER_SIZE 8
/*! \brief TWI slave driver struct.
*
* TWI slave struct. Holds pointer to TWI module and data processing routine,
* buffers and necessary variables.
*/
typedef struct TWI_Slave
{
TWI_t *interface; /*!< Pointer to what interface to use */
void (*Process_Data) (void); /*!< Pointer to process data function */
register8_t receivedData[TWIS_RECEIVE_BUFFER_SIZE]; /*!< Read data */
register8_t sendData[TWIS_SEND_BUFFER_SIZE]; /*!< Data to write */
register8_t bytesReceived; /*!< Number of bytes received */
register8_t bytesSent; /*!< Number of bytes sent */
register8_t status; /*!< Status of transaction */
register8_t result; /*!< Result of transaction */
bool abort; /*!< Strobe to abort */
}
TWI_Slave_t;
void TWI_SlaveInitializeDriver (TWI_Slave_t * twi,
TWI_t * module,
void (*processDataFunction) (void));
void TWI_SlaveInitializeModule (TWI_Slave_t * twi,
uint8_t address, TWI_SLAVE_INTLVL_t intLevel);
void TWI_SlaveInterruptHandler (TWI_Slave_t * twi);
void TWI_SlaveAddressMatchHandler (TWI_Slave_t * twi);
void TWI_SlaveStopHandler (TWI_Slave_t * twi);
void TWI_SlaveDataHandler (TWI_Slave_t * twi);
void TWI_SlaveReadHandler (TWI_Slave_t * twi);
void TWI_SlaveWriteHandler (TWI_Slave_t * twi);
void TWI_SlaveTransactionFinished (TWI_Slave_t * twi, uint8_t result);
/*! TWI slave interrupt service routine.
*
* Interrupt service routine for the TWI slave. Copy the interrupt vector
* into your code if needed.
*
ISR(TWIC_TWIS_vect)
{
TWI_SlaveInterruptHandler(&twiSlaveC);
}
*
*/
/*! \brief Enable Slave Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void
twi_slave_enable (TWI_t * twi)
{
twi->SLAVE.CTRLA |= TWI_SLAVE_ENABLE_bm;
}
/*! \brief Disable Slave Mode of the TWI.
*
* \param twi Base address of the TWI instance.
*/
static inline void
twi_slave_disable (TWI_t * twi)
{
twi->SLAVE.CTRLA &= (~TWI_SLAVE_ENABLE_bm);
}
/**
* \}
*/
#endif /* TWIS_H */
@@ -1,464 +1,464 @@
/**
* \file
*
* \brief USART driver for AVR XMEGA.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <stdint.h>
#include "compiler.h"
#include "usart.h"
#include "sysclk.h"
#include "ioport.h"
#include "status_codes.h"
/*
* Fix XMEGA header files
* USART.CTRLC bit masks and bit positions
*/
#ifndef USART_UCPHA_bm
# define USART_UCPHA_bm 0x02
#endif
#ifndef USART_DORD_bm
# define USART_DORD_bm 0x04
#endif
/**
* \brief Initialize USART in RS232 mode.
*
* This function initializes the USART module in RS232 mode using the
* usart_rs232_options_t configuration structure and CPU frequency.
*
* \param usart The USART module.
* \param opt The RS232 configuration option.
*
* \retval true if the initialization was successfull
* \retval false if the initialization failed (error in baud rate calculation)
*/
bool usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt)
{
bool result;
sysclk_enable_peripheral_clock(usart);
usart_set_mode(usart, USART_CMODE_ASYNCHRONOUS_gc);
usart_format_set(usart, opt->charlength, opt->paritytype,
opt->stopbits);
result = usart_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz());
usart_tx_enable(usart);
usart_rx_enable(usart);
return result;
}
/**
* \brief Initialize USART in SPI master mode.
*
* This function initializes the USART module in SPI master mode using the
* usart_spi_options_t configuration structure and CPU frequency.
*
* \param usart The USART module.
* \param opt The RS232 configuration option.
*/
void usart_init_spi(USART_t *usart, const usart_spi_options_t *opt)
{
ioport_pin_t sck_pin;
bool invert_sck;
sysclk_enable_peripheral_clock(usart);
usart_rx_disable(usart);
/* configure Clock polarity using INVEN bit of the correct SCK I/O port **/
invert_sck = (opt->spimode == 2) || (opt->spimode == 3);
UNUSED(invert_sck);
#ifdef USARTC0
if ((uint16_t)usart == (uint16_t)&USARTC0) {
# ifdef PORT_USART0_bm
if (PORTC.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTC, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTC, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTC, 1);
# endif
}
#endif
#ifdef USARTC1
if ((uint16_t)usart == (uint16_t)&USARTC1) {
sck_pin = IOPORT_CREATE_PIN(PORTC, 5);
}
#endif
#ifdef USARTD0
if ((uint16_t)usart == (uint16_t)&USARTD0) {
# ifdef PORT_USART0_bm
if (PORTD.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTD, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTD, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTD, 1);
# endif
}
#endif
#ifdef USARTD1
if ((uint16_t)usart == (uint16_t)&USARTD1) {
sck_pin = IOPORT_CREATE_PIN(PORTD, 5);
}
#endif
#ifdef USARTE0
if ((uint16_t)usart == (uint16_t)&USARTE0) {
# ifdef PORT_USART0_bm
if(PORTE.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTE, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTE, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTE, 1);
# endif
}
#endif
#ifdef USARTE1
if ((uint16_t)usart == (uint16_t)&USARTE1) {
sck_pin = IOPORT_CREATE_PIN(PORTE, 5);
}
#endif
#ifdef USARTF0
if ((uint16_t)usart == (uint16_t)&USARTF0) {
# ifdef PORT_USART0_bm
if(PORTF.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTF, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTF, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTF, 1);
# endif
}
#endif
#ifdef USARTF1
if ((uint16_t)usart == (uint16_t)&USARTF1) {
sck_pin = IOPORT_CREATE_PIN(PORTF, 5);
}
#endif
/* Configure the USART output pin */
ioport_set_pin_dir(sck_pin, IOPORT_DIR_OUTPUT);
ioport_set_pin_mode(sck_pin,
IOPORT_MODE_TOTEM | (invert_sck? IOPORT_MODE_INVERT_PIN : 0));
ioport_set_pin_level(sck_pin, IOPORT_PIN_LEVEL_HIGH);
usart_set_mode(usart, USART_CMODE_MSPI_gc);
if (opt->spimode == 1 || opt->spimode == 3) {
usart->CTRLC |= USART_UCPHA_bm;
} else {
usart->CTRLC &= ~USART_UCPHA_bm;
}
if (opt->data_order) {
(usart)->CTRLC |= USART_DORD_bm;
} else {
(usart)->CTRLC &= ~USART_DORD_bm;
}
usart_spi_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz());
usart_tx_enable(usart);
usart_rx_enable(usart);
}
/**
* \brief Send a data with the USART module
*
* This function outputs a data using the USART module.
*
* \param usart The USART module.
* \param c The data to send.
*
* \return STATUS_OK
*/
status_code_t usart_putchar(USART_t *usart, uint8_t c)
{
while (usart_data_register_is_empty(usart) == false) {
}
(usart)->DATA = c;
return STATUS_OK;
}
/**
* \brief Receive a data with the USART module
*
* This function returns the received data from the USART module.
*
* \param usart The USART module.
*
* \return The received data.
*/
uint8_t usart_getchar(USART_t *usart)
{
while (usart_rx_is_complete(usart) == false) {
}
return ((uint8_t)(usart)->DATA);
}
/**
* \brief Get the offset for lookup in the baudrate table
*
* \param baud The requested baudrate
*
* \return The baudrate offset in PROGMEM table
* \retval USART_BAUD_UNDEFINED for baudrates not in lookup table
*/
static uint8_t usart_get_baud_offset(uint32_t baud)
{
switch (baud) {
case 1200:
return (uint8_t)USART_BAUD_1200;
case 2400:
return (uint8_t)USART_BAUD_2400;
case 4800:
return (uint8_t)USART_BAUD_4800;
case 9600:
return (uint8_t)USART_BAUD_9600;
case 19200:
return (uint8_t)USART_BAUD_19200;
case 38400:
return (uint8_t)USART_BAUD_38400;
case 57600:
return (uint8_t)USART_BAUD_57600;
default:
return (uint8_t)USART_BAUD_UNDEFINED;
}
}
/**
* \brief Set the baudrate by setting the BSEL and BSCALE values in the USART
*
* This function sets the selected BSEL and BSCALE value in the BAUDCTRL
* registers with BSCALE 0. For calculation options, see table 21-1 in XMEGA A
* manual.
*
* \param usart The USART module.
* \param bsel Calculated BSEL value.
* \param bscale Calculated BSEL value.
*
*/
void usart_set_bsel_bscale_value(USART_t *usart, uint16_t bsel, uint8_t bscale)
{
(usart)->BAUDCTRLA = (uint8_t)(bsel);
(usart)->BAUDCTRLB = (uint8_t)(((bsel >> 8) & 0X0F) | (bscale << 4));
}
/**
* \brief Set the baudrate using precalculated BAUDCTRL values from PROGMEM
*
* \note This function only works for cpu_hz 2Mhz or 32Mhz and baudrate values
* 1200, 2400, 4800, 9600, 19200, 38400 and 57600.
*
* \param usart The USART module.
* \param baud The baudrate.
* \param cpu_hz The CPU frequency.
*
*/
void usart_set_baudrate_precalculated(USART_t *usart, uint32_t baud,
uint32_t cpu_hz)
{
uint8_t baud_offset;
uint16_t baudctrl = 0;
baud_offset = usart_get_baud_offset(baud);
if (cpu_hz == 2000000UL) {
baudctrl = PROGMEM_READ_WORD(baudctrl_2mhz + baud_offset);
} else if (cpu_hz == 32000000UL) {
baudctrl = PROGMEM_READ_WORD(baudctrl_32mhz + baud_offset);
} else {
/* Error, system clock speed or USART baud rate is not supported
* by the look-up table */
Assert(false);
}
if (baud_offset != USART_BAUD_UNDEFINED) {
(usart)->BAUDCTRLB = (uint8_t)((uint16_t)baudctrl);
(usart)->BAUDCTRLA = (uint8_t)((uint16_t)baudctrl >> 8);
}
}
/**
* \brief Set the baudrate value in the USART module
*
* This function sets the baudrate register with scaling regarding the CPU
* frequency and makes sure the baud rate is supported by the hardware.
* The function can be used if you don't want to calculate the settings
* yourself or changes to baudrate at runtime is required.
*
* \param usart The USART module.
* \param baud The baudrate.
* \param cpu_hz The CPU frequency.
*
* \retval true if the hardware supports the baud rate
* \retval false if the hardware does not support the baud rate (i.e. it's
* either too high or too low.)
*/
bool usart_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz)
{
int8_t exp;
uint32_t div;
uint32_t limit;
uint32_t ratio;
uint32_t min_rate;
uint32_t max_rate;
/*
* Check if the hardware supports the given baud rate
*/
/* 8 = (2^0) * 8 * (2^0) = (2^BSCALE_MIN) * 8 * (BSEL_MIN) */
max_rate = cpu_hz / 8;
/* 4194304 = (2^7) * 8 * (2^12) = (2^BSCALE_MAX) * 8 * (BSEL_MAX+1) */
min_rate = cpu_hz / 4194304;
if (!((usart)->CTRLB & USART_CLK2X_bm)) {
max_rate /= 2;
min_rate /= 2;
}
if ((baud > max_rate) || (baud < min_rate)) {
return false;
}
/* Check if double speed is enabled. */
if (!((usart)->CTRLB & USART_CLK2X_bm)) {
baud *= 2;
}
/* Find the lowest possible exponent. */
limit = 0xfffU >> 4;
ratio = cpu_hz / baud;
for (exp = -7; exp < 7; exp++) {
if (ratio < limit) {
break;
}
limit <<= 1;
if (exp < -3) {
limit |= 1;
}
}
/*
* Depending on the value of exp, scale either the input frequency or
* the target baud rate. By always scaling upwards, we never introduce
* any additional inaccuracy.
*
* We are including the final divide-by-8 (aka. right-shift-by-3) in
* this operation as it ensures that we never exceeed 2**32 at any
* point.
*
* The formula for calculating BSEL is slightly different when exp is
* negative than it is when exp is positive.
*/
if (exp < 0) {
/* We are supposed to subtract 1, then apply BSCALE. We want to
* apply BSCALE first, so we need to turn everything inside the
* parenthesis into a single fractional expression.
*/
cpu_hz -= 8 * baud;
/* If we end up with a left-shift after taking the final
* divide-by-8 into account, do the shift before the divide.
* Otherwise, left-shift the denominator instead (effectively
* resulting in an overall right shift.)
*/
if (exp <= -3) {
div = ((cpu_hz << (-exp - 3)) + baud / 2) / baud;
} else {
baud <<= exp + 3;
div = (cpu_hz + baud / 2) / baud;
}
} else {
/* We will always do a right shift in this case, but we need to
* shift three extra positions because of the divide-by-8.
*/
baud <<= exp + 3;
div = (cpu_hz + baud / 2) / baud - 1;
}
(usart)->BAUDCTRLB = (uint8_t)(((div >> 8) & 0X0F) | (exp << 4));
(usart)->BAUDCTRLA = (uint8_t)div;
return true;
}
/**
* \brief Set the baudrate value in the USART_SPI module
*
* This function sets the baudrate register regarding the CPU frequency.
*
* \param usart The USART(SPI) module.
* \param baud The baudrate.
* \param cpu_hz The CPU frequency.
*/
void usart_spi_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz)
{
uint16_t bsel_value;
/* Check if baudrate is less than the maximim limit specified in
* datasheet */
if (baud < (cpu_hz / 2)) {
bsel_value = (cpu_hz / (baud * 2)) - 1;
} else {
/* If baudrate is not within the specfication in datasheet,
* assign maximum baudrate possible for the current CPU frequency */
bsel_value = 0;
}
(usart)->BAUDCTRLB = (uint8_t)((~USART_BSCALE_gm) & (bsel_value >> 8));
(usart)->BAUDCTRLA = (uint8_t)(bsel_value);
}
/**
* \file
*
* \brief USART driver for AVR XMEGA.
*
* Copyright (c) 2009-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <stdint.h>
#include "compiler.h"
#include "usart.h"
#include "sysclk.h"
#include "ioport.h"
#include "status_codes.h"
/*
* Fix XMEGA header files
* USART.CTRLC bit masks and bit positions
*/
#ifndef USART_UCPHA_bm
# define USART_UCPHA_bm 0x02
#endif
#ifndef USART_DORD_bm
# define USART_DORD_bm 0x04
#endif
/**
* \brief Initialize USART in RS232 mode.
*
* This function initializes the USART module in RS232 mode using the
* usart_rs232_options_t configuration structure and CPU frequency.
*
* \param usart The USART module.
* \param opt The RS232 configuration option.
*
* \retval true if the initialization was successfull
* \retval false if the initialization failed (error in baud rate calculation)
*/
bool usart_init_rs232(USART_t *usart, const usart_rs232_options_t *opt)
{
bool result;
sysclk_enable_peripheral_clock(usart);
usart_set_mode(usart, USART_CMODE_ASYNCHRONOUS_gc);
usart_format_set(usart, opt->charlength, opt->paritytype,
opt->stopbits);
result = usart_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz());
usart_tx_enable(usart);
usart_rx_enable(usart);
return result;
}
/**
* \brief Initialize USART in SPI master mode.
*
* This function initializes the USART module in SPI master mode using the
* usart_spi_options_t configuration structure and CPU frequency.
*
* \param usart The USART module.
* \param opt The RS232 configuration option.
*/
void usart_init_spi(USART_t *usart, const usart_spi_options_t *opt)
{
ioport_pin_t sck_pin;
bool invert_sck;
sysclk_enable_peripheral_clock(usart);
usart_rx_disable(usart);
/* configure Clock polarity using INVEN bit of the correct SCK I/O port **/
invert_sck = (opt->spimode == 2) || (opt->spimode == 3);
UNUSED(invert_sck);
#ifdef USARTC0
if ((uint16_t)usart == (uint16_t)&USARTC0) {
# ifdef PORT_USART0_bm
if (PORTC.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTC, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTC, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTC, 1);
# endif
}
#endif
#ifdef USARTC1
if ((uint16_t)usart == (uint16_t)&USARTC1) {
sck_pin = IOPORT_CREATE_PIN(PORTC, 5);
}
#endif
#ifdef USARTD0
if ((uint16_t)usart == (uint16_t)&USARTD0) {
# ifdef PORT_USART0_bm
if (PORTD.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTD, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTD, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTD, 1);
# endif
}
#endif
#ifdef USARTD1
if ((uint16_t)usart == (uint16_t)&USARTD1) {
sck_pin = IOPORT_CREATE_PIN(PORTD, 5);
}
#endif
#ifdef USARTE0
if ((uint16_t)usart == (uint16_t)&USARTE0) {
# ifdef PORT_USART0_bm
if(PORTE.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTE, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTE, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTE, 1);
# endif
}
#endif
#ifdef USARTE1
if ((uint16_t)usart == (uint16_t)&USARTE1) {
sck_pin = IOPORT_CREATE_PIN(PORTE, 5);
}
#endif
#ifdef USARTF0
if ((uint16_t)usart == (uint16_t)&USARTF0) {
# ifdef PORT_USART0_bm
if(PORTF.REMAP & PORT_USART0_bm) {
sck_pin = IOPORT_CREATE_PIN(PORTF, 5);
} else {
sck_pin = IOPORT_CREATE_PIN(PORTF, 1);
}
# else
sck_pin = IOPORT_CREATE_PIN(PORTF, 1);
# endif
}
#endif
#ifdef USARTF1
if ((uint16_t)usart == (uint16_t)&USARTF1) {
sck_pin = IOPORT_CREATE_PIN(PORTF, 5);
}
#endif
/* Configure the USART output pin */
ioport_set_pin_dir(sck_pin, IOPORT_DIR_OUTPUT);
ioport_set_pin_mode(sck_pin,
IOPORT_MODE_TOTEM | (invert_sck? IOPORT_MODE_INVERT_PIN : 0));
ioport_set_pin_level(sck_pin, IOPORT_PIN_LEVEL_HIGH);
usart_set_mode(usart, USART_CMODE_MSPI_gc);
if (opt->spimode == 1 || opt->spimode == 3) {
usart->CTRLC |= USART_UCPHA_bm;
} else {
usart->CTRLC &= ~USART_UCPHA_bm;
}
if (opt->data_order) {
(usart)->CTRLC |= USART_DORD_bm;
} else {
(usart)->CTRLC &= ~USART_DORD_bm;
}
usart_spi_set_baudrate(usart, opt->baudrate, sysclk_get_per_hz());
usart_tx_enable(usart);
usart_rx_enable(usart);
}
/**
* \brief Send a data with the USART module
*
* This function outputs a data using the USART module.
*
* \param usart The USART module.
* \param c The data to send.
*
* \return STATUS_OK
*/
status_code_t usart_putchar(USART_t *usart, uint8_t c)
{
while (usart_data_register_is_empty(usart) == false) {
}
(usart)->DATA = c;
return STATUS_OK;
}
/**
* \brief Receive a data with the USART module
*
* This function returns the received data from the USART module.
*
* \param usart The USART module.
*
* \return The received data.
*/
uint8_t usart_getchar(USART_t *usart)
{
while (usart_rx_is_complete(usart) == false) {
}
return ((uint8_t)(usart)->DATA);
}
/**
* \brief Get the offset for lookup in the baudrate table
*
* \param baud The requested baudrate
*
* \return The baudrate offset in PROGMEM table
* \retval USART_BAUD_UNDEFINED for baudrates not in lookup table
*/
static uint8_t usart_get_baud_offset(uint32_t baud)
{
switch (baud) {
case 1200:
return (uint8_t)USART_BAUD_1200;
case 2400:
return (uint8_t)USART_BAUD_2400;
case 4800:
return (uint8_t)USART_BAUD_4800;
case 9600:
return (uint8_t)USART_BAUD_9600;
case 19200:
return (uint8_t)USART_BAUD_19200;
case 38400:
return (uint8_t)USART_BAUD_38400;
case 57600:
return (uint8_t)USART_BAUD_57600;
default:
return (uint8_t)USART_BAUD_UNDEFINED;
}
}
/**
* \brief Set the baudrate by setting the BSEL and BSCALE values in the USART
*
* This function sets the selected BSEL and BSCALE value in the BAUDCTRL
* registers with BSCALE 0. For calculation options, see table 21-1 in XMEGA A
* manual.
*
* \param usart The USART module.
* \param bsel Calculated BSEL value.
* \param bscale Calculated BSEL value.
*
*/
void usart_set_bsel_bscale_value(USART_t *usart, uint16_t bsel, uint8_t bscale)
{
(usart)->BAUDCTRLA = (uint8_t)(bsel);
(usart)->BAUDCTRLB = (uint8_t)(((bsel >> 8) & 0X0F) | (bscale << 4));
}
/**
* \brief Set the baudrate using precalculated BAUDCTRL values from PROGMEM
*
* \note This function only works for cpu_hz 2Mhz or 32Mhz and baudrate values
* 1200, 2400, 4800, 9600, 19200, 38400 and 57600.
*
* \param usart The USART module.
* \param baud The baudrate.
* \param cpu_hz The CPU frequency.
*
*/
void usart_set_baudrate_precalculated(USART_t *usart, uint32_t baud,
uint32_t cpu_hz)
{
uint8_t baud_offset;
uint16_t baudctrl = 0;
baud_offset = usart_get_baud_offset(baud);
if (cpu_hz == 2000000UL) {
baudctrl = PROGMEM_READ_WORD(baudctrl_2mhz + baud_offset);
} else if (cpu_hz == 32000000UL) {
baudctrl = PROGMEM_READ_WORD(baudctrl_32mhz + baud_offset);
} else {
/* Error, system clock speed or USART baud rate is not supported
* by the look-up table */
Assert(false);
}
if (baud_offset != USART_BAUD_UNDEFINED) {
(usart)->BAUDCTRLB = (uint8_t)((uint16_t)baudctrl);
(usart)->BAUDCTRLA = (uint8_t)((uint16_t)baudctrl >> 8);
}
}
/**
* \brief Set the baudrate value in the USART module
*
* This function sets the baudrate register with scaling regarding the CPU
* frequency and makes sure the baud rate is supported by the hardware.
* The function can be used if you don't want to calculate the settings
* yourself or changes to baudrate at runtime is required.
*
* \param usart The USART module.
* \param baud The baudrate.
* \param cpu_hz The CPU frequency.
*
* \retval true if the hardware supports the baud rate
* \retval false if the hardware does not support the baud rate (i.e. it's
* either too high or too low.)
*/
bool usart_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz)
{
int8_t exp;
uint32_t div;
uint32_t limit;
uint32_t ratio;
uint32_t min_rate;
uint32_t max_rate;
/*
* Check if the hardware supports the given baud rate
*/
/* 8 = (2^0) * 8 * (2^0) = (2^BSCALE_MIN) * 8 * (BSEL_MIN) */
max_rate = cpu_hz / 8;
/* 4194304 = (2^7) * 8 * (2^12) = (2^BSCALE_MAX) * 8 * (BSEL_MAX+1) */
min_rate = cpu_hz / 4194304;
if (!((usart)->CTRLB & USART_CLK2X_bm)) {
max_rate /= 2;
min_rate /= 2;
}
if ((baud > max_rate) || (baud < min_rate)) {
return false;
}
/* Check if double speed is enabled. */
if (!((usart)->CTRLB & USART_CLK2X_bm)) {
baud *= 2;
}
/* Find the lowest possible exponent. */
limit = 0xfffU >> 4;
ratio = cpu_hz / baud;
for (exp = -7; exp < 7; exp++) {
if (ratio < limit) {
break;
}
limit <<= 1;
if (exp < -3) {
limit |= 1;
}
}
/*
* Depending on the value of exp, scale either the input frequency or
* the target baud rate. By always scaling upwards, we never introduce
* any additional inaccuracy.
*
* We are including the final divide-by-8 (aka. right-shift-by-3) in
* this operation as it ensures that we never exceeed 2**32 at any
* point.
*
* The formula for calculating BSEL is slightly different when exp is
* negative than it is when exp is positive.
*/
if (exp < 0) {
/* We are supposed to subtract 1, then apply BSCALE. We want to
* apply BSCALE first, so we need to turn everything inside the
* parenthesis into a single fractional expression.
*/
cpu_hz -= 8 * baud;
/* If we end up with a left-shift after taking the final
* divide-by-8 into account, do the shift before the divide.
* Otherwise, left-shift the denominator instead (effectively
* resulting in an overall right shift.)
*/
if (exp <= -3) {
div = ((cpu_hz << (-exp - 3)) + baud / 2) / baud;
} else {
baud <<= exp + 3;
div = (cpu_hz + baud / 2) / baud;
}
} else {
/* We will always do a right shift in this case, but we need to
* shift three extra positions because of the divide-by-8.
*/
baud <<= exp + 3;
div = (cpu_hz + baud / 2) / baud - 1;
}
(usart)->BAUDCTRLB = (uint8_t)(((div >> 8) & 0X0F) | (exp << 4));
(usart)->BAUDCTRLA = (uint8_t)div;
return true;
}
/**
* \brief Set the baudrate value in the USART_SPI module
*
* This function sets the baudrate register regarding the CPU frequency.
*
* \param usart The USART(SPI) module.
* \param baud The baudrate.
* \param cpu_hz The CPU frequency.
*/
void usart_spi_set_baudrate(USART_t *usart, uint32_t baud, uint32_t cpu_hz)
{
uint16_t bsel_value;
/* Check if baudrate is less than the maximim limit specified in
* datasheet */
if (baud < (cpu_hz / 2)) {
bsel_value = (cpu_hz / (baud * 2)) - 1;
} else {
/* If baudrate is not within the specfication in datasheet,
* assign maximum baudrate possible for the current CPU frequency */
bsel_value = 0;
}
(usart)->BAUDCTRLB = (uint8_t)((~USART_BSCALE_gm) & (bsel_value >> 8));
(usart)->BAUDCTRLA = (uint8_t)(bsel_value);
}
File diff suppressed because it is too large Load Diff
@@ -1,216 +1,216 @@
/**
* \file
*
* \brief AVR XMEGA WatchDog Timer driver.
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "compiler.h"
#include "ccp.h"
#include "wdt.h"
/*! \brief Set Watchdog timeout period.
*
* This function sets the coded field of the WDT timeout period.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param to_period WDT timeout coded period
*/
void wdt_set_timeout_period(enum wdt_timeout_period_t to_period)
{
uint8_t temp = (WDT_PER_gm & (to_period << WDT_PER_gp)) |
(WDT.CTRL & WDT_ENABLE_bm) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
wdt_wait_while_busy();
}
/*! \brief Set Watchdog window period.
*
* This function sets the coded field of the WDT closed window period.
* Note that this setting is available only if the WDT is enabled (hardware
* behaviour relayed by software).
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param win_period Window coded period
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_set_window_period(enum wdt_window_period_t win_period)
{
if (!(wdt_is_enabled())) {
return false;
}
uint8_t temp = (WDT_WPER_gm & (win_period << WDT_WPER_gp)) |
(WDT.WINCTRL & WDT_WEN_bm) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
wdt_wait_while_busy();
return true;
}
/*! \brief Disable Watchdog.
*
* This function disables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*/
void wdt_disable(void)
{
uint8_t temp = (WDT.CTRL & ~WDT_ENABLE_bm) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
}
/*! \brief Enable Watchdog.
*
* This function enables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*/
void wdt_enable(void)
{
uint8_t temp = (WDT.CTRL & WDT_PER_gm) |
(1 << WDT_ENABLE_bp) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
wdt_wait_while_busy();
}
/*! \brief Disable Watchdog window mode without changing period settings.
*
* This function disables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*
* \retval true The WDT was enabled and the window mode is disabled.
* false The WDT (& the window mode) is already disabled.
*/
bool wdt_disable_window_mode(void)
{
if (!(wdt_is_enabled())) {
return false;
}
uint8_t temp = (WDT.WINCTRL & ~WDT_WEN_bm) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
return true;
}
/*! \brief Enable Watchdog window mode.
*
* This function enables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_enable_window_mode(void)
{
if (!(wdt_is_enabled())) {
return false;
}
uint8_t temp = (WDT.WINCTRL & WDT_WPER_gm) |
(1 << WDT_WEN_bp) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
wdt_wait_while_busy();
return true;
}
/*! \brief Reset MCU via Watchdog.
*
* This function generates an hardware microcontroller reset using the WDT.
*
* The function loads enables the WDT in window mode. Executing a "wdr" asm
* instruction when the windows is closed, provides a quick mcu reset.
*
*/
void wdt_reset_mcu(void)
{
uint8_t temp;
/*
* WDT enabled (minimum timeout period for max. security)
*/
temp = WDT_PER_8CLK_gc | (1 << WDT_ENABLE_bp) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
wdt_wait_while_busy();
/*
* WDT enabled (maximum window period for max. security)
*/
temp = WDT_WPER_8KCLK_gc | (1 << WDT_WEN_bp) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
wdt_wait_while_busy();
/*
* WDT Reset during window => WDT generates an Hard Reset.
*/
wdt_reset();
/*
* No exit to prevent the execution of the following instructions.
*/
while (true) {
/* Wait for Watchdog reset. */
}
}
/**
* \file
*
* \brief AVR XMEGA WatchDog Timer driver.
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include "compiler.h"
#include "ccp.h"
#include "wdt.h"
/*! \brief Set Watchdog timeout period.
*
* This function sets the coded field of the WDT timeout period.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param to_period WDT timeout coded period
*/
void wdt_set_timeout_period(enum wdt_timeout_period_t to_period)
{
uint8_t temp = (WDT_PER_gm & (to_period << WDT_PER_gp)) |
(WDT.CTRL & WDT_ENABLE_bm) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
wdt_wait_while_busy();
}
/*! \brief Set Watchdog window period.
*
* This function sets the coded field of the WDT closed window period.
* Note that this setting is available only if the WDT is enabled (hardware
* behaviour relayed by software).
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param win_period Window coded period
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_set_window_period(enum wdt_window_period_t win_period)
{
if (!(wdt_is_enabled())) {
return false;
}
uint8_t temp = (WDT_WPER_gm & (win_period << WDT_WPER_gp)) |
(WDT.WINCTRL & WDT_WEN_bm) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
wdt_wait_while_busy();
return true;
}
/*! \brief Disable Watchdog.
*
* This function disables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*/
void wdt_disable(void)
{
uint8_t temp = (WDT.CTRL & ~WDT_ENABLE_bm) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
}
/*! \brief Enable Watchdog.
*
* This function enables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*/
void wdt_enable(void)
{
uint8_t temp = (WDT.CTRL & WDT_PER_gm) |
(1 << WDT_ENABLE_bp) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
wdt_wait_while_busy();
}
/*! \brief Disable Watchdog window mode without changing period settings.
*
* This function disables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*
* \retval true The WDT was enabled and the window mode is disabled.
* false The WDT (& the window mode) is already disabled.
*/
bool wdt_disable_window_mode(void)
{
if (!(wdt_is_enabled())) {
return false;
}
uint8_t temp = (WDT.WINCTRL & ~WDT_WEN_bm) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
return true;
}
/*! \brief Enable Watchdog window mode.
*
* This function enables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_enable_window_mode(void)
{
if (!(wdt_is_enabled())) {
return false;
}
uint8_t temp = (WDT.WINCTRL & WDT_WPER_gm) |
(1 << WDT_WEN_bp) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
wdt_wait_while_busy();
return true;
}
/*! \brief Reset MCU via Watchdog.
*
* This function generates an hardware microcontroller reset using the WDT.
*
* The function loads enables the WDT in window mode. Executing a "wdr" asm
* instruction when the windows is closed, provides a quick mcu reset.
*
*/
void wdt_reset_mcu(void)
{
uint8_t temp;
/*
* WDT enabled (minimum timeout period for max. security)
*/
temp = WDT_PER_8CLK_gc | (1 << WDT_ENABLE_bp) | (1 << WDT_CEN_bp);
ccp_write_io((void *)&WDT.CTRL, temp);
wdt_wait_while_busy();
/*
* WDT enabled (maximum window period for max. security)
*/
temp = WDT_WPER_8KCLK_gc | (1 << WDT_WEN_bp) | (1 << WDT_WCEN_bp);
ccp_write_io((void *)&WDT.WINCTRL, temp);
wdt_wait_while_busy();
/*
* WDT Reset during window => WDT generates an Hard Reset.
*/
wdt_reset();
/*
* No exit to prevent the execution of the following instructions.
*/
while (true) {
/* Wait for Watchdog reset. */
}
}
@@ -1,420 +1,420 @@
/**
* \file
*
* \brief AVR XMEGA WatchDog Timer driver.
*
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _WDT_H_
#define _WDT_H_
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
#include "compiler.h"
/**
* \defgroup wdt_group Watchdog Timer (WDT)
*
* See \ref wdt_quickstart.
*
* This is a driver for configuring, enabling, disabling and use of the on-chip
* WDT.
*
* \section dependencies Dependencies
*
* The WDT module depends on the following modules:
* - \ref ccp_group for writing in a CCP-protected 8-bit I/O register.
*
* @{
*/
//! Watchdog timeout period setting
enum wdt_timeout_period_t {
//! Timeout period = 8 cycles or 8 ms @ 3.3V
WDT_TIMEOUT_PERIOD_8CLK = (0x00),
//! Timeout period = 16 cycles or 16 ms @ 3.3V
WDT_TIMEOUT_PERIOD_16CLK = (0x01),
//! Timeout period = 32 cycles or 32m s @ 3.3V
WDT_TIMEOUT_PERIOD_32CLK = (0x02),
//! Timeout period = 64 cycles or 64ms @ 3.3V
WDT_TIMEOUT_PERIOD_64CLK = (0x03),
//! Timeout period = 125 cycles or 125ms @ 3.3V
WDT_TIMEOUT_PERIOD_125CLK = (0x04),
//! 250 cycles or 250ms @ 3.3V)
WDT_TIMEOUT_PERIOD_250CLK = (0x05),
//! Timeout period = 500 cycles or 500ms @ 3.3V
WDT_TIMEOUT_PERIOD_500CLK = (0x06),
//! Timeout period =1K cycles or 1s @ 3.3V
WDT_TIMEOUT_PERIOD_1KCLK = (0x07),
//! Timeout period = 2K cycles or 2s @ 3.3V
WDT_TIMEOUT_PERIOD_2KCLK = (0x08),
//! Timeout period = 4K cycles or 4s @ 3.3V
WDT_TIMEOUT_PERIOD_4KCLK = (0x09),
//! Timeout period = 8K cycles or 8s @ 3.3V
WDT_TIMEOUT_PERIOD_8KCLK = (0x0A),
};
//! Watchdog window period setting
enum wdt_window_period_t {
//! Window period = 8 cycles or 8 ms @ 3.3V
WDT_WINDOW_PERIOD_8CLK = (0x00),
//! Window period = 16 cycles or 16 ms @ 3.3V
WDT_WINDOW_PERIOD_16CLK = (0x01),
//! Window period = 32 cycles or 32m s @ 3.3V
WDT_WINDOW_PERIOD_32CLK = (0x02),
//! Window period = 64 cycles or 64ms @ 3.3V
WDT_WINDOW_PERIOD_64CLK = (0x03),
//! Window period = 125 cycles or 125ms @ 3.3V
WDT_WINDOW_PERIOD_125CLK = (0x04),
//! 250 cycles or 250ms @ 3.3V)
WDT_WINDOW_PERIOD_250CLK = (0x05),
//! Window period = 500 cycles or 500ms @ 3.3V
WDT_WINDOW_PERIOD_500CLK = (0x06),
//! Window period =1K cycles or 1s @ 3.3V
WDT_WINDOW_PERIOD_1KCLK = (0x07),
//! Window period = 2K cycles or 2s @ 3.3V
WDT_WINDOW_PERIOD_2KCLK = (0x08),
//! Window period = 4K cycles or 4s @ 3.3V
WDT_WINDOW_PERIOD_4KCLK = (0x09),
//! Window period = 8K cycles or 8s @ 3.3V
WDT_WINDOW_PERIOD_8KCLK = (0x0A),
};
/*! \brief This macro resets (clears/refreshes) the Watchdog Timer.
*/
#if defined(__GNUC__)
#define wdt_reset() __asm__ __volatile__("wdr");
#elif defined(__ICCAVR__)
#define wdt_reset() __watchdog_reset();
#else
#error Unsupported compiler.
#endif
/*! \brief Wait until WD settings are synchronized to the WD clock domain.
*
*/
static inline void wdt_wait_while_busy(void)
{
while ((WDT.STATUS & WDT_SYNCBUSY_bm) == WDT_SYNCBUSY_bm) {
// Wait until synchronization
}
}
/*! \brief Check if the Watchdog Enable flag is set.
*
* \retval false WDT disabled
* true WDT enabled
*/
static inline bool wdt_is_enabled(void)
{
return ((WDT.CTRL & WDT_ENABLE_bm) == WDT_ENABLE_bm);
}
/*! \brief Check if the Watchdog Window mode flag is set.
*
* \retval false WDT Window disabled
* true WDT Window enabled
*/
static inline bool wdt_window_mode_is_enabled(void)
{
return ((WDT.WINCTRL & WDT_WEN_bm) == WDT_WEN_bm);
}
/*! \brief Gets the Watchdog timeout period.
*
* This function reads the value of the WDT timeout period.
*
* \retval The WDT timeout period.
*/
static inline enum wdt_timeout_period_t wdt_get_timeout_period(void)
{
return ((enum wdt_timeout_period_t)
((WDT.CTRL & WDT_PER_gm) >> WDT_PER_gp));
}
/*! \brief Gets the Watchdog window period.
*
* This function reads the value of the WDT closed window coded period.
*
* \retval The WDT window period.
*/
static inline enum wdt_window_period_t wdt_get_window_period(void)
{
return ((enum wdt_window_period_t)
((WDT.WINCTRL & WDT_WPER_gm) >> WDT_WPER_gp));
}
/*! \brief Set Watchdog timeout period.
*
* This function sets the coded field of the WDT timeout period.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param to_period WDT timeout coded period
*/
void wdt_set_timeout_period(enum wdt_timeout_period_t to_period);
/*! \brief Set Watchdog window period.
*
* This function sets the coded field of the WDT closed window period.
* Note that this setting is available only if the WDT is enabled (hardware
* behaviour relayed by software).
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param win_period Window coded period
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_set_window_period(enum wdt_window_period_t win_period);
/*! \brief Disable Watchdog.
*
* This function disables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*/
void wdt_disable(void);
/*! \brief Enable Watchdog.
*
* This function enables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*/
void wdt_enable(void);
/*! \brief Disable Watchdog window mode without changing period settings.
*
* This function disables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*
* \retval true The WDT was enabled and the window mode is disabled.
* false The WDT (& the window mode) is already disabled.
*/
bool wdt_disable_window_mode(void);
/*! \brief Enable Watchdog window mode.
*
* This function enables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_enable_window_mode(void);
/*! \brief Reset MCU via Watchdog.
*
* This function generates an hardware microcontroller reset using the WDT.
*
* The function loads enables the WDT in window mode. Executing a "wdr" asm
* instruction when the windows is closed, provides a quick mcu reset.
*
*/
void wdt_reset_mcu(void);
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
/**
* \page wdt_quickstart Quick start guide for WDT driver
*
* This is the quick start guide for the \ref wdt_group, with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section wdt_basic_use_case Basic use case
* \section wdt_use_cases WDT use cases
* - \ref wdt_basic_use_case
* - \subpage wdt_use_case_1
*
* \section wdt_basic_use_case Basic use case - Reset WDT in standard mode
* In this use case, the WDT is configured for:
* - Standard mode
* - Timeout period of 8 ms
*
* The use case enables the WDT, and resets it after 5 ms to prevent system
* reset after time out period of 8 ms.
*
* \section wdt_basic_use_case_setup Setup steps
*
* \subsection wdt_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref group_common_services_delay "Busy-Wait Delay Routines"
*
* \subsection wdt_basic_use_case_setup_code Example code
* Add to application initialization:
* \code
* wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_8CLK);
* wdt_enable();
* \endcode
*
* \subsection wdt_basic_use_case_setup_flow Workflow
* -# Set timeout period to 8 cycles or 8 ms:
* - \code wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_8CLK); \endcode
* -# Enable WDT:
* - \code wdt_enable(); \endcode
* \section wdt_basic_use_case_usage Usage steps
*
* \subsection wdt_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* delay_ms(5);
* wdt_reset();
* \endcode
*
* \subsection wdt_basic_use_case_usage_flow Workflow
* -# Wait for 5 ms:
* - \code delay_ms(5); \endcode
* -# Reset the WDT before the timeout period is over to prevent system reset:
* - \code wdt_reset(); \endcode
*/
/**
* \page wdt_use_case_1 Reset WDT in window mode
*
* In this use case, the WDT is configured for:
* - Window mode
* - Timeout period of 16 ms
*
* The use case enables the WDT in window mode, and resets it after 10 ms to
* prevent system reset before window timeout after 8 ms and after time out
* period of 16 ms.
*
* \section wdt_use_case_1_setup Setup steps
*
* \subsection usart_use_case_1_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref group_common_services_delay "Busy-Wait Delay Routines"
*
* \subsection wdt_use_case_1_setup_code Example code
* Add to application initialization:
* \code
* wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_16CLK);
* wdt_enable();
* wdt_set_window_period(WDT_TIMEOUT_PERIOD_8CLK);
* wdt_enable_window_mode();
* \endcode
*
* \subsection wdt_use_case_1_setup_flow Workflow
* -# Set timeout period to 16 cycles or 16 ms:
* - \code wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_16CLK); \endcode
* -# Enable WDT:
* - \code wdt_enable(); \endcode
* -# Set window period to 8 cycles or 8 ms:
* - \code wdt_set_window_period(WDT_TIMEOUT_PERIOD_8CLK); \endcode
* -# Enable window mode:
* - \code wdt_enable_window_mode(); \endcode
*
* \section wdt_use_case_1_usage Usage steps
*
* \subsection wdt_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* delay_ms(10);
* wdt_reset();
* \endcode
*
* \subsection wdt_use_case_1_usage_flow Workflow
* -# Wait for 10 ms to not reset the WDT before window timeout:
* - \code delay_ms(10); \endcode
* -# Reset the WDT before the timeout period is over to prevent system reset:
* - \code wdt_reset(); \endcode
*/
#endif // _WDT_H_
/**
* \file
*
* \brief AVR XMEGA WatchDog Timer driver.
*
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _WDT_H_
#define _WDT_H_
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
#include "compiler.h"
/**
* \defgroup wdt_group Watchdog Timer (WDT)
*
* See \ref wdt_quickstart.
*
* This is a driver for configuring, enabling, disabling and use of the on-chip
* WDT.
*
* \section dependencies Dependencies
*
* The WDT module depends on the following modules:
* - \ref ccp_group for writing in a CCP-protected 8-bit I/O register.
*
* @{
*/
//! Watchdog timeout period setting
enum wdt_timeout_period_t {
//! Timeout period = 8 cycles or 8 ms @ 3.3V
WDT_TIMEOUT_PERIOD_8CLK = (0x00),
//! Timeout period = 16 cycles or 16 ms @ 3.3V
WDT_TIMEOUT_PERIOD_16CLK = (0x01),
//! Timeout period = 32 cycles or 32m s @ 3.3V
WDT_TIMEOUT_PERIOD_32CLK = (0x02),
//! Timeout period = 64 cycles or 64ms @ 3.3V
WDT_TIMEOUT_PERIOD_64CLK = (0x03),
//! Timeout period = 125 cycles or 125ms @ 3.3V
WDT_TIMEOUT_PERIOD_125CLK = (0x04),
//! 250 cycles or 250ms @ 3.3V)
WDT_TIMEOUT_PERIOD_250CLK = (0x05),
//! Timeout period = 500 cycles or 500ms @ 3.3V
WDT_TIMEOUT_PERIOD_500CLK = (0x06),
//! Timeout period =1K cycles or 1s @ 3.3V
WDT_TIMEOUT_PERIOD_1KCLK = (0x07),
//! Timeout period = 2K cycles or 2s @ 3.3V
WDT_TIMEOUT_PERIOD_2KCLK = (0x08),
//! Timeout period = 4K cycles or 4s @ 3.3V
WDT_TIMEOUT_PERIOD_4KCLK = (0x09),
//! Timeout period = 8K cycles or 8s @ 3.3V
WDT_TIMEOUT_PERIOD_8KCLK = (0x0A),
};
//! Watchdog window period setting
enum wdt_window_period_t {
//! Window period = 8 cycles or 8 ms @ 3.3V
WDT_WINDOW_PERIOD_8CLK = (0x00),
//! Window period = 16 cycles or 16 ms @ 3.3V
WDT_WINDOW_PERIOD_16CLK = (0x01),
//! Window period = 32 cycles or 32m s @ 3.3V
WDT_WINDOW_PERIOD_32CLK = (0x02),
//! Window period = 64 cycles or 64ms @ 3.3V
WDT_WINDOW_PERIOD_64CLK = (0x03),
//! Window period = 125 cycles or 125ms @ 3.3V
WDT_WINDOW_PERIOD_125CLK = (0x04),
//! 250 cycles or 250ms @ 3.3V)
WDT_WINDOW_PERIOD_250CLK = (0x05),
//! Window period = 500 cycles or 500ms @ 3.3V
WDT_WINDOW_PERIOD_500CLK = (0x06),
//! Window period =1K cycles or 1s @ 3.3V
WDT_WINDOW_PERIOD_1KCLK = (0x07),
//! Window period = 2K cycles or 2s @ 3.3V
WDT_WINDOW_PERIOD_2KCLK = (0x08),
//! Window period = 4K cycles or 4s @ 3.3V
WDT_WINDOW_PERIOD_4KCLK = (0x09),
//! Window period = 8K cycles or 8s @ 3.3V
WDT_WINDOW_PERIOD_8KCLK = (0x0A),
};
/*! \brief This macro resets (clears/refreshes) the Watchdog Timer.
*/
#if defined(__GNUC__)
#define wdt_reset() __asm__ __volatile__("wdr");
#elif defined(__ICCAVR__)
#define wdt_reset() __watchdog_reset();
#else
#error Unsupported compiler.
#endif
/*! \brief Wait until WD settings are synchronized to the WD clock domain.
*
*/
static inline void wdt_wait_while_busy(void)
{
while ((WDT.STATUS & WDT_SYNCBUSY_bm) == WDT_SYNCBUSY_bm) {
// Wait until synchronization
}
}
/*! \brief Check if the Watchdog Enable flag is set.
*
* \retval false WDT disabled
* true WDT enabled
*/
static inline bool wdt_is_enabled(void)
{
return ((WDT.CTRL & WDT_ENABLE_bm) == WDT_ENABLE_bm);
}
/*! \brief Check if the Watchdog Window mode flag is set.
*
* \retval false WDT Window disabled
* true WDT Window enabled
*/
static inline bool wdt_window_mode_is_enabled(void)
{
return ((WDT.WINCTRL & WDT_WEN_bm) == WDT_WEN_bm);
}
/*! \brief Gets the Watchdog timeout period.
*
* This function reads the value of the WDT timeout period.
*
* \retval The WDT timeout period.
*/
static inline enum wdt_timeout_period_t wdt_get_timeout_period(void)
{
return ((enum wdt_timeout_period_t)
((WDT.CTRL & WDT_PER_gm) >> WDT_PER_gp));
}
/*! \brief Gets the Watchdog window period.
*
* This function reads the value of the WDT closed window coded period.
*
* \retval The WDT window period.
*/
static inline enum wdt_window_period_t wdt_get_window_period(void)
{
return ((enum wdt_window_period_t)
((WDT.WINCTRL & WDT_WPER_gm) >> WDT_WPER_gp));
}
/*! \brief Set Watchdog timeout period.
*
* This function sets the coded field of the WDT timeout period.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param to_period WDT timeout coded period
*/
void wdt_set_timeout_period(enum wdt_timeout_period_t to_period);
/*! \brief Set Watchdog window period.
*
* This function sets the coded field of the WDT closed window period.
* Note that this setting is available only if the WDT is enabled (hardware
* behaviour relayed by software).
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \param win_period Window coded period
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_set_window_period(enum wdt_window_period_t win_period);
/*! \brief Disable Watchdog.
*
* This function disables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*/
void wdt_disable(void);
/*! \brief Enable Watchdog.
*
* This function enables the WDT without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the CTRL register. Interrupts are
* automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*/
void wdt_enable(void);
/*! \brief Disable Watchdog window mode without changing period settings.
*
* This function disables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. Disable functions
* operate asynchronously with immediate effect.
*
* \retval true The WDT was enabled and the window mode is disabled.
* false The WDT (& the window mode) is already disabled.
*/
bool wdt_disable_window_mode(void);
/*! \brief Enable Watchdog window mode.
*
* This function enables the WDT window mode without changing period settings.
*
* The function writes the correct signature to the Configuration
* Change Protection register before writing the WINCTRL register. Interrupts
* are automatically ignored during the change enable period. The function will
* wait for the WDT to be synchronized to the WDT clock domain before
* proceeding
*
* \retval true The WDT was enabled and the setting is done.
* false The WDT is disabled and the setting is discarded.
*/
bool wdt_enable_window_mode(void);
/*! \brief Reset MCU via Watchdog.
*
* This function generates an hardware microcontroller reset using the WDT.
*
* The function loads enables the WDT in window mode. Executing a "wdr" asm
* instruction when the windows is closed, provides a quick mcu reset.
*
*/
void wdt_reset_mcu(void);
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
/**
* \page wdt_quickstart Quick start guide for WDT driver
*
* This is the quick start guide for the \ref wdt_group, with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section wdt_basic_use_case Basic use case
* \section wdt_use_cases WDT use cases
* - \ref wdt_basic_use_case
* - \subpage wdt_use_case_1
*
* \section wdt_basic_use_case Basic use case - Reset WDT in standard mode
* In this use case, the WDT is configured for:
* - Standard mode
* - Timeout period of 8 ms
*
* The use case enables the WDT, and resets it after 5 ms to prevent system
* reset after time out period of 8 ms.
*
* \section wdt_basic_use_case_setup Setup steps
*
* \subsection wdt_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref group_common_services_delay "Busy-Wait Delay Routines"
*
* \subsection wdt_basic_use_case_setup_code Example code
* Add to application initialization:
* \code
* wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_8CLK);
* wdt_enable();
* \endcode
*
* \subsection wdt_basic_use_case_setup_flow Workflow
* -# Set timeout period to 8 cycles or 8 ms:
* - \code wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_8CLK); \endcode
* -# Enable WDT:
* - \code wdt_enable(); \endcode
* \section wdt_basic_use_case_usage Usage steps
*
* \subsection wdt_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* delay_ms(5);
* wdt_reset();
* \endcode
*
* \subsection wdt_basic_use_case_usage_flow Workflow
* -# Wait for 5 ms:
* - \code delay_ms(5); \endcode
* -# Reset the WDT before the timeout period is over to prevent system reset:
* - \code wdt_reset(); \endcode
*/
/**
* \page wdt_use_case_1 Reset WDT in window mode
*
* In this use case, the WDT is configured for:
* - Window mode
* - Timeout period of 16 ms
*
* The use case enables the WDT in window mode, and resets it after 10 ms to
* prevent system reset before window timeout after 8 ms and after time out
* period of 16 ms.
*
* \section wdt_use_case_1_setup Setup steps
*
* \subsection usart_use_case_1_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref group_common_services_delay "Busy-Wait Delay Routines"
*
* \subsection wdt_use_case_1_setup_code Example code
* Add to application initialization:
* \code
* wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_16CLK);
* wdt_enable();
* wdt_set_window_period(WDT_TIMEOUT_PERIOD_8CLK);
* wdt_enable_window_mode();
* \endcode
*
* \subsection wdt_use_case_1_setup_flow Workflow
* -# Set timeout period to 16 cycles or 16 ms:
* - \code wdt_set_timeout_period(WDT_TIMEOUT_PERIOD_16CLK); \endcode
* -# Enable WDT:
* - \code wdt_enable(); \endcode
* -# Set window period to 8 cycles or 8 ms:
* - \code wdt_set_window_period(WDT_TIMEOUT_PERIOD_8CLK); \endcode
* -# Enable window mode:
* - \code wdt_enable_window_mode(); \endcode
*
* \section wdt_use_case_1_usage Usage steps
*
* \subsection wdt_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code
* delay_ms(10);
* wdt_reset();
* \endcode
*
* \subsection wdt_use_case_1_usage_flow Workflow
* -# Wait for 10 ms to not reset the WDT before window timeout:
* - \code delay_ms(10); \endcode
* -# Reset the WDT before the timeout period is over to prevent system reset:
* - \code wdt_reset(); \endcode
*/
#endif // _WDT_H_
@@ -1,244 +1,244 @@
/**
* \file
*
* \brief PWM service for XMEGA.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <asf.h>
/**
* \brief Calculate TC settings from PWM frequency
*
* This function will find the correct TC settings (clock prescaler and
* period) which will give the wanted PWM frequency.
*
* \note Since we want to be able to run the PWM at all duty-cycles ranging
* from 0-100%, we require a period of at least 100 to achieve this. Thus, the
* highest possible PWM frequency is CPU frequency / 100.
*
* \param config Pointer to PWM configuration.
* \param freq_hz Wanted PWM frequency in Hz.
*/
void pwm_set_frequency(struct pwm_config *config, uint16_t freq_hz)
{
uint32_t cpu_hz = sysclk_get_cpu_hz();
uint16_t smallest_div;
uint16_t dividor;
/* Avoid division by zero. */
Assert(freq_hz != 0);
/* Calculate the smallest divider for the requested frequency
related to the CPU frequency */
smallest_div = cpu_hz / freq_hz / 0xFFFF;
if (smallest_div < 1) {
dividor = 1;
config->clk_sel = PWM_CLK_DIV1;
} else if (smallest_div < 2) {
dividor = 2;
config->clk_sel = PWM_CLK_DIV2;
} else if (smallest_div < 4) {
dividor = 4;
config->clk_sel = PWM_CLK_DIV4;
} else if (smallest_div < 8) {
dividor = 8;
config->clk_sel = PWM_CLK_DIV8;
} else if (smallest_div < 64) {
dividor = 64;
config->clk_sel = PWM_CLK_DIV64;
} else if (smallest_div < 256) {
dividor = 256;
config->clk_sel = PWM_CLK_DIV256;
} else {
dividor = 1024;
config->clk_sel = PWM_CLK_DIV1024;
}
/* Calculate the period from the just found divider */
config->period = cpu_hz / dividor / freq_hz;
/* Make sure our period is at least 100 ticks so we are able to provide
a full range (0-100% duty cycle */
if (config->period < 100) {
/* The period is too short. */
config->clk_sel = PWM_CLK_OFF;
config->period = 0;
Assert(false);
}
}
/**
* \brief Initialize PWM configuration struct and set correct I/O pin to output
*
* \param config Pointer to PWM configuration struct.
* \param tc \ref pwm_tc_t "TC" to use for this PWM.
* \param channel \ref pwm_channel_t "CC channel" to use for this PWM.
* \param freq_hz Frequency to use for this PWM.
*/
void pwm_init(struct pwm_config *config, enum pwm_tc_t tc,
enum pwm_channel_t channel, uint16_t freq_hz)
{
/* Number of channels for this TC */
uint8_t num_chan = 0;
UNUSED(num_chan);
/* Set TC and correct I/O pin to output */
switch (tc) {
#if defined(TCC0)
case PWM_TCC0:
config->tc = &TCC0;
PORTC.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCC1)
case PWM_TCC1:
config->tc = &TCC1;
PORTC.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
#if defined(TCD0)
case PWM_TCD0:
config->tc = &TCD0;
PORTD.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCD1)
case PWM_TCD1:
config->tc = &TCD1;
PORTD.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
#if defined(TCE0)
case PWM_TCE0:
config->tc = &TCE0;
PORTE.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCE1)
case PWM_TCE1:
config->tc = &TCE1;
PORTE.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
#if defined(TCF0)
case PWM_TCF0:
config->tc = &TCF0;
PORTF.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCF1)
case PWM_TCF1:
config->tc = &TCF1;
PORTF.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
default:
Assert(false);
break;
}
/* Make sure we are not given a channel number larger
than this TC can handle */
Assert(channel <= num_chan);
config->channel = channel;
/* Set the correct cc_mask */
switch (channel) {
case PWM_CH_A:
config->cc_mask = TC_CCAEN;
break;
case PWM_CH_B:
config->cc_mask = TC_CCBEN;
break;
case PWM_CH_C:
config->cc_mask = TC_CCCEN;
break;
case PWM_CH_D:
config->cc_mask = TC_CCDEN;
break;
default:
Assert(false);
break;
}
/* Enable peripheral clock for this TC */
tc_enable(config->tc);
/* Set this TC's waveform generator in single slope mode */
tc_set_wgm(config->tc, TC_WG_SS);
/* Default values (disable TC and set minimum period)*/
config->period = 0;
config->clk_sel = PWM_CLK_OFF;
tc_write_clock_source(config->tc, PWM_CLK_OFF);
/* Set the PWM frequency */
pwm_set_frequency(config, freq_hz);
}
/**
* \brief Start a PWM channel
*
* This function enables a channel with a given duty cycle.
*
* \param *config Pointer to the PWM configuration struct
* \param duty_cycle_scale Duty cycle as a value between 0 and 100.
*/
void pwm_start(struct pwm_config *config, uint8_t duty_cycle_scale)
{
/* Set given duty cycle */
pwm_set_duty_cycle_percent(config, duty_cycle_scale);
/* Set correct TC period */
tc_write_period(config->tc, config->period);
/* Enable CC channel for this TC */
tc_enable_cc_channels(config->tc, config->cc_mask);
/* Enable TC by setting correct clock prescaler */
tc_write_clock_source(config->tc, config->clk_sel);
}
/**
* \file
*
* \brief PWM service for XMEGA.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <asf.h>
/**
* \brief Calculate TC settings from PWM frequency
*
* This function will find the correct TC settings (clock prescaler and
* period) which will give the wanted PWM frequency.
*
* \note Since we want to be able to run the PWM at all duty-cycles ranging
* from 0-100%, we require a period of at least 100 to achieve this. Thus, the
* highest possible PWM frequency is CPU frequency / 100.
*
* \param config Pointer to PWM configuration.
* \param freq_hz Wanted PWM frequency in Hz.
*/
void pwm_set_frequency(struct pwm_config *config, uint16_t freq_hz)
{
uint32_t cpu_hz = sysclk_get_cpu_hz();
uint16_t smallest_div;
uint16_t dividor;
/* Avoid division by zero. */
Assert(freq_hz != 0);
/* Calculate the smallest divider for the requested frequency
related to the CPU frequency */
smallest_div = cpu_hz / freq_hz / 0xFFFF;
if (smallest_div < 1) {
dividor = 1;
config->clk_sel = PWM_CLK_DIV1;
} else if (smallest_div < 2) {
dividor = 2;
config->clk_sel = PWM_CLK_DIV2;
} else if (smallest_div < 4) {
dividor = 4;
config->clk_sel = PWM_CLK_DIV4;
} else if (smallest_div < 8) {
dividor = 8;
config->clk_sel = PWM_CLK_DIV8;
} else if (smallest_div < 64) {
dividor = 64;
config->clk_sel = PWM_CLK_DIV64;
} else if (smallest_div < 256) {
dividor = 256;
config->clk_sel = PWM_CLK_DIV256;
} else {
dividor = 1024;
config->clk_sel = PWM_CLK_DIV1024;
}
/* Calculate the period from the just found divider */
config->period = cpu_hz / dividor / freq_hz;
/* Make sure our period is at least 100 ticks so we are able to provide
a full range (0-100% duty cycle */
if (config->period < 100) {
/* The period is too short. */
config->clk_sel = PWM_CLK_OFF;
config->period = 0;
Assert(false);
}
}
/**
* \brief Initialize PWM configuration struct and set correct I/O pin to output
*
* \param config Pointer to PWM configuration struct.
* \param tc \ref pwm_tc_t "TC" to use for this PWM.
* \param channel \ref pwm_channel_t "CC channel" to use for this PWM.
* \param freq_hz Frequency to use for this PWM.
*/
void pwm_init(struct pwm_config *config, enum pwm_tc_t tc,
enum pwm_channel_t channel, uint16_t freq_hz)
{
/* Number of channels for this TC */
uint8_t num_chan = 0;
UNUSED(num_chan);
/* Set TC and correct I/O pin to output */
switch (tc) {
#if defined(TCC0)
case PWM_TCC0:
config->tc = &TCC0;
PORTC.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCC1)
case PWM_TCC1:
config->tc = &TCC1;
PORTC.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
#if defined(TCD0)
case PWM_TCD0:
config->tc = &TCD0;
PORTD.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCD1)
case PWM_TCD1:
config->tc = &TCD1;
PORTD.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
#if defined(TCE0)
case PWM_TCE0:
config->tc = &TCE0;
PORTE.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCE1)
case PWM_TCE1:
config->tc = &TCE1;
PORTE.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
#if defined(TCF0)
case PWM_TCF0:
config->tc = &TCF0;
PORTF.DIR |= (1 << (channel-1));
num_chan = 4;
break;
#endif
#if defined(TCF1)
case PWM_TCF1:
config->tc = &TCF1;
PORTF.DIR |= (1 << (channel+3));
num_chan = 2;
break;
#endif
default:
Assert(false);
break;
}
/* Make sure we are not given a channel number larger
than this TC can handle */
Assert(channel <= num_chan);
config->channel = channel;
/* Set the correct cc_mask */
switch (channel) {
case PWM_CH_A:
config->cc_mask = TC_CCAEN;
break;
case PWM_CH_B:
config->cc_mask = TC_CCBEN;
break;
case PWM_CH_C:
config->cc_mask = TC_CCCEN;
break;
case PWM_CH_D:
config->cc_mask = TC_CCDEN;
break;
default:
Assert(false);
break;
}
/* Enable peripheral clock for this TC */
tc_enable(config->tc);
/* Set this TC's waveform generator in single slope mode */
tc_set_wgm(config->tc, TC_WG_SS);
/* Default values (disable TC and set minimum period)*/
config->period = 0;
config->clk_sel = PWM_CLK_OFF;
tc_write_clock_source(config->tc, PWM_CLK_OFF);
/* Set the PWM frequency */
pwm_set_frequency(config, freq_hz);
}
/**
* \brief Start a PWM channel
*
* This function enables a channel with a given duty cycle.
*
* \param *config Pointer to the PWM configuration struct
* \param duty_cycle_scale Duty cycle as a value between 0 and 100.
*/
void pwm_start(struct pwm_config *config, uint8_t duty_cycle_scale)
{
/* Set given duty cycle */
pwm_set_duty_cycle_percent(config, duty_cycle_scale);
/* Set correct TC period */
tc_write_period(config->tc, config->period);
/* Enable CC channel for this TC */
tc_enable_cc_channels(config->tc, config->cc_mask);
/* Enable TC by setting correct clock prescaler */
tc_write_clock_source(config->tc, config->clk_sel);
}
@@ -1,352 +1,352 @@
/**
* \file
*
* \brief PWM service for XMEGA.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef PWM_H
#define PWM_H
#include "tc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup pwm_group XMEGA Pulse Width Modulation (PWM) service
*
* See \ref pwm_quickstart.
*
* This is a service for single slope wave form generation on the XMEGA.
* It provides functions for enabling, disabling and configuring the TC modules
* in single slope PWM mode.
*
* The API uses a \ref pwm_config "structure" which contain the configuration.
* This structure must be set up before the PWM can be started.
*
* \section dependencies Dependencies
* This driver depends on the following modules:
* - \ref tc_group to set up TC in PWM mode.
* @{
*/
/**
* \brief PWM compare channel index
*/
enum pwm_channel_t {
/** Channel A. PWM output on pin 0 */
PWM_CH_A = 1,
/** Channel B. PWM output on pin 1 */
PWM_CH_B = 2,
/** Channel C. PWM output on pin 2 */
PWM_CH_C = 3,
/** Channel D. PWM output on pin 3 */
PWM_CH_D = 4,
};
/**
* \brief Valid timer/counters to use
* \note Not all timer/counters are available on all devices.
* Please refer to the datasheet for more information on what
* timer/counters are available for the device you are using.
*/
enum pwm_tc_t {
/** PWM on port C, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCC0,
/** PWM on port C, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCC1,
/** PWM on port D, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCD0,
/** PWM on port D, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCD1,
/** PWM on port E, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCE0,
/** PWM on port E, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCE1,
/** PWM on port F, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCF0,
/** PWM on port F, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCF1,
};
/**
* \brief Valid clock source indexes
*/
enum pwm_clk_sel {
PWM_CLK_OFF = TC_CLKSEL_OFF_gc,
PWM_CLK_DIV1 = TC_CLKSEL_DIV1_gc,
PWM_CLK_DIV2 = TC_CLKSEL_DIV2_gc,
PWM_CLK_DIV4 = TC_CLKSEL_DIV4_gc,
PWM_CLK_DIV8 = TC_CLKSEL_DIV8_gc,
PWM_CLK_DIV64 = TC_CLKSEL_DIV64_gc,
PWM_CLK_DIV256 = TC_CLKSEL_DIV256_gc,
PWM_CLK_DIV1024 = TC_CLKSEL_DIV1024_gc,
};
/**
* \brief PWM configuration
*/
struct pwm_config {
void *tc;
enum pwm_channel_t channel;
enum tc_cc_channel_mask_enable_t cc_mask;
enum pwm_clk_sel clk_sel;
uint16_t period;
};
/** \brief Interrupt callback type */
typedef void (*pwm_callback_t) (void);
void pwm_init(struct pwm_config *config, enum pwm_tc_t tc,
enum pwm_channel_t channel, uint16_t freq_hz);
void pwm_set_frequency(struct pwm_config *config, uint16_t freq_hz);
void pwm_start(struct pwm_config *config, uint8_t duty_cycle_scale);
/**
* \brief Function to set PWM duty cycle
*
* The duty cycle can be set on a scale between 0-100%. This value
* will be used to update the CCx register for the selected PWM channel.
*
* \param *config Pointer to the PWM configuration struct
* \param duty_cycle_scale Duty cycle as a value between 0 and 100.
*/
static inline void pwm_set_duty_cycle_percent(struct pwm_config *config,
uint8_t duty_cycle_scale)
{
Assert( duty_cycle_scale <= 100 );
tc_write_cc_buffer(config->tc, config->channel,
(uint16_t)(((uint32_t)config->period *
(uint32_t)duty_cycle_scale) / 100));
}
/**
* \brief Function that stops the PWM timer
*
* The PWM timer is stopped by writing the prescaler register to "clock off"
*
* \param *config Pointer to the PWM configuration struct
*/
static inline void pwm_stop(struct pwm_config *config)
{
tc_write_clock_source(config->tc, TC_CLKSEL_OFF_gc);
}
/**
* \brief Disable the PWM timer
*
* This function disables the peripheral clock for the timer and shut down
* module when unused in order to save power.
*
* \param *config Pointer to the PWM configuration struct
*/
static inline void pwm_disable(struct pwm_config *config)
{
pwm_stop(config);
tc_disable(config->tc);
}
/**
* \brief Function that resets the PWM timer
*
* This function reset the CNT register for the selected timer used for PWM
*
* \param *config Pointer to the PWM configuration struct
*/
static inline void pwm_timer_reset(struct pwm_config *config)
{
tc_write_count(config->tc, 0);
}
/**
* \brief Callback function for timer overflow interrupts
*
* This function enables T/C overflow interrupts (low level interrupts)
* and defines the callback function for the overflow ISR interrupt routine.
*
* \param *config Pointer to the PWM configuration struct
* \param callback Callback function
*/
static inline void pwm_overflow_int_callback(struct pwm_config *config,
pwm_callback_t callback)
{
tc_set_overflow_interrupt_level(config->tc, TC_INT_LVL_LO);
tc_set_overflow_interrupt_callback(config->tc, callback);
}
/** @} */
#ifdef __cplusplus
}
#endif
/**
* \page pwm_quickstart Quickstart guide for AVR XMEGA PWM service
*
* This is the quickstart guide for the \ref pwm_group,
* with step-by-step instructions on how to configure and use the service in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section basic_use_case Basic use case
* In the most basic use case, we configure one PWM channel in non-interrupt
* mode.
*
* \section pwm_basic_use_case_setup Setup steps
* \subsection pwm_basic_use_case_setup_code Example code
* Add to application C-file:
* \code
* struct pwm_config pwm_cfg;
*
* sysclk_init();
* pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 500);
* \endcode
*
* \subsection pwm_basic_use_case_setup_flow Workflow
* -# Ensure that \ref conf_clock.h is present for the driver.
* \note This file is only for the driver and should not be included by the
* user.
* -# Define config struct for PWM module:
* \code struct pwm_config pwm_cfg; \endcode
* -# Initialize sysclock module:
* \code sysclk_init();\endcode
* -# Initialize config struct and set up PWM with frequency of 500 Hz.\n
* \code pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 500); \endcode
* \note Since the timer/counter \ref PWM_TCE0 and channel \ref PWM_CH_A
* is used, the PWM will be output on port E, pin 0.
* See \ref pwm_tc_t and \ref pwm_channel_t for more information
* on what port/pin is used for different timer/counters.
* \attention This step must not be skipped or the initial content of the
* structs will be unpredictable, possibly causing misconfiguration.
*
* \section pwm_basic_use_case_usage Usage steps
* \subsection pwm_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code pwm_start(&pwm_config, 50); \endcode
*
* \subsection pwm_basic_use_case_usage_flow Workflow
* -# Start PWM with 50% duty cycle:
* \code pwm_start(&pwm_config, 50); \endcode
*
* \section pwm_use_cases Advanced use cases
* For more advanced use of the PWM service, see the following use cases:
* - \subpage pwm_use_case_1 : PWM with interrupt
*/
/**
* \page pwm_use_case_1 Use case #1
* In this use case the PWM module is configured with overflow interrupt.
*
* \section pwm_use_case_1_setup Setup steps
* \subsection pwm_use_case_1_setup_code Example code
*
* Add to application C-file:
* \code
* struct pwm_config pwm_cfg;
*
* void my_callback(void)
* {
* do_something();
* }
* void pwm_init(void)
* {
* pmic_init();
* sysclk_init();
*
* cpu_irq_enable();
*
* pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 75);
* pwm_overflow_int_callback(&pwm_cfg, my_callback);
* }
* \endcode
*
* \subsection pwm_use_case_1_setup_flow Workflow
* -# Define config struct for PWM module:
* \code struct pwm_config pwm_cfg; \endcode
* -# Define a callback function in the application which does whatever task
* you want it to do:
* \code
* void my_callback(void)
* {
* do_something();
* }
* \endcode
* -# Initialize interrupt controller module:
* \code pmic_init();\endcode
* -# Initialize sysclock module:
* \code sysclk_init();\endcode
* -# Enable global interrupts:
* \code cpu_irq_enable();\endcode
* -# Initialize config struct and set up PWM with frequency of 75 Hz:
* \code pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 75); \endcode
* \note Since the timer/counter \ref PWM_TCE0 and channel \ref PWM_CH_A
* is used, the PWM will be output on port E, pin 0.
* See \ref pwm_tc_t and \ref pwm_channel_t for more information
* on what port/pin is used for different timer/counters.
* \attention This step must not be skipped or the initial content of the
* structs will be unpredictable, possibly causing misconfiguration.
* -# Set callback function on PWM TC channel overflow:
* \code pwm_overflow_int_callback(&pwm_cfg, my_callback); \endcode
*
* \section pwm_use_case_1_usage Usage steps
* \subsection pwm_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code pwm_start(&pwm_cfg, 50); \endcode
*
* \subsection pwm_basic_use_case_usage_flow Workflow
* -# Start PWM with 50% duty cycle:
* \code pwm_start(&pwm_cfg, 50); \endcode
*
*/
#endif /* PWM_H */
/**
* \file
*
* \brief PWM service for XMEGA.
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef PWM_H
#define PWM_H
#include "tc.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* \defgroup pwm_group XMEGA Pulse Width Modulation (PWM) service
*
* See \ref pwm_quickstart.
*
* This is a service for single slope wave form generation on the XMEGA.
* It provides functions for enabling, disabling and configuring the TC modules
* in single slope PWM mode.
*
* The API uses a \ref pwm_config "structure" which contain the configuration.
* This structure must be set up before the PWM can be started.
*
* \section dependencies Dependencies
* This driver depends on the following modules:
* - \ref tc_group to set up TC in PWM mode.
* @{
*/
/**
* \brief PWM compare channel index
*/
enum pwm_channel_t {
/** Channel A. PWM output on pin 0 */
PWM_CH_A = 1,
/** Channel B. PWM output on pin 1 */
PWM_CH_B = 2,
/** Channel C. PWM output on pin 2 */
PWM_CH_C = 3,
/** Channel D. PWM output on pin 3 */
PWM_CH_D = 4,
};
/**
* \brief Valid timer/counters to use
* \note Not all timer/counters are available on all devices.
* Please refer to the datasheet for more information on what
* timer/counters are available for the device you are using.
*/
enum pwm_tc_t {
/** PWM on port C, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCC0,
/** PWM on port C, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCC1,
/** PWM on port D, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCD0,
/** PWM on port D, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCD1,
/** PWM on port E, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCE0,
/** PWM on port E, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCE1,
/** PWM on port F, pin 0, 1, 2 or 3 (depending on
\ref pwm_channel_t "channel") */
PWM_TCF0,
/** PWM on port F, pin 4 or 5 (depending on
\ref pwm_channel_t "channel") */
PWM_TCF1,
};
/**
* \brief Valid clock source indexes
*/
enum pwm_clk_sel {
PWM_CLK_OFF = TC_CLKSEL_OFF_gc,
PWM_CLK_DIV1 = TC_CLKSEL_DIV1_gc,
PWM_CLK_DIV2 = TC_CLKSEL_DIV2_gc,
PWM_CLK_DIV4 = TC_CLKSEL_DIV4_gc,
PWM_CLK_DIV8 = TC_CLKSEL_DIV8_gc,
PWM_CLK_DIV64 = TC_CLKSEL_DIV64_gc,
PWM_CLK_DIV256 = TC_CLKSEL_DIV256_gc,
PWM_CLK_DIV1024 = TC_CLKSEL_DIV1024_gc,
};
/**
* \brief PWM configuration
*/
struct pwm_config {
void *tc;
enum pwm_channel_t channel;
enum tc_cc_channel_mask_enable_t cc_mask;
enum pwm_clk_sel clk_sel;
uint16_t period;
};
/** \brief Interrupt callback type */
typedef void (*pwm_callback_t) (void);
void pwm_init(struct pwm_config *config, enum pwm_tc_t tc,
enum pwm_channel_t channel, uint16_t freq_hz);
void pwm_set_frequency(struct pwm_config *config, uint16_t freq_hz);
void pwm_start(struct pwm_config *config, uint8_t duty_cycle_scale);
/**
* \brief Function to set PWM duty cycle
*
* The duty cycle can be set on a scale between 0-100%. This value
* will be used to update the CCx register for the selected PWM channel.
*
* \param *config Pointer to the PWM configuration struct
* \param duty_cycle_scale Duty cycle as a value between 0 and 100.
*/
static inline void pwm_set_duty_cycle_percent(struct pwm_config *config,
uint8_t duty_cycle_scale)
{
Assert( duty_cycle_scale <= 100 );
tc_write_cc_buffer(config->tc, config->channel,
(uint16_t)(((uint32_t)config->period *
(uint32_t)duty_cycle_scale) / 100));
}
/**
* \brief Function that stops the PWM timer
*
* The PWM timer is stopped by writing the prescaler register to "clock off"
*
* \param *config Pointer to the PWM configuration struct
*/
static inline void pwm_stop(struct pwm_config *config)
{
tc_write_clock_source(config->tc, TC_CLKSEL_OFF_gc);
}
/**
* \brief Disable the PWM timer
*
* This function disables the peripheral clock for the timer and shut down
* module when unused in order to save power.
*
* \param *config Pointer to the PWM configuration struct
*/
static inline void pwm_disable(struct pwm_config *config)
{
pwm_stop(config);
tc_disable(config->tc);
}
/**
* \brief Function that resets the PWM timer
*
* This function reset the CNT register for the selected timer used for PWM
*
* \param *config Pointer to the PWM configuration struct
*/
static inline void pwm_timer_reset(struct pwm_config *config)
{
tc_write_count(config->tc, 0);
}
/**
* \brief Callback function for timer overflow interrupts
*
* This function enables T/C overflow interrupts (low level interrupts)
* and defines the callback function for the overflow ISR interrupt routine.
*
* \param *config Pointer to the PWM configuration struct
* \param callback Callback function
*/
static inline void pwm_overflow_int_callback(struct pwm_config *config,
pwm_callback_t callback)
{
tc_set_overflow_interrupt_level(config->tc, TC_INT_LVL_LO);
tc_set_overflow_interrupt_callback(config->tc, callback);
}
/** @} */
#ifdef __cplusplus
}
#endif
/**
* \page pwm_quickstart Quickstart guide for AVR XMEGA PWM service
*
* This is the quickstart guide for the \ref pwm_group,
* with step-by-step instructions on how to configure and use the service in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section basic_use_case Basic use case
* In the most basic use case, we configure one PWM channel in non-interrupt
* mode.
*
* \section pwm_basic_use_case_setup Setup steps
* \subsection pwm_basic_use_case_setup_code Example code
* Add to application C-file:
* \code
* struct pwm_config pwm_cfg;
*
* sysclk_init();
* pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 500);
* \endcode
*
* \subsection pwm_basic_use_case_setup_flow Workflow
* -# Ensure that \ref conf_clock.h is present for the driver.
* \note This file is only for the driver and should not be included by the
* user.
* -# Define config struct for PWM module:
* \code struct pwm_config pwm_cfg; \endcode
* -# Initialize sysclock module:
* \code sysclk_init();\endcode
* -# Initialize config struct and set up PWM with frequency of 500 Hz.\n
* \code pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 500); \endcode
* \note Since the timer/counter \ref PWM_TCE0 and channel \ref PWM_CH_A
* is used, the PWM will be output on port E, pin 0.
* See \ref pwm_tc_t and \ref pwm_channel_t for more information
* on what port/pin is used for different timer/counters.
* \attention This step must not be skipped or the initial content of the
* structs will be unpredictable, possibly causing misconfiguration.
*
* \section pwm_basic_use_case_usage Usage steps
* \subsection pwm_basic_use_case_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code pwm_start(&pwm_config, 50); \endcode
*
* \subsection pwm_basic_use_case_usage_flow Workflow
* -# Start PWM with 50% duty cycle:
* \code pwm_start(&pwm_config, 50); \endcode
*
* \section pwm_use_cases Advanced use cases
* For more advanced use of the PWM service, see the following use cases:
* - \subpage pwm_use_case_1 : PWM with interrupt
*/
/**
* \page pwm_use_case_1 Use case #1
* In this use case the PWM module is configured with overflow interrupt.
*
* \section pwm_use_case_1_setup Setup steps
* \subsection pwm_use_case_1_setup_code Example code
*
* Add to application C-file:
* \code
* struct pwm_config pwm_cfg;
*
* void my_callback(void)
* {
* do_something();
* }
* void pwm_init(void)
* {
* pmic_init();
* sysclk_init();
*
* cpu_irq_enable();
*
* pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 75);
* pwm_overflow_int_callback(&pwm_cfg, my_callback);
* }
* \endcode
*
* \subsection pwm_use_case_1_setup_flow Workflow
* -# Define config struct for PWM module:
* \code struct pwm_config pwm_cfg; \endcode
* -# Define a callback function in the application which does whatever task
* you want it to do:
* \code
* void my_callback(void)
* {
* do_something();
* }
* \endcode
* -# Initialize interrupt controller module:
* \code pmic_init();\endcode
* -# Initialize sysclock module:
* \code sysclk_init();\endcode
* -# Enable global interrupts:
* \code cpu_irq_enable();\endcode
* -# Initialize config struct and set up PWM with frequency of 75 Hz:
* \code pwm_init(&pwm_cfg, PWM_TCE0, PWM_CH_A, 75); \endcode
* \note Since the timer/counter \ref PWM_TCE0 and channel \ref PWM_CH_A
* is used, the PWM will be output on port E, pin 0.
* See \ref pwm_tc_t and \ref pwm_channel_t for more information
* on what port/pin is used for different timer/counters.
* \attention This step must not be skipped or the initial content of the
* structs will be unpredictable, possibly causing misconfiguration.
* -# Set callback function on PWM TC channel overflow:
* \code pwm_overflow_int_callback(&pwm_cfg, my_callback); \endcode
*
* \section pwm_use_case_1_usage Usage steps
* \subsection pwm_use_case_1_usage_code Example code
* Add to, e.g., main loop in application C-file:
* \code pwm_start(&pwm_cfg, 50); \endcode
*
* \subsection pwm_basic_use_case_usage_flow Workflow
* -# Start PWM with 50% duty cycle:
* \code pwm_start(&pwm_cfg, 50); \endcode
*
*/
#endif /* PWM_H */
@@ -1,231 +1,231 @@
/**
* \file timeout.c
*
* \brief Timeout service for XMEGA
*
* Copyright (C) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <asf.h>
#include <conf_timeout.h>
/* Check if RTC32 is defined, otherwise use RTC as default */
#if defined(CLOCK_SOURCE_RTC32)
#include <rtc32.h>
#else
#include <rtc.h>
#endif
/** \brief Timeout timekeeping data */
struct timeout_struct {
/**
* Current count-down value. Counts down for every tick.
* Will be considered as expired when it reaches 0, and
* may then be reloaded with period.
*/
uint16_t count;
/**
* Period between expires. Used to reload count.
* If 0, the count won't be reloaded.
*/
uint16_t period;
};
/** Array of configurable timeout timekeeping data */
static struct timeout_struct timeout_array[TIMEOUT_COUNT];
/** Bitmask of active timeouts */
static uint8_t timeout_active;
/** Bitmask of expired timeouts */
static uint8_t timeout_expired;
/**
* \brief Callback function for RTC compare interrupt handler
*
* The function executes when the RTC compare interrupt occurs and loop
* through all timeout channels. The timeout_array[channel_index] which
* contains the remaining ticks before timeout is decremented and the timeout
* active/expired masks are updated.
*/
static void tick_handler(uint32_t time)
{
uint8_t i;
/* Loop through all timeout channels */
for (i = 0; i < TIMEOUT_COUNT; i++) {
/* Skip processing on current channel if not active */
if (!(timeout_active & (1 << i))) {
continue;
}
/* Decrement current channel with one tick */
timeout_array[i].count--;
/* Skip further processing on current channel if not expired */
if (timeout_array[i].count) {
continue;
} else {
/* Update expired bit mask with current channel */
timeout_expired |= 1 << i;
/* If Periodic timer, reset timeout counter to period
* time */
if (timeout_array[i].period) {
timeout_array[i].count
= timeout_array[i].period;
}
/* If not periodic timeout, set current channel to
* in-active */
else {
timeout_active &= ~(1 << i);
}
}
}
/* Reset RTC before next tick */
rtc_set_time(0);
rtc_set_alarm(TIMEOUT_COMP);
}
/**
* \brief Initialize timeout
*
* Initializes timeout counter for desired tick rate and starts it. The device
* interrupt controller should be initialized prior to calling this function,
* and global interrupts must be enabled.
*
* \note If the service is configured to use the asynchronous RTC32 module,
* there are restrictions on the timeout period that can be used - see
* to \ref rtc32_min_alarm_time for details.
*/
void timeout_init(void)
{
rtc_init();
rtc_set_callback(tick_handler);
rtc_set_time(0);
rtc_set_alarm(TIMEOUT_COMP);
}
/**
* \brief Start periodic timeout with a specific start timeout
*
* \param id \ref timeout_id_t
* \param period Time period in number of ticks
* \param offset Time to first timeout in number of ticks
*/
void timeout_start_offset(timeout_id_t id, uint16_t period, uint16_t offset)
{
/* Check that ID within the TIMEOUT_COUNT range */
if (id < TIMEOUT_COUNT) {
/* Disable interrupts before tweaking the bitmasks */
irqflags_t flags;
flags = cpu_irq_save();
/* Update timeout struct with offset and period */
timeout_array[id].count = offset;
timeout_array[id].period = period;
/* Set current timeout channel bitmasks to active and not
* expired */
timeout_active |= 1 << id;
timeout_expired &= ~(1 << id);
/* Restore interrupts */
cpu_irq_restore(flags);
}
}
/**
* \brief Start singleshot timeout
*
* \param id \ref timeout_id_t
* \param timeout Timeout in number of ticks
*/
void timeout_start_singleshot(timeout_id_t id, uint16_t timeout)
{
timeout_start_offset(id, 0, timeout);
}
/**
* \brief Start periodic timeout
*
* \param id \ref timeout_id_t
* \param period Time period in number of ticks
*/
void timeout_start_periodic(timeout_id_t id, uint16_t period)
{
timeout_start_offset(id, period, period);
}
/**
* \brief Test and clear expired flag for running timeout
*
* \param id \ref timeout_id_t
* \retval true Timer have expired; clearing expired flag
* \retval false Timer still running
*/
bool timeout_test_and_clear_expired(timeout_id_t id)
{
/* Check that ID within the TIMEOUT_COUNT range */
if (id < TIMEOUT_COUNT) {
irqflags_t flags;
/* Check if timeout has expired */
if (timeout_expired & (1 << id)) {
flags = cpu_irq_save();
timeout_expired &= ~(1 << id);
cpu_irq_restore(flags);
return true;
}
}
return false;
}
/**
* \brief Stop running timeout
*
* \param id \ref timeout_id_t
*/
void timeout_stop(timeout_id_t id)
{
irqflags_t flags;
flags = cpu_irq_save();
timeout_active &= ~(1 << id);
cpu_irq_restore(flags);
}
/**
* \file timeout.c
*
* \brief Timeout service for XMEGA
*
* Copyright (C) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#include <asf.h>
#include <conf_timeout.h>
/* Check if RTC32 is defined, otherwise use RTC as default */
#if defined(CLOCK_SOURCE_RTC32)
#include <rtc32.h>
#else
#include <rtc.h>
#endif
/** \brief Timeout timekeeping data */
struct timeout_struct {
/**
* Current count-down value. Counts down for every tick.
* Will be considered as expired when it reaches 0, and
* may then be reloaded with period.
*/
uint16_t count;
/**
* Period between expires. Used to reload count.
* If 0, the count won't be reloaded.
*/
uint16_t period;
};
/** Array of configurable timeout timekeeping data */
static struct timeout_struct timeout_array[TIMEOUT_COUNT];
/** Bitmask of active timeouts */
static uint8_t timeout_active;
/** Bitmask of expired timeouts */
static uint8_t timeout_expired;
/**
* \brief Callback function for RTC compare interrupt handler
*
* The function executes when the RTC compare interrupt occurs and loop
* through all timeout channels. The timeout_array[channel_index] which
* contains the remaining ticks before timeout is decremented and the timeout
* active/expired masks are updated.
*/
static void tick_handler(uint32_t time)
{
uint8_t i;
/* Loop through all timeout channels */
for (i = 0; i < TIMEOUT_COUNT; i++) {
/* Skip processing on current channel if not active */
if (!(timeout_active & (1 << i))) {
continue;
}
/* Decrement current channel with one tick */
timeout_array[i].count--;
/* Skip further processing on current channel if not expired */
if (timeout_array[i].count) {
continue;
} else {
/* Update expired bit mask with current channel */
timeout_expired |= 1 << i;
/* If Periodic timer, reset timeout counter to period
* time */
if (timeout_array[i].period) {
timeout_array[i].count
= timeout_array[i].period;
}
/* If not periodic timeout, set current channel to
* in-active */
else {
timeout_active &= ~(1 << i);
}
}
}
/* Reset RTC before next tick */
rtc_set_time(0);
rtc_set_alarm(TIMEOUT_COMP);
}
/**
* \brief Initialize timeout
*
* Initializes timeout counter for desired tick rate and starts it. The device
* interrupt controller should be initialized prior to calling this function,
* and global interrupts must be enabled.
*
* \note If the service is configured to use the asynchronous RTC32 module,
* there are restrictions on the timeout period that can be used - see
* to \ref rtc32_min_alarm_time for details.
*/
void timeout_init(void)
{
rtc_init();
rtc_set_callback(tick_handler);
rtc_set_time(0);
rtc_set_alarm(TIMEOUT_COMP);
}
/**
* \brief Start periodic timeout with a specific start timeout
*
* \param id \ref timeout_id_t
* \param period Time period in number of ticks
* \param offset Time to first timeout in number of ticks
*/
void timeout_start_offset(timeout_id_t id, uint16_t period, uint16_t offset)
{
/* Check that ID within the TIMEOUT_COUNT range */
if (id < TIMEOUT_COUNT) {
/* Disable interrupts before tweaking the bitmasks */
irqflags_t flags;
flags = cpu_irq_save();
/* Update timeout struct with offset and period */
timeout_array[id].count = offset;
timeout_array[id].period = period;
/* Set current timeout channel bitmasks to active and not
* expired */
timeout_active |= 1 << id;
timeout_expired &= ~(1 << id);
/* Restore interrupts */
cpu_irq_restore(flags);
}
}
/**
* \brief Start singleshot timeout
*
* \param id \ref timeout_id_t
* \param timeout Timeout in number of ticks
*/
void timeout_start_singleshot(timeout_id_t id, uint16_t timeout)
{
timeout_start_offset(id, 0, timeout);
}
/**
* \brief Start periodic timeout
*
* \param id \ref timeout_id_t
* \param period Time period in number of ticks
*/
void timeout_start_periodic(timeout_id_t id, uint16_t period)
{
timeout_start_offset(id, period, period);
}
/**
* \brief Test and clear expired flag for running timeout
*
* \param id \ref timeout_id_t
* \retval true Timer have expired; clearing expired flag
* \retval false Timer still running
*/
bool timeout_test_and_clear_expired(timeout_id_t id)
{
/* Check that ID within the TIMEOUT_COUNT range */
if (id < TIMEOUT_COUNT) {
irqflags_t flags;
/* Check if timeout has expired */
if (timeout_expired & (1 << id)) {
flags = cpu_irq_save();
timeout_expired &= ~(1 << id);
cpu_irq_restore(flags);
return true;
}
}
return false;
}
/**
* \brief Stop running timeout
*
* \param id \ref timeout_id_t
*/
void timeout_stop(timeout_id_t id)
{
irqflags_t flags;
flags = cpu_irq_save();
timeout_active &= ~(1 << id);
cpu_irq_restore(flags);
}
@@ -1,380 +1,380 @@
/**
* \file timeout.h
*
* \brief Timeout service for XMEGA
*
* Copyright (C) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef TIMEOUT_H
#define TIMEOUT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <compiler.h>
#include <asf.h>
#include "conf_timeout.h"
/**
* \defgroup timeout_group Timeout service XMEGA
*
* See \ref timeout_quickstart.
*
* The timeout service uses the asynchronous RTC/RTC32 in order to have a
* system tick. Typical tick rate is 1-1000Hz. Clock sources available:
* - Internal 32kHz ULP oscillator
* - Internal 32kHz calibrated RC oscillator
* - External 32kHz crystal oscillator
* - External clock (Not available on all devices)
*
* The timeout service is configurable to a number of independent timeout
* channels, each with different delay setup in a number of ticks. Both
* singleshot and periodic timeouts are supported.
*
* As this service provides a software layer on top of the RTC/RTC32 module it
* will have some performance penalty, so for high performance it would be
* recommended to implement a more specific use by implementing your own
* interrupt handler based on this as a reference.
*
* \section timeout_configuration Configuration
* Configuration is done in the config file : conf_timeout.h
*
* Configuration defines:
* - \ref TIMEOUT_CLOCK_SOURCE_HZ : Frequency of clock source, used in
* calculation of tick rate
*
* - \ref TIMEOUT_COUNT : Number of independent timeout channels
* (Max 8 channels)
*
* - \ref TIMEOUT_TICK_HZ : Desired tick rate in Hz
*
* - \ref CLOCK_SOURCE_RTC32 Used to disable the RTC module (default)
* and use the RTC32 module found in ATxmegaA3B
* and ATxmegaA3BU.
*
* \section tc_timeout_interface Interface
* The timeout internal setup needs to be configured and this is done by the
* function tc_timeout_init().
*
* There are different functions for starting a timer:
* - \ref timeout_start_singleshot() : Start a singleshot timeout.
* - \ref timeout_start_periodic() : Start a periodic timeout.
* - \ref timeout_start_offset() : Start a periodic timeout with a specific
* start offset.
*
* Polling for timer status can be done with
* \ref timeout_test_and_clear_expired(), and this will also clear the
* expired flag in case of periodic timer.
*
* A running timer can be stopped with \ref timeout_stop().
*
* Common to all the function arguments are a timeout identifier, this is a
* number starting from 0 to identify the timeout channel. Maximum of this
* parameter is controlled by the configuration \ref TIMEOUT_COUNT.
*
* The start timeout functions uses timeout values represented in number of
* ticks.
*
* \subsection tc_timeout_usage Usage
* First of all, the include file is needed:
* \code #include "timeout.h" \endcode
*
* Then the timeout internals need to be set up by calling:
* \code timeout_init(); \endcode
*
* For simple usage starting a singleshot timeout for timeout id 0 and a timeout
* value of 100 ticks:
* \code
* tc_timeout_start_singleshot(0, 100);
* while (!timeout_test_and_clear_expired(0));
* // do whats needed after timeout has expired
* \endcode
*
* \section tc_timeout_accuracy Accuracy
* Since this is a timeout layer on top of a system tick; the trigger time of a
* timeout is fully depending on this system tick. This means that you might
* not know when the next tick will count down your timeout, and this inaccuracy
* can be from 0 to 1 system tick.
*
* E.g.: If you want a timeout of 1 system tick and use 1 as your timeout
* value, this might trigger immediately. So, if you have a requirement to wait
* at least 1 system tick, it would be recommended to use the requested value
* + 1.
*
* However, if you know the system tick has passed or are using periodic timeout
* you can be confident in the timing.
*/
// Test for missing configurations
#if !defined(TIMEOUT_CLOCK_SOURCE_HZ)
# error "configuration define missing: TIMEOUT_CLOCK_SOURCE_HZ"
#endif
#if !defined(TIMEOUT_TICK_HZ)
# error "configuration define missing: TIMEOUT_TICK_HZ"
#endif
#if !defined(TIMEOUT_COUNT)
# error "configuration define missing: TIMEOUT_COUNT"
#endif
// Check if timeout count is within allowed range
#if (TIMEOUT_COUNT > 8)
# error "TIMEOUT_COUNT outside allowed range"
#endif
// Calculate tick rate
#define TIMEOUT_COMP TIMEOUT_CLOCK_SOURCE_HZ / TIMEOUT_TICK_HZ
/**
* \brief Timeout identifier
*
* Index for timeout channel to use. Limited by max value configured with \ref
* TIMEOUT_COUNT.
*/
typedef uint8_t timeout_id_t;
// API functions
void timeout_init(void);
void timeout_start_singleshot(timeout_id_t id, uint16_t timeout);
void timeout_start_periodic(timeout_id_t id, uint16_t period);
void timeout_start_offset(timeout_id_t id, uint16_t period,
uint16_t start_offset);
bool timeout_test_and_clear_expired(timeout_id_t id);
void timeout_stop(timeout_id_t id);
#ifdef __cplusplus
}
#endif
/**
* \page timeout_quickstart Quick start guide for Timeout service
*
* This is the quick start guide for the \ref timeout_group, with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section timeout_use_cases Timeout use cases
* - \ref timeout_basic_use_case
* - \subpage timeout_use_case_1
*
* \section timeout_basic_use_case Basic use case - Toggle LEDs with periodic timeout
* In this use case, two periodic timeouts are used to toggle two leds.
*
* \section timeout_basic_use_case_setup Setup steps
*
* \subsection timeout_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group
* -# \ref pmic_group
* -# \ref gpio_group
* -# \ref rtc_group
* -# Configuration info for the timeout service must be added to the
* conf_timeout.h file (located in the config folder):
* \code
* #define TIMEOUT_CLOCK_SOURCE_HZ 1024
* #define TIMEOUT_COUNT 8
* #define TIMEOUT_TICK_HZ 4
* \endcode
* -# Configuration info for the RTC driver must be added to the
* conf_rtc.h file (located in the config folder):
* \code
* #define CONFIG_RTC_PRESCALER RTC_PRESCALER_DIV1_gc
* #define CONFIG_RTC_CLOCK_SOURCE CLK_RTCSRC_ULP_gc
* \endcode
*
* \subsection timeout_basic_use_case_setup_code Example code
* The following must be added to the project:
* \code
* #define TIMEOUT_0 0
* #define TIMEOUT_1 1
* \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
* pmic_init();
* timeout_init();
* timeout_start_periodic(TIMEOUT_0, 1);
* timeout_start_periodic(TIMEOUT_1, 2);
* \endcode
*
* \subsection timeout_basic_use_case_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Initialize the PMIC driver:
* - \code pmic_init(); \endcode
* -# Initialize timeout service:
* - \code timout_init(); \endcode
* -# Start timeout channel 0 with a period of 1 tick:
* - \code timeout_start_periodic(TIMEOUT_0, 1); \endcode
* -# Start timeout channel 1 with a period of 2 ticks:
* - \code timeout_start_periodic(TIMEOUT_1, 2); \endcode
*
* \section timeout_basic_use_case_usage Usage steps
*
* \subsection timeout_basic_use_case_usage_code Example code
* Add to application C-file:
* \code
* while (1) {
* if (timeout_test_and_clear_expired(TIMEOUT_0)) {
* gpio_toggle_pin(LED0_GPIO);
* }
* if (timeout_test_and_clear_expired(TIMEOUT_1)) {
* gpio_toggle_pin(LED1_GPIO);
* }
* }
* \endcode
*
* \subsection timeout_basic_use_case_usage_flow Workflow
* -# Check if timeout on channel 0 has expired, and toggle led if it has:
* - \code
* if (timeout_test_and_clear_expired(TIMEOUT_0)) {
* gpio_toggle_pin(LED0_GPIO);
* }
* \endcode
* -# Check if timeout on channel 1 has expired, and toggle led if it has:
* - \code
* if (timeout_test_and_clear_expired(TIMEOUT_1)) {
* gpio_toggle_pin(LED1_GPIO);
* }
* \endcode
*/
/**
* \page timeout_use_case_1 Debounce filter on a button
*
* In this use case, a simple debounce filter on a button will be set up.
*
* \section timeout_use_case_1_setup Setup steps
*
* \subsection timeout_use_case_1_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group
* -# \ref pmic_group
* -# \ref gpio_group
* -# \ref rtc_group
* -# Configuration info for the timeout service must be added to the
* conf_timeout.h file (located in the config folder):
* \code
* #define TIMEOUT_CLOCK_SOURCE_HZ 1024
* #define TIMEOUT_COUNT 1
* #define TIMEOUT_TICK_HZ 100
* \endcode
* -# Configuration info for the RTC driver must be added to the
* conf_rtc.h file (located in the config folder):
* \code
* #define CONFIG_RTC_PRESCALER RTC_PRESCALER_DIV1_gc
* #define CONFIG_RTC_CLOCK_SOURCE CLK_RTCSRC_ULP_gc
* \endcode
*
* \subsection timeout_use_case_1_setup_code Example code
* The following must be added to the project:
* \code
* #define DEBOUNCE_TIMEOUT 0
* #define DEBOUNCE_TICKS (50 * TIMEOUT_TICK_HZ / 1000)
* \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
* pmic_init();
* timeout_init();
* \endcode
*
* \subsection timeout_use_case_1_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Initialize the PMIC driver:
* - \code pmic_init(); \endcode
* -# Initialize timeout service:
* - \code timout_init(); \endcode
*
* \subsection timeout_use_case_1_usage_code Example code
* Add to application C-file:
* \code
* bool button_pressed;
* bool button_previous_state_pressed = false;
* while (1) {
* button_pressed = gpio_pin_is_low(GPIO_PUSH_BUTTON_0);
* if (button_previous_state_pressed != button_pressed) {
* timeout_start_singleshot(DEBOUNCE_TIMEOUT, DEBOUNCE_TICKS);
* button_previous_state_pressed = button_pressed;
* }
*
* if (timeout_test_and_clear_expired(DEBOUNCE_TIMEOUT)) {
* if (button_pressed) {
* gpio_toggle_pin(LED0_GPIO);
* }
* }
* }
* \endcode
*
* \subsection timeout_use_case_1_usage_flow Workflow
* -# Create a variable to hold state of push button:
* - \code bool button_pressed; \endcode
* -# Create a variable to hold previous state of push button:
* - \code bool button_previous_state_pressed; \endcode
* -# Get button state:
* - \code button_pressed = gpio_pin_is_low(GPIO_PUSH_BUTTON_0); \endcode
* -# Check if button state has changed since last iteration:
* - \code if (button_previous_state_pressed != button_pressed) \endcode
* -# Start debounce timeout:
* - \code
* timeout_start_singleshot(DEBOUNCE_TIMEOUT, DEBOUNCE_TICKS);
* \endcode
* -# Set previous state of button:
* - \code button_previous_state_pressed = button_pressed; \endcode
* -# Check if debounce timeout has expired:
* - \code if (timeout_test_and_clear_expired(DEBOUNCE_TIMEOUT)) \endcode
* -# Check if button is pressed down:
* - \code if (button_pressed) \endcode
* -# Toggle led:
* - \code gpio_toggle_pin(LED0_GPIO); \endcode
*/
#endif /* TIMEOUT_H */
/**
* \file timeout.h
*
* \brief Timeout service for XMEGA
*
* Copyright (C) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef TIMEOUT_H
#define TIMEOUT_H
#ifdef __cplusplus
extern "C" {
#endif
#include <compiler.h>
#include <asf.h>
#include "conf_timeout.h"
/**
* \defgroup timeout_group Timeout service XMEGA
*
* See \ref timeout_quickstart.
*
* The timeout service uses the asynchronous RTC/RTC32 in order to have a
* system tick. Typical tick rate is 1-1000Hz. Clock sources available:
* - Internal 32kHz ULP oscillator
* - Internal 32kHz calibrated RC oscillator
* - External 32kHz crystal oscillator
* - External clock (Not available on all devices)
*
* The timeout service is configurable to a number of independent timeout
* channels, each with different delay setup in a number of ticks. Both
* singleshot and periodic timeouts are supported.
*
* As this service provides a software layer on top of the RTC/RTC32 module it
* will have some performance penalty, so for high performance it would be
* recommended to implement a more specific use by implementing your own
* interrupt handler based on this as a reference.
*
* \section timeout_configuration Configuration
* Configuration is done in the config file : conf_timeout.h
*
* Configuration defines:
* - \ref TIMEOUT_CLOCK_SOURCE_HZ : Frequency of clock source, used in
* calculation of tick rate
*
* - \ref TIMEOUT_COUNT : Number of independent timeout channels
* (Max 8 channels)
*
* - \ref TIMEOUT_TICK_HZ : Desired tick rate in Hz
*
* - \ref CLOCK_SOURCE_RTC32 Used to disable the RTC module (default)
* and use the RTC32 module found in ATxmegaA3B
* and ATxmegaA3BU.
*
* \section tc_timeout_interface Interface
* The timeout internal setup needs to be configured and this is done by the
* function tc_timeout_init().
*
* There are different functions for starting a timer:
* - \ref timeout_start_singleshot() : Start a singleshot timeout.
* - \ref timeout_start_periodic() : Start a periodic timeout.
* - \ref timeout_start_offset() : Start a periodic timeout with a specific
* start offset.
*
* Polling for timer status can be done with
* \ref timeout_test_and_clear_expired(), and this will also clear the
* expired flag in case of periodic timer.
*
* A running timer can be stopped with \ref timeout_stop().
*
* Common to all the function arguments are a timeout identifier, this is a
* number starting from 0 to identify the timeout channel. Maximum of this
* parameter is controlled by the configuration \ref TIMEOUT_COUNT.
*
* The start timeout functions uses timeout values represented in number of
* ticks.
*
* \subsection tc_timeout_usage Usage
* First of all, the include file is needed:
* \code #include "timeout.h" \endcode
*
* Then the timeout internals need to be set up by calling:
* \code timeout_init(); \endcode
*
* For simple usage starting a singleshot timeout for timeout id 0 and a timeout
* value of 100 ticks:
* \code
* tc_timeout_start_singleshot(0, 100);
* while (!timeout_test_and_clear_expired(0));
* // do whats needed after timeout has expired
* \endcode
*
* \section tc_timeout_accuracy Accuracy
* Since this is a timeout layer on top of a system tick; the trigger time of a
* timeout is fully depending on this system tick. This means that you might
* not know when the next tick will count down your timeout, and this inaccuracy
* can be from 0 to 1 system tick.
*
* E.g.: If you want a timeout of 1 system tick and use 1 as your timeout
* value, this might trigger immediately. So, if you have a requirement to wait
* at least 1 system tick, it would be recommended to use the requested value
* + 1.
*
* However, if you know the system tick has passed or are using periodic timeout
* you can be confident in the timing.
*/
// Test for missing configurations
#if !defined(TIMEOUT_CLOCK_SOURCE_HZ)
# error "configuration define missing: TIMEOUT_CLOCK_SOURCE_HZ"
#endif
#if !defined(TIMEOUT_TICK_HZ)
# error "configuration define missing: TIMEOUT_TICK_HZ"
#endif
#if !defined(TIMEOUT_COUNT)
# error "configuration define missing: TIMEOUT_COUNT"
#endif
// Check if timeout count is within allowed range
#if (TIMEOUT_COUNT > 8)
# error "TIMEOUT_COUNT outside allowed range"
#endif
// Calculate tick rate
#define TIMEOUT_COMP TIMEOUT_CLOCK_SOURCE_HZ / TIMEOUT_TICK_HZ
/**
* \brief Timeout identifier
*
* Index for timeout channel to use. Limited by max value configured with \ref
* TIMEOUT_COUNT.
*/
typedef uint8_t timeout_id_t;
// API functions
void timeout_init(void);
void timeout_start_singleshot(timeout_id_t id, uint16_t timeout);
void timeout_start_periodic(timeout_id_t id, uint16_t period);
void timeout_start_offset(timeout_id_t id, uint16_t period,
uint16_t start_offset);
bool timeout_test_and_clear_expired(timeout_id_t id);
void timeout_stop(timeout_id_t id);
#ifdef __cplusplus
}
#endif
/**
* \page timeout_quickstart Quick start guide for Timeout service
*
* This is the quick start guide for the \ref timeout_group, with
* step-by-step instructions on how to configure and use the driver in a
* selection of use cases.
*
* The use cases contain several code fragments. The code fragments in the
* steps for setup can be copied into a custom initialization function, while
* the steps for usage can be copied into, e.g., the main application function.
*
* \section timeout_use_cases Timeout use cases
* - \ref timeout_basic_use_case
* - \subpage timeout_use_case_1
*
* \section timeout_basic_use_case Basic use case - Toggle LEDs with periodic timeout
* In this use case, two periodic timeouts are used to toggle two leds.
*
* \section timeout_basic_use_case_setup Setup steps
*
* \subsection timeout_basic_use_case_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group
* -# \ref pmic_group
* -# \ref gpio_group
* -# \ref rtc_group
* -# Configuration info for the timeout service must be added to the
* conf_timeout.h file (located in the config folder):
* \code
* #define TIMEOUT_CLOCK_SOURCE_HZ 1024
* #define TIMEOUT_COUNT 8
* #define TIMEOUT_TICK_HZ 4
* \endcode
* -# Configuration info for the RTC driver must be added to the
* conf_rtc.h file (located in the config folder):
* \code
* #define CONFIG_RTC_PRESCALER RTC_PRESCALER_DIV1_gc
* #define CONFIG_RTC_CLOCK_SOURCE CLK_RTCSRC_ULP_gc
* \endcode
*
* \subsection timeout_basic_use_case_setup_code Example code
* The following must be added to the project:
* \code
* #define TIMEOUT_0 0
* #define TIMEOUT_1 1
* \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
* pmic_init();
* timeout_init();
* timeout_start_periodic(TIMEOUT_0, 1);
* timeout_start_periodic(TIMEOUT_1, 2);
* \endcode
*
* \subsection timeout_basic_use_case_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Initialize the PMIC driver:
* - \code pmic_init(); \endcode
* -# Initialize timeout service:
* - \code timout_init(); \endcode
* -# Start timeout channel 0 with a period of 1 tick:
* - \code timeout_start_periodic(TIMEOUT_0, 1); \endcode
* -# Start timeout channel 1 with a period of 2 ticks:
* - \code timeout_start_periodic(TIMEOUT_1, 2); \endcode
*
* \section timeout_basic_use_case_usage Usage steps
*
* \subsection timeout_basic_use_case_usage_code Example code
* Add to application C-file:
* \code
* while (1) {
* if (timeout_test_and_clear_expired(TIMEOUT_0)) {
* gpio_toggle_pin(LED0_GPIO);
* }
* if (timeout_test_and_clear_expired(TIMEOUT_1)) {
* gpio_toggle_pin(LED1_GPIO);
* }
* }
* \endcode
*
* \subsection timeout_basic_use_case_usage_flow Workflow
* -# Check if timeout on channel 0 has expired, and toggle led if it has:
* - \code
* if (timeout_test_and_clear_expired(TIMEOUT_0)) {
* gpio_toggle_pin(LED0_GPIO);
* }
* \endcode
* -# Check if timeout on channel 1 has expired, and toggle led if it has:
* - \code
* if (timeout_test_and_clear_expired(TIMEOUT_1)) {
* gpio_toggle_pin(LED1_GPIO);
* }
* \endcode
*/
/**
* \page timeout_use_case_1 Debounce filter on a button
*
* In this use case, a simple debounce filter on a button will be set up.
*
* \section timeout_use_case_1_setup Setup steps
*
* \subsection timeout_use_case_1_setup_prereq Prerequisites
* For the setup code of this use case to work, the following must
* be added to the project:
* -# \ref sysclk_group
* -# \ref pmic_group
* -# \ref gpio_group
* -# \ref rtc_group
* -# Configuration info for the timeout service must be added to the
* conf_timeout.h file (located in the config folder):
* \code
* #define TIMEOUT_CLOCK_SOURCE_HZ 1024
* #define TIMEOUT_COUNT 1
* #define TIMEOUT_TICK_HZ 100
* \endcode
* -# Configuration info for the RTC driver must be added to the
* conf_rtc.h file (located in the config folder):
* \code
* #define CONFIG_RTC_PRESCALER RTC_PRESCALER_DIV1_gc
* #define CONFIG_RTC_CLOCK_SOURCE CLK_RTCSRC_ULP_gc
* \endcode
*
* \subsection timeout_use_case_1_setup_code Example code
* The following must be added to the project:
* \code
* #define DEBOUNCE_TIMEOUT 0
* #define DEBOUNCE_TICKS (50 * TIMEOUT_TICK_HZ / 1000)
* \endcode
*
* Add to application initialization:
* \code
* sysclk_init();
* pmic_init();
* timeout_init();
* \endcode
*
* \subsection timeout_use_case_1_setup_flow Workflow
* -# Initialize system clock:
* - \code sysclk_init(); \endcode
* -# Initialize the PMIC driver:
* - \code pmic_init(); \endcode
* -# Initialize timeout service:
* - \code timout_init(); \endcode
*
* \subsection timeout_use_case_1_usage_code Example code
* Add to application C-file:
* \code
* bool button_pressed;
* bool button_previous_state_pressed = false;
* while (1) {
* button_pressed = gpio_pin_is_low(GPIO_PUSH_BUTTON_0);
* if (button_previous_state_pressed != button_pressed) {
* timeout_start_singleshot(DEBOUNCE_TIMEOUT, DEBOUNCE_TICKS);
* button_previous_state_pressed = button_pressed;
* }
*
* if (timeout_test_and_clear_expired(DEBOUNCE_TIMEOUT)) {
* if (button_pressed) {
* gpio_toggle_pin(LED0_GPIO);
* }
* }
* }
* \endcode
*
* \subsection timeout_use_case_1_usage_flow Workflow
* -# Create a variable to hold state of push button:
* - \code bool button_pressed; \endcode
* -# Create a variable to hold previous state of push button:
* - \code bool button_previous_state_pressed; \endcode
* -# Get button state:
* - \code button_pressed = gpio_pin_is_low(GPIO_PUSH_BUTTON_0); \endcode
* -# Check if button state has changed since last iteration:
* - \code if (button_previous_state_pressed != button_pressed) \endcode
* -# Start debounce timeout:
* - \code
* timeout_start_singleshot(DEBOUNCE_TIMEOUT, DEBOUNCE_TICKS);
* \endcode
* -# Set previous state of button:
* - \code button_previous_state_pressed = button_pressed; \endcode
* -# Check if debounce timeout has expired:
* - \code if (timeout_test_and_clear_expired(DEBOUNCE_TIMEOUT)) \endcode
* -# Check if button is pressed down:
* - \code if (button_pressed) \endcode
* -# Toggle led:
* - \code gpio_toggle_pin(LED0_GPIO); \endcode
*/
#endif /* TIMEOUT_H */
@@ -1,156 +1,156 @@
/**
* \file
*
* \brief Assembler abstraction layer and utilities
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef ASSEMBLER_H_INCLUDED
#define ASSEMBLER_H_INCLUDED
#if !defined(__ASSEMBLER__) && !defined(__IAR_SYSTEMS_ASM__) \
&& !defined(__DOXYGEN__)
# error This file may only be included from assembly files
#endif
#if defined(__ASSEMBLER__)
# include "assembler/gas.h"
# include <avr/io.h>
#elif defined(__IAR_SYSTEMS_ASM__)
# include "assembler/iar.h"
# include <ioavr.h>
#endif
/**
* \ingroup group_xmega_utils
* \defgroup assembler_group Assembler Support
*
* This group provides a good handful of macros intended to smooth out
* the differences between various assemblers, similar to what compiler.h does
* for compilers, except that assemblers tend to be much less standardized than
* compilers.
*
* @{
*/
//! \name Control Statements
//@{
/**
* \def REPEAT(count)
* \brief Repeat the following statements \a count times
*/
/**
* \def END_REPEAT()
* \brief Mark the end of the statements to be repeated
*/
/**
* \def SET_LOC(offset)
* \brief Set the location counter to \a offset
*/
/**
* \def END_FILE()
* \brief Mark the end of the file
*/
//@}
//! \name Data Objects
//@{
/**
* \def FILL_BYTES(count)
* \brief Allocate space for \a count bytes
*/
//@}
//! \name Symbol Definition
//@{
/**
* \def L(name)
* \brief Turn \a name into a local symbol, if possible
*/
/**
* \def EXTERN_SYMBOL(name)
* \brief Declare \a name as an external symbol referenced by this file
*/
/**
* \def FUNCTION(name)
* \brief Define a file-local function called \a name
*/
/**
* \def PUBLIC_FUNCTION(name)
* \brief Define a globally visible function called \a name
*/
/**
* \def WEAK_FUNCTION(name)
* \brief Define a weak function called \a name
*
* Weak functions are only referenced if no strong definitions are found
*/
/**
* \def WEAK_FUNCTION_ALIAS(name, strong_name)
* \brief Define \a name as a weak alias for the function \a strong_name
* \sa WEAK_FUNCTION
*/
/**
* \def END_FUNC(name)
* \brief Mark the end of the function called \a name
*/
//@}
//! \name Section Definition
//@{
/**
* \def TEXT_SECTION(name)
* \brief Start a new section containing executable code
*/
/**
* \def RODATA_SECTION(name)
* \brief Start a new section containing read-only data
*/
/**
* \def DATA_SECTION(name)
* \brief Start a new section containing writeable initialized data
*/
/**
* \def BSS_SECTION(name)
* \brief Start a new section containing writeable zero-initialized data
*/
//@}
//! @}
#endif /* ASSEMBLER_H_INCLUDED */
/**
* \file
*
* \brief Assembler abstraction layer and utilities
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef ASSEMBLER_H_INCLUDED
#define ASSEMBLER_H_INCLUDED
#if !defined(__ASSEMBLER__) && !defined(__IAR_SYSTEMS_ASM__) \
&& !defined(__DOXYGEN__)
# error This file may only be included from assembly files
#endif
#if defined(__ASSEMBLER__)
# include "assembler/gas.h"
# include <avr/io.h>
#elif defined(__IAR_SYSTEMS_ASM__)
# include "assembler/iar.h"
# include <ioavr.h>
#endif
/**
* \ingroup group_xmega_utils
* \defgroup assembler_group Assembler Support
*
* This group provides a good handful of macros intended to smooth out
* the differences between various assemblers, similar to what compiler.h does
* for compilers, except that assemblers tend to be much less standardized than
* compilers.
*
* @{
*/
//! \name Control Statements
//@{
/**
* \def REPEAT(count)
* \brief Repeat the following statements \a count times
*/
/**
* \def END_REPEAT()
* \brief Mark the end of the statements to be repeated
*/
/**
* \def SET_LOC(offset)
* \brief Set the location counter to \a offset
*/
/**
* \def END_FILE()
* \brief Mark the end of the file
*/
//@}
//! \name Data Objects
//@{
/**
* \def FILL_BYTES(count)
* \brief Allocate space for \a count bytes
*/
//@}
//! \name Symbol Definition
//@{
/**
* \def L(name)
* \brief Turn \a name into a local symbol, if possible
*/
/**
* \def EXTERN_SYMBOL(name)
* \brief Declare \a name as an external symbol referenced by this file
*/
/**
* \def FUNCTION(name)
* \brief Define a file-local function called \a name
*/
/**
* \def PUBLIC_FUNCTION(name)
* \brief Define a globally visible function called \a name
*/
/**
* \def WEAK_FUNCTION(name)
* \brief Define a weak function called \a name
*
* Weak functions are only referenced if no strong definitions are found
*/
/**
* \def WEAK_FUNCTION_ALIAS(name, strong_name)
* \brief Define \a name as a weak alias for the function \a strong_name
* \sa WEAK_FUNCTION
*/
/**
* \def END_FUNC(name)
* \brief Mark the end of the function called \a name
*/
//@}
//! \name Section Definition
//@{
/**
* \def TEXT_SECTION(name)
* \brief Start a new section containing executable code
*/
/**
* \def RODATA_SECTION(name)
* \brief Start a new section containing read-only data
*/
/**
* \def DATA_SECTION(name)
* \brief Start a new section containing writeable initialized data
*/
/**
* \def BSS_SECTION(name)
* \brief Start a new section containing writeable zero-initialized data
*/
//@}
//! @}
#endif /* ASSEMBLER_H_INCLUDED */
@@ -1,121 +1,121 @@
/**
* \file
*
* \brief Assembler abstraction layer: GNU Assembler specifics
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef ASSEMBLER_GAS_H_INCLUDED
#define ASSEMBLER_GAS_H_INCLUDED
#ifndef __DOXYGEN__
/* IAR doesn't accept dots in macro names */
.macro ld_addr, reg, sym
lda.w \reg, \sym
.endm
/* Define a function \a name that is either globally visible or only
* file-local.
*/
.macro gas_begin_func name, is_public
.if \is_public
.global \name
.endif
.section .text.\name, "ax", @progbits
.type \name, @function
\name :
.endm
/* Define a function \a name that is either globally visible or only
* file-local in a given segment.
*/
.macro gas_begin_func_segm name, is_public, segment
.if \is_public
.global \name
.endif
.section .\segment, "ax", @progbits
.type \name, @function
\name :
.endm
/* Define \a name as a weak alias for the function \a strong_name */
.macro gas_weak_function_alias name, strong_name
.global \name
.weak \name
.type \name, @function
.set \name, \strong_name
.endm
/* Define a weak function called \a name */
.macro gas_weak_function name
.weak \name
gas_begin_func \name 1
.endm
#define REPEAT(count) .rept count
#define END_REPEAT() .endr
#define FILL_BYTES(count) .fill count
#define SET_LOC(offset) .org offset
#define L(name) .L##name
#define EXTERN_SYMBOL(name)
#define TEXT_SECTION(name) \
.section name, "ax", @progbits
#define RODATA_SECTION(name) \
.section name, "a", @progbits
#define DATA_SECTION(name) \
.section name, "aw", @progbits
#define BSS_SECTION(name) \
.section name, "aw", @nobits
#define FUNCTION(name) gas_begin_func name 0
#define PUBLIC_FUNCTION(name) gas_begin_func name 1
#define PUBLIC_FUNCTION_SEGMENT(name, segment) \
gas_begin_func_segm name 1 segment
#define WEAK_FUNCTION(name) gas_weak_function name
#define WEAK_FUNCTION_ALIAS(name, strong_name) \
gas_weak_function_alias name strong_name
#define END_FUNC(name) \
.size name, . - name
#define END_FILE()
#endif /* __DOXYGEN__ */
#endif /* ASSEMBLER_GAS_H_INCLUDED */
/**
* \file
*
* \brief Assembler abstraction layer: GNU Assembler specifics
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef ASSEMBLER_GAS_H_INCLUDED
#define ASSEMBLER_GAS_H_INCLUDED
#ifndef __DOXYGEN__
/* IAR doesn't accept dots in macro names */
.macro ld_addr, reg, sym
lda.w \reg, \sym
.endm
/* Define a function \a name that is either globally visible or only
* file-local.
*/
.macro gas_begin_func name, is_public
.if \is_public
.global \name
.endif
.section .text.\name, "ax", @progbits
.type \name, @function
\name :
.endm
/* Define a function \a name that is either globally visible or only
* file-local in a given segment.
*/
.macro gas_begin_func_segm name, is_public, segment
.if \is_public
.global \name
.endif
.section .\segment, "ax", @progbits
.type \name, @function
\name :
.endm
/* Define \a name as a weak alias for the function \a strong_name */
.macro gas_weak_function_alias name, strong_name
.global \name
.weak \name
.type \name, @function
.set \name, \strong_name
.endm
/* Define a weak function called \a name */
.macro gas_weak_function name
.weak \name
gas_begin_func \name 1
.endm
#define REPEAT(count) .rept count
#define END_REPEAT() .endr
#define FILL_BYTES(count) .fill count
#define SET_LOC(offset) .org offset
#define L(name) .L##name
#define EXTERN_SYMBOL(name)
#define TEXT_SECTION(name) \
.section name, "ax", @progbits
#define RODATA_SECTION(name) \
.section name, "a", @progbits
#define DATA_SECTION(name) \
.section name, "aw", @progbits
#define BSS_SECTION(name) \
.section name, "aw", @nobits
#define FUNCTION(name) gas_begin_func name 0
#define PUBLIC_FUNCTION(name) gas_begin_func name 1
#define PUBLIC_FUNCTION_SEGMENT(name, segment) \
gas_begin_func_segm name 1 segment
#define WEAK_FUNCTION(name) gas_weak_function name
#define WEAK_FUNCTION_ALIAS(name, strong_name) \
gas_weak_function_alias name strong_name
#define END_FUNC(name) \
.size name, . - name
#define END_FILE()
#endif /* __DOXYGEN__ */
#endif /* ASSEMBLER_GAS_H_INCLUDED */
@@ -1,235 +1,235 @@
/**
* \file
*
* \brief CLZ/CTZ C implementation.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CLZ_CTH_H
#define CLZ_CTH_H
/**
* \brief Count leading zeros in unsigned integer
*
* This macro takes unsigned integers of any size, and evaluates to a call to
* the clz-function for its size. These functions count the number of zeros,
* starting with the MSB, before a one occurs in the integer.
*
* \param x Unsigned integer to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
#define clz(x) compiler_demux_size(sizeof(x), clz, (x))
/**
* \internal
* \brief Count leading zeros in unsigned, 8-bit integer
*
* \param x Unsigned byte to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
clz8 (uint8_t x)
{
uint8_t bit = 0;
if (x & 0xf0)
{
x >>= 4;
}
else
{
bit += 4;
}
if (x & 0x0c)
{
x >>= 2;
}
else
{
bit += 2;
}
if (!(x & 0x02))
{
bit++;
}
return bit;
}
/**
* \internal
* \brief Count leading zeros in unsigned, 16-bit integer
*
* \param x Unsigned word to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
clz16 (uint16_t x)
{
uint8_t bit = 0;
if (x & 0xff00)
{
x >>= 8;
}
else
{
bit += 8;
}
return bit + clz8 (x);
}
/**
* \internal
* \brief Count leading zeros in unsigned, 32-bit integer
*
* \param x Unsigned double word to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
clz32 (uint32_t x)
{
uint8_t bit = 0;
if (x & 0xffff0000)
{
x >>= 16;
}
else
{
bit += 16;
}
return bit + clz16 (x);
}
/**
* \brief Count trailing zeros in unsigned integer
*
* This macro takes unsigned integers of any size, and evaluates to a call to
* the ctz-function for its size. These functions count the number of zeros,
* starting with the LSB, before a one occurs in the integer.
*
* \param x Unsigned integer to count the trailing zeros in.
*
* \return The number of trailing zeros in \a x.
*/
#define ctz(x) compiler_demux_size(sizeof(x), ctz, (x))
/**
* \internal
* \brief Count trailing zeros in unsigned, 8-bit integer
*
* \param x Unsigned byte to count the trailing zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
ctz8 (uint8_t x)
{
uint8_t bit = 0;
if (!(x & 0x0f))
{
bit += 4;
x >>= 4;
}
if (!(x & 0x03))
{
bit += 2;
x >>= 2;
}
if (!(x & 0x01))
bit++;
return bit;
}
/**
* \internal
* \brief Count trailing zeros in unsigned, 16-bit integer
*
* \param x Unsigned word to count the trailing zeros in.
*
* \return The number of trailing zeros in \a x.
*/
__always_inline static uint8_t
ctz16 (uint16_t x)
{
uint8_t bit = 0;
if (!(x & 0x00ff))
{
bit += 8;
x >>= 8;
}
return bit + ctz8 (x);
}
/**
* \internal
* \brief Count trailing zeros in unsigned, 32-bit integer
*
* \param x Unsigned double word to count the trailing zeros in.
*
* \return The number of trailing zeros in \a x.
*/
__always_inline static uint8_t
ctz32 (uint32_t x)
{
uint8_t bit = 0;
if (!(x & 0x0000ffff))
{
bit += 16;
x >>= 16;
}
return bit + ctz16 (x);
}
#endif /* CLZ_CTZ_H */
/**
* \file
*
* \brief CLZ/CTZ C implementation.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CLZ_CTH_H
#define CLZ_CTH_H
/**
* \brief Count leading zeros in unsigned integer
*
* This macro takes unsigned integers of any size, and evaluates to a call to
* the clz-function for its size. These functions count the number of zeros,
* starting with the MSB, before a one occurs in the integer.
*
* \param x Unsigned integer to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
#define clz(x) compiler_demux_size(sizeof(x), clz, (x))
/**
* \internal
* \brief Count leading zeros in unsigned, 8-bit integer
*
* \param x Unsigned byte to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
clz8 (uint8_t x)
{
uint8_t bit = 0;
if (x & 0xf0)
{
x >>= 4;
}
else
{
bit += 4;
}
if (x & 0x0c)
{
x >>= 2;
}
else
{
bit += 2;
}
if (!(x & 0x02))
{
bit++;
}
return bit;
}
/**
* \internal
* \brief Count leading zeros in unsigned, 16-bit integer
*
* \param x Unsigned word to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
clz16 (uint16_t x)
{
uint8_t bit = 0;
if (x & 0xff00)
{
x >>= 8;
}
else
{
bit += 8;
}
return bit + clz8 (x);
}
/**
* \internal
* \brief Count leading zeros in unsigned, 32-bit integer
*
* \param x Unsigned double word to count the leading zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
clz32 (uint32_t x)
{
uint8_t bit = 0;
if (x & 0xffff0000)
{
x >>= 16;
}
else
{
bit += 16;
}
return bit + clz16 (x);
}
/**
* \brief Count trailing zeros in unsigned integer
*
* This macro takes unsigned integers of any size, and evaluates to a call to
* the ctz-function for its size. These functions count the number of zeros,
* starting with the LSB, before a one occurs in the integer.
*
* \param x Unsigned integer to count the trailing zeros in.
*
* \return The number of trailing zeros in \a x.
*/
#define ctz(x) compiler_demux_size(sizeof(x), ctz, (x))
/**
* \internal
* \brief Count trailing zeros in unsigned, 8-bit integer
*
* \param x Unsigned byte to count the trailing zeros in.
*
* \return The number of leading zeros in \a x.
*/
__always_inline static uint8_t
ctz8 (uint8_t x)
{
uint8_t bit = 0;
if (!(x & 0x0f))
{
bit += 4;
x >>= 4;
}
if (!(x & 0x03))
{
bit += 2;
x >>= 2;
}
if (!(x & 0x01))
bit++;
return bit;
}
/**
* \internal
* \brief Count trailing zeros in unsigned, 16-bit integer
*
* \param x Unsigned word to count the trailing zeros in.
*
* \return The number of trailing zeros in \a x.
*/
__always_inline static uint8_t
ctz16 (uint16_t x)
{
uint8_t bit = 0;
if (!(x & 0x00ff))
{
bit += 8;
x >>= 8;
}
return bit + ctz8 (x);
}
/**
* \internal
* \brief Count trailing zeros in unsigned, 32-bit integer
*
* \param x Unsigned double word to count the trailing zeros in.
*
* \return The number of trailing zeros in \a x.
*/
__always_inline static uint8_t
ctz32 (uint32_t x)
{
uint8_t bit = 0;
if (!(x & 0x0000ffff))
{
bit += 16;
x >>= 16;
}
return bit + ctz16 (x);
}
#endif /* CLZ_CTZ_H */
File diff suppressed because it is too large Load Diff
@@ -1,335 +1,335 @@
/**
* \file
*
* \brief Preprocessor macro repeating utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _MREPEAT_H_
#define _MREPEAT_H_
/**
* \defgroup group_xmega_utils_mrepeat Macro Repeat
*
* \ingroup group_xmega_utils
*
* \{
*/
#include "preprocessor.h"
//! Maximal number of repetitions supported by MREPEAT.
#define MREPEAT_LIMIT 256
/*! \brief Macro repeat.
*
* This macro represents a horizontal repetition construct.
*
* \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT.
* \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with
* the current repetition number and the auxiliary data argument.
* \param data Auxiliary data passed to macro.
*
* \return <tt>macro(0, data) macro(1, data) ... macro(count - 1, data)</tt>
*/
#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data)
#define MREPEAT0( macro, data)
#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data)
#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data)
#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data)
#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data)
#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data)
#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data)
#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data)
#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data)
#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data)
#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data)
#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data)
#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data)
#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data)
#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data)
#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data)
#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data)
#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data)
#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data)
#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data)
#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data)
#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data)
#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data)
#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data)
#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data)
#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data)
#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data)
#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data)
#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data)
#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data)
#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data)
#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data)
#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data)
#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data)
#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data)
#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data)
#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data)
#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data)
#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data)
#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data)
#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data)
#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data)
#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data)
#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data)
#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data)
#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data)
#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data)
#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data)
#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data)
#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data)
#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data)
#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data)
#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data)
#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data)
#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data)
#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data)
#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data)
#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data)
#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data)
#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data)
#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data)
#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data)
#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data)
#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data)
#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data)
#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data)
#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data)
#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data)
#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data)
#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data)
#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data)
#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data)
#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data)
#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data)
#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data)
#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data)
#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data)
#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data)
#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data)
#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data)
#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data)
#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data)
#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data)
#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data)
#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data)
#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data)
#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data)
#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data)
#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data)
#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data)
#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data)
#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data)
#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data)
#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data)
#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data)
#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data)
#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data)
#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data)
#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data)
#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data)
#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data)
#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data)
#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data)
#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data)
#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data)
#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data)
#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data)
#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data)
#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data)
#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data)
#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data)
#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data)
#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data)
#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data)
#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data)
#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data)
#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data)
#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data)
#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data)
#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data)
#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data)
#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data)
#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data)
#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data)
#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data)
#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data)
#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data)
#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data)
#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data)
#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data)
#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data)
#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data)
#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data)
#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data)
#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data)
#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data)
#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data)
#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data)
#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data)
#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data)
#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data)
#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data)
#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data)
#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data)
#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data)
#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data)
#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data)
#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data)
#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data)
#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data)
#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data)
#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data)
#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data)
#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data)
#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data)
#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data)
#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data)
#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data)
#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data)
#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data)
#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data)
#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data)
#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data)
#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data)
#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data)
#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data)
#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data)
#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data)
#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data)
#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data)
#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data)
#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data)
#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data)
#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data)
#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data)
#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data)
#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data)
#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data)
#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data)
#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data)
#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data)
#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data)
#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data)
#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data)
#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data)
#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data)
#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data)
#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data)
#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data)
#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data)
#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data)
#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data)
#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data)
#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data)
#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data)
#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data)
#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data)
#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data)
#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data)
#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data)
#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data)
#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data)
#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data)
#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data)
#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data)
#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data)
#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data)
#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data)
#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data)
#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data)
#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data)
#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data)
#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data)
#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data)
#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data)
#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data)
#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data)
#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data)
#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data)
#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data)
#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data)
#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data)
#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data)
#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data)
#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data)
#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data)
#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data)
#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data)
#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data)
#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data)
#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data)
#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data)
#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data)
#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data)
#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data)
#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data)
#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data)
#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data)
#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data)
#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data)
#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data)
#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data)
#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data)
#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data)
#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data)
#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data)
#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data)
#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data)
#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data)
#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data)
#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data)
#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data)
#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data)
#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data)
#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data)
#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data)
#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data)
/**
* \}
*/
#endif // _MREPEAT_H_
/**
* \file
*
* \brief Preprocessor macro repeating utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _MREPEAT_H_
#define _MREPEAT_H_
/**
* \defgroup group_xmega_utils_mrepeat Macro Repeat
*
* \ingroup group_xmega_utils
*
* \{
*/
#include "preprocessor.h"
//! Maximal number of repetitions supported by MREPEAT.
#define MREPEAT_LIMIT 256
/*! \brief Macro repeat.
*
* This macro represents a horizontal repetition construct.
*
* \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT.
* \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with
* the current repetition number and the auxiliary data argument.
* \param data Auxiliary data passed to macro.
*
* \return <tt>macro(0, data) macro(1, data) ... macro(count - 1, data)</tt>
*/
#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data)
#define MREPEAT0( macro, data)
#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data)
#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data)
#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data)
#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data)
#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data)
#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data)
#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data)
#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data)
#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data)
#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data)
#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data)
#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data)
#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data)
#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data)
#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data)
#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data)
#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data)
#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data)
#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data)
#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data)
#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data)
#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data)
#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data)
#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data)
#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data)
#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data)
#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data)
#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data)
#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data)
#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data)
#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data)
#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data)
#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data)
#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data)
#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data)
#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data)
#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data)
#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data)
#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data)
#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data)
#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data)
#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data)
#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data)
#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data)
#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data)
#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data)
#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data)
#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data)
#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data)
#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data)
#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data)
#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data)
#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data)
#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data)
#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data)
#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data)
#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data)
#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data)
#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data)
#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data)
#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data)
#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data)
#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data)
#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data)
#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data)
#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data)
#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data)
#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data)
#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data)
#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data)
#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data)
#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data)
#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data)
#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data)
#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data)
#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data)
#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data)
#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data)
#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data)
#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data)
#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data)
#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data)
#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data)
#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data)
#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data)
#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data)
#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data)
#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data)
#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data)
#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data)
#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data)
#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data)
#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data)
#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data)
#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data)
#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data)
#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data)
#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data)
#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data)
#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data)
#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data)
#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data)
#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data)
#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data)
#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data)
#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data)
#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data)
#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data)
#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data)
#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data)
#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data)
#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data)
#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data)
#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data)
#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data)
#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data)
#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data)
#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data)
#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data)
#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data)
#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data)
#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data)
#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data)
#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data)
#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data)
#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data)
#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data)
#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data)
#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data)
#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data)
#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data)
#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data)
#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data)
#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data)
#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data)
#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data)
#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data)
#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data)
#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data)
#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data)
#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data)
#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data)
#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data)
#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data)
#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data)
#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data)
#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data)
#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data)
#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data)
#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data)
#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data)
#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data)
#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data)
#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data)
#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data)
#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data)
#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data)
#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data)
#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data)
#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data)
#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data)
#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data)
#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data)
#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data)
#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data)
#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data)
#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data)
#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data)
#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data)
#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data)
#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data)
#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data)
#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data)
#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data)
#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data)
#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data)
#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data)
#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data)
#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data)
#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data)
#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data)
#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data)
#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data)
#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data)
#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data)
#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data)
#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data)
#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data)
#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data)
#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data)
#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data)
#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data)
#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data)
#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data)
#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data)
#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data)
#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data)
#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data)
#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data)
#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data)
#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data)
#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data)
#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data)
#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data)
#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data)
#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data)
#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data)
#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data)
#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data)
#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data)
#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data)
#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data)
#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data)
#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data)
#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data)
#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data)
#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data)
#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data)
#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data)
#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data)
#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data)
#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data)
#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data)
#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data)
#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data)
#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data)
#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data)
#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data)
#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data)
#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data)
#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data)
#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data)
#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data)
#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data)
#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data)
#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data)
#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data)
#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data)
#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data)
#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data)
#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data)
#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data)
#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data)
#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data)
#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data)
#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data)
#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data)
#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data)
#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data)
#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data)
#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data)
#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data)
#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data)
#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data)
#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data)
#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data)
/**
* \}
*/
#endif // _MREPEAT_H_
@@ -1,51 +1,51 @@
/**
* \file
*
* \brief Preprocessor utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _PREPROCESSOR_H_
#define _PREPROCESSOR_H_
#include "tpaste.h"
#include "stringz.h"
#include "mrepeat.h"
#endif // _PREPROCESSOR_H_
/**
* \file
*
* \brief Preprocessor utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _PREPROCESSOR_H_
#define _PREPROCESSOR_H_
#include "tpaste.h"
#include "stringz.h"
#include "mrepeat.h"
#endif // _PREPROCESSOR_H_
@@ -1,81 +1,81 @@
/**
* \file
*
* \brief Preprocessor stringizing utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _STRINGZ_H_
#define _STRINGZ_H_
/**
* \defgroup group_xmega_utils_stringz Stringize
*
* \ingroup group_xmega_utils
*
* \{
*/
/*! \brief Stringize.
*
* Stringize a preprocessing token, this token being allowed to be \#defined.
*
* May be used only within macros with the token passed as an argument if the token is \#defined.
*
* For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN)
* and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to
* writing "A0".
*/
#define STRINGZ(x) #x
/*! \brief Absolute stringize.
*
* Stringize a preprocessing token, this token being allowed to be \#defined.
*
* No restriction of use if the token is \#defined.
*
* For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is
* equivalent to writing "A0".
*/
#define ASTRINGZ(x) STRINGZ(x)
/**
* \}
*/
#endif // _STRINGZ_H_
/**
* \file
*
* \brief Preprocessor stringizing utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _STRINGZ_H_
#define _STRINGZ_H_
/**
* \defgroup group_xmega_utils_stringz Stringize
*
* \ingroup group_xmega_utils
*
* \{
*/
/*! \brief Stringize.
*
* Stringize a preprocessing token, this token being allowed to be \#defined.
*
* May be used only within macros with the token passed as an argument if the token is \#defined.
*
* For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN)
* and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to
* writing "A0".
*/
#define STRINGZ(x) #x
/*! \brief Absolute stringize.
*
* Stringize a preprocessing token, this token being allowed to be \#defined.
*
* No restriction of use if the token is \#defined.
*
* For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is
* equivalent to writing "A0".
*/
#define ASTRINGZ(x) STRINGZ(x)
/**
* \}
*/
#endif // _STRINGZ_H_
@@ -1,101 +1,101 @@
/**
* \file
*
* \brief Preprocessor token pasting utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _TPASTE_H_
#define _TPASTE_H_
/**
* \defgroup group_xmega_utils_tpaste Token Paste
*
* \ingroup group_xmega_utils
*
* \{
*/
/*! \name Token Paste
*
* Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
*
* May be used only within macros with the tokens passed as arguments if the tokens are \#defined.
*
* For example, writing TPASTE2(U, WIDTH) within a macro \#defined by
* UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is
* equivalent to writing U32.
*/
//! @{
#define TPASTE2( a, b) a##b
#define TPASTE3( a, b, c) a##b##c
#define TPASTE4( a, b, c, d) a##b##c##d
#define TPASTE5( a, b, c, d, e) a##b##c##d##e
#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f
#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g
#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h
#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i
#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j
//! @}
/*! \name Absolute Token Paste
*
* Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
*
* No restriction of use if the tokens are \#defined.
*
* For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined
* as 32 is equivalent to writing U32.
*/
//! @{
#define ATPASTE2( a, b) TPASTE2( a, b)
#define ATPASTE3( a, b, c) TPASTE3( a, b, c)
#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d)
#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e)
#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f)
#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g)
#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h)
#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i)
#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j)
//! @}
/**
* \}
*/
#endif // _TPASTE_H_
/**
* \file
*
* \brief Preprocessor token pasting utils.
*
* Copyright (c) 2009 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _TPASTE_H_
#define _TPASTE_H_
/**
* \defgroup group_xmega_utils_tpaste Token Paste
*
* \ingroup group_xmega_utils
*
* \{
*/
/*! \name Token Paste
*
* Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
*
* May be used only within macros with the tokens passed as arguments if the tokens are \#defined.
*
* For example, writing TPASTE2(U, WIDTH) within a macro \#defined by
* UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is
* equivalent to writing U32.
*/
//! @{
#define TPASTE2( a, b) a##b
#define TPASTE3( a, b, c) a##b##c
#define TPASTE4( a, b, c, d) a##b##c##d
#define TPASTE5( a, b, c, d, e) a##b##c##d##e
#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f
#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g
#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h
#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i
#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j
//! @}
/*! \name Absolute Token Paste
*
* Paste N preprocessing tokens together, these tokens being allowed to be \#defined.
*
* No restriction of use if the tokens are \#defined.
*
* For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined
* as 32 is equivalent to writing U32.
*/
//! @{
#define ATPASTE2( a, b) TPASTE2( a, b)
#define ATPASTE3( a, b, c) TPASTE3( a, b, c)
#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d)
#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e)
#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f)
#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g)
#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h)
#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i)
#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j)
//! @}
/**
* \}
*/
#endif // _TPASTE_H_
@@ -1,99 +1,99 @@
/**
* \file
*
* \brief Program memory access
*
* Copyright (c) 2010 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef UTILS_PROGMEM_H
#define UTILS_PROGMEM_H
/**
* \defgroup group_xmega_utils_progmem Program memory
*
* \ingroup group_xmega_utils
*
* \{
*/
/*! \name Program memory
*
* Macros for locating and accessing data in program memory.
*
* @{
*/
#if defined(__GNUC__) || defined(__DOXYGEN__)
# include <avr/pgmspace.h>
# define PROGMEM_LOCATION(type, name, loc) \
type name __attribute__((section (#loc)))
# define PROGMEM_DECLARE(type, name) const type name __attribute__((__progmem__))
# define PROGMEM_STRING(x) PSTR(x)
# define PROGMEM_STRING_T PGM_P
# define PROGMEM_T const
# define PROGMEM_PTR_T const *
# define PROGMEM_BYTE_ARRAY_T uint8_t*
# define PROGMEM_WORD_ARRAY_T uint16_t*
# define PROGMEM_READ_BYTE(x) pgm_read_byte(x)
# define PROGMEM_READ_WORD(x) pgm_read_word(x)
#elif defined(__ICCAVR__)
# include <pgmspace.h>
# ifndef __HAS_ELPM__
# define _MEMATTR_ASF __flash
# else /* __HAS_ELPM__ */
# define _MEMATTR_ASF __hugeflash
# endif /* __HAS_ELPM__ */
# define PROGMEM_LOCATION(type, name, loc) const _MEMATTR_ASF type name @ loc
# define PROGMEM_DECLARE(type, name) _MEMATTR_ASF type name
# define PROGMEM_STRING(x) ((_MEMATTR_ASF const char *)(x))
# define PROGMEM_STRING_T char const _MEMATTR_ASF *
# define PROGMEM_T const _MEMATTR_ASF
# define PROGMEM_PTR_T const _MEMATTR_ASF *
# define PROGMEM_BYTE_ARRAY_T uint8_t const _MEMATTR_ASF *
# define PROGMEM_WORD_ARRAY_T uint16_t const _MEMATTR_ASF *
# define PROGMEM_READ_BYTE(x) *(x)
# define PROGMEM_READ_WORD(x) *(x)
#endif
//! @}
/**
* \}
*/
#endif /* UTILS_PROGMEM_H */
/**
* \file
*
* \brief Program memory access
*
* Copyright (c) 2010 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef UTILS_PROGMEM_H
#define UTILS_PROGMEM_H
/**
* \defgroup group_xmega_utils_progmem Program memory
*
* \ingroup group_xmega_utils
*
* \{
*/
/*! \name Program memory
*
* Macros for locating and accessing data in program memory.
*
* @{
*/
#if defined(__GNUC__) || defined(__DOXYGEN__)
# include <avr/pgmspace.h>
# define PROGMEM_LOCATION(type, name, loc) \
type name __attribute__((section (#loc)))
# define PROGMEM_DECLARE(type, name) const type name __attribute__((__progmem__))
# define PROGMEM_STRING(x) PSTR(x)
# define PROGMEM_STRING_T PGM_P
# define PROGMEM_T const
# define PROGMEM_PTR_T const *
# define PROGMEM_BYTE_ARRAY_T uint8_t*
# define PROGMEM_WORD_ARRAY_T uint16_t*
# define PROGMEM_READ_BYTE(x) pgm_read_byte(x)
# define PROGMEM_READ_WORD(x) pgm_read_word(x)
#elif defined(__ICCAVR__)
# include <pgmspace.h>
# ifndef __HAS_ELPM__
# define _MEMATTR_ASF __flash
# else /* __HAS_ELPM__ */
# define _MEMATTR_ASF __hugeflash
# endif /* __HAS_ELPM__ */
# define PROGMEM_LOCATION(type, name, loc) const _MEMATTR_ASF type name @ loc
# define PROGMEM_DECLARE(type, name) _MEMATTR_ASF type name
# define PROGMEM_STRING(x) ((_MEMATTR_ASF const char *)(x))
# define PROGMEM_STRING_T char const _MEMATTR_ASF *
# define PROGMEM_T const _MEMATTR_ASF
# define PROGMEM_PTR_T const _MEMATTR_ASF *
# define PROGMEM_BYTE_ARRAY_T uint8_t const _MEMATTR_ASF *
# define PROGMEM_WORD_ARRAY_T uint16_t const _MEMATTR_ASF *
# define PROGMEM_READ_BYTE(x) *(x)
# define PROGMEM_READ_WORD(x) *(x)
#endif
//! @}
/**
* \}
*/
#endif /* UTILS_PROGMEM_H */
@@ -1,119 +1,119 @@
/**
* \file
*
* \brief Status code definitions.
*
* This file defines various status codes returned by functions,
* indicating success or failure as well as what kind of failure.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef STATUS_CODES_H_INCLUDED
#define STATUS_CODES_H_INCLUDED
/**
* \defgroup group_xmega_utils_status_codes Status Codes
*
* \ingroup group_xmega_utils
*
* \{
*/
/* Note: this is a local workaround to avoid a pre-processor clash due to the
* lwIP macro ERR_TIMEOUT. */
#if defined(__LWIP_ERR_H__) && defined(ERR_TIMEOUT)
#if (ERR_TIMEOUT != -3)
/* Internal check to make sure that the later restore of lwIP's ERR_TIMEOUT
* macro is set to the correct value. Note that it is highly improbable that
* this value ever changes in lwIP. */
#error ASF developers: check lwip err.h new value for ERR_TIMEOUT
#endif
#undef ERR_TIMEOUT
#endif
/**
* Status code that may be returned by shell commands and protocol
* implementations.
*
* \note Any change to these status codes and the corresponding
* message strings is strictly forbidden. New codes can be added,
* however, but make sure that any message string tables are updated
* at the same time.
*/
enum status_code
{
STATUS_OK = 0, //!< Success
ERR_IO_ERROR = -1, //!< I/O error
ERR_FLUSHED = -2, //!< Request flushed from queue
ERR_TIMEOUT = -3, //!< Operation timed out
ERR_BAD_DATA = -4, //!< Data integrity check failed
ERR_PROTOCOL = -5, //!< Protocol error
ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device
ERR_NO_MEMORY = -7, //!< Insufficient memory
ERR_INVALID_ARG = -8, //!< Invalid argument
ERR_BAD_ADDRESS = -9, //!< Bad address
ERR_BUSY = -10, //!< Resource is busy
ERR_BAD_FORMAT = -11, //!< Data format not recognized
ERR_NO_TIMER = -12, //!< No timer available
ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running
ERR_TIMER_NOT_RUNNING = -14, //!< Timer not running
/**
* \brief Operation in progress
*
* This status code is for driver-internal use when an operation
* is currently being performed.
*
* \note Drivers should never return this status code to any
* callers. It is strictly for internal use.
*/
OPERATION_IN_PROGRESS = -128,
};
typedef enum status_code status_code_t;
#if defined(__LWIP_ERR_H__)
#define ERR_TIMEOUT -3
#endif
/**
* \}
*/
#endif /* STATUS_CODES_H_INCLUDED */
/**
* \file
*
* \brief Status code definitions.
*
* This file defines various status codes returned by functions,
* indicating success or failure as well as what kind of failure.
*
* Copyright (c) 2009-2013 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef STATUS_CODES_H_INCLUDED
#define STATUS_CODES_H_INCLUDED
/**
* \defgroup group_xmega_utils_status_codes Status Codes
*
* \ingroup group_xmega_utils
*
* \{
*/
/* Note: this is a local workaround to avoid a pre-processor clash due to the
* lwIP macro ERR_TIMEOUT. */
#if defined(__LWIP_ERR_H__) && defined(ERR_TIMEOUT)
#if (ERR_TIMEOUT != -3)
/* Internal check to make sure that the later restore of lwIP's ERR_TIMEOUT
* macro is set to the correct value. Note that it is highly improbable that
* this value ever changes in lwIP. */
#error ASF developers: check lwip err.h new value for ERR_TIMEOUT
#endif
#undef ERR_TIMEOUT
#endif
/**
* Status code that may be returned by shell commands and protocol
* implementations.
*
* \note Any change to these status codes and the corresponding
* message strings is strictly forbidden. New codes can be added,
* however, but make sure that any message string tables are updated
* at the same time.
*/
enum status_code
{
STATUS_OK = 0, //!< Success
ERR_IO_ERROR = -1, //!< I/O error
ERR_FLUSHED = -2, //!< Request flushed from queue
ERR_TIMEOUT = -3, //!< Operation timed out
ERR_BAD_DATA = -4, //!< Data integrity check failed
ERR_PROTOCOL = -5, //!< Protocol error
ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device
ERR_NO_MEMORY = -7, //!< Insufficient memory
ERR_INVALID_ARG = -8, //!< Invalid argument
ERR_BAD_ADDRESS = -9, //!< Bad address
ERR_BUSY = -10, //!< Resource is busy
ERR_BAD_FORMAT = -11, //!< Data format not recognized
ERR_NO_TIMER = -12, //!< No timer available
ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running
ERR_TIMER_NOT_RUNNING = -14, //!< Timer not running
/**
* \brief Operation in progress
*
* This status code is for driver-internal use when an operation
* is currently being performed.
*
* \note Drivers should never return this status code to any
* callers. It is strictly for internal use.
*/
OPERATION_IN_PROGRESS = -128,
};
typedef enum status_code status_code_t;
#if defined(__LWIP_ERR_H__)
#define ERR_TIMEOUT -3
#endif
/**
* \}
*/
#endif /* STATUS_CODES_H_INCLUDED */
+183 -183
View File
@@ -1,183 +1,183 @@
/**************************************************************************
*
* Copyright (C) 2014 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <asf.h>
#include <util/atomic.h>
#include "adc-hdw.h"
/* samples */
#define ADC_CHANNELS_MAX 10
static uint16_t ADC_Channel_Value[ADC_CHANNELS_MAX];
static uint8_t ADC_Current_Channel;
/*************************************************************************
* DESCRIPTION: set the active channel in the ADC
* RETURN: nothing
* NOTES: called from ISR, so handle as non-blocking
**************************************************************************/
static void adc_set_channel(unsigned channel)
{
struct adc_channel_config adc_ch_conf;
ADC_Current_Channel = channel;
adcch_read_configuration(&ADCA, ADC_CH0, &adc_ch_conf);
switch (channel) {
case 0:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN7, ADCCH_NEG_PIN1, 1);
break;
case 1:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN8, ADCCH_NEG_PIN1, 1);
break;
case 2:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN9, ADCCH_NEG_PIN1, 1);
break;
case 3:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN10, ADCCH_NEG_PIN1, 1);
break;
case 4:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN11, ADCCH_NEG_PIN1, 1);
break;
case 5:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN2, ADCCH_NEG_PIN1, 1);
break;
case 6:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN3, ADCCH_NEG_PIN1, 1);
break;
case 7:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN4, ADCCH_NEG_PIN1, 1);
break;
case 8:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN5, ADCCH_NEG_PIN1, 1);
break;
case 9:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN6, ADCCH_NEG_PIN1, 1);
break;
default:
break;
}
adcch_set_interrupt_mode(&adc_ch_conf, ADCCH_MODE_COMPLETE);
adcch_enable_interrupt(&adc_ch_conf);
adcch_write_configuration(&ADCA, ADC_CH0, &adc_ch_conf);
}
/*************************************************************************
* DESCRIPTION: run the active channels through the ADC
* RETURN: nothing
* NOTES: called from ISR, so handle as non-blocking
**************************************************************************/
static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t raw_value)
{
unsigned channel;
channel = ADC_Current_Channel;
if (channel < ADC_CHANNELS_MAX) {
ADC_Channel_Value[channel] = raw_value;
}
channel++;
if (channel >= ADC_CHANNELS_MAX) {
channel = 0;
}
adc_set_channel(channel);
}
/*************************************************************************
* DESCRIPTION: initialize Analog to Digital Converter (ADC)
* RETURN: nothing
* NOTES: none
**************************************************************************/
void adc_init(void)
{
struct adc_config adc_conf;
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 7),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 0),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 2),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 3),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 3),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 4),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 5),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 6),IOPORT_DIR_INPUT);
/* Clear the ADC configuration structs */
adc_read_configuration(&ADCA, &adc_conf);
adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_AREFA);
adc_set_clock_rate(&adc_conf, 200000UL);
adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
adc_write_configuration(&ADCA, &adc_conf);
adc_set_callback(&ADCA, &adc_handler);
adc_set_channel(0);
/* Enable the ADC and start the first conversion. */
adc_enable(&ADCA);
}
/*************************************************************************
* DESCRIPTION: Get a result from the ADC 10-bit value
* RETURN: 12-bit ADC value
* NOTES: channel 0..9 are supported
**************************************************************************/
uint16_t adc_result_12bit(uint8_t channel)
{
uint16_t value = 0;
if (channel < ADC_CHANNELS_MAX) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
value = ADC_Channel_Value[channel];
}
}
return value;
}
/*************************************************************************
* DESCRIPTION: Get a result from the ADC 10-bit value
* RETURN: 10-bit ADC value
* NOTES: channel 0..9 are supported
**************************************************************************/
uint16_t adc_result_10bit(uint8_t channel)
{
uint16_t result;
result = adc_result_12bit(channel);
result >>= 2;
return result;
}
/*************************************************************************
* DESCRIPTION: Get a result from the ADC 8-bit value
* RETURN: 8-bit ADC value
* NOTES: channel 0..9 are supported
**************************************************************************/
uint8_t adc_result_8bit(uint8_t channel)
{
uint16_t result;
result = adc_result_12bit(channel);
result >>= 4;
return result;
}
/**************************************************************************
*
* Copyright (C) 2014 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <asf.h>
#include <util/atomic.h>
#include "adc-hdw.h"
/* samples */
#define ADC_CHANNELS_MAX 10
static uint16_t ADC_Channel_Value[ADC_CHANNELS_MAX];
static uint8_t ADC_Current_Channel;
/*************************************************************************
* DESCRIPTION: set the active channel in the ADC
* RETURN: nothing
* NOTES: called from ISR, so handle as non-blocking
**************************************************************************/
static void adc_set_channel(unsigned channel)
{
struct adc_channel_config adc_ch_conf;
ADC_Current_Channel = channel;
adcch_read_configuration(&ADCA, ADC_CH0, &adc_ch_conf);
switch (channel) {
case 0:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN7, ADCCH_NEG_PIN1, 1);
break;
case 1:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN8, ADCCH_NEG_PIN1, 1);
break;
case 2:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN9, ADCCH_NEG_PIN1, 1);
break;
case 3:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN10, ADCCH_NEG_PIN1, 1);
break;
case 4:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN11, ADCCH_NEG_PIN1, 1);
break;
case 5:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN2, ADCCH_NEG_PIN1, 1);
break;
case 6:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN3, ADCCH_NEG_PIN1, 1);
break;
case 7:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN4, ADCCH_NEG_PIN1, 1);
break;
case 8:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN5, ADCCH_NEG_PIN1, 1);
break;
case 9:
adcch_set_input(&adc_ch_conf, ADCCH_POS_PIN6, ADCCH_NEG_PIN1, 1);
break;
default:
break;
}
adcch_set_interrupt_mode(&adc_ch_conf, ADCCH_MODE_COMPLETE);
adcch_enable_interrupt(&adc_ch_conf);
adcch_write_configuration(&ADCA, ADC_CH0, &adc_ch_conf);
}
/*************************************************************************
* DESCRIPTION: run the active channels through the ADC
* RETURN: nothing
* NOTES: called from ISR, so handle as non-blocking
**************************************************************************/
static void adc_handler(ADC_t *adc, uint8_t ch_mask, adc_result_t raw_value)
{
unsigned channel;
channel = ADC_Current_Channel;
if (channel < ADC_CHANNELS_MAX) {
ADC_Channel_Value[channel] = raw_value;
}
channel++;
if (channel >= ADC_CHANNELS_MAX) {
channel = 0;
}
adc_set_channel(channel);
}
/*************************************************************************
* DESCRIPTION: initialize Analog to Digital Converter (ADC)
* RETURN: nothing
* NOTES: none
**************************************************************************/
void adc_init(void)
{
struct adc_config adc_conf;
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 7),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 0),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 1),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 2),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTB, 3),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 2),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 3),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 4),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 5),IOPORT_DIR_INPUT);
ioport_configure_pin(IOPORT_CREATE_PIN(PORTA, 6),IOPORT_DIR_INPUT);
/* Clear the ADC configuration structs */
adc_read_configuration(&ADCA, &adc_conf);
adc_set_conversion_parameters(&adc_conf, ADC_SIGN_ON, ADC_RES_12, ADC_REF_AREFA);
adc_set_clock_rate(&adc_conf, 200000UL);
adc_set_conversion_trigger(&adc_conf, ADC_TRIG_MANUAL, 1, 0);
adc_write_configuration(&ADCA, &adc_conf);
adc_set_callback(&ADCA, &adc_handler);
adc_set_channel(0);
/* Enable the ADC and start the first conversion. */
adc_enable(&ADCA);
}
/*************************************************************************
* DESCRIPTION: Get a result from the ADC 10-bit value
* RETURN: 12-bit ADC value
* NOTES: channel 0..9 are supported
**************************************************************************/
uint16_t adc_result_12bit(uint8_t channel)
{
uint16_t value = 0;
if (channel < ADC_CHANNELS_MAX) {
ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
value = ADC_Channel_Value[channel];
}
}
return value;
}
/*************************************************************************
* DESCRIPTION: Get a result from the ADC 10-bit value
* RETURN: 10-bit ADC value
* NOTES: channel 0..9 are supported
**************************************************************************/
uint16_t adc_result_10bit(uint8_t channel)
{
uint16_t result;
result = adc_result_12bit(channel);
result >>= 2;
return result;
}
/*************************************************************************
* DESCRIPTION: Get a result from the ADC 8-bit value
* RETURN: 8-bit ADC value
* NOTES: channel 0..9 are supported
**************************************************************************/
uint8_t adc_result_8bit(uint8_t channel)
{
uint16_t result;
result = adc_result_12bit(channel);
result >>= 4;
return result;
}
+42 -42
View File
@@ -1,42 +1,42 @@
/**************************************************************************
*
* Copyright (C) 2014 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef ADC_HDW_H
#define ADC_HDW_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void adc_init (void);
uint16_t adc_result_12bit(uint8_t channel);
uint16_t adc_result_10bit(uint8_t channel);
uint8_t adc_result_8bit(uint8_t channel);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2014 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef ADC_HDW_H
#define ADC_HDW_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void adc_init (void);
uint16_t adc_result_12bit(uint8_t channel);
uint16_t adc_result_10bit(uint8_t channel);
uint8_t adc_result_8bit(uint8_t channel);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+372 -372
View File
@@ -1,372 +1,372 @@
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Input Objects customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h"
#include "ai.h"
#include "handlers.h"
#ifndef MAX_ANALOG_INPUTS
#define MAX_ANALOG_INPUTS 2
#endif
static float Present_Value[MAX_ANALOG_INPUTS];
static bool Out_Of_Service[MAX_ANALOG_INPUTS];
static BACNET_ENGINEERING_UNITS Units[MAX_ANALOG_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Input_Properties_Optional[] = {
-1
};
static const int Analog_Input_Properties_Proprietary[] = {
-1
};
void Analog_Input_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
if (pRequired)
*pRequired = Analog_Input_Properties_Required;
if (pOptional)
*pOptional = Analog_Input_Properties_Optional;
if (pProprietary)
*pProprietary = Analog_Input_Properties_Proprietary;
return;
}
void Analog_Input_Init(
void)
{
return;
}
/* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance(
unsigned index)
{
return index;
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Instance_To_Index(
uint32_t instance)
{
return instance;
}
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(
uint32_t object_instance)
{
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
return true;
}
return false;
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Count(
void)
{
return MAX_ANALOG_INPUTS;
}
bool Analog_Input_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
{
static char text_string[32]; /* okay for single thread */
bool status = false;
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
sprintf(text_string, "AI-%lu", object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
float Analog_Input_Present_Value(
uint32_t object_instance)
{
float value = 0.0;
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
value = Present_Value[index];
}
return value;
}
void Analog_Input_Present_Value_Set(
uint32_t object_instance,
float value)
{
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
Present_Value[index] = value;
}
}
bool Analog_Input_Out_Of_Service(
uint32_t object_instance)
{
unsigned index = 0;
bool value = false;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
value = Out_Of_Service[index];
}
return value;
}
void Analog_Input_Out_Of_Service_Set(
uint32_t object_instance,
bool value)
{
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
Out_Of_Service[index] = value;
}
}
bool Analog_Input_Units_Set(
uint32_t object_instance,
uint16_t value)
{
unsigned index = 0;
bool status = false;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
Units[index] = value;
status = true;
}
return status;
}
uint16_t Analog_Input_Units(
uint32_t object_instance)
{
unsigned index = 0;
uint16_t value = UNITS_NO_UNITS;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
value = Units[index];
}
return value;
}
/* return apdu length, or -1 on error */
/* assumption - object already exists */
int Analog_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
{
int apdu_len = 0; /* return value */
BACNET_CHARACTER_STRING char_string = { 0 };
BACNET_BIT_STRING bit_string = { 0 };
uint8_t *apdu = NULL;
if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], rpdata->object_type,
rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
Analog_Input_Object_Name(rpdata->object_instance, &char_string);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], rpdata->object_type);
break;
case PROP_PRESENT_VALUE:
apdu_len =
encode_application_real(&apdu[0],
Analog_Input_Present_Value(rpdata->object_instance));
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE,
Analog_Input_Out_Of_Service(rpdata->object_instance));
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0],
Analog_Input_Out_Of_Service(rpdata->object_instance));
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0],
Analog_Input_Units(rpdata->object_instance));
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = BACNET_STATUS_ERROR;
break;
}
/* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR;
}
return apdu_len;
}
/* returns true if successful */
bool Analog_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
/* error while decoding - a value larger than we can handle */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
return false;
}
/* only array properties can have array options */
if ((wp_data->object_property != PROP_EVENT_TIME_STAMPS) &&
(wp_data->array_index != BACNET_ARRAY_ALL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false;
}
switch ((int) wp_data->object_property) {
case PROP_PRESENT_VALUE:
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code);
if (status) {
if (Analog_Input_Out_Of_Service(wp_data->object_instance)) {
Analog_Input_Present_Value_Set(wp_data->object_instance,
value.type.Real);
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
status = false;
}
}
break;
case PROP_OUT_OF_SERVICE:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Analog_Input_Out_Of_Service_Set(
wp_data->object_instance,
value.type.Boolean);
}
break;
case PROP_UNITS:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Analog_Input_Out_Of_Service_Set(
wp_data->object_instance,
value.type.Enumerated);
}
break;
case PROP_OBJECT_IDENTIFIER:
case PROP_OBJECT_NAME:
case PROP_OBJECT_TYPE:
case PROP_STATUS_FLAGS:
case PROP_EVENT_STATE:
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
default:
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
break;
}
return status;
}
/**************************************************************************
*
* Copyright (C) 2005 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
/* Analog Input Objects customize for your use */
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacenum.h"
#include "config.h"
#include "ai.h"
#include "handlers.h"
#ifndef MAX_ANALOG_INPUTS
#define MAX_ANALOG_INPUTS 2
#endif
static float Present_Value[MAX_ANALOG_INPUTS];
static bool Out_Of_Service[MAX_ANALOG_INPUTS];
static BACNET_ENGINEERING_UNITS Units[MAX_ANALOG_INPUTS];
/* These three arrays are used by the ReadPropertyMultiple handler */
static const int Analog_Input_Properties_Required[] = {
PROP_OBJECT_IDENTIFIER,
PROP_OBJECT_NAME,
PROP_OBJECT_TYPE,
PROP_PRESENT_VALUE,
PROP_STATUS_FLAGS,
PROP_EVENT_STATE,
PROP_OUT_OF_SERVICE,
PROP_UNITS,
-1
};
static const int Analog_Input_Properties_Optional[] = {
-1
};
static const int Analog_Input_Properties_Proprietary[] = {
-1
};
void Analog_Input_Property_Lists(
const int **pRequired,
const int **pOptional,
const int **pProprietary)
{
if (pRequired)
*pRequired = Analog_Input_Properties_Required;
if (pOptional)
*pOptional = Analog_Input_Properties_Optional;
if (pProprietary)
*pProprietary = Analog_Input_Properties_Proprietary;
return;
}
void Analog_Input_Init(
void)
{
return;
}
/* we simply have 0-n object instances. */
uint32_t Analog_Input_Index_To_Instance(
unsigned index)
{
return index;
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Instance_To_Index(
uint32_t instance)
{
return instance;
}
/* we simply have 0-n object instances. Yours might be */
/* more complex, and then you need validate that the */
/* given instance exists */
bool Analog_Input_Valid_Instance(
uint32_t object_instance)
{
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
return true;
}
return false;
}
/* we simply have 0-n object instances. */
unsigned Analog_Input_Count(
void)
{
return MAX_ANALOG_INPUTS;
}
bool Analog_Input_Object_Name(
uint32_t object_instance,
BACNET_CHARACTER_STRING * object_name)
{
static char text_string[32]; /* okay for single thread */
bool status = false;
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
sprintf(text_string, "AI-%lu", object_instance);
status = characterstring_init_ansi(object_name, text_string);
}
return status;
}
float Analog_Input_Present_Value(
uint32_t object_instance)
{
float value = 0.0;
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
value = Present_Value[index];
}
return value;
}
void Analog_Input_Present_Value_Set(
uint32_t object_instance,
float value)
{
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
Present_Value[index] = value;
}
}
bool Analog_Input_Out_Of_Service(
uint32_t object_instance)
{
unsigned index = 0;
bool value = false;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
value = Out_Of_Service[index];
}
return value;
}
void Analog_Input_Out_Of_Service_Set(
uint32_t object_instance,
bool value)
{
unsigned index = 0;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
Out_Of_Service[index] = value;
}
}
bool Analog_Input_Units_Set(
uint32_t object_instance,
uint16_t value)
{
unsigned index = 0;
bool status = false;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
Units[index] = value;
status = true;
}
return status;
}
uint16_t Analog_Input_Units(
uint32_t object_instance)
{
unsigned index = 0;
uint16_t value = UNITS_NO_UNITS;
index = Analog_Input_Instance_To_Index(object_instance);
if (index < MAX_ANALOG_INPUTS) {
value = Units[index];
}
return value;
}
/* return apdu length, or -1 on error */
/* assumption - object already exists */
int Analog_Input_Read_Property(
BACNET_READ_PROPERTY_DATA * rpdata)
{
int apdu_len = 0; /* return value */
BACNET_CHARACTER_STRING char_string = { 0 };
BACNET_BIT_STRING bit_string = { 0 };
uint8_t *apdu = NULL;
if ((rpdata == NULL) || (rpdata->application_data == NULL) ||
(rpdata->application_data_len == 0)) {
return 0;
}
apdu = rpdata->application_data;
switch (rpdata->object_property) {
case PROP_OBJECT_IDENTIFIER:
apdu_len =
encode_application_object_id(&apdu[0], rpdata->object_type,
rpdata->object_instance);
break;
case PROP_OBJECT_NAME:
Analog_Input_Object_Name(rpdata->object_instance, &char_string);
apdu_len =
encode_application_character_string(&apdu[0], &char_string);
break;
case PROP_OBJECT_TYPE:
apdu_len =
encode_application_enumerated(&apdu[0], rpdata->object_type);
break;
case PROP_PRESENT_VALUE:
apdu_len =
encode_application_real(&apdu[0],
Analog_Input_Present_Value(rpdata->object_instance));
break;
case PROP_STATUS_FLAGS:
bitstring_init(&bit_string);
bitstring_set_bit(&bit_string, STATUS_FLAG_IN_ALARM, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_FAULT, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OVERRIDDEN, false);
bitstring_set_bit(&bit_string, STATUS_FLAG_OUT_OF_SERVICE,
Analog_Input_Out_Of_Service(rpdata->object_instance));
apdu_len = encode_application_bitstring(&apdu[0], &bit_string);
break;
case PROP_EVENT_STATE:
apdu_len =
encode_application_enumerated(&apdu[0], EVENT_STATE_NORMAL);
break;
case PROP_OUT_OF_SERVICE:
apdu_len = encode_application_boolean(&apdu[0],
Analog_Input_Out_Of_Service(rpdata->object_instance));
break;
case PROP_UNITS:
apdu_len = encode_application_enumerated(&apdu[0],
Analog_Input_Units(rpdata->object_instance));
break;
default:
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
apdu_len = BACNET_STATUS_ERROR;
break;
}
/* only array properties can have array options */
if ((apdu_len >= 0) && (rpdata->array_index != BACNET_ARRAY_ALL)) {
rpdata->error_class = ERROR_CLASS_PROPERTY;
rpdata->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
apdu_len = BACNET_STATUS_ERROR;
}
return apdu_len;
}
/* returns true if successful */
bool Analog_Input_Write_Property(
BACNET_WRITE_PROPERTY_DATA * wp_data)
{
bool status = false; /* return value */
int len = 0;
BACNET_APPLICATION_DATA_VALUE value;
/* decode the some of the request */
len =
bacapp_decode_application_data(wp_data->application_data,
wp_data->application_data_len, &value);
/* FIXME: len < application_data_len: more data? */
if (len < 0) {
/* error while decoding - a value larger than we can handle */
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
return false;
}
/* only array properties can have array options */
if ((wp_data->object_property != PROP_EVENT_TIME_STAMPS) &&
(wp_data->array_index != BACNET_ARRAY_ALL)) {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_PROPERTY_IS_NOT_AN_ARRAY;
return false;
}
switch ((int) wp_data->object_property) {
case PROP_PRESENT_VALUE:
status = WPValidateArgType(&value, BACNET_APPLICATION_TAG_REAL,
&wp_data->error_class, &wp_data->error_code);
if (status) {
if (Analog_Input_Out_Of_Service(wp_data->object_instance)) {
Analog_Input_Present_Value_Set(wp_data->object_instance,
value.type.Real);
} else {
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
status = false;
}
}
break;
case PROP_OUT_OF_SERVICE:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_BOOLEAN,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Analog_Input_Out_Of_Service_Set(
wp_data->object_instance,
value.type.Boolean);
}
break;
case PROP_UNITS:
status =
WPValidateArgType(&value, BACNET_APPLICATION_TAG_ENUMERATED,
&wp_data->error_class, &wp_data->error_code);
if (status) {
Analog_Input_Out_Of_Service_Set(
wp_data->object_instance,
value.type.Enumerated);
}
break;
case PROP_OBJECT_IDENTIFIER:
case PROP_OBJECT_NAME:
case PROP_OBJECT_TYPE:
case PROP_STATUS_FLAGS:
case PROP_EVENT_STATE:
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_WRITE_ACCESS_DENIED;
break;
default:
wp_data->error_class = ERROR_CLASS_PROPERTY;
wp_data->error_code = ERROR_CODE_UNKNOWN_PROPERTY;
break;
}
return status;
}
+134 -134
View File
@@ -1,134 +1,134 @@
/**
* \file
*
* \brief Autogenerated API include file for the Atmel Software Framework (ASF)
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef ASF_H
#define ASF_H
/*
* This file includes all API header files for the selected drivers from ASF.
* Note: There might be duplicate includes required by more than one driver.
*
* The file is automatically generated and will be re-written when
* running the ASF driver selector tool. Any changes will be discarded.
*/
// From module: ADC - XMEGA A/AU Implementation
#include <adc.h>
// From module: CPU specific features
#include <ccp.h>
#include <xmega_reset_cause.h>
// From module: Delay routines
#include <delay.h>
// From module: GPIO - General purpose Input/Output
#include <gpio.h>
// From module: Generic board support
#include <board.h>
// From module: IOPORT - General purpose I/O service
#include <ioport.h>
// From module: Interrupt management - XMEGA implementation
#include <interrupt.h>
// From module: NVM - Non Volatile Memory
#include <nvm.h>
// From module: NVM - Non volatile memory access
#include <common_nvm.h>
// From module: PMIC - Programmable Multi-level Interrupt Controller
#include <pmic.h>
// From module: PWM service using timer/counter
#include <pwm.h>
// From module: Part identification macros
#include <parts.h>
// From module: RTC32 - Real Time Counter 32
#include <rtc32.h>
// From module: Sleep Controller driver
#include <sleep.h>
// From module: Sleep manager - XMEGA A/AU/B/D implementation
#include <sleepmgr.h>
#include <xmega/sleepmgr.h>
// From module: Standard serial I/O (stdio) - XMEGA implementation
#include <stdio_serial.h>
// From module: System Clock Control - XMEGA A1U/A3U/A3BU/A4U/B/C implementation
#include <sysclk.h>
// From module: TC - Timer Counter
#include <tc.h>
// From module: Timeout Service XMEGA
#include <timeout.h>
// From module: USART - Serial interface - XMEGA implementation
#include <serial.h>
// From module: TWI - Two-wire Master and Slave Interface
//#include <twim.h>
//#include <twis.h>
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
#include <usart.h>
// From module: WDT - Watchdog Timer
#include <wdt.h>
// From module: XMEGA compiler driver
#include <compiler.h>
#include <status_codes.h>
// From module: XMEGA-A3BU Xplained LED support enabled
#include <led.h>
#endif // ASF_H
/**
* \file
*
* \brief Autogenerated API include file for the Atmel Software Framework (ASF)
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef ASF_H
#define ASF_H
/*
* This file includes all API header files for the selected drivers from ASF.
* Note: There might be duplicate includes required by more than one driver.
*
* The file is automatically generated and will be re-written when
* running the ASF driver selector tool. Any changes will be discarded.
*/
// From module: ADC - XMEGA A/AU Implementation
#include <adc.h>
// From module: CPU specific features
#include <ccp.h>
#include <xmega_reset_cause.h>
// From module: Delay routines
#include <delay.h>
// From module: GPIO - General purpose Input/Output
#include <gpio.h>
// From module: Generic board support
#include <board.h>
// From module: IOPORT - General purpose I/O service
#include <ioport.h>
// From module: Interrupt management - XMEGA implementation
#include <interrupt.h>
// From module: NVM - Non Volatile Memory
#include <nvm.h>
// From module: NVM - Non volatile memory access
#include <common_nvm.h>
// From module: PMIC - Programmable Multi-level Interrupt Controller
#include <pmic.h>
// From module: PWM service using timer/counter
#include <pwm.h>
// From module: Part identification macros
#include <parts.h>
// From module: RTC32 - Real Time Counter 32
#include <rtc32.h>
// From module: Sleep Controller driver
#include <sleep.h>
// From module: Sleep manager - XMEGA A/AU/B/D implementation
#include <sleepmgr.h>
#include <xmega/sleepmgr.h>
// From module: Standard serial I/O (stdio) - XMEGA implementation
#include <stdio_serial.h>
// From module: System Clock Control - XMEGA A1U/A3U/A3BU/A4U/B/C implementation
#include <sysclk.h>
// From module: TC - Timer Counter
#include <tc.h>
// From module: Timeout Service XMEGA
#include <timeout.h>
// From module: USART - Serial interface - XMEGA implementation
#include <serial.h>
// From module: TWI - Two-wire Master and Slave Interface
//#include <twim.h>
//#include <twis.h>
// From module: USART - Universal Synchronous/Asynchronous Receiver/Transmitter
#include <usart.h>
// From module: WDT - Watchdog Timer
#include <wdt.h>
// From module: XMEGA compiler driver
#include <compiler.h>
#include <status_codes.h>
// From module: XMEGA-A3BU Xplained LED support enabled
#include <led.h>
#endif // ASF_H
+234 -234
View File
@@ -1,234 +1,234 @@
/**************************************************************************
*
* Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
/* hardware layer includes */
#include "rs485.h"
#include "nvmdata.h"
#include "wdt.h"
#include "led.h"
#include "adc-hdw.h"
/* BACnet Stack includes */
#include "datalink.h"
#include "npdu.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#include "dcc.h"
#include "iam.h"
#include "timer.h"
#include "tsm.h"
#include "ringbuf.h"
/* BACnet objects */
#include "device.h"
#include "ai.h"
/* me */
#include "bacnet.h"
/* buffer for incoming BACnet messages */
struct mstp_rx_packet {
BACNET_ADDRESS src;
uint16_t length;
uint8_t buffer[MAX_MPDU];
};
/* count must be a power of 2 for ringbuf library */
#ifndef MSTP_RECEIVE_PACKET_COUNT
#define MSTP_RECEIVE_PACKET_COUNT 2
#endif
static volatile struct mstp_rx_packet Receive_Buffer[MSTP_RECEIVE_PACKET_COUNT];
static RING_BUFFER Receive_Queue;
/* Device ID to track changes */
static uint32_t Device_ID = 0xFFFFFFFF;
/* timer for device communications control */
static struct itimer DCC_Timer;
#define DCC_CYCLE_SECONDS 1
/* timer for COV */
static struct itimer COV_Timer;
#define COV_CYCLE_SECONDS 1
/* timer for TSM */
static struct itimer TSM_Timer;
#define TSM_CYCLE_SECONDS 1
/* timer for Reinit */
static struct itimer Reinit_Timer;
/* buffer for incoming packets */
static uint8_t PDUBuffer[MAX_MPDU];
/**************************************************************************
* Description: handles reinitializing the device after a few seconds
* Returns: none
* Notes: gives the device enough time to acknowledge the RD request
**************************************************************************/
static void reinit_task(void)
{
BACNET_REINITIALIZED_STATE state = BACNET_REINIT_IDLE;
state = Device_Reinitialized_State();
if (state == BACNET_REINIT_IDLE) {
/* set timer to never expire */
timer_interval_infinity(&Reinit_Timer);
} else if (timer_interval_active(&Reinit_Timer)) {
if (timer_interval_expired(&Reinit_Timer)) {
/* reset MCU via watchdog timeout */
wdt_reset_mcu();
}
} else {
timer_interval_start_seconds(&Reinit_Timer, 3);
}
}
/**************************************************************************
* Description: handles recurring strictly timed task
* Returns: none
* Notes: called by ISR every 5 milliseconds
**************************************************************************/
void bacnet_task_timed(
void)
{
struct mstp_rx_packet *pkt = NULL;
uint16_t pdu_len = 0;
BACNET_ADDRESS src;
pdu_len = dlmstp_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 5);
if (pdu_len) {
pkt = (struct mstp_rx_packet *) Ringbuf_Data_Peek(&Receive_Queue);
if (pkt) {
memcpy(pkt->buffer, PDUBuffer, MAX_MPDU);
bacnet_address_copy(&pkt->src, &src);
pkt->length = pdu_len;
Ringbuf_Data_Put(&Receive_Queue, pkt);
}
}
}
/**************************************************************************
* Description: handles recurring task
* Returns: none
* Notes: none
**************************************************************************/
static void bacnet_test_task(void)
{
static unsigned index = 0;
uint32_t instance;
float float_value;
uint16_t adc_value;
instance = Analog_Input_Index_To_Instance(index);
if (!Analog_Input_Out_Of_Service(instance)) {
adc_value = adc_result_12bit(index);
float_value = adc_value;
float_value /= 4095;
Analog_Input_Present_Value_Set(instance, float_value);
}
index++;
if (index >= MAX_ANALOG_INPUTS) {
index = 0;
}
}
/**************************************************************************
* Description: handles recurring task
* Returns: none
* Notes: none
**************************************************************************/
void bacnet_task(void)
{
struct mstp_rx_packet pkt = {{0}};
bool pdu_available = false;
/* hello, World! */
if (Device_ID != Device_Object_Instance_Number()) {
Device_ID = Device_Object_Instance_Number();
Send_I_Am(&Handler_Transmit_Buffer[0]);
}
/* handle the timers */
if (timer_interval_expired(&DCC_Timer)) {
timer_interval_reset(&DCC_Timer);
dcc_timer_seconds(DCC_CYCLE_SECONDS);
led_on_interval(LED_DEBUG,500);
}
if (timer_interval_expired(&TSM_Timer)) {
timer_interval_reset(&TSM_Timer);
tsm_timer_milliseconds(timer_interval(&TSM_Timer));
}
reinit_task();
bacnet_test_task();
/* handle the messaging */
if ((!dlmstp_send_pdu_queue_full()) &&
(!Ringbuf_Empty(&Receive_Queue))) {
Ringbuf_Pop(&Receive_Queue, (uint8_t *)&pkt);
pdu_available = true;
}
if (pdu_available) {
led_on_interval(LED_APDU,125);
npdu_handler(&pkt.src, &pkt.buffer[0], pkt.length);
}
}
/**************************************************************************
* Description: initializes the BACnet library
* Returns: none
* Notes: none
**************************************************************************/
void bacnet_init(void)
{
unsigned i;
Ringbuf_Init(&Receive_Queue, (uint8_t *) & Receive_Buffer,
sizeof(struct mstp_rx_packet), MSTP_RECEIVE_PACKET_COUNT);
dlmstp_init(NULL);
/* initialize objects */
Device_Init(NULL);
/* set up our confirmed service unrecognized service handler - required! */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
handler_reinitialize_device);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property);
/* handle communication so we can shut up when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
/* start the cyclic 1 second timer for DCC */
timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS);
/* start the cyclic 1 second timer for COV */
timer_interval_start_seconds(&COV_Timer, COV_CYCLE_SECONDS);
/* start the cyclic 1 second timer for TSM */
timer_interval_start_seconds(&TSM_Timer, TSM_CYCLE_SECONDS);
for (i = 0; i < MAX_ANALOG_INPUTS; i++) {
Analog_Input_Units_Set(
Analog_Input_Index_To_Instance(i),
UNITS_PERCENT);
}
}
/**************************************************************************
*
* Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
/* hardware layer includes */
#include "rs485.h"
#include "nvmdata.h"
#include "wdt.h"
#include "led.h"
#include "adc-hdw.h"
/* BACnet Stack includes */
#include "datalink.h"
#include "npdu.h"
#include "handlers.h"
#include "client.h"
#include "txbuf.h"
#include "dcc.h"
#include "iam.h"
#include "timer.h"
#include "tsm.h"
#include "ringbuf.h"
/* BACnet objects */
#include "device.h"
#include "ai.h"
/* me */
#include "bacnet.h"
/* buffer for incoming BACnet messages */
struct mstp_rx_packet {
BACNET_ADDRESS src;
uint16_t length;
uint8_t buffer[MAX_MPDU];
};
/* count must be a power of 2 for ringbuf library */
#ifndef MSTP_RECEIVE_PACKET_COUNT
#define MSTP_RECEIVE_PACKET_COUNT 2
#endif
static volatile struct mstp_rx_packet Receive_Buffer[MSTP_RECEIVE_PACKET_COUNT];
static RING_BUFFER Receive_Queue;
/* Device ID to track changes */
static uint32_t Device_ID = 0xFFFFFFFF;
/* timer for device communications control */
static struct itimer DCC_Timer;
#define DCC_CYCLE_SECONDS 1
/* timer for COV */
static struct itimer COV_Timer;
#define COV_CYCLE_SECONDS 1
/* timer for TSM */
static struct itimer TSM_Timer;
#define TSM_CYCLE_SECONDS 1
/* timer for Reinit */
static struct itimer Reinit_Timer;
/* buffer for incoming packets */
static uint8_t PDUBuffer[MAX_MPDU];
/**************************************************************************
* Description: handles reinitializing the device after a few seconds
* Returns: none
* Notes: gives the device enough time to acknowledge the RD request
**************************************************************************/
static void reinit_task(void)
{
BACNET_REINITIALIZED_STATE state = BACNET_REINIT_IDLE;
state = Device_Reinitialized_State();
if (state == BACNET_REINIT_IDLE) {
/* set timer to never expire */
timer_interval_infinity(&Reinit_Timer);
} else if (timer_interval_active(&Reinit_Timer)) {
if (timer_interval_expired(&Reinit_Timer)) {
/* reset MCU via watchdog timeout */
wdt_reset_mcu();
}
} else {
timer_interval_start_seconds(&Reinit_Timer, 3);
}
}
/**************************************************************************
* Description: handles recurring strictly timed task
* Returns: none
* Notes: called by ISR every 5 milliseconds
**************************************************************************/
void bacnet_task_timed(
void)
{
struct mstp_rx_packet *pkt = NULL;
uint16_t pdu_len = 0;
BACNET_ADDRESS src;
pdu_len = dlmstp_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 5);
if (pdu_len) {
pkt = (struct mstp_rx_packet *) Ringbuf_Data_Peek(&Receive_Queue);
if (pkt) {
memcpy(pkt->buffer, PDUBuffer, MAX_MPDU);
bacnet_address_copy(&pkt->src, &src);
pkt->length = pdu_len;
Ringbuf_Data_Put(&Receive_Queue, pkt);
}
}
}
/**************************************************************************
* Description: handles recurring task
* Returns: none
* Notes: none
**************************************************************************/
static void bacnet_test_task(void)
{
static unsigned index = 0;
uint32_t instance;
float float_value;
uint16_t adc_value;
instance = Analog_Input_Index_To_Instance(index);
if (!Analog_Input_Out_Of_Service(instance)) {
adc_value = adc_result_12bit(index);
float_value = adc_value;
float_value /= 4095;
Analog_Input_Present_Value_Set(instance, float_value);
}
index++;
if (index >= MAX_ANALOG_INPUTS) {
index = 0;
}
}
/**************************************************************************
* Description: handles recurring task
* Returns: none
* Notes: none
**************************************************************************/
void bacnet_task(void)
{
struct mstp_rx_packet pkt = {{0}};
bool pdu_available = false;
/* hello, World! */
if (Device_ID != Device_Object_Instance_Number()) {
Device_ID = Device_Object_Instance_Number();
Send_I_Am(&Handler_Transmit_Buffer[0]);
}
/* handle the timers */
if (timer_interval_expired(&DCC_Timer)) {
timer_interval_reset(&DCC_Timer);
dcc_timer_seconds(DCC_CYCLE_SECONDS);
led_on_interval(LED_DEBUG,500);
}
if (timer_interval_expired(&TSM_Timer)) {
timer_interval_reset(&TSM_Timer);
tsm_timer_milliseconds(timer_interval(&TSM_Timer));
}
reinit_task();
bacnet_test_task();
/* handle the messaging */
if ((!dlmstp_send_pdu_queue_full()) &&
(!Ringbuf_Empty(&Receive_Queue))) {
Ringbuf_Pop(&Receive_Queue, (uint8_t *)&pkt);
pdu_available = true;
}
if (pdu_available) {
led_on_interval(LED_APDU,125);
npdu_handler(&pkt.src, &pkt.buffer[0], pkt.length);
}
}
/**************************************************************************
* Description: initializes the BACnet library
* Returns: none
* Notes: none
**************************************************************************/
void bacnet_init(void)
{
unsigned i;
Ringbuf_Init(&Receive_Queue, (uint8_t *) & Receive_Buffer,
sizeof(struct mstp_rx_packet), MSTP_RECEIVE_PACKET_COUNT);
dlmstp_init(NULL);
/* initialize objects */
Device_Init(NULL);
/* set up our confirmed service unrecognized service handler - required! */
apdu_set_unrecognized_service_handler_handler
(handler_unrecognized_service);
/* we need to handle who-is to support dynamic device binding */
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_IS, handler_who_is);
apdu_set_unconfirmed_handler(SERVICE_UNCONFIRMED_WHO_HAS, handler_who_has);
/* Set the handlers for any confirmed services that we support. */
/* We must implement read property - it's required! */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROPERTY,
handler_read_property);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_READ_PROP_MULTIPLE,
handler_read_property_multiple);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_REINITIALIZE_DEVICE,
handler_reinitialize_device);
apdu_set_confirmed_handler(SERVICE_CONFIRMED_WRITE_PROPERTY,
handler_write_property);
/* handle communication so we can shut up when asked */
apdu_set_confirmed_handler(SERVICE_CONFIRMED_DEVICE_COMMUNICATION_CONTROL,
handler_device_communication_control);
/* start the cyclic 1 second timer for DCC */
timer_interval_start_seconds(&DCC_Timer, DCC_CYCLE_SECONDS);
/* start the cyclic 1 second timer for COV */
timer_interval_start_seconds(&COV_Timer, COV_CYCLE_SECONDS);
/* start the cyclic 1 second timer for TSM */
timer_interval_start_seconds(&TSM_Timer, TSM_CYCLE_SECONDS);
for (i = 0; i < MAX_ANALOG_INPUTS; i++) {
Analog_Input_Units_Set(
Analog_Input_Index_To_Instance(i),
UNITS_PERCENT);
}
}
+42 -42
View File
@@ -1,42 +1,42 @@
/**************************************************************************
*
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef BACNET_H
#define BACNET_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void bacnet_init (void);
void bacnet_task (void);
void bacnet_task_timed(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef BACNET_H
#define BACNET_H
#include <stdint.h>
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
void bacnet_init (void);
void bacnet_task (void);
void bacnet_task_timed(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+281 -281
View File
@@ -1,281 +1,281 @@
/**************************************************************************
*
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacstr.h"
#include "nvmdata.h"
#include "device.h"
#include "bname.h"
/*************************************************************************
* DESCRIPTION: Test the BACnet CharacterString for validity
* RETURN: true if valid
* NOTES: none
**************************************************************************/
static bool bacnet_name_isvalid(uint8_t encoding,
uint8_t length,
char *str)
{
bool valid = false;
if ((encoding < MAX_CHARACTER_STRING_ENCODING) &&
(length <= NVM_NAME_SIZE)) {
if (encoding == CHARACTER_UTF8) {
valid = utf8_isvalid(str, length);
} else {
valid = true;
}
}
return valid;
}
/*************************************************************************
* DESCRIPTION: Copy the name from non-volatile memory at offset
* RETURN: number of bytes read, or -1 on error
* NOTES: none
**************************************************************************/
int bacnet_name_copy(
uint16_t offset,
uint8_t *dest,
uint8_t dest_len)
{
uint8_t encoding = 0;
uint8_t length = 0;
char name[NVM_NAME_SIZE + 1] = "";
unsigned i = 0;
int bytes_read = -1;
nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
nvm_read(NVM_NAME_STRING(offset),
(uint8_t *) & name, NVM_NAME_SIZE);
if (bacnet_name_isvalid(encoding, length, name)) {
if (dest_len > NVM_NAME_SIZE) {
dest_len = NVM_NAME_SIZE;
}
bytes_read = dest_len;
for (i = 0; i < dest_len; i++) {
if (i < length) {
dest[i] = name[i];
} else {
dest[i] = 0;
}
}
} else {
for (i = 0; i < dest_len; i++) {
dest[i] = 0;
}
}
return bytes_read;
}
/*************************************************************************
* DESCRIPTION: Encode the name in a buffer in the sequence stored in EEPROM.
* RETURN: number of bytes in buffer, or 0 if too big to fit.
* NOTES: none
**************************************************************************/
uint8_t bacnet_name_encode(
uint8_t *buffer,
uint8_t buffer_len,
uint8_t encoding,
char *str,
uint8_t str_len)
{
unsigned len = 0;
unsigned i = 0;
if (str_len < (255-2)) {
len = 1 + 1 + str_len;
if (len <= buffer_len) {
buffer[NVM_NAME_LENGTH(0)] = str_len;
buffer[NVM_NAME_ENCODING(0)] = encoding;
for (i = 0; i < str_len; i++) {
buffer[NVM_NAME_STRING(0)+i] = str[i];
}
} else {
len = 0;
}
}
return len;
}
/*************************************************************************
* DESCRIPTION: Store the name to non-volatile memory at offset
* RETURN: true if name is a valid set of characters
* NOTES: none
**************************************************************************/
bool bacnet_name_save(
uint16_t offset,
uint8_t encoding,
char *str,
uint8_t str_len)
{
uint8_t buffer[NVM_NAME_SIZE] = { 0 };
uint8_t length = 0;
if (bacnet_name_isvalid(encoding, str_len, str)) {
length = bacnet_name_encode(
buffer,
sizeof(buffer),
encoding,
str,
str_len);
if (length) {
nvm_write(
offset,
&buffer[0],length);
return true;
}
}
return false;
}
bool bacnet_name_set(uint16_t offset,
BACNET_CHARACTER_STRING * char_string)
{
uint8_t encoding = 0;
uint8_t length = 0;
char *str = NULL;
length = characterstring_length(char_string);
encoding = characterstring_encoding(char_string);
str = characterstring_value(char_string);
return bacnet_name_save(offset, encoding, str, length);
}
bool bacnet_name_write_unique(uint16_t offset,
int object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false;
size_t length = 0;
uint8_t encoding = 0;
int duplicate_type = 0;
uint32_t duplicate_instance = 0;
length = characterstring_length(char_string);
if (length < 1) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (length <= NVM_NAME_SIZE) {
encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) {
if (Device_Valid_Object_Name(char_string, &duplicate_type,
&duplicate_instance)) {
if ((duplicate_type == object_type) &&
(duplicate_instance == object_instance)) {
/* writing same name to same object */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_DUPLICATE_NAME;
}
} else {
status = bacnet_name_set(offset, char_string);
if (status) {
Device_Inc_Database_Revision();
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
}
return status;
}
/* no required minumum length or duplicate checking */
bool bacnet_name_write(uint16_t offset,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false;
size_t length = 0;
uint8_t encoding = 0;
length = characterstring_length(char_string);
if (length <= NVM_NAME_SIZE) {
encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) {
status = bacnet_name_set(offset, char_string);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
}
return status;
}
void bacnet_name_init(uint16_t offset,
char *default_string)
{
(void) bacnet_name_save(offset, CHARACTER_UTF8, default_string,
strlen(default_string));
}
void bacnet_name(uint16_t offset,
BACNET_CHARACTER_STRING * char_string,
char *default_string)
{
uint8_t encoding = 0;
uint8_t length = 0;
char name[NVM_NAME_SIZE + 1] = "";
nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
nvm_read(NVM_NAME_STRING(offset), (uint8_t *) & name[0], NVM_NAME_SIZE);
if (bacnet_name_isvalid(encoding, length, name)) {
characterstring_init(char_string, encoding, &name[0], length);
} else if (default_string) {
characterstring_init_ansi(char_string, default_string);
}
}
/**************************************************************************
*
* Copyright (C) 2011 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include "bacdef.h"
#include "bacdcode.h"
#include "bacstr.h"
#include "nvmdata.h"
#include "device.h"
#include "bname.h"
/*************************************************************************
* DESCRIPTION: Test the BACnet CharacterString for validity
* RETURN: true if valid
* NOTES: none
**************************************************************************/
static bool bacnet_name_isvalid(uint8_t encoding,
uint8_t length,
char *str)
{
bool valid = false;
if ((encoding < MAX_CHARACTER_STRING_ENCODING) &&
(length <= NVM_NAME_SIZE)) {
if (encoding == CHARACTER_UTF8) {
valid = utf8_isvalid(str, length);
} else {
valid = true;
}
}
return valid;
}
/*************************************************************************
* DESCRIPTION: Copy the name from non-volatile memory at offset
* RETURN: number of bytes read, or -1 on error
* NOTES: none
**************************************************************************/
int bacnet_name_copy(
uint16_t offset,
uint8_t *dest,
uint8_t dest_len)
{
uint8_t encoding = 0;
uint8_t length = 0;
char name[NVM_NAME_SIZE + 1] = "";
unsigned i = 0;
int bytes_read = -1;
nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
nvm_read(NVM_NAME_STRING(offset),
(uint8_t *) & name, NVM_NAME_SIZE);
if (bacnet_name_isvalid(encoding, length, name)) {
if (dest_len > NVM_NAME_SIZE) {
dest_len = NVM_NAME_SIZE;
}
bytes_read = dest_len;
for (i = 0; i < dest_len; i++) {
if (i < length) {
dest[i] = name[i];
} else {
dest[i] = 0;
}
}
} else {
for (i = 0; i < dest_len; i++) {
dest[i] = 0;
}
}
return bytes_read;
}
/*************************************************************************
* DESCRIPTION: Encode the name in a buffer in the sequence stored in EEPROM.
* RETURN: number of bytes in buffer, or 0 if too big to fit.
* NOTES: none
**************************************************************************/
uint8_t bacnet_name_encode(
uint8_t *buffer,
uint8_t buffer_len,
uint8_t encoding,
char *str,
uint8_t str_len)
{
unsigned len = 0;
unsigned i = 0;
if (str_len < (255-2)) {
len = 1 + 1 + str_len;
if (len <= buffer_len) {
buffer[NVM_NAME_LENGTH(0)] = str_len;
buffer[NVM_NAME_ENCODING(0)] = encoding;
for (i = 0; i < str_len; i++) {
buffer[NVM_NAME_STRING(0)+i] = str[i];
}
} else {
len = 0;
}
}
return len;
}
/*************************************************************************
* DESCRIPTION: Store the name to non-volatile memory at offset
* RETURN: true if name is a valid set of characters
* NOTES: none
**************************************************************************/
bool bacnet_name_save(
uint16_t offset,
uint8_t encoding,
char *str,
uint8_t str_len)
{
uint8_t buffer[NVM_NAME_SIZE] = { 0 };
uint8_t length = 0;
if (bacnet_name_isvalid(encoding, str_len, str)) {
length = bacnet_name_encode(
buffer,
sizeof(buffer),
encoding,
str,
str_len);
if (length) {
nvm_write(
offset,
&buffer[0],length);
return true;
}
}
return false;
}
bool bacnet_name_set(uint16_t offset,
BACNET_CHARACTER_STRING * char_string)
{
uint8_t encoding = 0;
uint8_t length = 0;
char *str = NULL;
length = characterstring_length(char_string);
encoding = characterstring_encoding(char_string);
str = characterstring_value(char_string);
return bacnet_name_save(offset, encoding, str, length);
}
bool bacnet_name_write_unique(uint16_t offset,
int object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false;
size_t length = 0;
uint8_t encoding = 0;
int duplicate_type = 0;
uint32_t duplicate_instance = 0;
length = characterstring_length(char_string);
if (length < 1) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
} else if (length <= NVM_NAME_SIZE) {
encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) {
if (Device_Valid_Object_Name(char_string, &duplicate_type,
&duplicate_instance)) {
if ((duplicate_type == object_type) &&
(duplicate_instance == object_instance)) {
/* writing same name to same object */
status = true;
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_DUPLICATE_NAME;
}
} else {
status = bacnet_name_set(offset, char_string);
if (status) {
Device_Inc_Database_Revision();
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
}
return status;
}
/* no required minumum length or duplicate checking */
bool bacnet_name_write(uint16_t offset,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code)
{
bool status = false;
size_t length = 0;
uint8_t encoding = 0;
length = characterstring_length(char_string);
if (length <= NVM_NAME_SIZE) {
encoding = characterstring_encoding(char_string);
if (encoding < MAX_CHARACTER_STRING_ENCODING) {
status = bacnet_name_set(offset, char_string);
if (!status) {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_VALUE_OUT_OF_RANGE;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_CHARACTER_SET_NOT_SUPPORTED;
}
} else {
*error_class = ERROR_CLASS_PROPERTY;
*error_code = ERROR_CODE_NO_SPACE_TO_WRITE_PROPERTY;
}
return status;
}
void bacnet_name_init(uint16_t offset,
char *default_string)
{
(void) bacnet_name_save(offset, CHARACTER_UTF8, default_string,
strlen(default_string));
}
void bacnet_name(uint16_t offset,
BACNET_CHARACTER_STRING * char_string,
char *default_string)
{
uint8_t encoding = 0;
uint8_t length = 0;
char name[NVM_NAME_SIZE + 1] = "";
nvm_read(NVM_NAME_ENCODING(offset), &encoding, 1);
nvm_read(NVM_NAME_LENGTH(offset), &length, 1);
nvm_read(NVM_NAME_STRING(offset), (uint8_t *) & name[0], NVM_NAME_SIZE);
if (bacnet_name_isvalid(encoding, length, name)) {
characterstring_init(char_string, encoding, &name[0], length);
} else if (default_string) {
characterstring_init_ansi(char_string, default_string);
}
}
+76 -76
View File
@@ -1,76 +1,76 @@
/**************************************************************************
*
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef BACNET_NAME_H
#define BACNET_NAME_H
#include <stdint.h>
#include "bacstr.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int bacnet_name_copy(
uint16_t offset,
uint8_t *dest,
uint8_t dest_len);
bool bacnet_name_set(
uint16_t eeprom_offset,
BACNET_CHARACTER_STRING * char_string);
void bacnet_name_init(
uint16_t eeprom_offset,
char *default_string);
uint8_t bacnet_name_encode(
uint8_t *buffer,
uint8_t buffer_len,
uint8_t encoding,
char *str,
uint8_t str_len);
bool bacnet_name_save(
uint16_t offset,
uint8_t encoding,
char *str,
uint8_t str_len);
void bacnet_name(
uint16_t eeprom_offset,
BACNET_CHARACTER_STRING * char_string,
char *default_string);
bool bacnet_name_write_unique(
uint16_t offset,
int object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
/* no required minumum length or duplicate checking */
bool bacnet_name_write(
uint16_t offset,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2010 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef BACNET_NAME_H
#define BACNET_NAME_H
#include <stdint.h>
#include "bacstr.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
int bacnet_name_copy(
uint16_t offset,
uint8_t *dest,
uint8_t dest_len);
bool bacnet_name_set(
uint16_t eeprom_offset,
BACNET_CHARACTER_STRING * char_string);
void bacnet_name_init(
uint16_t eeprom_offset,
char *default_string);
uint8_t bacnet_name_encode(
uint8_t *buffer,
uint8_t buffer_len,
uint8_t encoding,
char *str,
uint8_t str_len);
bool bacnet_name_save(
uint16_t offset,
uint8_t encoding,
char *str,
uint8_t str_len);
void bacnet_name(
uint16_t eeprom_offset,
BACNET_CHARACTER_STRING * char_string,
char *default_string);
bool bacnet_name_write_unique(
uint16_t offset,
int object_type,
uint32_t object_instance,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
/* no required minumum length or duplicate checking */
bool bacnet_name_write(
uint16_t offset,
BACNET_CHARACTER_STRING * char_string,
BACNET_ERROR_CLASS * error_class,
BACNET_ERROR_CODE * error_code);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+49 -49
View File
@@ -1,49 +1,49 @@
/**
* \file
*
* \brief Chip-specific ADC configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_ADC_H
#define CONF_ADC_H
#define CONFIG_ADC_CALLBACK_ENABLE
#define CONFIG_ADC_CALLBACK_TYPE uint16_t
#endif /* CONF_ADC_H */
/**
* \file
*
* \brief Chip-specific ADC configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_ADC_H
#define CONF_ADC_H
#define CONFIG_ADC_CALLBACK_ENABLE
#define CONFIG_ADC_CALLBACK_TYPE uint16_t
#endif /* CONF_ADC_H */
+51 -51
View File
@@ -1,51 +1,51 @@
/**
* \file
*
* \brief Board configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_BOARD_H_INCLUDED
#define CONF_BOARD_H_INCLUDED
#define CONF_BOARD_C12832A1Z
// Enable AT45DBX Component.
#define CONF_BOARD_AT45DBX
#endif /* CONF_BOARD_H_INCLUDED */
/**
* \file
*
* \brief Board configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_BOARD_H_INCLUDED
#define CONF_BOARD_H_INCLUDED
#define CONF_BOARD_C12832A1Z
// Enable AT45DBX Component.
#define CONF_BOARD_AT45DBX
#endif /* CONF_BOARD_H_INCLUDED */
+60 -60
View File
@@ -1,60 +1,60 @@
/**
* \file
*
* \brief Clock system configuration
*
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_CLOCK_H_INCLUDED
#define CONF_CLOCK_H_INCLUDED
//! Configuration using On-Chip RC oscillator at 48MHz
//! The RC oscillator is calibrated via USB Start Of Frame
//! Clk USB = 48MHz (used by USB)
//! Clk sys = 48MHz
//! Clk cpu/per = 24MHz
#define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC
#define CONFIG_OSC_RC32_CAL 48000000UL
#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF
#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ
#define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2
#define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1
#endif /* CONF_CLOCK_H_INCLUDED */
/**
* \file
*
* \brief Clock system configuration
*
* Copyright (c) 2011-2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_CLOCK_H_INCLUDED
#define CONF_CLOCK_H_INCLUDED
//! Configuration using On-Chip RC oscillator at 48MHz
//! The RC oscillator is calibrated via USB Start Of Frame
//! Clk USB = 48MHz (used by USB)
//! Clk sys = 48MHz
//! Clk cpu/per = 24MHz
#define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC
#define CONFIG_OSC_RC32_CAL 48000000UL
#define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF
#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC32MHZ
#define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_2
#define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1
#endif /* CONF_CLOCK_H_INCLUDED */
+47 -47
View File
@@ -1,47 +1,47 @@
/**
* \file
*
* \brief Non volatile memories management for XMEGA devices
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_NVM_H_INCLUDED
#define CONF_NVM_H_INCLUDED
#endif /* CONF_NVM_H_INCLUDED */
/**
* \file
*
* \brief Non volatile memories management for XMEGA devices
*
* Copyright (c) 2012 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_NVM_H_INCLUDED
#define CONF_NVM_H_INCLUDED
#endif /* CONF_NVM_H_INCLUDED */
+49 -49
View File
@@ -1,49 +1,49 @@
/**
* \file
*
* \brief RTC32 configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_RTC32_H
#define CONF_RTC32_H
//#define CONFIG_RTC32_COMPARE_INT_LEVEL RTC32_COMPINTLVL_LO_gc
//#define CONFIG_RTC32_CLOCK_1024HZ
#endif /* CONF_RTC32_H */
/**
* \file
*
* \brief RTC32 configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_RTC32_H
#define CONF_RTC32_H
//#define CONFIG_RTC32_COMPARE_INT_LEVEL RTC32_COMPINTLVL_LO_gc
//#define CONFIG_RTC32_CLOCK_1024HZ
#endif /* CONF_RTC32_H */
@@ -1,48 +1,48 @@
/**
* \file
*
* \brief Chip-specific sleep manager configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_SLEEPMGR_H
#define CONF_SLEEPMGR_H
#define CONFIG_SLEEPMGR_ENABLE
#endif /* CONF_SLEEPMGR_H */
/**
* \file
*
* \brief Chip-specific sleep manager configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_SLEEPMGR_H
#define CONF_SLEEPMGR_H
#define CONFIG_SLEEPMGR_ENABLE
#endif /* CONF_SLEEPMGR_H */
@@ -1,58 +1,58 @@
/**
* \file
*
* \brief Configuration file for timeout service
*
* Copyright (C) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_TIMEOUT_H
#define CONF_TIMEOUT_H
// For A3B devices with RTC32 module
#define CLOCK_SOURCE_RTC32
//! Define clock frequency
#define TIMEOUT_CLOCK_SOURCE_HZ 1024
//! Configure timeout channels
#define TIMEOUT_COUNT 1
//! Tick frequency
#define TIMEOUT_TICK_HZ 1
#endif /* CONF_TIMEOUT_H */
/**
* \file
*
* \brief Configuration file for timeout service
*
* Copyright (C) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_TIMEOUT_H
#define CONF_TIMEOUT_H
// For A3B devices with RTC32 module
#define CLOCK_SOURCE_RTC32
//! Define clock frequency
#define TIMEOUT_CLOCK_SOURCE_HZ 1024
//! Configure timeout channels
#define TIMEOUT_COUNT 1
//! Tick frequency
#define TIMEOUT_TICK_HZ 1
#endif /* CONF_TIMEOUT_H */
+49 -49
View File
@@ -1,49 +1,49 @@
/**
* \file
*
* \brief TWIM Configuration File for AVR XMEGA.
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _CONF_TWIM_H_
#define _CONF_TWIM_H_
#define CONF_TWIM_INTLVL TWI_MASTER_INTLVL_MED_gc
#define CONF_PMIC_INTLVL PMIC_MEDLVLEN_bm
#endif // _CONF_TWIM_H_
/**
* \file
*
* \brief TWIM Configuration File for AVR XMEGA.
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef _CONF_TWIM_H_
#define _CONF_TWIM_H_
#define CONF_TWIM_INTLVL TWI_MASTER_INTLVL_MED_gc
#define CONF_PMIC_INTLVL PMIC_MEDLVLEN_bm
#endif // _CONF_TWIM_H_
@@ -1,47 +1,47 @@
/**
* \file *********************************************************************
*
* \brief USART Serial configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_USART_SERIAL_H_INCLUDED
#define CONF_USART_SERIAL_H_INCLUDED
#endif /* CONF_USART_SERIAL_H_INCLUDED */
/**
* \file *********************************************************************
*
* \brief USART Serial configuration
*
* Copyright (c) 2011 Atmel Corporation. All rights reserved.
*
* \asf_license_start
*
* \page License
*
* 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.
*
* 4. This software may only be redistributed and used in connection with an
* Atmel microcontroller product.
*
* 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
* 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.
*
* \asf_license_stop
*
*/
#ifndef CONF_USART_SERIAL_H_INCLUDED
#define CONF_USART_SERIAL_H_INCLUDED
#endif /* CONF_USART_SERIAL_H_INCLUDED */
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+199 -199
View File
@@ -1,199 +1,199 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#include <stdint.h>
#include "board.h"
#include "ioport.h"
#include "timer.h"
#include "led.h"
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
#define RS485_XPLAINED_LD1 IOPORT_CREATE_PIN(PORTC, 6)
#define RS485_XPLAINED_LD2 IOPORT_CREATE_PIN(PORTC, 7)
#define RS485_XPLAINED_LD3 IOPORT_CREATE_PIN(PORTC, 4)
#define RS485_XPLAINED_LD4 IOPORT_CREATE_PIN(PORTC, 5)
static struct itimer Off_Delay_Timer[LEDS_MAX];
/*************************************************************************
* Description: Turn on an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_on(uint8_t index)
{
switch (index) {
case 0:
ioport_set_value(RS485_XPLAINED_LD1, 1);
break;
case 1:
ioport_set_value(RS485_XPLAINED_LD2, 1);
break;
case 2:
ioport_set_value(RS485_XPLAINED_LD3, 1);
break;
case 3:
ioport_set_value(RS485_XPLAINED_LD4, 1);
break;
default:
break;
}
if (index < LEDS_MAX) {
timer_interval_infinity(&Off_Delay_Timer[index]);
}
}
/*************************************************************************
* Description: Turn off an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_off(uint8_t index)
{
switch (index) {
case 0:
ioport_set_value(RS485_XPLAINED_LD1, 0);
break;
case 1:
ioport_set_value(RS485_XPLAINED_LD2, 0);
break;
case 2:
ioport_set_value(RS485_XPLAINED_LD3, 0);
break;
case 3:
ioport_set_value(RS485_XPLAINED_LD4, 0);
break;
default:
break;
}
if (index < LEDS_MAX) {
timer_interval_infinity(&Off_Delay_Timer[index]);
}
}
/*************************************************************************
* Description: Get the state of the LED
* Returns: true if on, false if off.
* Notes: none
*************************************************************************/
bool led_state(uint8_t index)
{
switch (index) {
case 0:
return ioport_pin_is_high(RS485_XPLAINED_LD1);
case 1:
return ioport_pin_is_high(RS485_XPLAINED_LD2);
case 2:
return ioport_pin_is_high(RS485_XPLAINED_LD3);
case 3:
return ioport_pin_is_high(RS485_XPLAINED_LD4);
default:
break;
}
return false;
}
/*************************************************************************
* Description: Toggle the state of the setup LED
* Returns: none
* Notes: none
*************************************************************************/
void led_toggle(uint8_t index)
{
if (led_state(index)) {
led_off(index);
} else {
led_on(index);
}
}
/*************************************************************************
* Description: Delay before going off to give minimum brightness.
* Returns: none
* Notes: none
*************************************************************************/
void led_off_delay(uint8_t index,
uint32_t delay_ms)
{
if (index < LEDS_MAX) {
timer_interval_start(&Off_Delay_Timer[index], delay_ms);
}
}
/*************************************************************************
* Description: Turn on, and delay before going off.
* Returns: none
* Notes: none
*************************************************************************/
void led_on_interval(uint8_t index,
uint16_t interval_ms)
{
if (index < LEDS_MAX) {
led_on(index);
timer_interval_start(&Off_Delay_Timer[index], interval_ms);
}
}
/*************************************************************************
* Description: Task for blinking LED
* Returns: none
* Notes: none
*************************************************************************/
void led_task(void)
{
uint8_t i; /* loop counter */
for (i = 0; i < LEDS_MAX; i++) {
if (timer_interval_expired(&Off_Delay_Timer[i])) {
timer_interval_infinity(&Off_Delay_Timer[i]);
led_off(i);
}
}
}
/*************************************************************************
* Description: Initialize the LED hardware
* Returns: none
* Notes: none
*************************************************************************/
void led_init(void)
{
uint8_t i; /* loop counter */
/* configure the LEDs for Rx and Tx indication */
ioport_configure_pin(RS485_XPLAINED_LD1,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_XPLAINED_LD2,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_XPLAINED_LD3,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_XPLAINED_LD4,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
/* initialize the timers, while giving LEDs a brief test */
for (i = 0; i < LEDS_MAX; i++) {
led_on(i);
led_off_delay(i,500);
}
}
#endif
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#include <stdint.h>
#include "board.h"
#include "ioport.h"
#include "timer.h"
#include "led.h"
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
#define RS485_XPLAINED_LD1 IOPORT_CREATE_PIN(PORTC, 6)
#define RS485_XPLAINED_LD2 IOPORT_CREATE_PIN(PORTC, 7)
#define RS485_XPLAINED_LD3 IOPORT_CREATE_PIN(PORTC, 4)
#define RS485_XPLAINED_LD4 IOPORT_CREATE_PIN(PORTC, 5)
static struct itimer Off_Delay_Timer[LEDS_MAX];
/*************************************************************************
* Description: Turn on an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_on(uint8_t index)
{
switch (index) {
case 0:
ioport_set_value(RS485_XPLAINED_LD1, 1);
break;
case 1:
ioport_set_value(RS485_XPLAINED_LD2, 1);
break;
case 2:
ioport_set_value(RS485_XPLAINED_LD3, 1);
break;
case 3:
ioport_set_value(RS485_XPLAINED_LD4, 1);
break;
default:
break;
}
if (index < LEDS_MAX) {
timer_interval_infinity(&Off_Delay_Timer[index]);
}
}
/*************************************************************************
* Description: Turn off an LED
* Returns: none
* Notes: none
*************************************************************************/
void led_off(uint8_t index)
{
switch (index) {
case 0:
ioport_set_value(RS485_XPLAINED_LD1, 0);
break;
case 1:
ioport_set_value(RS485_XPLAINED_LD2, 0);
break;
case 2:
ioport_set_value(RS485_XPLAINED_LD3, 0);
break;
case 3:
ioport_set_value(RS485_XPLAINED_LD4, 0);
break;
default:
break;
}
if (index < LEDS_MAX) {
timer_interval_infinity(&Off_Delay_Timer[index]);
}
}
/*************************************************************************
* Description: Get the state of the LED
* Returns: true if on, false if off.
* Notes: none
*************************************************************************/
bool led_state(uint8_t index)
{
switch (index) {
case 0:
return ioport_pin_is_high(RS485_XPLAINED_LD1);
case 1:
return ioport_pin_is_high(RS485_XPLAINED_LD2);
case 2:
return ioport_pin_is_high(RS485_XPLAINED_LD3);
case 3:
return ioport_pin_is_high(RS485_XPLAINED_LD4);
default:
break;
}
return false;
}
/*************************************************************************
* Description: Toggle the state of the setup LED
* Returns: none
* Notes: none
*************************************************************************/
void led_toggle(uint8_t index)
{
if (led_state(index)) {
led_off(index);
} else {
led_on(index);
}
}
/*************************************************************************
* Description: Delay before going off to give minimum brightness.
* Returns: none
* Notes: none
*************************************************************************/
void led_off_delay(uint8_t index,
uint32_t delay_ms)
{
if (index < LEDS_MAX) {
timer_interval_start(&Off_Delay_Timer[index], delay_ms);
}
}
/*************************************************************************
* Description: Turn on, and delay before going off.
* Returns: none
* Notes: none
*************************************************************************/
void led_on_interval(uint8_t index,
uint16_t interval_ms)
{
if (index < LEDS_MAX) {
led_on(index);
timer_interval_start(&Off_Delay_Timer[index], interval_ms);
}
}
/*************************************************************************
* Description: Task for blinking LED
* Returns: none
* Notes: none
*************************************************************************/
void led_task(void)
{
uint8_t i; /* loop counter */
for (i = 0; i < LEDS_MAX; i++) {
if (timer_interval_expired(&Off_Delay_Timer[i])) {
timer_interval_infinity(&Off_Delay_Timer[i]);
led_off(i);
}
}
}
/*************************************************************************
* Description: Initialize the LED hardware
* Returns: none
* Notes: none
*************************************************************************/
void led_init(void)
{
uint8_t i; /* loop counter */
/* configure the LEDs for Rx and Tx indication */
ioport_configure_pin(RS485_XPLAINED_LD1,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_XPLAINED_LD2,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_XPLAINED_LD3,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_XPLAINED_LD4,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
/* initialize the timers, while giving LEDs a brief test */
for (i = 0; i < LEDS_MAX; i++) {
led_on(i);
led_off_delay(i,500);
}
}
#endif
+76 -76
View File
@@ -1,76 +1,76 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef LED_H
#define LED_H
#include <stdint.h>
#include <stdbool.h>
#define LED_RS485_RX 0
#define LED_RS485_TX 1
#define LED_APDU 2
#define LED_DEBUG 3
#define LEDS_MAX 4
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
void led_on(
uint8_t index);
void led_on_interval(
uint8_t index,
uint16_t interval_ms);
void led_off(
uint8_t index);
void led_off_delay(
uint8_t index,
uint32_t delay_ms);
void led_toggle(
uint8_t index);
bool led_state(
uint8_t index);
void led_task(
void);
void led_init(
void);
#else
/* dummy stubs */
#define led_on(x)
#define led_on_interval(x, ms)
#define led_off(x)
#define led_off_delay(x, ms)
#define led_toggle(x)
#define led_state(x)
#define led_task()
#define led_init()
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef LED_H
#define LED_H
#include <stdint.h>
#include <stdbool.h>
#define LED_RS485_RX 0
#define LED_RS485_TX 1
#define LED_APDU 2
#define LED_DEBUG 3
#define LEDS_MAX 4
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
void led_on(
uint8_t index);
void led_on_interval(
uint8_t index,
uint16_t interval_ms);
void led_off(
uint8_t index);
void led_off_delay(
uint8_t index,
uint32_t delay_ms);
void led_toggle(
uint8_t index);
bool led_state(
uint8_t index);
void led_task(
void);
void led_init(
void);
#else
/* dummy stubs */
#define led_on(x)
#define led_on_interval(x, ms)
#define led_off(x)
#define led_off_delay(x, ms)
#define led_toggle(x)
#define led_state(x)
#define led_task()
#define led_init()
#endif
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+49 -49
View File
@@ -1,49 +1,49 @@
/**
* \file
*
* \brief XMEGA-A3BU BACnet application
*
*/
#include <asf.h>
#include "timer.h"
#include "rs485.h"
#include "led.h"
#include "adc-hdw.h"
#include "dlmstp.h"
#include "bacnet.h"
/**
* \brief Main function.
*
* Initializes the board, and runs the application in an infinite loop.
*/
int main(void)
{
/* hardware initialization */
sysclk_init();
board_init();
pmic_init();
timer_init();
rs485_init();
led_init();
adc_init();
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
// Enable display backlight
gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
#endif
// Workaround for known issue: Enable RTC32 sysclk
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) {
// Wait for RTC32 sysclk to become stable
}
cpu_irq_enable();
/* application initialization */
rs485_baud_rate_set(38400);
bacnet_init();
/* run forever - timed tasks */
timer_callback(bacnet_task_timed, 5);
for (;;) {
bacnet_task();
led_task();
}
}
/**
* \file
*
* \brief XMEGA-A3BU BACnet application
*
*/
#include <asf.h>
#include "timer.h"
#include "rs485.h"
#include "led.h"
#include "adc-hdw.h"
#include "dlmstp.h"
#include "bacnet.h"
/**
* \brief Main function.
*
* Initializes the board, and runs the application in an infinite loop.
*/
int main(void)
{
/* hardware initialization */
sysclk_init();
board_init();
pmic_init();
timer_init();
rs485_init();
led_init();
adc_init();
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
// Enable display backlight
gpio_set_pin_high(NHD_C12832A1Z_BACKLIGHT);
#endif
// Workaround for known issue: Enable RTC32 sysclk
sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC);
while (RTC32.SYNCCTRL & RTC32_SYNCBUSY_bm) {
// Wait for RTC32 sysclk to become stable
}
cpu_irq_enable();
/* application initialization */
rs485_baud_rate_set(38400);
bacnet_init();
/* run forever - timed tasks */
timer_callback(bacnet_task_timed, 5);
for (;;) {
bacnet_task();
led_task();
}
}
+41 -41
View File
@@ -1,41 +1,41 @@
/**
* @file
* @author Steve Karg <skarg@users.sourceforge.net>
* @date 2013
* @brief Store and retrieve non-volatile data
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "nvmdata.h"
#include "dlmstp.h"
#include "device.h"
/**
* Initializes the non-volatile memory module
*/
void nvm_data_init(void)
{
uint32_t device_id = 127;
uint8_t max_master = 127;
uint8_t mac_address = 127;
nvm_read(NVM_MAC_ADDRESS, &mac_address, 1);
if (mac_address == 255) {
/* uninitialized */
mac_address = 123;
}
dlmstp_set_mac_address(mac_address);
nvm_read(NVM_MAX_MASTER, &max_master, 1);
if (max_master > 127) {
max_master = 127;
}
dlmstp_set_max_master(max_master);
/* Get the device ID from the EEPROM */
nvm_read(NVM_DEVICE_0, (uint8_t *) & device_id, sizeof(device_id));
if (device_id < BACNET_MAX_INSTANCE) {
Device_Set_Object_Instance_Number(device_id);
} else {
Device_Set_Object_Instance_Number(mac_address);
}
}
/**
* @file
* @author Steve Karg <skarg@users.sourceforge.net>
* @date 2013
* @brief Store and retrieve non-volatile data
*
*/
#include <stdint.h>
#include <stdbool.h>
#include "nvmdata.h"
#include "dlmstp.h"
#include "device.h"
/**
* Initializes the non-volatile memory module
*/
void nvm_data_init(void)
{
uint32_t device_id = 127;
uint8_t max_master = 127;
uint8_t mac_address = 127;
nvm_read(NVM_MAC_ADDRESS, &mac_address, 1);
if (mac_address == 255) {
/* uninitialized */
mac_address = 123;
}
dlmstp_set_mac_address(mac_address);
nvm_read(NVM_MAX_MASTER, &max_master, 1);
if (max_master > 127) {
max_master = 127;
}
dlmstp_set_max_master(max_master);
/* Get the device ID from the EEPROM */
nvm_read(NVM_DEVICE_0, (uint8_t *) & device_id, sizeof(device_id));
if (device_id < BACNET_MAX_INSTANCE) {
Device_Set_Object_Instance_Number(device_id);
} else {
Device_Set_Object_Instance_Number(mac_address);
}
}
+84 -84
View File
@@ -1,84 +1,84 @@
/************************************************************************
*
* Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*************************************************************************/
#ifndef NVM_DATA_H
#define NVM_DATA_H
#include <avr/eeprom.h>
/* compatible functions could put in nvm.h to abstract more */
#define nvm_write(dst, src, len) \
eeprom_write_block((uint8_t *)(src),(uint8_t *)(dst), (size_t)(len))
#define nvm_read(src, dst, len) \
eeprom_read_block((uint8_t *)dst, (const uint8_t *)(src),(size_t)(len))
/*=============== EEPROM ================*/
/* define EEPROM signature version */
#define NVM_SIGNATURE 0
#define NVM_VERSION 1
/* define the MAC, BAUD, MAX Master, Device Instance internal
so that bootloader *could* use them. */
/* note: MAC could come from DIP switch, or be in non-volatile memory */
#define NVM_MAC_ADDRESS 2
/* 9=9.6k, 19=19.2k, 38=38.4k, 57=57.6k, 76=76.8k, 115=115.2k */
#define NVM_BAUD_K 3
#define NVM_MAX_MASTER 4
/* device instance is only 22 bits - easier if we use 32 bits */
#define NVM_DEVICE_0 5
#define NVM_DEVICE_1 6
#define NVM_DEVICE_2 7
#define NVM_DEVICE_3 8
/* free space - 9..31 */
/* BACnet Names - 32 bytes of data each */
#define NVM_NAME_LENGTH(n) ((n)+0)
#define NVM_NAME_ENCODING(n) ((n)+1)
#define NVM_NAME_STRING(n) ((n)+2)
#define NVM_NAME_SIZE 30
#define NVM_NAME_OFFSET (1+1+NVM_NAME_SIZE)
/* Device Name - starting offset */
#define NVM_DEVICE_NAME 32
/* Device Description - starting offset */
#define NVM_DEVICE_DESCRIPTION \
(NVM_DEVICE_NAME+NVM_NAME_OFFSET)
/* Device Location - starting offset */
#define NVM_DEVICE_LOCATION \
(NVM_DEVICE_DESCRIPTION+NVM_NAME_OFFSET)
/* free space 128..4096 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void nvm_data_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/************************************************************************
*
* Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*************************************************************************/
#ifndef NVM_DATA_H
#define NVM_DATA_H
#include <avr/eeprom.h>
/* compatible functions could put in nvm.h to abstract more */
#define nvm_write(dst, src, len) \
eeprom_write_block((uint8_t *)(src),(uint8_t *)(dst), (size_t)(len))
#define nvm_read(src, dst, len) \
eeprom_read_block((uint8_t *)dst, (const uint8_t *)(src),(size_t)(len))
/*=============== EEPROM ================*/
/* define EEPROM signature version */
#define NVM_SIGNATURE 0
#define NVM_VERSION 1
/* define the MAC, BAUD, MAX Master, Device Instance internal
so that bootloader *could* use them. */
/* note: MAC could come from DIP switch, or be in non-volatile memory */
#define NVM_MAC_ADDRESS 2
/* 9=9.6k, 19=19.2k, 38=38.4k, 57=57.6k, 76=76.8k, 115=115.2k */
#define NVM_BAUD_K 3
#define NVM_MAX_MASTER 4
/* device instance is only 22 bits - easier if we use 32 bits */
#define NVM_DEVICE_0 5
#define NVM_DEVICE_1 6
#define NVM_DEVICE_2 7
#define NVM_DEVICE_3 8
/* free space - 9..31 */
/* BACnet Names - 32 bytes of data each */
#define NVM_NAME_LENGTH(n) ((n)+0)
#define NVM_NAME_ENCODING(n) ((n)+1)
#define NVM_NAME_STRING(n) ((n)+2)
#define NVM_NAME_SIZE 30
#define NVM_NAME_OFFSET (1+1+NVM_NAME_SIZE)
/* Device Name - starting offset */
#define NVM_DEVICE_NAME 32
/* Device Description - starting offset */
#define NVM_DEVICE_DESCRIPTION \
(NVM_DEVICE_NAME+NVM_NAME_OFFSET)
/* Device Location - starting offset */
#define NVM_DEVICE_LOCATION \
(NVM_DEVICE_DESCRIPTION+NVM_NAME_OFFSET)
/* free space 128..4096 */
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void nvm_data_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+19 -19
View File
@@ -1,20 +1,20 @@
BACnet MS/TP on Atmel XMEGA-A3BU XPLAINED evaluation board.
An RS-485 add-on board (daughterboard, shield) was designed
to handle the RS-485 interface and some LEDs. See rs485-shield/
folder for EAGLE CAD design files.
Use the Configuration "Debug-XPLAINED" and not in "Debug" or "Release".
"CONF_BOARD_ENABLE_RS485_XPLAINED" is defined and used in led.c, rs485.c,
and main.c for specific board I/O. When it is not defined, the I/O is
either removed (i.e. led.c, main.c) or altered (rs485.c).
There are other defines in the "Debug-XPLAINED" Configuration
which include other parts of the XPLAINED platform code.
For your own board, you could just change rs485.c, main.c, and led.c
to use the I/O that you want to use, and not worry about the
"CONF_BOARD_ENABLE_RS485_XPLAINED". Or you can leave the
"CONF_BOARD_ENABLE_RS485_XPLAINED" in the files so that you can
always test on the XPLAINED platform with Debug-XPLAINED, and use
BACnet MS/TP on Atmel XMEGA-A3BU XPLAINED evaluation board.
An RS-485 add-on board (daughterboard, shield) was designed
to handle the RS-485 interface and some LEDs. See rs485-shield/
folder for EAGLE CAD design files.
Use the Configuration "Debug-XPLAINED" and not in "Debug" or "Release".
"CONF_BOARD_ENABLE_RS485_XPLAINED" is defined and used in led.c, rs485.c,
and main.c for specific board I/O. When it is not defined, the I/O is
either removed (i.e. led.c, main.c) or altered (rs485.c).
There are other defines in the "Debug-XPLAINED" Configuration
which include other parts of the XPLAINED platform code.
For your own board, you could just change rs485.c, main.c, and led.c
to use the I/O that you want to use, and not worry about the
"CONF_BOARD_ENABLE_RS485_XPLAINED". Or you can leave the
"CONF_BOARD_ENABLE_RS485_XPLAINED" in the files so that you can
always test on the XPLAINED platform with Debug-XPLAINED, and use
"Debug" or "Release" for your project.
+343 -343
View File
@@ -1,343 +1,343 @@
/*
* @file
*
* @brief RS-485 Interface
*
* Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
*
* @page License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "board.h"
#include "usart.h"
#include "ioport.h"
#include "sysclk.h"
#include "fifo.h"
#include "timer.h"
#include "led.h"
#include "mstpdef.h"
/* me! */
#include "rs485.h"
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
#define RS485_RE IOPORT_CREATE_PIN(PORTC, 1)
#define RS485_DE IOPORT_CREATE_PIN(PORTC, 0)
#define RS485_TXD IOPORT_CREATE_PIN(PORTC, 3)
#define RS485_RXD IOPORT_CREATE_PIN(PORTC, 2)
#define RS485_USART USARTC0
#define RS485_TXC_vect USARTC0_TXC_vect
#define RS485_RXC_vect USARTC0_RXC_vect
#else
#define RS485_RE IOPORT_CREATE_PIN(PORTE, 0)
#define RS485_DE IOPORT_CREATE_PIN(PORTE, 0)
#define RS485_TXD IOPORT_CREATE_PIN(PORTE, 3)
#define RS485_RXD IOPORT_CREATE_PIN(PORTE, 2)
#define RS485_USART USARTE0
#define RS485_TXC_vect USARTE0_TXC_vect
#define RS485_RXC_vect USARTE0_RXC_vect
#endif
/* buffer for storing received bytes - size must be power of two */
/* BACnet MAX_APDU for MS/TP is 480 bytes */
static uint8_t Receive_Queue_Data[512];
static FIFO_BUFFER Receive_Queue;
/* buffer for storing bytes to transmit - size must be power of two */
/* BACnet MAX_APDU for MS/TP is 480 bytes */
static uint8_t Transmit_Queue_Data[512];
static FIFO_BUFFER Transmit_Queue;
/* baud rate of the UART interface */
static uint32_t Baud_Rate;
/* timer for measuring line silence */
static struct etimer Silence_Timer;
/* flag to track RTS status */
static volatile bool RTS_Status;
/**
* Resets the silence timer
*/
void rs485_silence_reset(void)
{
timer_elapsed_start(&Silence_Timer);
}
/**
* Determine the amount of silence on the wire from the timer.
*
* @param interval - amount of time in milliseconds that line could be silent
*
* @return true if the line has been silent for the interval
*/
bool rs485_silence_elapsed(uint32_t interval)
{
return timer_elapsed_milliseconds(&Silence_Timer, interval);
}
/**
* enable the transmit-enable line on the RS-485 transceiver
*
* @param enable - true to enable RTS, false to disable RTS
*/
void rs485_rts_enable(bool enable)
{
if (enable) {
/* Turn Tx enable on */
ioport_set_value(RS485_RE, 1);
ioport_set_value(RS485_DE, 1);
led_on(LED_RS485_TX);
RTS_Status = true;
} else {
/* Turn Tx enable off */
ioport_set_value(RS485_RE, 0);
ioport_set_value(RS485_DE, 0);
led_off_delay(LED_RS485_TX, 10);
RTS_Status = false;
}
}
/**
* Determine the status of the transmit-enable line on the RS-485 transceiver
*
* @return true if RTS is enabled, false if RTS is disabled
*/
bool rs485_rts_enabled(void)
{
return RTS_Status;
}
/**
* Baud rate determines turnaround time.
* The minimum time after the end of the stop bit of the final octet of a
* received frame before a node may enable its EIA-485 driver: 40 bit times.
* At 9600 baud, 40 bit times would be about 4.166 milliseconds
* At 19200 baud, 40 bit times would be about 2.083 milliseconds
* At 38400 baud, 40 bit times would be about 1.041 milliseconds
* At 57600 baud, 40 bit times would be about 0.694 milliseconds
* At 76800 baud, 40 bit times would be about 0.520 milliseconds
* At 115200 baud, 40 bit times would be about 0.347 milliseconds
* 40 bits is 4 octets including a start and stop bit with each octet
*
* @return: amount of milliseconds to wait
*/
static uint16_t rs485_turnaround_time(void)
{
/* delay after reception before transmitting - per MS/TP spec */
/* wait a minimum 40 bit times since reception */
/* at least 2 ms for errors: rounding, clock tick */
return (2 + ((Tturnaround * 1000) / Baud_Rate));
}
/**
* Use the silence timer to determine turnaround time.
*
* @return true if the line has been silent for the turnaround interval
*/
bool rs485_turnaround_elapsed(void)
{
return timer_elapsed_milliseconds(&Silence_Timer, rs485_turnaround_time());
}
/**
* Checks for data on the receive UART, and handles errors
*
* @param data register to store the byte, if available (can be NULL)
*
* @return true if a byte is available
*/
bool rs485_byte_available(uint8_t * data_register)
{
bool data_available = false; /* return value */
if (FIFO_Empty(&Receive_Queue)) {
led_off_delay(LED_RS485_RX, 2);
} else {
led_on(LED_RS485_RX);
if (data_register) {
*data_register = FIFO_Get(&Receive_Queue);
}
data_available = true;
}
return data_available;
}
/**
* returns an error indication if errors are enabled
*
* @return returns true if error is detected and errors are enabled
*/
bool rs485_receive_error(void)
{
return false;
}
/**
* Determines if the entire frame is sent from USART FIFO
*
* @return true if the USART FIFO is empty
*/
bool rs485_frame_sent(void)
{
return usart_tx_is_complete(&RS485_USART);
}
/**
* Transmit one or more bytes on RS-485. Can be called while transmitting to add
* additional bytes to transmit queue.
*
* @param buffer - array of one or more bytes to transmit
* @param nbytes - number of bytes to transmit
*/
bool rs485_bytes_send(uint8_t * buffer,
uint16_t nbytes)
{
bool status = false;
bool start_required = false;
uint8_t ch = 0;
if (buffer && (nbytes > 0)) {
if (FIFO_Empty(&Transmit_Queue)) {
start_required = true;
}
status = FIFO_Add(&Transmit_Queue, buffer, nbytes);
if (start_required && status) {
rs485_rts_enable(true);
timer_elapsed_start(&Silence_Timer);
ch = FIFO_Get(&Transmit_Queue);
usart_clear_tx_complete(&RS485_USART);
usart_set_tx_interrupt_level(&RS485_USART, USART_INT_LVL_LO);
usart_putchar(&RS485_USART, ch);
}
}
return status;
}
/**
* RS485 RX interrupt
*/
ISR(RS485_RXC_vect)
{
unsigned char ch;
ch = usart_getchar(&RS485_USART);
FIFO_Put(&Receive_Queue, ch);
usart_clear_rx_complete(&RS485_USART);
}
/**
* RS485 TX interrupt
*/
ISR(RS485_TXC_vect)
{
uint8_t ch;
if (FIFO_Empty(&Transmit_Queue)) {
/* end of packet */
usart_set_tx_interrupt_level(&RS485_USART, USART_INT_LVL_OFF);
rs485_rts_enable(false);
} else {
rs485_rts_enable(true);
ch = FIFO_Get(&Transmit_Queue);
usart_putchar(&RS485_USART, ch);
}
}
/**
* Return the RS-485 baud rate
*
* @return baud - RS-485 baud rate in bits per second (bps)
*/
uint32_t rs485_baud_rate(
void)
{
return Baud_Rate;
}
/**
* Initialize the RS-485 baud rate
*
* @param baud - RS-485 baud rate in bits per second (bps)
*
* @return true if set and valid
*/
bool rs485_baud_rate_set(
uint32_t baud)
{
bool valid = true;
unsigned long frequency;
switch (baud) {
case 9600:
case 19200:
case 38400:
case 57600:
case 76800:
case 115200:
frequency = sysclk_get_peripheral_bus_hz(&RS485_USART);
valid = usart_set_baudrate (&RS485_USART, baud, frequency);
if (valid) {
Baud_Rate = baud;
}
break;
default:
valid = false;
break;
}
return valid;
}
/**
* Initialize the RS-485 UART interface, receive interrupts enabled
*/
void rs485_init(void)
{
usart_rs232_options_t option;
/* initialize the Rx and Tx byte queues */
FIFO_Init(&Receive_Queue, &Receive_Queue_Data[0],
(unsigned) sizeof(Receive_Queue_Data));
FIFO_Init(&Transmit_Queue, &Transmit_Queue_Data[0],
(unsigned) sizeof(Transmit_Queue_Data));
/* initialize the silence timer */
timer_elapsed_start(&Silence_Timer);
/* configure the TX pin */
ioport_configure_pin(RS485_TXD,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
/* configure the RX pin */
ioport_configure_pin(RS485_RXD,
IOPORT_DIR_INPUT);
/* configure the RTS pins */
ioport_configure_pin(RS485_RE,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_DE,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
option.baudrate = Baud_Rate;
option.charlength = USART_CHSIZE_8BIT_gc;
option.paritytype = USART_PMODE_DISABLED_gc;
option.stopbits = false;
usart_init_rs232(&RS485_USART, &option);
usart_set_rx_interrupt_level(&RS485_USART, USART_INT_LVL_HI);
}
/*
* @file
*
* @brief RS-485 Interface
*
* Copyright (C) 2013 Steve Karg <skarg@users.sourceforge.net>
*
* @page License
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include <string.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include "board.h"
#include "usart.h"
#include "ioport.h"
#include "sysclk.h"
#include "fifo.h"
#include "timer.h"
#include "led.h"
#include "mstpdef.h"
/* me! */
#include "rs485.h"
#ifdef CONF_BOARD_ENABLE_RS485_XPLAINED
#define RS485_RE IOPORT_CREATE_PIN(PORTC, 1)
#define RS485_DE IOPORT_CREATE_PIN(PORTC, 0)
#define RS485_TXD IOPORT_CREATE_PIN(PORTC, 3)
#define RS485_RXD IOPORT_CREATE_PIN(PORTC, 2)
#define RS485_USART USARTC0
#define RS485_TXC_vect USARTC0_TXC_vect
#define RS485_RXC_vect USARTC0_RXC_vect
#else
#define RS485_RE IOPORT_CREATE_PIN(PORTE, 0)
#define RS485_DE IOPORT_CREATE_PIN(PORTE, 0)
#define RS485_TXD IOPORT_CREATE_PIN(PORTE, 3)
#define RS485_RXD IOPORT_CREATE_PIN(PORTE, 2)
#define RS485_USART USARTE0
#define RS485_TXC_vect USARTE0_TXC_vect
#define RS485_RXC_vect USARTE0_RXC_vect
#endif
/* buffer for storing received bytes - size must be power of two */
/* BACnet MAX_APDU for MS/TP is 480 bytes */
static uint8_t Receive_Queue_Data[512];
static FIFO_BUFFER Receive_Queue;
/* buffer for storing bytes to transmit - size must be power of two */
/* BACnet MAX_APDU for MS/TP is 480 bytes */
static uint8_t Transmit_Queue_Data[512];
static FIFO_BUFFER Transmit_Queue;
/* baud rate of the UART interface */
static uint32_t Baud_Rate;
/* timer for measuring line silence */
static struct etimer Silence_Timer;
/* flag to track RTS status */
static volatile bool RTS_Status;
/**
* Resets the silence timer
*/
void rs485_silence_reset(void)
{
timer_elapsed_start(&Silence_Timer);
}
/**
* Determine the amount of silence on the wire from the timer.
*
* @param interval - amount of time in milliseconds that line could be silent
*
* @return true if the line has been silent for the interval
*/
bool rs485_silence_elapsed(uint32_t interval)
{
return timer_elapsed_milliseconds(&Silence_Timer, interval);
}
/**
* enable the transmit-enable line on the RS-485 transceiver
*
* @param enable - true to enable RTS, false to disable RTS
*/
void rs485_rts_enable(bool enable)
{
if (enable) {
/* Turn Tx enable on */
ioport_set_value(RS485_RE, 1);
ioport_set_value(RS485_DE, 1);
led_on(LED_RS485_TX);
RTS_Status = true;
} else {
/* Turn Tx enable off */
ioport_set_value(RS485_RE, 0);
ioport_set_value(RS485_DE, 0);
led_off_delay(LED_RS485_TX, 10);
RTS_Status = false;
}
}
/**
* Determine the status of the transmit-enable line on the RS-485 transceiver
*
* @return true if RTS is enabled, false if RTS is disabled
*/
bool rs485_rts_enabled(void)
{
return RTS_Status;
}
/**
* Baud rate determines turnaround time.
* The minimum time after the end of the stop bit of the final octet of a
* received frame before a node may enable its EIA-485 driver: 40 bit times.
* At 9600 baud, 40 bit times would be about 4.166 milliseconds
* At 19200 baud, 40 bit times would be about 2.083 milliseconds
* At 38400 baud, 40 bit times would be about 1.041 milliseconds
* At 57600 baud, 40 bit times would be about 0.694 milliseconds
* At 76800 baud, 40 bit times would be about 0.520 milliseconds
* At 115200 baud, 40 bit times would be about 0.347 milliseconds
* 40 bits is 4 octets including a start and stop bit with each octet
*
* @return: amount of milliseconds to wait
*/
static uint16_t rs485_turnaround_time(void)
{
/* delay after reception before transmitting - per MS/TP spec */
/* wait a minimum 40 bit times since reception */
/* at least 2 ms for errors: rounding, clock tick */
return (2 + ((Tturnaround * 1000) / Baud_Rate));
}
/**
* Use the silence timer to determine turnaround time.
*
* @return true if the line has been silent for the turnaround interval
*/
bool rs485_turnaround_elapsed(void)
{
return timer_elapsed_milliseconds(&Silence_Timer, rs485_turnaround_time());
}
/**
* Checks for data on the receive UART, and handles errors
*
* @param data register to store the byte, if available (can be NULL)
*
* @return true if a byte is available
*/
bool rs485_byte_available(uint8_t * data_register)
{
bool data_available = false; /* return value */
if (FIFO_Empty(&Receive_Queue)) {
led_off_delay(LED_RS485_RX, 2);
} else {
led_on(LED_RS485_RX);
if (data_register) {
*data_register = FIFO_Get(&Receive_Queue);
}
data_available = true;
}
return data_available;
}
/**
* returns an error indication if errors are enabled
*
* @return returns true if error is detected and errors are enabled
*/
bool rs485_receive_error(void)
{
return false;
}
/**
* Determines if the entire frame is sent from USART FIFO
*
* @return true if the USART FIFO is empty
*/
bool rs485_frame_sent(void)
{
return usart_tx_is_complete(&RS485_USART);
}
/**
* Transmit one or more bytes on RS-485. Can be called while transmitting to add
* additional bytes to transmit queue.
*
* @param buffer - array of one or more bytes to transmit
* @param nbytes - number of bytes to transmit
*/
bool rs485_bytes_send(uint8_t * buffer,
uint16_t nbytes)
{
bool status = false;
bool start_required = false;
uint8_t ch = 0;
if (buffer && (nbytes > 0)) {
if (FIFO_Empty(&Transmit_Queue)) {
start_required = true;
}
status = FIFO_Add(&Transmit_Queue, buffer, nbytes);
if (start_required && status) {
rs485_rts_enable(true);
timer_elapsed_start(&Silence_Timer);
ch = FIFO_Get(&Transmit_Queue);
usart_clear_tx_complete(&RS485_USART);
usart_set_tx_interrupt_level(&RS485_USART, USART_INT_LVL_LO);
usart_putchar(&RS485_USART, ch);
}
}
return status;
}
/**
* RS485 RX interrupt
*/
ISR(RS485_RXC_vect)
{
unsigned char ch;
ch = usart_getchar(&RS485_USART);
FIFO_Put(&Receive_Queue, ch);
usart_clear_rx_complete(&RS485_USART);
}
/**
* RS485 TX interrupt
*/
ISR(RS485_TXC_vect)
{
uint8_t ch;
if (FIFO_Empty(&Transmit_Queue)) {
/* end of packet */
usart_set_tx_interrupt_level(&RS485_USART, USART_INT_LVL_OFF);
rs485_rts_enable(false);
} else {
rs485_rts_enable(true);
ch = FIFO_Get(&Transmit_Queue);
usart_putchar(&RS485_USART, ch);
}
}
/**
* Return the RS-485 baud rate
*
* @return baud - RS-485 baud rate in bits per second (bps)
*/
uint32_t rs485_baud_rate(
void)
{
return Baud_Rate;
}
/**
* Initialize the RS-485 baud rate
*
* @param baud - RS-485 baud rate in bits per second (bps)
*
* @return true if set and valid
*/
bool rs485_baud_rate_set(
uint32_t baud)
{
bool valid = true;
unsigned long frequency;
switch (baud) {
case 9600:
case 19200:
case 38400:
case 57600:
case 76800:
case 115200:
frequency = sysclk_get_peripheral_bus_hz(&RS485_USART);
valid = usart_set_baudrate (&RS485_USART, baud, frequency);
if (valid) {
Baud_Rate = baud;
}
break;
default:
valid = false;
break;
}
return valid;
}
/**
* Initialize the RS-485 UART interface, receive interrupts enabled
*/
void rs485_init(void)
{
usart_rs232_options_t option;
/* initialize the Rx and Tx byte queues */
FIFO_Init(&Receive_Queue, &Receive_Queue_Data[0],
(unsigned) sizeof(Receive_Queue_Data));
FIFO_Init(&Transmit_Queue, &Transmit_Queue_Data[0],
(unsigned) sizeof(Transmit_Queue_Data));
/* initialize the silence timer */
timer_elapsed_start(&Silence_Timer);
/* configure the TX pin */
ioport_configure_pin(RS485_TXD,
IOPORT_DIR_OUTPUT | IOPORT_INIT_HIGH);
/* configure the RX pin */
ioport_configure_pin(RS485_RXD,
IOPORT_DIR_INPUT);
/* configure the RTS pins */
ioport_configure_pin(RS485_RE,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
ioport_configure_pin(RS485_DE,
IOPORT_DIR_OUTPUT | IOPORT_INIT_LOW);
option.baudrate = Baud_Rate;
option.charlength = USART_CHSIZE_8BIT_gc;
option.paritytype = USART_PMODE_DISABLED_gc;
option.stopbits = false;
usart_init_rs232(&RS485_USART, &option);
usart_set_rx_interrupt_level(&RS485_USART, USART_INT_LVL_HI);
}
+63 -63
View File
@@ -1,63 +1,63 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef RS485_H
#define RS485_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void rs485_rts_enable(
bool enable);
bool rs485_rts_enabled(
void);
bool rs485_byte_available(
uint8_t * data_register);
bool rs485_receive_error(
void);
bool rs485_bytes_send(
uint8_t * buffer, /* data to send */
uint16_t nbytes); /* number of bytes of data */
bool rs485_frame_sent(void);
bool rs485_turnaround_elapsed(
void);
uint32_t rs485_baud_rate(
void);
bool rs485_baud_rate_set(
uint32_t baud);
void rs485_silence_reset(
void);
bool rs485_silence_elapsed(
uint32_t interval);
void rs485_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#ifndef RS485_H
#define RS485_H
#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
void rs485_rts_enable(
bool enable);
bool rs485_rts_enabled(
void);
bool rs485_byte_available(
uint8_t * data_register);
bool rs485_receive_error(
void);
bool rs485_bytes_send(
uint8_t * buffer, /* data to send */
uint16_t nbytes); /* number of bytes of data */
bool rs485_frame_sent(void);
bool rs485_turnaround_elapsed(
void);
uint32_t rs485_baud_rate(
void);
bool rs485_baud_rate_set(
uint32_t baud);
void rs485_silence_reset(
void);
bool rs485_silence_elapsed(
uint32_t interval);
void rs485_init(void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+144 -144
View File
@@ -1,144 +1,144 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include "board.h"
/* me */
#include "stack.h"
#if defined(__GNUC__)
/* stack checking technique by Michael McTernan */
/* With AVR gcc, two symbols are defined by the linker
that can make this easy. These are _end and __stack
which define the first free byte of SRAM after
program variables, and the starting address of
the stack, respectively.
The stack starts at __stack, which is conventionally
the highest byte of SRAM, and grows towards zero;
_end will be somewhere between zero and __stack.
If the stack ever falls below _end, it has almost
certainly corrupted program data.
The following C declarations gain access to these
linker symbols:
*/
extern uint8_t _end;
extern uint8_t __stack;
/* canary value */
#define STACK_CANARY (0xC5)
/* This is declared in such a way that AVR-libc will
execute the assembly before the program has started
running or configured the stack. It also runs at a
point before some of the normal runtime setup,
hence assembly should be used as C may not be
fully reliable (this is discussed in the AVR libc manual).
*/
void stack_init(
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
/* The function itself simply fills the stack with the canary value,
the idea being that stack usage will overwrite this with some
other value, hence making stack usage detectable.
*/
void stack_init(
void)
{
#if 0
uint8_t *p = &_end;
while (p <= &__stack) {
*p = STACK_CANARY;
p++;
}
#else
__asm volatile (
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
#endif
}
unsigned stack_size(
void)
{
return (&__stack) - (&_end);
}
uint8_t stack_byte(
unsigned offset)
{
return *(&_end + offset);
}
/* The following function can be used to count
how many bytes of stack have not been overwritten.
This function can be called at any time
to check how much stack space has never been over written.
If it returns 0, you are probably in trouble as
all the stack has been used, most likely destroying
some program variables.
*/
unsigned stack_unused(
void)
{
uint8_t *p = &_end;
unsigned count = 0;
while (p <= &__stack) {
if ((*p) != STACK_CANARY) {
count = p - (&_end);
break;
}
p++;
}
return count;
}
#else
void stack_init(
void)
{
}
unsigned stack_size(
void)
{
return 0;
}
uint8_t stack_byte(
unsigned offset)
{
return 0;
}
unsigned stack_unused(
void)
{
return 0;
}
#endif
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#include "board.h"
/* me */
#include "stack.h"
#if defined(__GNUC__)
/* stack checking technique by Michael McTernan */
/* With AVR gcc, two symbols are defined by the linker
that can make this easy. These are _end and __stack
which define the first free byte of SRAM after
program variables, and the starting address of
the stack, respectively.
The stack starts at __stack, which is conventionally
the highest byte of SRAM, and grows towards zero;
_end will be somewhere between zero and __stack.
If the stack ever falls below _end, it has almost
certainly corrupted program data.
The following C declarations gain access to these
linker symbols:
*/
extern uint8_t _end;
extern uint8_t __stack;
/* canary value */
#define STACK_CANARY (0xC5)
/* This is declared in such a way that AVR-libc will
execute the assembly before the program has started
running or configured the stack. It also runs at a
point before some of the normal runtime setup,
hence assembly should be used as C may not be
fully reliable (this is discussed in the AVR libc manual).
*/
void stack_init(
void) __attribute__ ((naked)) __attribute__ ((section(".init1")));
/* The function itself simply fills the stack with the canary value,
the idea being that stack usage will overwrite this with some
other value, hence making stack usage detectable.
*/
void stack_init(
void)
{
#if 0
uint8_t *p = &_end;
while (p <= &__stack) {
*p = STACK_CANARY;
p++;
}
#else
__asm volatile (
" ldi r30,lo8(_end)\n" " ldi r31,hi8(_end)\n" " ldi r24,lo8(0xc5)\n" /* STACK_CANARY = 0xc5 */
" ldi r25,hi8(__stack)\n" " rjmp .cmp\n" ".loop:\n"
" st Z+,r24\n" ".cmp:\n" " cpi r30,lo8(__stack)\n"
" cpc r31,r25\n" " brlo .loop\n" " breq .loop"::);
#endif
}
unsigned stack_size(
void)
{
return (&__stack) - (&_end);
}
uint8_t stack_byte(
unsigned offset)
{
return *(&_end + offset);
}
/* The following function can be used to count
how many bytes of stack have not been overwritten.
This function can be called at any time
to check how much stack space has never been over written.
If it returns 0, you are probably in trouble as
all the stack has been used, most likely destroying
some program variables.
*/
unsigned stack_unused(
void)
{
uint8_t *p = &_end;
unsigned count = 0;
while (p <= &__stack) {
if ((*p) != STACK_CANARY) {
count = p - (&_end);
break;
}
p++;
}
return count;
}
#else
void stack_init(
void)
{
}
unsigned stack_size(
void)
{
return 0;
}
uint8_t stack_byte(
unsigned offset)
{
return 0;
}
unsigned stack_unused(
void)
{
return 0;
}
#endif
+51 -51
View File
@@ -1,51 +1,51 @@
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#ifndef STACK_H
#define STACK_H
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* C stack checking */
void stack_init(
void);
unsigned stack_size(
void);
uint8_t stack_byte(
unsigned offset);
unsigned stack_unused(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
/**************************************************************************
*
* Copyright (C) 2009 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*********************************************************************/
#ifndef STACK_H
#define STACK_H
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* C stack checking */
void stack_init(
void);
unsigned stack_size(
void);
uint8_t stack_byte(
unsigned offset);
unsigned stack_unused(
void);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif
+338 -338
View File
@@ -1,338 +1,338 @@
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "timer.h"
/* interval and elapsed millisecond timer */
/* interval not to exceed 49.7 days */
/* minimum interval of 1ms may be 0 to 1ms */
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_start(struct itimer *t, uint32_t interval)
{
uint32_t now = 0;
uint32_t elapsed = 0;
now = timer_milliseconds();
elapsed = now - t->start;
t->start = now;
t->interval = interval;
return elapsed;
}
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed seconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_start_seconds(struct itimer *t, uint32_t interval)
{
uint32_t elapsed = 0;
interval *= 1000L;
elapsed = timer_interval_start(t, interval);
elapsed /= 1000L;
return elapsed;
}
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed minutes since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_start_minutes(struct itimer *t, uint32_t interval)
{
uint32_t elapsed = 0;
interval *= 60L;
interval *= 1000L;
elapsed = timer_interval_start(t, interval);
elapsed /= 1000L;
elapsed /= 60L;
return elapsed;
}
/*************************************************************************
* Description: Change the timer interval without restart
* Returns: previous interval value
* Notes: none
**************************************************************************/
uint32_t timer_interval_adjust(struct itimer *t, uint32_t interval)
{
uint32_t previous_interval = t->interval;
t->interval = interval;
return previous_interval;
}
/*************************************************************************
* Description: Reset the timer with the same interval
* Returns: none
* Notes: none
**************************************************************************/
void timer_interval_reset(struct itimer *t)
{
t->start += t->interval;
}
/*************************************************************************
* Description: Restart the timer from now, syncing on existing interval
* Returns: elapsed milliseconds since last reset
* Notes: none
**************************************************************************/
uint32_t timer_interval_resync(struct itimer *t)
{
uint32_t elapsed;
uint32_t intervals;
uint32_t gap;
uint32_t now;
now = timer_milliseconds();
elapsed = now - t->start;
if ((t->interval != TIMER_INTERVAL_MAX) && (t->interval != 0)) {
if (elapsed >= t->interval) {
/* catch up to now */
intervals = elapsed / t->interval;
gap = intervals * t->interval;
t->start += gap;
}
}
return elapsed;
}
/*************************************************************************
* Description: Restart the timer from now
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_restart(struct itimer *t)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
t->start = now;
return elapsed;
}
/*************************************************************************
* Description: Reset the timer with the zero interval - always expired
* Returns: none
* Notes: none
**************************************************************************/
void timer_interval_none(struct itimer *t)
{
t->interval = 0;
}
/*************************************************************************
* Description: Reset the timer with the max interval - never expires
* Returns: none
* Notes: none
**************************************************************************/
void timer_interval_infinity(struct itimer *t)
{
t->interval = TIMER_INTERVAL_MAX;
}
/*************************************************************************
* Description: Determines if the timer has an active interval
* Returns: true if active
* Notes: none
**************************************************************************/
bool timer_interval_active(struct itimer *t)
{
return ((t->interval != TIMER_INTERVAL_MAX) && (t->interval != 0));
}
/*************************************************************************
* Description: Check to see if the time interval has elapsed
* Returns: true if expired
* Notes: Setting the interval to max never expires, to zero always expires
**************************************************************************/
bool timer_interval_expired(struct itimer *t)
{
uint32_t elapsed = 0;
bool status = false;
uint32_t now;
if (t->interval == 0) {
status = true;
} else if (t->interval == TIMER_INTERVAL_MAX) {
status = false;
} else {
now = timer_milliseconds();
elapsed = now - t->start;
if (elapsed >= t->interval) {
status = true;
}
}
return status;
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: number of milliseconds elapsed
* Notes: none
**************************************************************************/
uint32_t timer_interval_elapsed(struct itimer *t)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
return elapsed;
}
/*************************************************************************
* Description: Return the interval time
* Returns: number of milliseconds for which the interval is set
* Notes: none
**************************************************************************/
uint32_t timer_interval(struct itimer *t)
{
return t->interval;
}
/*************************************************************************
* Description: Return the interval time
* Returns: number of seconds for which the interval is set
* Notes: none
**************************************************************************/
uint32_t timer_interval_seconds(struct itimer *t)
{
return (t->interval/1000);
}
/* Elapsed Timer */
/*************************************************************************
* Description: Restart the timer from now
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_elapsed_start_offset(struct etimer *t, uint32_t offset)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
if (offset) {
t->start = now + offset;
} else {
t->start = now;
}
return elapsed;
}
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_elapsed_start(struct etimer *t)
{
return timer_elapsed_start_offset(t, 0);
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: true if interval has elapsed
* Notes: none
**************************************************************************/
bool timer_elapsed_milliseconds(struct etimer *t, uint32_t interval)
{
bool status = false;
uint32_t delta;
delta = timer_milliseconds() - t->start;
if (delta >= interval) {
status = true;
}
return status;
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: true if interval has elapsed
* Notes: none
**************************************************************************/
bool timer_elapsed_seconds(struct etimer *t, uint32_t interval)
{
/* convert to seconds */
interval *= 1000L;
return timer_elapsed_milliseconds(t, interval);
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: true if interval has elapsed
* Notes: none
**************************************************************************/
bool timer_elapsed_minutes(struct etimer *t, uint32_t interval)
{
/* convert to seconds */
interval *= 1000L;
/* convert to minutes */
interval *= 60L;
return timer_elapsed_milliseconds(t, interval);
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: number of milliseconds elapsed
* Notes: none
**************************************************************************/
uint32_t timer_elapsed_time(struct etimer *t)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
return elapsed;
}
/**************************************************************************
*
* Copyright (C) 2007 Steve Karg <skarg@users.sourceforge.net>
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*********************************************************************/
#include <stdbool.h>
#include <stdint.h>
#include "timer.h"
/* interval and elapsed millisecond timer */
/* interval not to exceed 49.7 days */
/* minimum interval of 1ms may be 0 to 1ms */
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_start(struct itimer *t, uint32_t interval)
{
uint32_t now = 0;
uint32_t elapsed = 0;
now = timer_milliseconds();
elapsed = now - t->start;
t->start = now;
t->interval = interval;
return elapsed;
}
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed seconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_start_seconds(struct itimer *t, uint32_t interval)
{
uint32_t elapsed = 0;
interval *= 1000L;
elapsed = timer_interval_start(t, interval);
elapsed /= 1000L;
return elapsed;
}
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed minutes since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_start_minutes(struct itimer *t, uint32_t interval)
{
uint32_t elapsed = 0;
interval *= 60L;
interval *= 1000L;
elapsed = timer_interval_start(t, interval);
elapsed /= 1000L;
elapsed /= 60L;
return elapsed;
}
/*************************************************************************
* Description: Change the timer interval without restart
* Returns: previous interval value
* Notes: none
**************************************************************************/
uint32_t timer_interval_adjust(struct itimer *t, uint32_t interval)
{
uint32_t previous_interval = t->interval;
t->interval = interval;
return previous_interval;
}
/*************************************************************************
* Description: Reset the timer with the same interval
* Returns: none
* Notes: none
**************************************************************************/
void timer_interval_reset(struct itimer *t)
{
t->start += t->interval;
}
/*************************************************************************
* Description: Restart the timer from now, syncing on existing interval
* Returns: elapsed milliseconds since last reset
* Notes: none
**************************************************************************/
uint32_t timer_interval_resync(struct itimer *t)
{
uint32_t elapsed;
uint32_t intervals;
uint32_t gap;
uint32_t now;
now = timer_milliseconds();
elapsed = now - t->start;
if ((t->interval != TIMER_INTERVAL_MAX) && (t->interval != 0)) {
if (elapsed >= t->interval) {
/* catch up to now */
intervals = elapsed / t->interval;
gap = intervals * t->interval;
t->start += gap;
}
}
return elapsed;
}
/*************************************************************************
* Description: Restart the timer from now
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_interval_restart(struct itimer *t)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
t->start = now;
return elapsed;
}
/*************************************************************************
* Description: Reset the timer with the zero interval - always expired
* Returns: none
* Notes: none
**************************************************************************/
void timer_interval_none(struct itimer *t)
{
t->interval = 0;
}
/*************************************************************************
* Description: Reset the timer with the max interval - never expires
* Returns: none
* Notes: none
**************************************************************************/
void timer_interval_infinity(struct itimer *t)
{
t->interval = TIMER_INTERVAL_MAX;
}
/*************************************************************************
* Description: Determines if the timer has an active interval
* Returns: true if active
* Notes: none
**************************************************************************/
bool timer_interval_active(struct itimer *t)
{
return ((t->interval != TIMER_INTERVAL_MAX) && (t->interval != 0));
}
/*************************************************************************
* Description: Check to see if the time interval has elapsed
* Returns: true if expired
* Notes: Setting the interval to max never expires, to zero always expires
**************************************************************************/
bool timer_interval_expired(struct itimer *t)
{
uint32_t elapsed = 0;
bool status = false;
uint32_t now;
if (t->interval == 0) {
status = true;
} else if (t->interval == TIMER_INTERVAL_MAX) {
status = false;
} else {
now = timer_milliseconds();
elapsed = now - t->start;
if (elapsed >= t->interval) {
status = true;
}
}
return status;
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: number of milliseconds elapsed
* Notes: none
**************************************************************************/
uint32_t timer_interval_elapsed(struct itimer *t)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
return elapsed;
}
/*************************************************************************
* Description: Return the interval time
* Returns: number of milliseconds for which the interval is set
* Notes: none
**************************************************************************/
uint32_t timer_interval(struct itimer *t)
{
return t->interval;
}
/*************************************************************************
* Description: Return the interval time
* Returns: number of seconds for which the interval is set
* Notes: none
**************************************************************************/
uint32_t timer_interval_seconds(struct itimer *t)
{
return (t->interval/1000);
}
/* Elapsed Timer */
/*************************************************************************
* Description: Restart the timer from now
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_elapsed_start_offset(struct etimer *t, uint32_t offset)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
if (offset) {
t->start = now + offset;
} else {
t->start = now;
}
return elapsed;
}
/*************************************************************************
* Description: Start a timer from now.
* Returns: elapsed milliseconds since last set
* Notes: none
**************************************************************************/
uint32_t timer_elapsed_start(struct etimer *t)
{
return timer_elapsed_start_offset(t, 0);
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: true if interval has elapsed
* Notes: none
**************************************************************************/
bool timer_elapsed_milliseconds(struct etimer *t, uint32_t interval)
{
bool status = false;
uint32_t delta;
delta = timer_milliseconds() - t->start;
if (delta >= interval) {
status = true;
}
return status;
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: true if interval has elapsed
* Notes: none
**************************************************************************/
bool timer_elapsed_seconds(struct etimer *t, uint32_t interval)
{
/* convert to seconds */
interval *= 1000L;
return timer_elapsed_milliseconds(t, interval);
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: true if interval has elapsed
* Notes: none
**************************************************************************/
bool timer_elapsed_minutes(struct etimer *t, uint32_t interval)
{
/* convert to seconds */
interval *= 1000L;
/* convert to minutes */
interval *= 60L;
return timer_elapsed_milliseconds(t, interval);
}
/*************************************************************************
* Description: Return the elapsed time
* Returns: number of milliseconds elapsed
* Notes: none
**************************************************************************/
uint32_t timer_elapsed_time(struct etimer *t)
{
uint32_t now;
uint32_t elapsed;
now = timer_milliseconds();
elapsed = now - t->start;
return elapsed;
}

Some files were not shown because too many files have changed in this diff Show More