Rename DummyTCB_t to StaticTCB_t.

Move structures used for static allocation of tasks and queues into FreeRTOS.h from their individual API header files.
Add SAME70 Xplained Atmel Studio project.
Update SAMV71 Atmel Studio project to use Studio 7.
Revert some changes to GenQTest.c standard demo task which only function correctly when a queue registry was used.
This commit is contained in:
Richard Barry
2016-01-18 15:57:02 +00:00
parent 41b5e486dd
commit eae4815bf3
195 changed files with 65113 additions and 84 deletions
@@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Atmel Studio Solution File, Format Version 11.00
VisualStudioVersion = 14.0.23107.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "RTOSDemo", "RTOSDemo.cproj", "{DCE6C7E3-EE26-4D79-826B-08594B9AD897}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Release|ARM = Release|ARM
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.ActiveCfg = Debug|ARM
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Debug|ARM.Build.0 = Debug|ARM
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.ActiveCfg = Release|ARM
{DCE6C7E3-EE26-4D79-826B-08594B9AD897}.Release|ARM.Build.0 = Release|ARM
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Store xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="AtmelPackComponentManagement">
<ProjectComponents />
</Store>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,433 @@
/**
* \file
*
* \brief Standard board header file.
*
* This file includes the appropriate board header file according to the
* defined board (parameter BOARD).
*
* Copyright (c) 2009-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 XMEGA_A1U_XPLAINED_PRO 20 //!< ATxmega128A1U XMEGA-A1U Xplained Pro 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 SAMD20_XPLAINED_PRO 59 //!< SAM D20 Xplained Pro board.
#define SAM4L8_XPLAINED_PRO 60 //!< SAM4L8 Xplained Pro board.
#define SAM4N_XPLAINED_PRO 61 //!< SAM4N Xplained Pro board.
#define XMEGA_A3_REB_CBB 62 //!< XMEGA REB Controller Base board.
#define ATMEGARFX_RCB 63 //!< RFR2 & RFA1 RCB.
#define SAM4C_EK 64 //!< SAM4C-EK board.
#define RCB256RFR2_XPRO 65 //!< RFR2 RCB Xplained Pro board.
#define SAMG53_XPLAINED_PRO 66 //!< SAMG53 Xplained Pro board.
#define SAM4CP16BMB 67 //!< SAM4CP16BMB board.
#define SAM4E_XPLAINED_PRO 68 //!< SAM4E Xplained Pro board.
#define SAMD21_XPLAINED_PRO 69 //!< SAM D21 Xplained Pro board.
#define SAMR21_XPLAINED_PRO 70 //!< SAM R21 Xplained Pro board.
#define SAM4CMP_DB 71 //!< SAM4CMP demo board.
#define SAM4CMS_DB 72 //!< SAM4CMS demo board.
#define ATPL230AMB 73 //!< ATPL230AMB board.
#define SAMD11_XPLAINED_PRO 74 //!< SAM D11 Xplained Pro board.
#define SAMG55_XPLAINED_PRO 75 //!< SAMG55 Xplained Pro board.
#define SAML21_XPLAINED_PRO 76 //!< SAM L21 Xplained Pro board.
#define SAMD10_XPLAINED_MINI 77 //!< SAM D10 Xplained Mini board.
#define SAMDA1_XPLAINED_PRO 78 //!< SAM DA1 Xplained Pro board.
#define SAMW25_XPLAINED_PRO 79 //!< SAMW25 Xplained Pro board.
#define SAMC21_XPLAINED_PRO 80 //!< SAM C21 Xplained Pro board.
#define SAMV71_XPLAINED_ULTRA 81 //!< SAMV71 Xplained Ultra board.
#define ATMEGA328P_XPLAINED_MINI 82 //!< ATMEGA328P Xplained MINI board.
#define ATMEGA328PB_XPLAINED_MINI 83 //!< ATMEGA328PB Xplained MINI board.
#define SAMB11_XPLAINED_PRO 84 //!< SAM B11 Xplained Pro board.
#define SAME70_XPLAINED 85 //!< SAME70 Xplained board.
#define SAML22_XPLAINED_PRO 86 //!< SAM L22 Xplained Pro board.
#define SAML22_XPLAINED_PRO_B 87 //!< SAM L22 Xplained Pro board.
#define SAMR21ZLL_EK 88 //!< SAMR21ZLL-EK board.
#define ATMEGA168PB_XPLAINED_MINI 89 //!< ATMEGA168PB Xplained MINI board.
#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices.
#define AVR_SIMULATOR_UC3 98 //!< Simulator for the 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 == SAMG53_XPLAINED_PRO
# include "samg53_xplained_pro/samg53_xplained_pro.h"
#elif BOARD == SAMG55_XPLAINED_PRO
# include "samg55_xplained_pro/samg55_xplained_pro.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 == XMEGA_A1U_XPLAINED_PRO
# include "xmega_a1u_xplained_pro/xmega_a1u_xplained_pro.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 == SAMD20_XPLAINED_PRO
# include "samd20_xplained_pro/samd20_xplained_pro.h"
#elif BOARD == SAMD21_XPLAINED_PRO
# include "samd21_xplained_pro/samd21_xplained_pro.h"
#elif BOARD == SAMR21_XPLAINED_PRO
# include "samr21_xplained_pro/samr21_xplained_pro.h"
#elif BOARD == SAMR21ZLL_EK
# include "samr21zll_ek/samr21zll_ek.h"
#elif BOARD == SAMD11_XPLAINED_PRO
# include "samd11_xplained_pro/samd11_xplained_pro.h"
#elif BOARD == SAML21_XPLAINED_PRO && defined(__SAML21J18A__)
# include "saml21_xplained_pro/saml21_xplained_pro.h"
#elif BOARD == SAML22_XPLAINED_PRO
# include "saml22_xplained_pro/saml22_xplained_pro.h"
#elif BOARD == SAML22_XPLAINED_PRO_B
# include "saml22_xplained_pro_b/saml22_xplained_pro_b.h"
#elif BOARD == SAML21_XPLAINED_PRO && defined(__SAML21J18B__)
# include "saml21_xplained_pro_b/saml21_xplained_pro.h"
#elif BOARD == SAMD10_XPLAINED_MINI
# include "samd10_xplained_mini/samd10_xplained_mini.h"
#elif BOARD == SAMDA1_XPLAINED_PRO
# include "samda1_xplained_pro/samda1_xplained_pro.h"
#elif BOARD == SAMC21_XPLAINED_PRO
# include "samc21_xplained_pro/samc21_xplained_pro.h"
#elif BOARD == SAM4N_XPLAINED_PRO
# include "sam4n_xplained_pro/sam4n_xplained_pro.h"
#elif BOARD == SAMW25_XPLAINED_PRO
# include "samw25_xplained_pro/samw25_xplained_pro.h"
#elif BOARD == SAMV71_XPLAINED_ULTRA
# include "samv71_xplained_ultra/samv71_xplained_ultra.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 == SAM4L8_XPLAINED_PRO
# include "sam4l8_xplained_pro/sam4l8_xplained_pro.h"
#elif BOARD == SAM4C_EK
# include "sam4c_ek/sam4c_ek.h"
#elif BOARD == SAM4CMP_DB
# include "sam4cmp_db/sam4cmp_db.h"
#elif BOARD == SAM4CMS_DB
# include "sam4cms_db/sam4cms_db.h"
#elif BOARD == SAM4CP16BMB
# include "sam4cp16bmb/sam4cp16bmb.h"
#elif BOARD == ATPL230AMB
# include "atpl230amb/atpl230amb.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_A3_REB_CBB
# include "xmega_a3_reb_cbb/xmega_a3_reb_cbb.h"
#elif BOARD == ATMEGARFX_RCB
# include "atmegarfx_rcb/atmegarfx_rcb.h"
#elif BOARD == RCB256RFR2_XPRO
# include "atmega256rfr2_rcb_xpro/atmega256rfr2_rcb_xpro.h"
#elif BOARD == XMEGA_RF212B_ZIGBIT
# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h"
#elif BOARD == SAM4E_XPLAINED_PRO
# include "sam4e_xplained_pro/sam4e_xplained_pro.h"
#elif BOARD == ATMEGA328P_XPLAINED_MINI
# include "atmega328p_xplained_mini/atmega328p_xplained_mini.h"
#elif BOARD == ATMEGA328PB_XPLAINED_MINI
# include "atmega328pb_xplained_mini/atmega328pb_xplained_mini.h"
#elif BOARD == SAMB11_XPLAINED_PRO
# include "samb11_xplained_pro/samb11_xplained_pro.h"
#elif BOARD == SAME70_XPLAINED
# include "same70_xplained/same70_xplained.h"
#elif BOARD == ATMEGA168PB_XPLAINED_MINI
# include "atmega168pb_xplained_mini/atmega168pb_xplained_mini.h"
#elif BOARD == SIMULATOR_XMEGA_A1
# include "simulator/xmega_a1/simulator_xmega_a1.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_
@@ -0,0 +1,199 @@
/**
* \file
*
* \brief Generic clock management
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 SAM4N
# include "sam4n/genclk.h"
#elif SAM4C
# include "sam4c/genclk.h"
#elif SAM4CM
# include "sam4cm/genclk.h"
#elif SAM4CP
# include "sam4cp/genclk.h"
#elif SAMG
# include "samg/genclk.h"
#elif SAMV71
# include "samv71/genclk.h"
#elif SAMV70
# include "samv70/genclk.h"
#elif SAME70
# include "same70/genclk.h"
#elif SAMS70
# include "sams70/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 */
@@ -0,0 +1,185 @@
/**
* \file
*
* \brief Oscillator management
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 SAM4C
# include "sam4c/osc.h"
#elif SAM4CM
# include "sam4cm/osc.h"
#elif SAM4CP
# include "sam4cp/osc.h"
#elif SAM4L
# include "sam4l/osc.h"
#elif SAM4N
# include "sam4n/osc.h"
#elif SAMG
# include "samg/osc.h"
#elif SAMV71
# include "samv71/osc.h"
#elif SAMV70
# include "samv70/osc.h"
#elif SAME70
# include "same70/osc.h"
#elif SAMS70
# include "sams70/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 */
@@ -0,0 +1,341 @@
/**
* \file
*
* \brief PLL management
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 SAM4C
# include "sam4c/pll.h"
#elif SAM4CM
# include "sam4cm/pll.h"
#elif SAM4CP
# include "sam4cp/pll.h"
#elif SAM4L
# include "sam4l/pll.h"
#elif SAM4N
# include "sam4n/pll.h"
#elif SAMG
# include "samg/pll.h"
#elif SAMV71
# include "samv71/pll.h"
#elif SAMV70
# include "samv70/pll.h"
#elif SAME70
# include "same70/pll.h"
#elif SAMS70
# include "sams70/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 */
@@ -0,0 +1,269 @@
/**
* \file
*
* \brief Chip-specific generic clock management.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CHIP_GENCLK_H_INCLUDED
#define CHIP_GENCLK_H_INCLUDED
#include <osc.h>
#include <pll.h>
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/**
* \weakgroup genclk_group
* @{
*/
//! \name Programmable Clock Identifiers (PCK)
//@{
#define GENCLK_PCK_0 0 //!< PCK0 ID
#define GENCLK_PCK_1 1 //!< PCK1 ID
#define GENCLK_PCK_2 2 //!< PCK2 ID
//@}
//! \name Programmable Clock Sources (PCK)
//@{
enum genclk_source {
GENCLK_PCK_SRC_SLCK_RC = 0,//!< Internal 32kHz RC oscillator as PCK source clock
GENCLK_PCK_SRC_SLCK_XTAL = 1,//!< External 32kHz crystal oscillator as PCK source clock
GENCLK_PCK_SRC_SLCK_BYPASS = 2,//!< External 32kHz bypass oscillator as PCK source clock
GENCLK_PCK_SRC_MAINCK_4M_RC = 3,//!< Internal 4MHz RC oscillator as PCK source clock
GENCLK_PCK_SRC_MAINCK_8M_RC = 4,//!< Internal 8MHz RC oscillator as PCK source clock
GENCLK_PCK_SRC_MAINCK_12M_RC = 5,//!< Internal 12MHz RC oscillator as PCK source clock
GENCLK_PCK_SRC_MAINCK_XTAL = 6,//!< External crystal oscillator as PCK source clock
GENCLK_PCK_SRC_MAINCK_BYPASS = 7,//!< External bypass oscillator as PCK source clock
GENCLK_PCK_SRC_PLLACK = 8,//!< Use PLLACK as PCK source clock
GENCLK_PCK_SRC_MCK = 9,//!< Use Master Clk as PCK source clock
};
//@}
//! \name Programmable Clock Prescalers (PCK)
//@{
enum genclk_divider {
GENCLK_PCK_PRES_1 = PMC_PCK_PRES(0), //!< Set PCK clock prescaler to 1
GENCLK_PCK_PRES_2 = PMC_PCK_PRES(1), //!< Set PCK clock prescaler to 2
GENCLK_PCK_PRES_4 = PMC_PCK_PRES(2), //!< Set PCK clock prescaler to 4
GENCLK_PCK_PRES_8 = PMC_PCK_PRES(3), //!< Set PCK clock prescaler to 8
GENCLK_PCK_PRES_16 = PMC_PCK_PRES(4), //!< Set PCK clock prescaler to 16
GENCLK_PCK_PRES_32 = PMC_PCK_PRES(5), //!< Set PCK clock prescaler to 32
GENCLK_PCK_PRES_64 = PMC_PCK_PRES(6), //!< Set PCK clock prescaler to 64
};
//@}
struct genclk_config {
uint32_t ctrl;
};
static inline void genclk_config_defaults(struct genclk_config *p_cfg,
uint32_t ul_id)
{
ul_id = ul_id;
p_cfg->ctrl = 0;
}
static inline void genclk_config_read(struct genclk_config *p_cfg,
uint32_t ul_id)
{
p_cfg->ctrl = PMC->PMC_PCK[ul_id];
}
static inline void genclk_config_write(const struct genclk_config *p_cfg,
uint32_t ul_id)
{
PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
}
//! \name Programmable Clock Source and Prescaler configuration
//@{
static inline void genclk_config_set_source(struct genclk_config *p_cfg,
enum genclk_source e_src)
{
p_cfg->ctrl &= (~PMC_PCK_CSS_Msk);
switch (e_src) {
case GENCLK_PCK_SRC_SLCK_RC:
case GENCLK_PCK_SRC_SLCK_XTAL:
case GENCLK_PCK_SRC_SLCK_BYPASS:
p_cfg->ctrl |= (PMC_PCK_CSS_SLOW_CLK);
break;
case GENCLK_PCK_SRC_MAINCK_4M_RC:
case GENCLK_PCK_SRC_MAINCK_8M_RC:
case GENCLK_PCK_SRC_MAINCK_12M_RC:
case GENCLK_PCK_SRC_MAINCK_XTAL:
case GENCLK_PCK_SRC_MAINCK_BYPASS:
p_cfg->ctrl |= (PMC_PCK_CSS_MAIN_CLK);
break;
case GENCLK_PCK_SRC_PLLACK:
p_cfg->ctrl |= (PMC_PCK_CSS_PLLA_CLK);
break;
case GENCLK_PCK_SRC_MCK:
p_cfg->ctrl |= (PMC_PCK_CSS_MCK);
break;
default:
break;
}
}
static inline void genclk_config_set_divider(struct genclk_config *p_cfg,
uint32_t e_divider)
{
p_cfg->ctrl &= ~PMC_PCK_PRES_Msk;
p_cfg->ctrl |= e_divider;
}
//@}
static inline void genclk_enable(const struct genclk_config *p_cfg, uint32_t ul_id)
{
PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
pmc_enable_pck(ul_id);
}
static inline void genclk_disable(uint32_t ul_id)
{
pmc_disable_pck(ul_id);
}
static inline void genclk_enable_source(enum genclk_source e_src)
{
switch (e_src) {
case GENCLK_PCK_SRC_SLCK_RC:
if (!osc_is_ready(OSC_SLCK_32K_RC)) {
osc_enable(OSC_SLCK_32K_RC);
osc_wait_ready(OSC_SLCK_32K_RC);
}
break;
case GENCLK_PCK_SRC_SLCK_XTAL:
if (!osc_is_ready(OSC_SLCK_32K_XTAL)) {
osc_enable(OSC_SLCK_32K_XTAL);
osc_wait_ready(OSC_SLCK_32K_XTAL);
}
break;
case GENCLK_PCK_SRC_SLCK_BYPASS:
if (!osc_is_ready(OSC_SLCK_32K_BYPASS)) {
osc_enable(OSC_SLCK_32K_BYPASS);
osc_wait_ready(OSC_SLCK_32K_BYPASS);
}
break;
case GENCLK_PCK_SRC_MAINCK_4M_RC:
if (!osc_is_ready(OSC_MAINCK_4M_RC)) {
osc_enable(OSC_MAINCK_4M_RC);
osc_wait_ready(OSC_MAINCK_4M_RC);
}
break;
case GENCLK_PCK_SRC_MAINCK_8M_RC:
if (!osc_is_ready(OSC_MAINCK_8M_RC)) {
osc_enable(OSC_MAINCK_8M_RC);
osc_wait_ready(OSC_MAINCK_8M_RC);
}
break;
case GENCLK_PCK_SRC_MAINCK_12M_RC:
if (!osc_is_ready(OSC_MAINCK_12M_RC)) {
osc_enable(OSC_MAINCK_12M_RC);
osc_wait_ready(OSC_MAINCK_12M_RC);
}
break;
case GENCLK_PCK_SRC_MAINCK_XTAL:
if (!osc_is_ready(OSC_MAINCK_XTAL)) {
osc_enable(OSC_MAINCK_XTAL);
osc_wait_ready(OSC_MAINCK_XTAL);
}
break;
case GENCLK_PCK_SRC_MAINCK_BYPASS:
if (!osc_is_ready(OSC_MAINCK_BYPASS)) {
osc_enable(OSC_MAINCK_BYPASS);
osc_wait_ready(OSC_MAINCK_BYPASS);
}
break;
#ifdef CONFIG_PLL0_SOURCE
case GENCLK_PCK_SRC_PLLACK:
pll_enable_config_defaults(0);
break;
#endif
case GENCLK_PCK_SRC_MCK:
break;
default:
Assert(false);
break;
}
}
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
#endif /* CHIP_GENCLK_H_INCLUDED */
@@ -0,0 +1,247 @@
/**
* \file
*
* \brief Chip-specific oscillator management functions.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CHIP_OSC_H_INCLUDED
#define CHIP_OSC_H_INCLUDED
#include "board.h"
#include "pmc.h"
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/*
* Below BOARD_XXX macros are related to the specific board, and
* should be defined by the board code, otherwise default value are used.
*/
#if !defined(BOARD_FREQ_SLCK_XTAL)
# warning The board slow clock xtal frequency has not been defined.
# define BOARD_FREQ_SLCK_XTAL (32768UL)
#endif
#if !defined(BOARD_FREQ_SLCK_BYPASS)
# warning The board slow clock bypass frequency has not been defined.
# define BOARD_FREQ_SLCK_BYPASS (32768UL)
#endif
#if !defined(BOARD_FREQ_MAINCK_XTAL)
# warning The board main clock xtal frequency has not been defined.
# define BOARD_FREQ_MAINCK_XTAL (12000000UL)
#endif
#if !defined(BOARD_FREQ_MAINCK_BYPASS)
# warning The board main clock bypass frequency has not been defined.
# define BOARD_FREQ_MAINCK_BYPASS (12000000UL)
#endif
#if !defined(BOARD_OSC_STARTUP_US)
# warning The board main clock xtal startup time has not been defined.
# define BOARD_OSC_STARTUP_US (15625UL)
#endif
/**
* \weakgroup osc_group
* @{
*/
//! \name Oscillator identifiers
//@{
#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator.
#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator.
#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator.
#define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator.
#define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator.
#define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator.
#define OSC_MAINCK_XTAL 6 //!< External crystal oscillator.
#define OSC_MAINCK_BYPASS 7 //!< External bypass oscillator.
//@}
//! \name Oscillator clock speed in hertz
//@{
#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator.
#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator.
#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator.
#define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator.
#define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator.
#define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator.
#define OSC_MAINCK_XTAL_HZ BOARD_FREQ_MAINCK_XTAL //!< External crystal oscillator.
#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator.
//@}
static inline void osc_enable(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
break;
case OSC_SLCK_32K_XTAL:
pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL);
break;
case OSC_SLCK_32K_BYPASS:
pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS);
break;
case OSC_MAINCK_4M_RC:
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
break;
case OSC_MAINCK_8M_RC:
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz);
break;
case OSC_MAINCK_12M_RC:
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
break;
case OSC_MAINCK_XTAL:
pmc_switch_mainck_to_xtal(PMC_OSC_XTAL,
pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US,
OSC_SLCK_32K_RC_HZ));
break;
case OSC_MAINCK_BYPASS:
pmc_switch_mainck_to_xtal(PMC_OSC_BYPASS,
pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US,
OSC_SLCK_32K_RC_HZ));
break;
}
}
static inline void osc_disable(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
case OSC_SLCK_32K_XTAL:
case OSC_SLCK_32K_BYPASS:
break;
case OSC_MAINCK_4M_RC:
case OSC_MAINCK_8M_RC:
case OSC_MAINCK_12M_RC:
pmc_osc_disable_fastrc();
break;
case OSC_MAINCK_XTAL:
pmc_osc_disable_xtal(PMC_OSC_XTAL);
break;
case OSC_MAINCK_BYPASS:
pmc_osc_disable_xtal(PMC_OSC_BYPASS);
break;
}
}
static inline bool osc_is_ready(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
return 1;
case OSC_SLCK_32K_XTAL:
case OSC_SLCK_32K_BYPASS:
return pmc_osc_is_ready_32kxtal();
case OSC_MAINCK_4M_RC:
case OSC_MAINCK_8M_RC:
case OSC_MAINCK_12M_RC:
case OSC_MAINCK_XTAL:
case OSC_MAINCK_BYPASS:
return pmc_osc_is_ready_mainck();
}
return 0;
}
static inline uint32_t osc_get_rate(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
return OSC_SLCK_32K_RC_HZ;
case OSC_SLCK_32K_XTAL:
return BOARD_FREQ_SLCK_XTAL;
case OSC_SLCK_32K_BYPASS:
return BOARD_FREQ_SLCK_BYPASS;
case OSC_MAINCK_4M_RC:
return OSC_MAINCK_4M_RC_HZ;
case OSC_MAINCK_8M_RC:
return OSC_MAINCK_8M_RC_HZ;
case OSC_MAINCK_12M_RC:
return OSC_MAINCK_12M_RC_HZ;
case OSC_MAINCK_XTAL:
return BOARD_FREQ_MAINCK_XTAL;
case OSC_MAINCK_BYPASS:
return BOARD_FREQ_MAINCK_BYPASS;
}
return 0;
}
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
#endif /* CHIP_OSC_H_INCLUDED */
@@ -0,0 +1,269 @@
/**
* \file
*
* \brief Chip-specific PLL definitions.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CHIP_PLL_H_INCLUDED
#define CHIP_PLL_H_INCLUDED
#include <osc.h>
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/**
* \weakgroup pll_group
* @{
*/
#define PLL_OUTPUT_MIN_HZ 160000000
#define PLL_OUTPUT_MAX_HZ 500000000
#define PLL_INPUT_MIN_HZ 3000000
#define PLL_INPUT_MAX_HZ 32000000
#define NR_PLLS 2
#define PLLA_ID 0
#define UPLL_ID 1 //!< USB UTMI PLL.
#define PLL_UPLL_HZ 480000000
#define PLL_COUNT 0x3fU
enum pll_source {
PLL_SRC_MAINCK_4M_RC = OSC_MAINCK_4M_RC, //!< Internal 4MHz RC oscillator.
PLL_SRC_MAINCK_8M_RC = OSC_MAINCK_8M_RC, //!< Internal 8MHz RC oscillator.
PLL_SRC_MAINCK_12M_RC = OSC_MAINCK_12M_RC, //!< Internal 12MHz RC oscillator.
PLL_SRC_MAINCK_XTAL = OSC_MAINCK_XTAL, //!< External crystal oscillator.
PLL_SRC_MAINCK_BYPASS = OSC_MAINCK_BYPASS, //!< External bypass oscillator.
PLL_NR_SOURCES, //!< Number of PLL sources.
};
struct pll_config {
uint32_t ctrl;
};
#define pll_get_default_rate(pll_id) \
((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \
* CONFIG_PLL##pll_id##_MUL) \
/ CONFIG_PLL##pll_id##_DIV)
/* Force UTMI PLL parameters (Hardware defined) */
#ifdef CONFIG_PLL1_SOURCE
# undef CONFIG_PLL1_SOURCE
#endif
#ifdef CONFIG_PLL1_MUL
# undef CONFIG_PLL1_MUL
#endif
#ifdef CONFIG_PLL1_DIV
# undef CONFIG_PLL1_DIV
#endif
#define CONFIG_PLL1_SOURCE PLL_SRC_MAINCK_XTAL
#define CONFIG_PLL1_MUL 0
#define CONFIG_PLL1_DIV 0
/**
* \note The SAMV71 PLL hardware interprets mul as mul+1. For readability the
* hardware mul+1 is hidden in this implementation. Use mul as mul effective
* value.
*/
static inline void pll_config_init(struct pll_config *p_cfg,
enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul)
{
uint32_t vco_hz;
Assert(e_src < PLL_NR_SOURCES);
if (ul_div == 0 && ul_mul == 0) { /* Must only be true for UTMI PLL */
p_cfg->ctrl = CKGR_UCKR_UPLLCOUNT(PLL_COUNT);
} else { /* PLLA */
/* Calculate internal VCO frequency */
vco_hz = osc_get_rate(e_src) / ul_div;
Assert(vco_hz >= PLL_INPUT_MIN_HZ);
Assert(vco_hz <= PLL_INPUT_MAX_HZ);
vco_hz *= ul_mul;
Assert(vco_hz >= PLL_OUTPUT_MIN_HZ);
Assert(vco_hz <= PLL_OUTPUT_MAX_HZ);
/* PMC hardware will automatically make it mul+1 */
p_cfg->ctrl = CKGR_PLLAR_MULA(ul_mul - 1) | CKGR_PLLAR_DIVA(ul_div) \
| CKGR_PLLAR_PLLACOUNT(PLL_COUNT);
}
}
#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 *p_cfg, uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
p_cfg->ctrl = PMC->CKGR_PLLAR;
} else {
p_cfg->ctrl = PMC->CKGR_UCKR;
}
}
static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
pmc_disable_pllack(); // Always stop PLL first!
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl;
} else {
PMC->CKGR_UCKR = p_cfg->ctrl;
}
}
static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
pmc_disable_pllack(); // Always stop PLL first!
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl;
} else {
PMC->CKGR_UCKR = p_cfg->ctrl | CKGR_UCKR_UPLLEN;
}
}
/**
* \note This will only disable the selected PLL, not the underlying oscillator (mainck).
*/
static inline void pll_disable(uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
pmc_disable_pllack();
} else {
PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN;
}
}
static inline uint32_t pll_is_locked(uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
return pmc_is_locked_pllack();
} else {
return pmc_is_locked_upll();
}
}
static inline void pll_enable_source(enum pll_source e_src)
{
switch (e_src) {
case PLL_SRC_MAINCK_4M_RC:
case PLL_SRC_MAINCK_8M_RC:
case PLL_SRC_MAINCK_12M_RC:
case PLL_SRC_MAINCK_XTAL:
case PLL_SRC_MAINCK_BYPASS:
osc_enable(e_src);
osc_wait_ready(e_src);
break;
default:
Assert(false);
break;
}
}
static inline void pll_enable_config_defaults(unsigned int ul_pll_id)
{
struct pll_config pllcfg;
if (pll_is_locked(ul_pll_id)) {
return; // Pll already running
}
switch (ul_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
#ifdef CONFIG_PLL1_SOURCE
case 1:
pll_enable_source(CONFIG_PLL1_SOURCE);
pll_config_init(&pllcfg,
CONFIG_PLL1_SOURCE,
CONFIG_PLL1_DIV,
CONFIG_PLL1_MUL);
break;
#endif
default:
Assert(false);
break;
}
pll_enable(&pllcfg, ul_pll_id);
while (!pll_is_locked(ul_pll_id));
}
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
#endif /* CHIP_PLL_H_INCLUDED */
@@ -0,0 +1,261 @@
/**
* \file
*
* \brief Chip-specific system clock management functions.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <sysclk.h>
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/**
* \weakgroup sysclk_group
* @{
*/
#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
/**
* \brief boolean signalling that the sysclk_init is done.
*/
uint32_t sysclk_initialized = 0;
#endif
/**
* \brief Set system clock prescaler configuration
*
* This function will change the system clock prescaler configuration to
* match the parameters.
*
* \note The parameters to this function are device-specific.
*
* \param ul_pres The CPU clock will be divided by \f$2^{mck\_pres}\f$
*/
void sysclk_set_prescalers(uint32_t ul_pres)
{
pmc_mck_set_prescaler(ul_pres);
SystemCoreClockUpdate();
}
/**
* \brief Change the source of the main system clock.
*
* \param ul_src The new system clock source. Must be one of the constants
* from the <em>System Clock Sources</em> section.
*/
void sysclk_set_source(uint32_t ul_src)
{
switch (ul_src) {
case SYSCLK_SRC_SLCK_RC:
case SYSCLK_SRC_SLCK_XTAL:
case SYSCLK_SRC_SLCK_BYPASS:
pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK);
break;
case SYSCLK_SRC_MAINCK_4M_RC:
case SYSCLK_SRC_MAINCK_8M_RC:
case SYSCLK_SRC_MAINCK_12M_RC:
case SYSCLK_SRC_MAINCK_XTAL:
case SYSCLK_SRC_MAINCK_BYPASS:
pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK);
break;
case SYSCLK_SRC_PLLACK:
pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK);
break;
case SYSCLK_SRC_UPLLCK:
pmc_mck_set_source(PMC_MCKR_CSS_UPLL_CLK);
break;
}
SystemCoreClockUpdate();
}
#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__)
/**
* \brief Enable USB clock.
*
* \note The SAMV71 UDP hardware interprets div as div+1. For readability the hardware div+1
* is hidden in this implementation. Use div as div effective value.
*
* \param pll_id Source of the USB clock.
* \param div Actual clock divisor. Must be superior to 0.
*/
void sysclk_enable_usb(void)
{
Assert(CONFIG_USBCLK_DIV > 0);
#ifdef CONFIG_PLL0_SOURCE
if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL0) {
struct pll_config pllcfg;
pll_enable_source(CONFIG_PLL0_SOURCE);
pll_config_defaults(&pllcfg, 0);
pll_enable(&pllcfg, 0);
pll_wait_for_lock(0);
pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1);
pmc_enable_udpck();
return;
}
#endif
if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_UPLL) {
pmc_enable_upll_clock();
pmc_switch_udpck_to_upllck(CONFIG_USBCLK_DIV - 1);
pmc_enable_udpck();
return;
}
}
/**
* \brief Disable the USB clock.
*
* \note This implementation does not switch off the PLL, it just turns off the USB clock.
*/
void sysclk_disable_usb(void)
{
pmc_disable_udpck();
}
#endif // CONFIG_USBCLK_SOURCE
void sysclk_init(void)
{
struct pll_config pllcfg;
/* Set flash wait state to max in case the below clock switching. */
system_init_flash(CHIP_FREQ_CPU_MAX);
/* Config system clock setting */
if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) {
osc_enable(OSC_SLCK_32K_RC);
osc_wait_ready(OSC_SLCK_32K_RC);
pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) {
osc_enable(OSC_SLCK_32K_XTAL);
osc_wait_ready(OSC_SLCK_32K_XTAL);
pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) {
osc_enable(OSC_SLCK_32K_BYPASS);
osc_wait_ready(OSC_SLCK_32K_BYPASS);
pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES);
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) {
/* Already running from SYSCLK_SRC_MAINCK_4M_RC */
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) {
osc_enable(OSC_MAINCK_8M_RC);
osc_wait_ready(OSC_MAINCK_8M_RC);
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) {
osc_enable(OSC_MAINCK_12M_RC);
osc_wait_ready(OSC_MAINCK_12M_RC);
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) {
osc_enable(OSC_MAINCK_XTAL);
osc_wait_ready(OSC_MAINCK_XTAL);
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
}
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) {
osc_enable(OSC_MAINCK_BYPASS);
osc_wait_ready(OSC_MAINCK_BYPASS);
pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES);
}
#ifdef CONFIG_PLL0_SOURCE
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) {
pll_enable_source(CONFIG_PLL0_SOURCE);
pll_config_defaults(&pllcfg, 0);
pll_enable(&pllcfg, 0);
pll_wait_for_lock(0);
pmc_mck_set_division(CONFIG_SYSCLK_DIV);
pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES);
}
#endif
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_UPLLCK) {
pll_enable_source(CONFIG_PLL1_SOURCE);
pll_config_defaults(&pllcfg, 1);
pll_enable(&pllcfg, 1);
pll_wait_for_lock(1);
pmc_mck_set_division(CONFIG_SYSCLK_DIV);
pmc_switch_mck_to_upllck(CONFIG_SYSCLK_PRES);
}
/* Update the SystemFrequency variable */
SystemCoreClockUpdate();
/* Set a flash wait state depending on the new cpu frequency */
system_init_flash(sysclk_get_cpu_hz());
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
/* Signal that the internal frequencies are setup */
sysclk_initialized = 1;
#endif
}
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
@@ -0,0 +1,473 @@
/**
* \file
*
* \brief Chip-specific system clock management functions.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef CHIP_SYSCLK_H_INCLUDED
#define CHIP_SYSCLK_H_INCLUDED
#include <osc.h>
#include <pll.h>
/**
* \page sysclk_quickstart Quick Start Guide for the System Clock Management
* service (SAMV71)
*
* This is the quick start guide for the \ref sysclk_group "System Clock
* Management" service, with step-by-step instructions on how to configure and
* use the service for specific use cases.
*
* \section sysclk_quickstart_usecases System Clock Management use cases
* - \ref sysclk_quickstart_basic
* - \ref sysclk_quickstart_use_case_2
*
* \section sysclk_quickstart_basic Basic usage of the System Clock Management
* service
* This section will present a basic use case for the System Clock Management
* service. This use case will configure the main system clock to 120MHz,
* using an internal PLL module to multiply the frequency of a crystal attached
* to the microcontroller.
*
* \subsection sysclk_quickstart_use_case_1_prereq Prerequisites
* - None
*
* \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code
* Add to the application initialization code:
* \code
sysclk_init();
\endcode
*
* \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow
* -# Configure the system clocks according to the settings in conf_clock.h:
* \code sysclk_init(); \endcode
*
* \subsection sysclk_quickstart_use_case_1_example_code Example code
* Add or uncomment the following in your conf_clock.h header file,
* commenting out all other definitions of the same symbol(s):
* \code
#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
// Fpll0 = (Fclk * PLL_mul) / PLL_div
#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
#define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
#define CONFIG_PLL0_DIV 1
// Fbus = Fsys / BUS_div
#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
\endcode
*
* \subsection sysclk_quickstart_use_case_1_example_workflow Workflow
* -# Configure the main system clock to use the output of the PLL module as
* its source:
* \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode
* -# Configure the PLL module to use the fast external fast crystal
* oscillator as its source:
* \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode
* -# Configure the PLL module to multiply the external fast crystal
* oscillator frequency up to 120MHz:
* \code
#define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL)
#define CONFIG_PLL0_DIV 1
\endcode
* \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the
* board \c conf_board.h configuration
* file as the frequency of the fast crystal attached to the microcontroller.
* -# Configure the main clock to run at the full 120MHz, disable scaling of
* the main system clock speed:
* \code
#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
\endcode
* \note Some dividers are powers of two, while others are integer division
* factors. Refer to the formulas in the conf_clock.h template commented
* above each division define.
*/
/**
* \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock
* Management (SAMV71)
*
* \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus
* Clock Management
* This section will present a more advanced use case for the System Clock
* Management service. This use case will configure the main system clock to
* 96MHz, using an internal PLL module to multiply the frequency of a crystal
* attached to the microcontroller. The USB clock will be configured via the
* same PLL module.
*
* \subsection sysclk_quickstart_use_case_2_prereq Prerequisites
* - None
*
* \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code
* Add to the application initialization code:
* \code
sysclk_init();
\endcode
*
* \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow
* -# Configure the system clocks according to the settings in conf_clock.h:
* \code sysclk_init(); \endcode
*
* \subsection sysclk_quickstart_use_case_2_example_code Example code
* Add or uncomment the following in your conf_clock.h header file,
* commenting out all other definitions of the same symbol(s):
* \code
#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK
// Fpll0 = (Fclk * PLL_mul) / PLL_div
#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL
#define CONFIG_PLL0_MUL (96000000UL / BOARD_FREQ_MAINCK_XTAL)
#define CONFIG_PLL0_DIV 1
// Fbus = Fsys / BUS_div
#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
// Fusb = Fsys / USB_div
#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0
#define CONFIG_USBCLK_DIV 2
\endcode
*
* \subsection sysclk_quickstart_use_case_2_example_workflow Workflow
* -# Configure the main system clock to use the output of the PLL0 module as
* its source:
* \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode
* -# Configure the PLL0 module to use the fast external fast crystal
* oscillator as its source:
* \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode
* -# Configure the PLL0 module to multiply the external fast crystal
* oscillator frequency up to 96MHz:
* \code
#define CONFIG_PLL0_MUL (96000000UL / BOARD_FREQ_MAINCK_XTAL)
#define CONFIG_PLL0_DIV 1
\endcode
* \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the
* board \c conf_board.h configuration file as the frequency of the fast
* crystal attached to the microcontroller.
* -# Configure the main clock to run at the full 96MHz, disable scaling of
* the main system clock speed:
* \code
#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1
\endcode
* \note Some dividers are powers of two, while others are integer division
* factors. Refer to the formulas in the conf_clock.h template commented
* above each division define.
* -# Configure the USB module clock to use the output of the PLL0 module as
* its source with division 2:
* \code
#define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0
#define CONFIG_USBCLK_DIV 2
\endcode
*/
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/**
* \weakgroup sysclk_group
* @{
*/
//! \name Configuration Symbols
//@{
/**
* \def CONFIG_SYSCLK_SOURCE
* \brief Initial/static main system clock source
*
* The main system clock will be configured to use this clock during
* initialization.
*/
#ifndef CONFIG_SYSCLK_SOURCE
# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC
#endif
/**
* \def CONFIG_SYSCLK_PRES
* \brief Initial CPU clock divider (mck)
*
* The MCK will run at
* \f[
* f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz}
* \f]
* after initialization.
*/
#ifndef CONFIG_SYSCLK_PRES
# define CONFIG_SYSCLK_PRES 0
#endif
//@}
//! \name Master Clock Sources (MCK)
//@{
#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock
#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock
#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock
#define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock
#define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock
#define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock
#define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock
#define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock
#define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock
#define SYSCLK_SRC_UPLLCK 9 //!< Use UPLLCK as master source clock
//@}
//! \name Master Clock Prescalers (MCK)
//@{
#define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1
#define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2
#define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4
#define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8
#define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16
#define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32
#define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64
#define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3
//@}
//! \name Master Clock Division (MCK)
//@{
#define SYSCLK_DIV_1 PMC_MCKR_MDIV_EQ_PCK //!< Set master clock division to 1
#define SYSCLK_DIV_2 PMC_MCKR_MDIV_PCK_DIV2 //!< Set master clock division to 2
#define SYSCLK_DIV_4 PMC_MCKR_MDIV_PCK_DIV4 //!< Set master clock division to 4
#define SYSCLK_DIV_3 PMC_MCKR_MDIV_PCK_DIV3 //!< Set master clock division to 3
//@}
//! \name USB Clock Sources
//@{
#define USBCLK_SRC_PLL0 0 //!< Use PLLA
#define USBCLK_SRC_UPLL 1 //!< Use UPLL
//@}
/**
* \def CONFIG_USBCLK_SOURCE
* \brief Configuration symbol for the USB generic clock source
*
* Sets the clock source to use for the USB. The source must also be properly
* configured.
*
* Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if
* USB is not required.
*/
#ifdef __DOXYGEN__
# define CONFIG_USBCLK_SOURCE
#endif
/**
* \def CONFIG_USBCLK_DIV
* \brief Configuration symbol for the USB generic clock divider setting
*
* Sets the clock division for the USB generic clock. If a USB clock source is
* selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be
* defined.
*/
#ifdef __DOXYGEN__
# define CONFIG_USBCLK_DIV
#endif
/**
* \name Querying the system clock
*
* The following functions may be used to query the current frequency of
* the system clock and the CPU and bus clocks derived from it.
* sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be
* available on all platforms, although some platforms may define
* additional accessors for various chip-internal bus clocks. These are
* usually not intended to be queried directly by generic code.
*/
//@{
/**
* \brief Return the current rate in Hz of the main system clock
*
* \todo This function assumes that the main clock source never changes
* once it's been set up, and that PLL0 always runs at the compile-time
* configured default rate. While this is probably the most common
* configuration, which we want to support as a special case for
* performance reasons, we will at some point need to support more
* dynamic setups as well.
*/
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
extern uint32_t sysclk_initialized;
#endif
static inline uint32_t sysclk_get_main_hz(void)
{
#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC)
if (!sysclk_initialized ) {
return OSC_MAINCK_4M_RC_HZ;
}
#endif
/* Config system clock setting */
if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) {
return OSC_SLCK_32K_RC_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) {
return OSC_SLCK_32K_XTAL_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) {
return OSC_SLCK_32K_BYPASS_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) {
return OSC_MAINCK_4M_RC_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) {
return OSC_MAINCK_8M_RC_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) {
return OSC_MAINCK_12M_RC_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) {
return OSC_MAINCK_XTAL_HZ;
} else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) {
return OSC_MAINCK_BYPASS_HZ;
}
#ifdef CONFIG_PLL0_SOURCE
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) {
return pll_get_default_rate(0);
}
#endif
#ifdef CONFIG_PLL1_SOURCE
else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_UPLLCK) {
return PLL_UPLL_HZ;
}
#endif
else {
/* unhandled_case(CONFIG_SYSCLK_SOURCE); */
return 0;
}
}
/**
* \brief Return the current rate in Hz of the CPU clock
*
* \todo This function assumes that the CPU always runs at the system
* clock frequency. We want to support at least two more scenarios:
* Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus
* clock dividers (which may change at run time). Ditto for all the bus
* clocks.
*
* \return Frequency of the CPU clock, in Hz.
*/
static inline uint32_t sysclk_get_cpu_hz(void)
{
/* CONFIG_SYSCLK_PRES is the register value for setting the expected */
/* prescaler, not an immediate value. */
return sysclk_get_main_hz() /
((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 :
(1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos)));
}
/**
* \brief Retrieves the current rate in Hz of the peripheral clocks.
*
* \return Frequency of the peripheral clocks, in Hz.
*/
static inline uint32_t sysclk_get_peripheral_hz(void)
{
/* CONFIG_SYSCLK_PRES is the register value for setting the expected */
/* prescaler, not an immediate value. */
return sysclk_get_main_hz() /
(((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))) * CONFIG_SYSCLK_DIV);
}
/**
* \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached
* to the specified peripheral.
*
* \param module Pointer to the module's base address.
*
* \return Frequency of the bus attached to the specified peripheral, in Hz.
*/
static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module)
{
UNUSED(module);
return sysclk_get_peripheral_hz();
}
//@}
//! \name Enabling and disabling synchronous clocks
//@{
/**
* \brief Enable a peripheral's clock.
*
* \param ul_id Id (number) of the peripheral clock.
*/
static inline void sysclk_enable_peripheral_clock(uint32_t ul_id)
{
pmc_enable_periph_clk(ul_id);
}
/**
* \brief Disable a peripheral's clock.
*
* \param ul_id Id (number) of the peripheral clock.
*/
static inline void sysclk_disable_peripheral_clock(uint32_t ul_id)
{
pmc_disable_periph_clk(ul_id);
}
//@}
//! \name System Clock Source and Prescaler configuration
//@{
extern void sysclk_set_prescalers(uint32_t ul_pres);
extern void sysclk_set_source(uint32_t ul_src);
//@}
extern void sysclk_enable_usb(void);
extern void sysclk_disable_usb(void);
extern void sysclk_init(void);
//! @}
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
#endif /* CHIP_SYSCLK_H_INCLUDED */
@@ -0,0 +1,194 @@
/**
* \file
*
* \brief System clock management
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 SAM4C
# include "sam4c/sysclk.h"
#elif SAM4CM
# include "sam4cm/sysclk.h"
#elif SAM4CP
# include "sam4cp/sysclk.h"
#elif SAM4L
# include "sam4l/sysclk.h"
#elif SAM4N
# include "sam4n/sysclk.h"
#elif SAMG
# include "samg/sysclk.h"
#elif SAMV71
# include "samv71/sysclk.h"
#elif SAMV70
# include "samv70/sysclk.h"
#elif SAME70
# include "same70/sysclk.h"
#elif SAMS70
# include "sams70/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 */
@@ -0,0 +1,86 @@
/**
* \file
*
* \brief Common GPIO API.
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _GPIO_H_
#define _GPIO_H_
#include <parts.h>
#if (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
# 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_ */
@@ -0,0 +1,83 @@
/**
* \file
*
* \brief GPIO service for SAM.
*
* Copyright (c) 2011-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SAM_GPIO_H_INCLUDED
#define SAM_GPIO_H_INCLUDED
#include "compiler.h"
#include "pio.h"
#define gpio_pin_is_low(io_id) \
(pio_get_pin_value(io_id) ? 0 : 1)
#define gpio_pin_is_high(io_id) \
(pio_get_pin_value(io_id) ? 1 : 0)
#define gpio_set_pin_high(io_id) \
pio_set_pin_high(io_id)
#define gpio_set_pin_low(io_id) \
pio_set_pin_low(io_id)
#define gpio_toggle_pin(io_id) \
pio_toggle_pin(io_id)
#define gpio_configure_pin(io_id,io_flags) \
pio_configure_pin(io_id,io_flags)
#define gpio_configure_group(port_id,port_mask,io_flags) \
pio_configure_pin_group(port_id,port_mask,io_flags)
#define gpio_set_pin_group_high(port_id,mask) \
pio_set_pin_group_high(port_id,mask)
#define gpio_set_pin_group_low(port_id,mask) \
pio_set_pin_group_low(port_id,mask)
#define gpio_toggle_pin_group(port_id,mask) \
pio_toggle_pin_group(port_id,mask)
#endif /* SAM_GPIO_H_INCLUDED */
@@ -0,0 +1,380 @@
/**
* \file
*
* \brief SAM architecture specific IOPORT service implementation header file.
*
* Copyright (c) 2012-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef IOPORT_SAM_H
#define IOPORT_SAM_H
#include <sysclk.h>
#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 32 + (pin))
#define IOPORT_BASE_ADDRESS (uintptr_t)PIOA
#define IOPORT_PIO_OFFSET ((uintptr_t)PIOB - (uintptr_t)PIOA)
#define IOPORT_PIOA 0
#define IOPORT_PIOB 1
#define IOPORT_PIOC 2
#define IOPORT_PIOD 3
#define IOPORT_PIOE 4
#define IOPORT_PIOF 5
/**
* \weakgroup ioport_group
* \section ioport_modes IOPORT Modes
*
* For details on these please see the SAM Manual.
*
* @{
*/
/** \name IOPORT Mode bit definitions */
/** @{ */
#define IOPORT_MODE_MUX_MASK (0x7 << 0) /*!< MUX bits mask */
#define IOPORT_MODE_MUX_BIT0 ( 1 << 0) /*!< MUX BIT0 mask */
#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
#define IOPORT_MODE_MUX_BIT1 ( 1 << 1) /*!< MUX BIT1 mask */
#endif
#define IOPORT_MODE_MUX_A ( 0 << 0) /*!< MUX function A */
#define IOPORT_MODE_MUX_B ( 1 << 0) /*!< MUX function B */
#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
#define IOPORT_MODE_MUX_C ( 2 << 0) /*!< MUX function C */
#define IOPORT_MODE_MUX_D ( 3 << 0) /*!< MUX function D */
#endif
#define IOPORT_MODE_PULLUP ( 1 << 3) /*!< Pull-up */
#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAME70 || SAMS70
#define IOPORT_MODE_PULLDOWN ( 1 << 4) /*!< Pull-down */
#endif
#define IOPORT_MODE_OPEN_DRAIN ( 1 << 5) /*!< Open drain */
#define IOPORT_MODE_GLITCH_FILTER ( 1 << 6) /*!< Glitch filter */
#define IOPORT_MODE_DEBOUNCE ( 1 << 7) /*!< Input debounce */
/** @} */
/** @} */
typedef uint32_t ioport_mode_t;
typedef uint32_t ioport_pin_t;
typedef uint32_t ioport_port_t;
typedef uint32_t ioport_port_mask_t;
__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin)
{
return pin >> 5;
}
__always_inline static Pio *arch_ioport_port_to_base(ioport_port_t port)
{
#if (SAM4C || SAM4CM || SAM4CP)
if (port == IOPORT_PIOC) {
return (Pio *)(uintptr_t)PIOC;
# ifdef ID_PIOD
} else if (port == IOPORT_PIOD) {
return (Pio *)(uintptr_t)PIOD;
# endif
} else {
return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS +
(IOPORT_PIO_OFFSET * port));
}
#else
return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS +
(IOPORT_PIO_OFFSET * port));
#endif
}
__always_inline static Pio *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 & 0x1F);
}
__always_inline static void arch_ioport_init(void)
{
#ifdef ID_PIOA
sysclk_enable_peripheral_clock(ID_PIOA);
#endif
#ifdef ID_PIOB
sysclk_enable_peripheral_clock(ID_PIOB);
#endif
#ifdef ID_PIOC
sysclk_enable_peripheral_clock(ID_PIOC);
#endif
#ifdef ID_PIOD
sysclk_enable_peripheral_clock(ID_PIOD);
#endif
#ifdef ID_PIOE
sysclk_enable_peripheral_clock(ID_PIOE);
#endif
#ifdef ID_PIOF
sysclk_enable_peripheral_clock(ID_PIOF);
#endif
}
__always_inline static void arch_ioport_enable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->PIO_PER = mask;
}
__always_inline static void arch_ioport_disable_port(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->PIO_PDR = mask;
}
__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin)
{
arch_ioport_enable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin)
{
arch_ioport_disable_port(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin));
}
__always_inline static void arch_ioport_set_port_mode(ioport_port_t port,
ioport_port_mask_t mask, ioport_mode_t mode)
{
Pio *base = arch_ioport_port_to_base(port);
if (mode & IOPORT_MODE_PULLUP) {
base->PIO_PUER = mask;
} else {
base->PIO_PUDR = mask;
}
#if defined(IOPORT_MODE_PULLDOWN)
if (mode & IOPORT_MODE_PULLDOWN) {
base->PIO_PPDER = mask;
} else {
base->PIO_PPDDR = mask;
}
#endif
if (mode & IOPORT_MODE_OPEN_DRAIN) {
base->PIO_MDER = mask;
} else {
base->PIO_MDDR = mask;
}
if (mode & (IOPORT_MODE_GLITCH_FILTER | IOPORT_MODE_DEBOUNCE)) {
base->PIO_IFER = mask;
} else {
base->PIO_IFDR = mask;
}
if (mode & IOPORT_MODE_DEBOUNCE) {
#if SAM3U || SAM3XA
base->PIO_DIFSR = mask;
#else
base->PIO_IFSCER = mask;
#endif
} else {
#if SAM3U || SAM3XA
base->PIO_SCIFSR = mask;
#else
base->PIO_IFSCDR = mask;
#endif
}
#if !defined(IOPORT_MODE_MUX_BIT1)
if (mode & IOPORT_MODE_MUX_BIT0) {
base->PIO_ABSR |= mask;
} else {
base->PIO_ABSR &= ~mask;
}
#else
if (mode & IOPORT_MODE_MUX_BIT0) {
base->PIO_ABCDSR[0] |= mask;
} else {
base->PIO_ABCDSR[0] &= ~mask;
}
if (mode & IOPORT_MODE_MUX_BIT1) {
base->PIO_ABCDSR[1] |= mask;
} else {
base->PIO_ABCDSR[1] &= ~mask;
}
#endif
}
__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin,
ioport_mode_t mode)
{
arch_ioport_set_port_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), mode);
}
__always_inline static void arch_ioport_set_port_dir(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_direction group_direction)
{
Pio *base = arch_ioport_port_to_base(port);
if (group_direction == IOPORT_DIR_OUTPUT) {
base->PIO_OER = mask;
} else if (group_direction == IOPORT_DIR_INPUT) {
base->PIO_ODR = mask;
}
base->PIO_OWER = mask;
}
__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin,
enum ioport_direction dir)
{
Pio *base = arch_ioport_pin_to_base(pin);
if (dir == IOPORT_DIR_OUTPUT) {
base->PIO_OER = arch_ioport_pin_to_mask(pin);
} else if (dir == IOPORT_DIR_INPUT) {
base->PIO_ODR = arch_ioport_pin_to_mask(pin);
}
base->PIO_OWER = arch_ioport_pin_to_mask(pin);
}
__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin,
bool level)
{
Pio *base = arch_ioport_pin_to_base(pin);
if (level) {
base->PIO_SODR = arch_ioport_pin_to_mask(pin);
} else {
base->PIO_CODR = 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)
{
Pio *base = arch_ioport_port_to_base(port);
base->PIO_SODR = mask & level;
base->PIO_CODR = mask & ~level;
}
__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin)
{
return arch_ioport_pin_to_base(pin)->PIO_PDSR & 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)
{
return arch_ioport_port_to_base(port)->PIO_PDSR & mask;
}
__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin)
{
Pio *port = arch_ioport_pin_to_base(pin);
ioport_port_mask_t mask = arch_ioport_pin_to_mask(pin);
if (port->PIO_PDSR & arch_ioport_pin_to_mask(pin)) {
port->PIO_CODR = mask;
} else {
port->PIO_SODR = mask;
}
}
__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port,
ioport_port_mask_t mask)
{
arch_ioport_port_to_base(port)->PIO_ODSR ^= mask;
}
__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port,
ioport_port_mask_t mask, enum ioport_sense pin_sense)
{
Pio *base = arch_ioport_port_to_base(port);
/* AIMMR ELSR FRLHSR
* 0 X X IOPORT_SENSE_BOTHEDGES (Default)
* 1 0 0 IOPORT_SENSE_FALLING
* 1 0 1 IOPORT_SENSE_RISING
* 1 1 0 IOPORT_SENSE_LEVEL_LOW
* 1 1 1 IOPORT_SENSE_LEVEL_HIGH
*/
switch(pin_sense) {
case IOPORT_SENSE_LEVEL_LOW:
base->PIO_LSR = mask;
base->PIO_FELLSR = mask;
break;
case IOPORT_SENSE_LEVEL_HIGH:
base->PIO_LSR = mask;
base->PIO_REHLSR = mask;
break;
case IOPORT_SENSE_FALLING:
base->PIO_ESR = mask;
base->PIO_FELLSR = mask;
break;
case IOPORT_SENSE_RISING:
base->PIO_ESR = mask;
base->PIO_REHLSR = mask;
break;
default:
base->PIO_AIMDR = mask;
return;
}
base->PIO_AIMER = mask;
}
__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin,
enum ioport_sense pin_sense)
{
arch_ioport_set_port_sense_mode(arch_ioport_pin_to_port_id(pin),
arch_ioport_pin_to_mask(pin), pin_sense);
}
#endif /* IOPORT_SAM_H */
@@ -0,0 +1,279 @@
/**
* \file
*
* \brief Serial Mode management
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 (SAMB)
#include "samb_uart/uart_serial.h"
#elif (SAM0)
#include "sam0_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_uart_serial.h file, but it can also be added to your main application file.)
*
* \note The following takes SAM3X configuration for example, other devices have similar
* configuration, but their parameters may be different, refer to corresponding header files.
*
* \code
#define USART_SERIAL &USARTD0
#define USART_SERIAL_BAUDRATE 9600
#define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
#define USART_SERIAL_PARITY US_MR_PAR_NO
#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_uart_serial.h file, but it can also be added to your main application file.):
*
* \note The following takes SAM3X configuration for example, other devices have similar
* configuration, but their parameters may be different, refer to corresponding header files.
*
* \code
#define USART_SERIAL &USARTD0
#define USART_SERIAL_BAUDRATE 9600
#define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT
#define USART_SERIAL_PARITY US_MR_PAR_NO
#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 */
@@ -0,0 +1,87 @@
/**
*
* \file
*
* \brief USART Serial driver functions.
*
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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;
}
@@ -0,0 +1,142 @@
/**
* \file
*
* \brief Global interrupt management for 8- and 32-bit AVR
*
* Copyright (c) 2010-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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 SAM || SAMB
# 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 compatibility across 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 */
@@ -0,0 +1,86 @@
/**
* \file
*
* \brief Global interrupt management for SAM D20, SAM3 and SAM4 (NVIC based)
*
* Copyright (c) 2012-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "interrupt_sam_nvic.h"
#if !defined(__DOXYGEN__)
/* Deprecated - global flag to determine the global interrupt state. Required by
* QTouch library, however new applications should use cpu_irq_is_enabled()
* which probes the true global interrupt state from the CPU special registers.
*/
volatile bool g_interrupt_enabled = true;
#endif
void cpu_irq_enter_critical(void)
{
if (cpu_irq_critical_section_counter == 0) {
if (cpu_irq_is_enabled()) {
cpu_irq_disable();
cpu_irq_prev_interrupt_state = true;
} else {
/* Make sure the to save the prev state as false */
cpu_irq_prev_interrupt_state = false;
}
}
cpu_irq_critical_section_counter++;
}
void cpu_irq_leave_critical(void)
{
/* Check if the user is trying to leave a critical section when not in a critical section */
Assert(cpu_irq_critical_section_counter > 0);
cpu_irq_critical_section_counter--;
/* Only enable global interrupts when the counter reaches 0 and the state of the global interrupt flag
was enabled when entering critical state */
if ((cpu_irq_critical_section_counter == 0) && (cpu_irq_prev_interrupt_state)) {
cpu_irq_enable();
}
}
@@ -0,0 +1,189 @@
/**
* \file
*
* \brief Global interrupt management for SAM D20, SAM3 and SAM4 (NVIC based)
*
* Copyright (c) 2012-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef UTILS_INTERRUPT_INTERRUPT_H
#define UTILS_INTERRUPT_INTERRUPT_H
#include <compiler.h>
#include <parts.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* \weakgroup interrupt_group
*
* @{
*/
/**
* \name Interrupt Service Routine definition
*
* @{
*/
/**
* \brief Define service routine
*
* \note For NVIC devices the interrupt service routines are predefined to
* add to vector table in binary generation, so there is no service
* register at run time. The routine collections are in exceptions.h.
*
* Usage:
* \code
ISR(foo_irq_handler)
{
// Function definition
...
}
\endcode
*
* \param func Name for the function.
*/
# define ISR(func) \
void func (void)
/**
* \brief Initialize interrupt vectors
*
* For NVIC the interrupt vectors are put in vector table. So nothing
* to do to initialize them, except defined the vector function with
* right name.
*
* This must be called prior to \ref irq_register_handler.
*/
# define irq_initialize_vectors() \
do { \
} while(0)
/**
* \brief Register handler for interrupt
*
* For NVIC the interrupt vectors are put in vector table. So nothing
* to do to register them, except defined the vector function with
* right name.
*
* Usage:
* \code
irq_initialize_vectors();
irq_register_handler(foo_irq_handler);
\endcode
*
* \note The function \a func must be defined with the \ref ISR macro.
* \note The functions prototypes can be found in the device exception header
* files (exceptions.h).
*/
# define irq_register_handler(int_num, int_prio) \
NVIC_ClearPendingIRQ( (IRQn_Type)int_num); \
NVIC_SetPriority( (IRQn_Type)int_num, int_prio); \
NVIC_EnableIRQ( (IRQn_Type)int_num); \
//@}
# define cpu_irq_enable() \
do { \
g_interrupt_enabled = true; \
__DMB(); \
__enable_irq(); \
} while (0)
# define cpu_irq_disable() \
do { \
__disable_irq(); \
__DMB(); \
g_interrupt_enabled = false; \
} while (0)
typedef uint32_t irqflags_t;
#if !defined(__DOXYGEN__)
extern volatile bool g_interrupt_enabled;
#endif
#define cpu_irq_is_enabled() (__get_PRIMASK() == 0)
static volatile uint32_t cpu_irq_critical_section_counter;
static volatile bool cpu_irq_prev_interrupt_state;
static inline irqflags_t cpu_irq_save(void)
{
irqflags_t flags = cpu_irq_is_enabled();
cpu_irq_disable();
return flags;
}
static inline bool cpu_irq_is_enabled_flags(irqflags_t flags)
{
return (flags);
}
static inline void cpu_irq_restore(irqflags_t flags)
{
if (cpu_irq_is_enabled_flags(flags))
cpu_irq_enable();
}
void cpu_irq_enter_critical(void);
void cpu_irq_leave_critical(void);
/**
* \weakgroup interrupt_deprecated_group
* @{
*/
#define Enable_global_interrupt() cpu_irq_enable()
#define Disable_global_interrupt() cpu_irq_disable()
#define Is_global_interrupt_enabled() cpu_irq_is_enabled()
//@}
//@}
#ifdef __cplusplus
}
#endif
#endif /* UTILS_INTERRUPT_INTERRUPT_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,167 @@
/**
* \file
*
* \brief System-specific implementation of the \ref _read function used by
* the standard library.
*
* Copyright (c) 2009-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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
/**
* \}
*/
@@ -0,0 +1,129 @@
/**
*
* \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-2015 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
*
******************************************************************************/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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"
#ifndef SAMD20
# include "sysclk.h"
#endif
#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_
@@ -0,0 +1,147 @@
/**
* \file
*
* \brief System-specific implementation of the \ref _write function used by
* the standard library.
*
* Copyright (c) 2009-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#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
/**
* \}
*/
@@ -0,0 +1,81 @@
/**
* \file
*
* \brief SAME70-XPLD LEDs support package.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef LED_H_INCLUDED
#define LED_H_INCLUDED
#include "compiler.h"
#include "ioport.h"
/**
* \brief Turns off the specified LEDs.
*
* \param led LED to turn off (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_Off(led) ioport_set_pin_level(led##_GPIO, led##_INACTIVE_LEVEL)
/**
* \brief Turns on the specified LEDs.
*
* \param led LED to turn on (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_On(led) ioport_set_pin_level(led##_GPIO, led##_ACTIVE_LEVEL)
/**
* \brief Toggles the specified LEDs.
*
* \param led LED to toggle (LEDx_GPIO).
*
* \note The pins of the specified LEDs are set to GPIO output mode.
*/
#define LED_Toggle(led) ioport_toggle_pin_level(led##_GPIO)
#endif // LED_H_INCLUDED
@@ -0,0 +1,158 @@
/**
* \file
*
* \brief Matrix driver for SAM.
*
* Copyright (c) 2012-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef MATRIX_H_INCLUDED
#define MATRIX_H_INCLUDED
#include "compiler.h"
/* / @cond 0 */
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/* / @endcond */
#ifndef MATRIX_MCFG_ULBT
#define MATRIX_MCFG_ULBT(value) MATRIX_MCFG0_ULBT(value)
#endif
/** \brief Matrix master: undefined length burst type */
typedef enum {
MATRIX_ULBT_INFINITE_LENGTH_BURST = MATRIX_MCFG_ULBT(0),
MATRIX_ULBT_SINGLE_ACCESS = MATRIX_MCFG_ULBT(1),
MATRIX_ULBT_4_BEAT_BURST = MATRIX_MCFG_ULBT(2),
MATRIX_ULBT_8_BEAT_BURST = MATRIX_MCFG_ULBT(3),
MATRIX_ULBT_16_BEAT_BURST = MATRIX_MCFG_ULBT(4),
#if SAM4C || SAM4CP || SAM4CM || SAM4E || SAMV71 || SAMV70 || SAME70 || SAMS70
MATRIX_ULBT_32_BEAT_BURST = MATRIX_MCFG_ULBT(5),
MATRIX_ULBT_64_BEAT_BURST = MATRIX_MCFG_ULBT(6),
MATRIX_ULBT_128_BEAT_BURST = MATRIX_MCFG_ULBT(7),
#endif
} burst_type_t;
/** \brief Matrix slave: default master type */
typedef enum {
MATRIX_DEFMSTR_NO_DEFAULT_MASTER = MATRIX_SCFG_DEFMSTR_TYPE(0),
MATRIX_DEFMSTR_LAST_DEFAULT_MASTER = MATRIX_SCFG_DEFMSTR_TYPE(1),
MATRIX_DEFMSTR_FIXED_DEFAULT_MASTER = MATRIX_SCFG_DEFMSTR_TYPE(2)
} defaut_master_t;
#if !SAM4E && !SAM4C && !SAM4CP && !SAM4CM && \
!SAMV71 && !SAMV70 && !SAMS70 && !SAME70
/** \brief Matrix slave: arbitration type */
typedef enum {
MATRIX_ARBT_ROUND_ROBIN = MATRIX_SCFG_ARBT(0),
MATRIX_ARBT_FIXED_PRIORITY = MATRIX_SCFG_ARBT(1)
} arbitration_type_t;
#endif
void matrix_set_master_burst_type(uint32_t ul_id, burst_type_t burst_type);
burst_type_t matrix_get_master_burst_type(uint32_t ul_id);
void matrix_set_slave_slot_cycle(uint32_t ul_id, uint32_t ul_slot_cycle);
uint32_t matrix_get_slave_slot_cycle(uint32_t ul_id);
void matrix_set_slave_default_master_type(uint32_t ul_id, defaut_master_t type);
defaut_master_t matrix_get_slave_default_master_type(uint32_t ul_id);
void matrix_set_slave_fixed_default_master(uint32_t ul_id,
uint32_t ul_fixed_id);
uint32_t matrix_get_slave_fixed_default_master(uint32_t ul_id);
#if !SAM4E && !SAM4C && !SAM4CP && !SAM4CM && \
!SAMV71 && !SAMV70 && !SAMS70 && !SAME70
void matrix_set_slave_arbitration_type(uint32_t ul_id, arbitration_type_t type);
arbitration_type_t matrix_get_slave_arbitration_type(uint32_t ul_id);
#endif
void matrix_set_slave_priority(uint32_t ul_id, uint32_t ul_prio);
uint32_t matrix_get_slave_priority(uint32_t ul_id);
#if (SAMV71 || SAMV70|| SAME70 || SAMS70)
void matrix_set_slave_priority_b(uint32_t ul_id, uint32_t ul_prio_b);
uint32_t matrix_get_slave_priority_b(uint32_t ul_id);
#endif
#if (SAM3XA || SAM3U || SAM4E || \
SAMV71 || SAMV70 || SAMS70 || SAME70)
void matrix_set_master_remap(uint32_t ul_remap);
uint32_t matrix_get_master_remap(void);
#endif
#if (SAM3S || SAM3XA || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \
SAMV71 || SAMV70 || SAMS70 || SAME70)
void matrix_set_system_io(uint32_t ul_io);
uint32_t matrix_get_system_io(void);
#endif
#if (SAM3S || SAM4S || SAM4E || SAM4C || SAM4CP || SAM4CM || \
SAMV71 || SAMV70 || SAMS70 || SAME70)
void matrix_set_nandflash_cs(uint32_t ul_cs);
uint32_t matrix_get_nandflash_cs(void);
#endif
#if (!SAMG)
void matrix_set_writeprotect(uint32_t ul_enable);
uint32_t matrix_get_writeprotect_status(void);
#endif
#if SAMG55
void matrix_set_usb_device(void);
void matrix_set_usb_host(void);
#endif
#if (SAMV71 || SAMV70|| SAME70)
void matrix_set_can0_addr(uint32_t base_addr);
void matrix_set_can1_addr(uint32_t base_addr);
#endif
/* / @cond 0 */
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/* / @endcond */
#endif /* MATRIX_H_INCLUDED */
@@ -0,0 +1,180 @@
/**
* \file
*
* \brief SAMV70/SAMV71/SAME70/SAMS70-XULTRA board mpu config.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "mpu.h"
/** \file */
/**
* \addtogroup mmu MMU Initialization
*
* \section Usage
*
* Translation Look-aside Buffers (TLBs) are an implementation technique that
* caches translations or translation table entries. TLBs avoid the requirement
* for every memory access to perform a translation table lookup.
* The ARM architecture does not specify the exact form of the TLB structures
* for any design. In a similar way to the requirements for caches, the
* architecture only defines certain principles for TLBs:
*
* The MMU supports memory accesses based on memory sections or pages:
* Super-sections Consist of 16MB blocks of memory. Support for Super sections
* is optional.
* -# Sections Consist of 1MB blocks of memory.
* -# Large pages Consist of 64KB blocks of memory.
* -# Small pages Consist of 4KB blocks of memory.
*
* Access to a memory region is controlled by the access permission bits and
* the domain field in the TLB entry.
* Memory region attributes
* Each TLB entry has an associated set of memory region attributes. These
* control accesses to the caches,
* how the write buffer is used, and if the memory region is Shareable and
* therefore must be kept coherent.
*
* Related files:\n
* \ref mmu.c\n
* \ref mmu.h \n
*/
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Enables the MPU module.
*
* \param dwMPUEnable Enable/Disable the memory region.
*/
void mpu_enable(uint32_t dw_mpu_enable)
{
MPU->CTRL = dw_mpu_enable ;
}
/**
* \brief Set active memory region.
*
* \param dwRegionNum The memory region to be active.
*/
void mpu_set_region_num(uint32_t dw_region_num)
{
MPU->RNR = dw_region_num;
}
/**
* \brief Disable the current active region.
*/
void mpu_disable_region(void)
{
MPU->RASR &= 0xfffffffe;
}
/**
* \brief Setup a memory region.
*
* \param dwRegionBaseAddr Memory region base address.
* \param dwRegionAttr Memory region attributes.
*/
void mpu_set_region(uint32_t dw_region_base_addr, uint32_t dw_region_attr)
{
MPU->RBAR = dw_region_base_addr;
MPU->RASR = dw_region_attr;
}
/**
* \brief Calculate region size for the RASR.
*/
uint32_t mpu_cal_mpu_region_size(uint32_t dw_actual_size_in_bytes)
{
uint32_t dwRegionSize = 32;
uint32_t dwReturnValue = 4;
while( dwReturnValue < 31 ) {
if( dw_actual_size_in_bytes <= dwRegionSize ) {
break;
} else {
dwReturnValue++;
}
dwRegionSize <<= 1;
}
return ( dwReturnValue << 1 );
}
/**
* \brief Update MPU regions.
*
* \return Unused (ANSI-C compatibility).
*/
void mpu_update_regions(uint32_t dw_region_num, uint32_t dw_region_base_addr, uint32_t dw_region_attr)
{
/* Disable interrupt */
__disable_irq();
/* Clean up data and instruction buffer */
__DSB();
__ISB();
/* Set active region */
mpu_set_region_num(dw_region_num);
/* Disable region */
mpu_disable_region();
/* Update region attribute */
mpu_set_region( dw_region_base_addr, dw_region_attr);
/* Clean up data and instruction buffer to make the new region taking
effect at once */
__DSB();
__ISB();
/* Enable the interrupt */
__enable_irq();
}
@@ -0,0 +1,199 @@
/**
* \file
*
* \brief SAMV70/SAMV71/SAME70/SAMS70-XULTRA board mpu config.
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _MPU_H_
#define _MPU_H_
#include "compiler.h"
/*----------------------------------------------------------------------------
* Definitions
*----------------------------------------------------------------------------*/
#define ARM_MODE_USR 0x10
#define PRIVILEGE_MODE 0
#define USER_MODE 1
#define MPU_DEFAULT_ITCM_REGION ( 1 )
#define MPU_DEFAULT_IFLASH_REGION ( 2 )
#define MPU_DEFAULT_DTCM_REGION ( 3 )
#define MPU_DEFAULT_SRAM_REGION_1 ( 4 )
#define MPU_DEFAULT_SRAM_REGION_2 ( 5 )
#define MPU_PERIPHERALS_REGION ( 6 )
#define MPU_EXT_EBI_REGION ( 7 )
#define MPU_DEFAULT_SDRAM_REGION ( 8 )
#define MPU_QSPIMEM_REGION ( 9 )
#define MPU_USBHSRAM_REGION ( 10 )
#if defined MPU_HAS_NOCACHE_REGION
#define MPU_NOCACHE_SRAM_REGION ( 11 )
#endif
#define MPU_REGION_VALID ( 0x10 )
#define MPU_REGION_ENABLE ( 0x01 )
#define MPU_REGION_DISABLE ( 0x0 )
#define MPU_ENABLE ( 0x1 << MPU_CTRL_ENABLE_Pos)
#define MPU_HFNMIENA ( 0x1 << MPU_CTRL_HFNMIENA_Pos )
#define MPU_PRIVDEFENA ( 0x1 << MPU_CTRL_PRIVDEFENA_Pos )
#define MPU_REGION_BUFFERABLE ( 0x01 << MPU_RASR_B_Pos )
#define MPU_REGION_CACHEABLE ( 0x01 << MPU_RASR_C_Pos )
#define MPU_REGION_SHAREABLE ( 0x01 << MPU_RASR_S_Pos )
#define MPU_REGION_EXECUTE_NEVER ( 0x01 << MPU_RASR_XN_Pos )
#define MPU_AP_NO_ACCESS ( 0x00 << MPU_RASR_AP_Pos )
#define MPU_AP_PRIVILEGED_READ_WRITE ( 0x01 << MPU_RASR_AP_Pos )
#define MPU_AP_UNPRIVILEGED_READONLY ( 0x02 << MPU_RASR_AP_Pos )
#define MPU_AP_FULL_ACCESS ( 0x03 << MPU_RASR_AP_Pos )
#define MPU_AP_RES ( 0x04 << MPU_RASR_AP_Pos )
#define MPU_AP_PRIVILEGED_READONLY ( 0x05 << MPU_RASR_AP_Pos )
#define MPU_AP_READONLY ( 0x06 << MPU_RASR_AP_Pos )
#define MPU_AP_READONLY2 ( 0x07 << MPU_RASR_AP_Pos )
#define MPU_TEX_B000 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B001 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B010 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B011 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B100 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B101 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B110 ( 0x01 << MPU_RASR_TEX_Pos )
#define MPU_TEX_B111 ( 0x01 << MPU_RASR_TEX_Pos )
#define SHAREABLE 1
#define NON_SHAREABLE 0
#define INNER_NORMAL_WB_RWA_TYPE(x) (( 0x04 << MPU_RASR_TEX_Pos ) | ( DISABLE << MPU_RASR_C_Pos ) | ( ENABLE << MPU_RASR_B_Pos ) | ( x << MPU_RASR_S_Pos ))
#define INNER_NORMAL_WB_NWA_TYPE(x) (( 0x04 << MPU_RASR_TEX_Pos ) | ( ENABLE << MPU_RASR_C_Pos ) | ( ENABLE << MPU_RASR_B_Pos ) | ( x << MPU_RASR_S_Pos ))
#define STRONGLY_ORDERED_SHAREABLE_TYPE (( 0x00 << MPU_RASR_TEX_Pos ) | ( DISABLE << MPU_RASR_C_Pos ) | ( DISABLE << MPU_RASR_B_Pos )) // DO not care //
#define SHAREABLE_DEVICE_TYPE (( 0x00 << MPU_RASR_TEX_Pos ) | ( DISABLE << MPU_RASR_C_Pos ) | ( ENABLE << MPU_RASR_B_Pos )) // DO not care //
/* Default memory map
Address range Memory region Memory type Shareability Cache policy
0x00000000- 0x1FFFFFFF Code Normal Non-shareable WT
0x20000000- 0x3FFFFFFF SRAM Normal Non-shareable WBWA
0x40000000- 0x5FFFFFFF Peripheral Device Non-shareable -
0x60000000- 0x7FFFFFFF RAM Normal Non-shareable WBWA
0x80000000- 0x9FFFFFFF RAM Normal Non-shareable WT
0xA0000000- 0xBFFFFFFF Device Device Shareable
0xC0000000- 0xDFFFFFFF Device Device Non Shareable
0xE0000000- 0xFFFFFFFF System - -
*/
/********* IFLASH memory macros *********************/
#define ITCM_START_ADDRESS 0x00000000UL
#define ITCM_END_ADDRESS 0x003FFFFFUL
#define IFLASH_START_ADDRESS 0x00400000UL
#define IFLASH_END_ADDRESS 0x005FFFFFUL
#define IFLASH_PRIVILEGE_START_ADDRESS (IFLASH_START_ADDRESS)
#define IFLASH_PRIVILEGE_END_ADDRESS (IFLASH_START_ADDRESS + 0xFFF)
#define IFLASH_UNPRIVILEGE_START_ADDRESS (IFLASH_PRIVILEGE_END_ADDRESS + 1)
#define IFLASH_UNPRIVILEGE_END_ADDRESS (IFLASH_END_ADDRESS)
/**************** DTCM *******************************/
#define DTCM_START_ADDRESS 0x20000000UL
#define DTCM_END_ADDRESS 0x203FFFFFUL
/******* SRAM memory macros ***************************/
#define SRAM_START_ADDRESS 0x20400000UL
#define SRAM_END_ADDRESS 0x2045FFFFUL
#if defined MPU_HAS_NOCACHE_REGION
#define NOCACHE_SRAM_REGION_SIZE 0x1000
#endif
/* Regions should be a 2^(N+1) where 4 < N < 31 */
#define SRAM_FIRST_START_ADDRESS (SRAM_START_ADDRESS)
#define SRAM_FIRST_END_ADDRESS (SRAM_FIRST_START_ADDRESS + 0x3FFFF) // (2^18) 256 KB
#if defined MPU_HAS_NOCACHE_REGION
#define SRAM_SECOND_START_ADDRESS (SRAM_FIRST_END_ADDRESS+1)
#define SRAM_SECOND_END_ADDRESS (SRAM_END_ADDRESS - NOCACHE_SRAM_REGION_SIZE ) // (2^17) 128 - 0x1000 KB
#define SRAM_NOCACHE_START_ADDRESS (SRAM_SECOND_END_ADDRESS + 1)
#define SRAM_NOCACHE_END_ADDRESS (SRAM_END_ADDRESS )
#else
#define SRAM_SECOND_START_ADDRESS (SRAM_FIRST_END_ADDRESS + 1)
#define SRAM_SECOND_END_ADDRESS (SRAM_END_ADDRESS) // (2^17) 128 KB
#endif
/************** Peripherals memory region macros ********/
#define PERIPHERALS_START_ADDRESS 0x40000000UL
#define PERIPHERALS_END_ADDRESS 0x5FFFFFFFUL
/******* Ext EBI memory macros ***************************/
#define EXT_EBI_START_ADDRESS 0x60000000UL
#define EXT_EBI_END_ADDRESS 0x6FFFFFFFUL
/******* Ext-SRAM memory macros ***************************/
#define SDRAM_START_ADDRESS 0x70000000UL
#define SDRAM_END_ADDRESS 0x7FFFFFFFUL
/******* QSPI macros ***************************/
#define QSPI_START_ADDRESS 0x80000000UL
#define QSPI_END_ADDRESS 0x9FFFFFFFUL
/************** USBHS_RAM region macros ******************/
#define USBHSRAM_START_ADDRESS 0xA0100000UL
#define USBHSRAM_END_ADDRESS 0xA01FFFFFUL
/*----------------------------------------------------------------------------
* Export functions
*----------------------------------------------------------------------------*/
void mpu_enable(uint32_t dw_mpu_enable);
void mpu_set_region(uint32_t dw_region_base_addr, uint32_t dw_region_attr);
void mpu_set_region_num(uint32_t dw_region_num);
void mpu_disable_region(void);
uint32_t mpu_cal_mpu_region_size(uint32_t dw_actual_size_in_bytes);
void mpu_update_regions(uint32_t dw_region_num, uint32_t dw_region_base_addr, uint32_t dw_region_attr);
#endif /* #ifndef _MPU_H_ */
@@ -0,0 +1,377 @@
/**
* \file
*
* \brief Parallel Input/Output (PIO) Controller driver for SAM.
*
* Copyright (c) 2011-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef PIO_H_INCLUDED
#define PIO_H_INCLUDED
#include "compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
/* Compute PIO register length */
#define PIO_DELTA ((uint32_t) PIOB - (uint32_t) PIOA)
/* GPIO Support */
#define PIO_TYPE_Pos 27
/* PIO Type Mask */
#define PIO_TYPE_Msk (0xFu << PIO_TYPE_Pos)
/* The pin is not a function pin. */
#define PIO_TYPE_NOT_A_PIN (0x0u << PIO_TYPE_Pos)
/* The pin is controlled by the peripheral A. */
#define PIO_TYPE_PIO_PERIPH_A (0x1u << PIO_TYPE_Pos)
/* The pin is controlled by the peripheral B. */
#define PIO_TYPE_PIO_PERIPH_B (0x2u << PIO_TYPE_Pos)
/* The pin is controlled by the peripheral C. */
#define PIO_TYPE_PIO_PERIPH_C (0x3u << PIO_TYPE_Pos)
/* The pin is controlled by the peripheral D. */
#define PIO_TYPE_PIO_PERIPH_D (0x4u << PIO_TYPE_Pos)
/* The pin is an input. */
#define PIO_TYPE_PIO_INPUT (0x5u << PIO_TYPE_Pos)
/* The pin is an output and has a default level of 0. */
#define PIO_TYPE_PIO_OUTPUT_0 (0x6u << PIO_TYPE_Pos)
/* The pin is an output and has a default level of 1. */
#define PIO_TYPE_PIO_OUTPUT_1 (0x7u << PIO_TYPE_Pos)
typedef enum _pio_type {
PIO_NOT_A_PIN = PIO_TYPE_NOT_A_PIN,
PIO_PERIPH_A = PIO_TYPE_PIO_PERIPH_A,
PIO_PERIPH_B = PIO_TYPE_PIO_PERIPH_B,
#if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
PIO_PERIPH_C = PIO_TYPE_PIO_PERIPH_C,
PIO_PERIPH_D = PIO_TYPE_PIO_PERIPH_D,
#endif
PIO_INPUT = PIO_TYPE_PIO_INPUT,
PIO_OUTPUT_0 = PIO_TYPE_PIO_OUTPUT_0,
PIO_OUTPUT_1 = PIO_TYPE_PIO_OUTPUT_1
} pio_type_t;
/* Default pin configuration (no attribute). */
#define PIO_DEFAULT (0u << 0)
/* The internal pin pull-up is active. */
#define PIO_PULLUP (1u << 0)
/* The internal glitch filter is active. */
#define PIO_DEGLITCH (1u << 1)
/* The pin is open-drain. */
#define PIO_OPENDRAIN (1u << 2)
/* The internal debouncing filter is active. */
#define PIO_DEBOUNCE (1u << 3)
/* Enable additional interrupt modes. */
#define PIO_IT_AIME (1u << 4)
/* Interrupt High Level/Rising Edge detection is active. */
#define PIO_IT_RE_OR_HL (1u << 5)
/* Interrupt Edge detection is active. */
#define PIO_IT_EDGE (1u << 6)
/* Low level interrupt is active */
#define PIO_IT_LOW_LEVEL (0 | 0 | PIO_IT_AIME)
/* High level interrupt is active */
#define PIO_IT_HIGH_LEVEL (PIO_IT_RE_OR_HL | 0 | PIO_IT_AIME)
/* Falling edge interrupt is active */
#define PIO_IT_FALL_EDGE (0 | PIO_IT_EDGE | PIO_IT_AIME)
/* Rising edge interrupt is active */
#define PIO_IT_RISE_EDGE (PIO_IT_RE_OR_HL | PIO_IT_EDGE | PIO_IT_AIME)
/*
* The #attribute# field is a bitmask that can either be set to PIO_DEFAULT,
* or combine (using bitwise OR '|') any number of the following constants:
* - PIO_PULLUP
* - PIO_DEGLITCH
* - PIO_DEBOUNCE
* - PIO_OPENDRAIN
* - PIO_IT_LOW_LEVEL
* - PIO_IT_HIGH_LEVEL
* - PIO_IT_FALL_EDGE
* - PIO_IT_RISE_EDGE
*/
void pio_pull_up(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_pull_up_enable);
void pio_set_debounce_filter(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_cut_off);
void pio_set(Pio *p_pio, const uint32_t ul_mask);
void pio_clear(Pio *p_pio, const uint32_t ul_mask);
uint32_t pio_get(Pio *p_pio, const pio_type_t ul_type,
const uint32_t ul_mask);
void pio_set_peripheral(Pio *p_pio, const pio_type_t ul_type,
const uint32_t ul_mask);
void pio_set_input(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_attribute);
void pio_set_output(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_default_level,
const uint32_t ul_multidrive_enable,
const uint32_t ul_pull_up_enable);
uint32_t pio_configure(Pio *p_pio, const pio_type_t ul_type,
const uint32_t ul_mask, const uint32_t ul_attribute);
uint32_t pio_get_output_data_status(const Pio *p_pio,
const uint32_t ul_mask);
void pio_set_multi_driver(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_multi_driver_enable);
uint32_t pio_get_multi_driver_status(const Pio *p_pio);
#if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
void pio_pull_down(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_pull_down_enable);
#endif
void pio_enable_output_write(Pio *p_pio, const uint32_t ul_mask);
void pio_disable_output_write(Pio *p_pio, const uint32_t ul_mask);
uint32_t pio_get_output_write_status(const Pio *p_pio);
void pio_sync_output_write(Pio *p_pio, const uint32_t ul_mask);
#if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || SAMV71 || SAMV70 || SAME70 || SAMS70)
void pio_set_schmitt_trigger(Pio *p_pio, const uint32_t ul_mask);
uint32_t pio_get_schmitt_trigger(const Pio *p_pio);
#endif
void pio_configure_interrupt(Pio *p_pio, const uint32_t ul_mask,
const uint32_t ul_attr);
void pio_enable_interrupt(Pio *p_pio, const uint32_t ul_mask);
void pio_disable_interrupt(Pio *p_pio, const uint32_t ul_mask);
uint32_t pio_get_interrupt_status(const Pio *p_pio);
uint32_t pio_get_interrupt_mask(const Pio *p_pio);
void pio_set_additional_interrupt_mode(Pio *p_pio,
const uint32_t ul_mask, const uint32_t ul_attribute);
void pio_set_writeprotect(Pio *p_pio, const uint32_t ul_enable);
uint32_t pio_get_writeprotect_status(const Pio *p_pio);
#if (SAM3S || SAM4S || SAM4E || SAMV71 || SAMV70 || SAME70 || SAMS70)
void pio_capture_set_mode(Pio *p_pio, uint32_t ul_mode);
void pio_capture_enable(Pio *p_pio);
void pio_capture_disable(Pio *p_pio);
uint32_t pio_capture_read(const Pio *p_pio, uint32_t * pul_data);
void pio_capture_enable_interrupt(Pio *p_pio, const uint32_t ul_mask);
void pio_capture_disable_interrupt(Pio * p_pio, const uint32_t ul_mask);
uint32_t pio_capture_get_interrupt_status(const Pio *p_pio);
uint32_t pio_capture_get_interrupt_mask(const Pio *p_pio);
#if !(SAMV71 || SAMV70 || SAME70 || SAMS70)
Pdc *pio_capture_get_pdc_base(const Pio *p_pio);
#endif
#endif
/* GPIO Support */
uint32_t pio_get_pin_value(uint32_t pin);
void pio_set_pin_high(uint32_t pin);
void pio_set_pin_low(uint32_t pin);
void pio_toggle_pin(uint32_t pin);
void pio_enable_pin_interrupt(uint32_t pin);
void pio_disable_pin_interrupt(uint32_t pin);
Pio *pio_get_pin_group(uint32_t pin);
uint32_t pio_get_pin_group_id(uint32_t pin);
uint32_t pio_get_pin_group_mask(uint32_t pin);
uint32_t pio_configure_pin(uint32_t ul_pin, const uint32_t ul_flags);
void pio_set_pin_group_high(Pio *p_pio, uint32_t ul_mask);
void pio_set_pin_group_low(Pio *p_pio, uint32_t ul_mask);
void pio_toggle_pin_group(Pio *p_pio, uint32_t ul_mask);
uint32_t pio_configure_pin_group(Pio *p_pio, uint32_t ul_mask,
const uint32_t ul_flags);
#if (SAM4C || SAM4CP || SAM4CM || SAMG55)
enum pio_io_drive_mode {
PIO_IO_DRIVE_LOW = 0,
PIO_IO_DRIVE_HIGH,
};
void pio_set_io_drive(Pio *p_pio, uint32_t ul_line,
enum pio_io_drive_mode mode);
#endif
#if (SAMV71 || SAMV70 || SAME70 || SAMS70)
void pio_keypad_enable(Pio *p_pio);
void pio_keypad_disable(Pio *p_pio);
void pio_keypad_set_row_num(Pio *p_pio, uint8_t num);
uint8_t pio_keypad_get_row_num(const Pio *p_pio);
void pio_keypad_set_column_num(Pio *p_pio, uint8_t num);
uint8_t pio_keypad_get_column_num(const Pio *p_pio);
void pio_keypad_set_debouncing_value(Pio *p_pio, uint16_t value);
uint16_t pio_keypad_get_debouncing_value(const Pio *p_pio);
void pio_keypad_enable_interrupt(Pio *p_pio, uint32_t ul_mask);
void pio_keypad_disable_interrupt(Pio *p_pio, uint32_t ul_mask);
uint32_t pio_keypad_get_interrupt_mask(const Pio *p_pio);
uint32_t pio_keypad_get_press_status(const Pio *p_pio);
uint32_t pio_keypad_get_release_status(const Pio *p_pio);
uint8_t pio_keypad_get_simult_press_num(const Pio *p_pio);
uint8_t pio_keypad_get_simult_release_num(const Pio *p_pio);
uint8_t pio_keypad_get_press_row_index(const Pio *p_pio, uint8_t queue);
uint8_t pio_keypad_get_press_column_index(const Pio *p_pio, uint8_t queue);
uint8_t pio_keypad_get_release_row_index(const Pio *p_pio, uint8_t queue);
uint8_t pio_keypad_get_release_column_index(const Pio *p_pio, uint8_t queue);
#endif
/**
* \page sam_pio_quickstart Quick Start Guide for the SAM PIO driver
*
* This is the quick start guide for the \ref sam_drivers_pio_group "PIO Driver",
* with step-by-step instructions on how to configure and use the driver for
* specific use cases.
*
* The section described below can be compiled into e.g. the main application
* loop or any other function that will need to interface with the IO port.
*
* \section sam_pio_usecases PIO use cases
* - \ref sam_pio_quickstart_basic
* - \ref sam_pio_quickstart_use_case_2
*
* \section sam_pio_quickstart_basic Basic usage of the PIO driver
* This section will present a basic use case for the PIO driver. This use case
* will configure pin 23 on port A as output and pin 16 as an input with pullup,
* and then toggle the output pin's value to match that of the input pin.
*
* \subsection sam_pio_quickstart_use_case_1_prereq Prerequisites
* - \ref group_pmc "Power Management Controller driver"
*
* \subsection sam_pio_quickstart_use_case_1_setup_steps Initialization code
* Add to the application initialization code:
* \code
pmc_enable_periph_clk(ID_PIOA);
pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE);
pio_set_input(PIOA, PIO_PA16, PIO_PULLUP);
\endcode
*
* \subsection sam_pio_quickstart_use_case_1_setup_steps_workflow Workflow
* -# Enable the module clock to the PIOA peripheral:
* \code pmc_enable_periph_clk(ID_PIOA); \endcode
* -# Set pin 23 direction on PIOA as output, default low level:
* \code pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); \endcode
* -# Set pin 16 direction on PIOA as input, with pullup:
* \code pio_set_input(PIOA, PIO_PA16, PIO_PULLUP); \endcode
*
* \subsection sam_pio_quickstart_use_case_1_example_code Example code
* Set the state of output pin 23 to match input pin 16:
* \code
if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16))
pio_clear(PIOA, PIO_PA23);
else
pio_set(PIOA, PIO_PA23);
\endcode
*
* \subsection sam_pio_quickstart_use_case_1_example_workflow Workflow
* -# We check the value of the pin:
* \code
if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16))
\endcode
* -# Then we set the new output value based on the read pin value:
* \code
pio_clear(PIOA, PIO_PA23);
else
pio_set(PIOA, PIO_PA23);
\endcode
*/
/**
* \page sam_pio_quickstart_use_case_2 Advanced use case - Interrupt driven edge detection
*
* \section sam_pio_quickstart_use_case_2 Advanced Use Case 1
* This section will present a more advanced use case for the PIO driver. This use case
* will configure pin 23 on port A as output and pin 16 as an input with pullup,
* and then toggle the output pin's value to match that of the input pin using the interrupt
* controller within the device.
*
* \subsection sam_pio_quickstart_use_case_2_prereq Prerequisites
* - \ref group_pmc "Power Management Controller driver"
*
* \subsection sam_pio_quickstart_use_case_2_setup_steps Initialization code
* Add to the application initialization code:
* \code
pmc_enable_periph_clk(ID_PIOA);
pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE);
pio_set_input(PIOA, PIO_PA16, PIO_PULLUP);
pio_handler_set(PIOA, ID_PIOA, PIO_PA16, PIO_IT_EDGE, pin_edge_handler);
pio_enable_interrupt(PIOA, PIO_PA16);
NVIC_EnableIRQ(PIOA_IRQn);
\endcode
*
* \subsection sam_pio_quickstart_use_case_2_setup_steps_workflow Workflow
* -# Enable the module clock to the PIOA peripheral:
* \code pmc_enable_periph_clk(ID_PIOA); \endcode
* -# Set pin 23 direction on PIOA as output, default low level:
* \code pio_set_output(PIOA, PIO_PA23, LOW, DISABLE, ENABLE); \endcode
* -# Set pin 16 direction on PIOA as input, with pullup:
* \code pio_set_input(PIOA, PIO_PA16, PIO_PULLUP); \endcode
* -# Configure the input pin 16 interrupt mode and handler:
* \code pio_handler_set(PIOA, ID_PIOA, PIO_PA16, PIO_IT_EDGE, pin_edge_handler); \endcode
* -# Enable the interrupt for the configured input pin:
* \code pio_enable_interrupt(PIOA, PIO_PA16); \endcode
* -# Enable interrupt handling from the PIOA module:
* \code NVIC_EnableIRQ(PIOA_IRQn); \endcode
*
* \subsection sam_pio_quickstart_use_case_2_example_code Example code
* Add the following function to your application:
* \code
void pin_edge_handler(const uint32_t id, const uint32_t index)
{
if ((id == ID_PIOA) && (index == PIO_PA16)){
if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16))
pio_clear(PIOA, PIO_PA23);
else
pio_set(PIOA, PIO_PA23);
}
}
\endcode
*
* \subsection sam_pio_quickstart_use_case_2_example_workflow Workflow
* -# We check the value of the pin:
* \code
if (pio_get(PIOA, PIO_TYPE_PIO_INPUT, PIO_PA16))
\endcode
* -# Then we set the new output value based on the read pin value:
* \code
pio_clear(PIOA, PIO_PA23);
else
pio_set(PIOA, PIO_PA23);
\endcode
*/
#ifdef __cplusplus
}
#endif
#endif /* PIO_H_INCLUDED */
@@ -0,0 +1,286 @@
/**
* \file
*
* \brief Parallel Input/Output (PIO) interrupt handler for SAM.
*
* Copyright (c) 2011-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include "pio.h"
#include "pio_handler.h"
/**
* Maximum number of interrupt sources that can be defined. This
* constant can be increased, but the current value is the smallest possible one
* that will be compatible with all existing projects.
*/
#define MAX_INTERRUPT_SOURCES 7
/**
* Describes a PIO interrupt source, including the PIO instance triggering the
* interrupt and the associated interrupt handler.
*/
struct s_interrupt_source {
uint32_t id;
uint32_t mask;
uint32_t attr;
/* Interrupt handler. */
void (*handler) (const uint32_t, const uint32_t);
};
/* List of interrupt sources. */
static struct s_interrupt_source gs_interrupt_sources[MAX_INTERRUPT_SOURCES];
/* Number of currently defined interrupt sources. */
static uint32_t gs_ul_nb_sources = 0;
#if (SAM3S || SAM4S || SAM4E)
/* PIO Capture handler */
static void (*pio_capture_handler)(Pio *) = NULL;
extern uint32_t pio_capture_enable_flag;
#endif
/**
* \brief Process an interrupt request on the given PIO controller.
*
* \param p_pio PIO controller base address.
* \param ul_id PIO controller ID.
*/
void pio_handler_process(Pio *p_pio, uint32_t ul_id)
{
uint32_t status;
uint32_t i;
/* Read PIO controller status */
status = pio_get_interrupt_status(p_pio);
status &= pio_get_interrupt_mask(p_pio);
/* Check pending events */
if (status != 0) {
/* Find triggering source */
i = 0;
while (status != 0) {
/* Source is configured on the same controller */
if (gs_interrupt_sources[i].id == ul_id) {
/* Source has PIOs whose statuses have changed */
if ((status & gs_interrupt_sources[i].mask) != 0) {
gs_interrupt_sources[i].handler(gs_interrupt_sources[i].id,
gs_interrupt_sources[i].mask);
status &= ~(gs_interrupt_sources[i].mask);
}
}
i++;
if (i >= MAX_INTERRUPT_SOURCES) {
break;
}
}
}
/* Check capture events */
#if (SAM3S || SAM4S || SAM4E)
if (pio_capture_enable_flag) {
if (pio_capture_handler) {
pio_capture_handler(p_pio);
}
}
#endif
}
/**
* \brief Set an interrupt handler for the provided pins.
* The provided handler will be called with the triggering pin as its parameter
* as soon as an interrupt is detected.
*
* \param p_pio PIO controller base address.
* \param ul_id PIO ID.
* \param ul_mask Pins (bit mask) to configure.
* \param ul_attr Pins attribute to configure.
* \param p_handler Interrupt handler function pointer.
*
* \return 0 if successful, 1 if the maximum number of sources has been defined.
*/
uint32_t pio_handler_set(Pio *p_pio, uint32_t ul_id, uint32_t ul_mask,
uint32_t ul_attr, void (*p_handler) (uint32_t, uint32_t))
{
struct s_interrupt_source *pSource;
if (gs_ul_nb_sources >= MAX_INTERRUPT_SOURCES)
return 1;
/* Define new source */
pSource = &(gs_interrupt_sources[gs_ul_nb_sources]);
pSource->id = ul_id;
pSource->mask = ul_mask;
pSource->attr = ul_attr;
pSource->handler = p_handler;
gs_ul_nb_sources++;
/* Configure interrupt mode */
pio_configure_interrupt(p_pio, ul_mask, ul_attr);
return 0;
}
#if (SAM3S || SAM4S || SAM4E)
/**
* \brief Set a capture interrupt handler for all PIO.
*
* The handler will be called with the triggering PIO as its parameter
* as soon as an interrupt is detected.
*
* \param p_handler Interrupt handler function pointer.
*
*/
void pio_capture_handler_set(void (*p_handler)(Pio *))
{
pio_capture_handler = p_handler;
}
#endif
#ifdef ID_PIOA
/**
* \brief Set an interrupt handler for the specified pin.
* The provided handler will be called with the triggering pin as its parameter
* as soon as an interrupt is detected.
*
* \param ul_pin Pin index to configure.
* \param ul_flag Pin flag.
* \param p_handler Interrupt handler function pointer.
*
* \return 0 if successful, 1 if the maximum number of sources has been defined.
*/
uint32_t pio_handler_set_pin(uint32_t ul_pin, uint32_t ul_flag,
void (*p_handler) (uint32_t, uint32_t))
{
Pio *p_pio = pio_get_pin_group(ul_pin);
uint32_t group_id = pio_get_pin_group_id(ul_pin);
uint32_t group_mask = pio_get_pin_group_mask(ul_pin);
return pio_handler_set(p_pio, group_id, group_mask, ul_flag, p_handler);
}
/**
* \brief Parallel IO Controller A interrupt handler.
* Redefined PIOA interrupt handler for NVIC interrupt table.
*/
void PIOA_Handler(void)
{
pio_handler_process(PIOA, ID_PIOA);
}
#endif
#ifdef ID_PIOB
/**
* \brief Parallel IO Controller B interrupt handler
* Redefined PIOB interrupt handler for NVIC interrupt table.
*/
void PIOB_Handler(void)
{
pio_handler_process(PIOB, ID_PIOB);
}
#endif
#ifdef ID_PIOC
/**
* \brief Parallel IO Controller C interrupt handler.
* Redefined PIOC interrupt handler for NVIC interrupt table.
*/
void PIOC_Handler(void)
{
pio_handler_process(PIOC, ID_PIOC);
}
#endif
#ifdef ID_PIOD
/**
* \brief Parallel IO Controller D interrupt handler.
* Redefined PIOD interrupt handler for NVIC interrupt table.
*/
void PIOD_Handler(void)
{
pio_handler_process(PIOD, ID_PIOD);
}
#endif
#ifdef ID_PIOE
/**
* \brief Parallel IO Controller E interrupt handler.
* Redefined PIOE interrupt handler for NVIC interrupt table.
*/
void PIOE_Handler(void)
{
pio_handler_process(PIOE, ID_PIOE);
}
#endif
#ifdef ID_PIOF
/**
* \brief Parallel IO Controller F interrupt handler.
* Redefined PIOF interrupt handler for NVIC interrupt table.
*/
void PIOF_Handler(void)
{
pio_handler_process(PIOF, ID_PIOF);
}
#endif
/**
* \brief Initialize PIO interrupt management logic.
*
* \param p_pio PIO controller base address.
* \param ul_irqn NVIC line number.
* \param ul_priority PIO controller interrupts priority.
*/
void pio_handler_set_priority(Pio *p_pio, IRQn_Type ul_irqn, uint32_t ul_priority)
{
uint32_t bitmask = 0;
bitmask = pio_get_interrupt_mask(p_pio);
pio_disable_interrupt(p_pio, 0xFFFFFFFF);
pio_get_interrupt_status(p_pio);
NVIC_DisableIRQ(ul_irqn);
NVIC_ClearPendingIRQ(ul_irqn);
NVIC_SetPriority(ul_irqn, ul_priority);
NVIC_EnableIRQ(ul_irqn);
pio_enable_interrupt(p_pio, bitmask);
}
@@ -0,0 +1,69 @@
/**
* \file
*
* \brief Parallel Input/Output (PIO) interrupt handler for SAM.
*
* Copyright (c) 2011-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef PIO_HANDLER_H_INCLUDED
#define PIO_HANDLER_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
void pio_handler_process(Pio *p_pio, uint32_t ul_id);
void pio_handler_set_priority(Pio *p_pio, IRQn_Type ul_irqn, uint32_t ul_priority);
uint32_t pio_handler_set(Pio *p_pio, uint32_t ul_id, uint32_t ul_mask,
uint32_t ul_attr, void (*p_handler) (uint32_t, uint32_t));
uint32_t pio_handler_set_pin(uint32_t ul_pin, uint32_t ul_flag,
void (*p_handler) (uint32_t, uint32_t));
#if (SAM3S || SAM4S || SAM4E)
void pio_capture_handler_set(void (*p_handler)(Pio *));
#endif
#ifdef __cplusplus
}
#endif
#endif /* PIO_HANDLER_H_INCLUDED */
@@ -0,0 +1,389 @@
/**
* \file
*
* \brief Sleep mode access
*
* Copyright (c) 2012-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#include <compiler.h>
#include "sleep.h"
/* SAM3,SAM4,SAMG,SAMV,SAMS and SAME series */
#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \
SAM4CM || SAMG || SAM4CP || SAMV71 || SAMV70 || SAMS70 || SAME70)
# include "pmc.h"
# include "board.h"
/* Checking board configuration of main clock xtal statup time */
#if !defined(BOARD_OSC_STARTUP_US)
# warning The board main clock xtal statup time has not been defined. Using default settings.
# define BOARD_OSC_STARTUP_US (15625UL)
#endif
#if !defined(EFC0)
# define EFC0 EFC
#endif
/**
* Save clock settings and shutdown PLLs
*/
__always_inline static void pmc_save_clock_settings(
uint32_t *p_osc_setting,
uint32_t *p_pll0_setting,
uint32_t *p_pll1_setting,
uint32_t *p_mck_setting,
uint32_t *p_fmr_setting,
#if defined(EFC1)
uint32_t *p_fmr_setting1,
#endif
const bool disable_xtal)
{
uint32_t mor = PMC->CKGR_MOR;
uint32_t mckr = PMC->PMC_MCKR;
uint32_t fmr = EFC0->EEFC_FMR;
# if defined(EFC1)
uint32_t fmr1 = EFC1->EEFC_FMR;
# endif
if (p_osc_setting) {
*p_osc_setting = mor;
}
if (p_pll0_setting) {
*p_pll0_setting = PMC->CKGR_PLLAR;
}
if (p_pll1_setting) {
#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP)
*p_pll1_setting = PMC->CKGR_PLLBR;
#elif (SAM3U || SAM3XA)
*p_pll1_setting = PMC->CKGR_UCKR;
#else
*p_pll1_setting = 0;
#endif
}
if (p_mck_setting) {
*p_mck_setting = mckr;
}
if (p_fmr_setting) {
*p_fmr_setting = fmr;
}
#if defined(EFC1)
if (p_fmr_setting1) {
*p_fmr_setting1 = fmr1;
}
#endif
/* Enable FAST RC */
PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor | CKGR_MOR_MOSCRCEN;
/* if MCK source is PLL, switch to mainck */
if ((mckr & PMC_MCKR_CSS_Msk) > PMC_MCKR_CSS_MAIN_CLK) {
/* MCK -> MAINCK */
mckr = (mckr & (~PMC_MCKR_CSS_Msk)) | PMC_MCKR_CSS_MAIN_CLK;
PMC->PMC_MCKR = mckr;
while(!(PMC->PMC_SR & PMC_SR_MCKRDY));
}
/* MCK prescale -> 1 */
if (mckr & PMC_MCKR_PRES_Msk) {
mckr = (mckr & (~PMC_MCKR_PRES_Msk));
PMC->PMC_MCKR = mckr;
while(!(PMC->PMC_SR & PMC_SR_MCKRDY));
}
/* Disable PLLs */
pmc_disable_pllack();
#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP)
pmc_disable_pllbck();
#elif (SAM3U || SAM3XA)
pmc_disable_upll_clock();
#endif
/* Prepare for entering WAIT mode */
/* Wait fast RC ready */
while (!(PMC->PMC_SR & PMC_SR_MOSCRCS));
/* Switch mainck to FAST RC */
#if SAMG
/**
* For the sleepwalking feature, we need an accurate RC clock. Only 24M and
* 16M are trimmed in production. Here we select the 24M.
* And so wait state need to be 1.
*/
EFC0->EEFC_FMR = (fmr & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(1);
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_MOSCRCF_24_MHz |
CKGR_MOR_KEY_PASSWD;
#else
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) |
CKGR_MOR_KEY_PASSWD;
#endif
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
#if (!SAMG)
/* FWS update */
EFC0->EEFC_FMR = fmr & (~EEFC_FMR_FWS_Msk);
#if defined(EFC1)
EFC1->EEFC_FMR = fmr1 & (~EEFC_FMR_FWS_Msk);
#endif
#endif
/* Disable XTALs */
if (disable_xtal) {
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) |
CKGR_MOR_KEY_PASSWD;
}
}
/**
* Restore clock settings
*/
__always_inline static void pmc_restore_clock_setting(
const uint32_t osc_setting,
const uint32_t pll0_setting,
const uint32_t pll1_setting,
const uint32_t mck_setting,
const uint32_t fmr_setting
#if defined(EFC1)
, const uint32_t fmr_setting1
#endif
)
{
uint32_t mckr;
uint32_t pll_sr = 0;
/* Switch mainck to external xtal */
if (CKGR_MOR_MOSCXTBY == (osc_setting & CKGR_MOR_MOSCXTBY)) {
/* Bypass mode */
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) |
CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY |
CKGR_MOR_MOSCSEL;
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN &
~CKGR_MOR_MOSCRCF_Msk)
| CKGR_MOR_KEY_PASSWD;
} else if (CKGR_MOR_MOSCXTEN == (osc_setting & CKGR_MOR_MOSCXTEN)) {
/* Enable External XTAL */
if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCXTEN)) {
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) |
CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN;
/* Wait the Xtal to stabilize */
while (!(PMC->PMC_SR & PMC_SR_MOSCXTS));
}
/* Select External XTAL */
if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)) {
PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL;
while (!(PMC->PMC_SR & PMC_SR_MOSCSELS));
}
/* Disable Fast RC */
PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN &
~CKGR_MOR_MOSCRCF_Msk)
| CKGR_MOR_KEY_PASSWD;
}
if (pll0_setting & CKGR_PLLAR_MULA_Msk) {
#if (SAM4C || SAM4CM || SAMG || SAM4CP)
PMC->CKGR_PLLAR = pll0_setting;
#else
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | pll0_setting;
#endif
pll_sr |= PMC_SR_LOCKA;
}
#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP)
if (pll1_setting & CKGR_PLLBR_MULB_Msk) {
PMC->CKGR_PLLBR = pll1_setting;
pll_sr |= PMC_SR_LOCKB;
}
#elif (SAM3U || SAM3XA)
if (pll1_setting & CKGR_UCKR_UPLLEN) {
PMC->CKGR_UCKR = pll1_setting;
pll_sr |= PMC_SR_LOCKU;
}
#else
UNUSED(pll1_setting);
#endif
/* Wait MCK source ready */
switch(mck_setting & PMC_MCKR_CSS_Msk) {
case PMC_MCKR_CSS_PLLA_CLK:
while (!(PMC->PMC_SR & PMC_SR_LOCKA));
break;
#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP)
case PMC_MCKR_CSS_PLLB_CLK:
while (!(PMC->PMC_SR & PMC_SR_LOCKB));
break;
#elif (SAM3U || SAM3XA)
case PMC_MCKR_CSS_UPLL_CLK:
while (!(PMC->PMC_SR & PMC_SR_LOCKU));
break;
#endif
}
/* Switch to faster clock */
mckr = PMC->PMC_MCKR;
/* Set PRES */
PMC->PMC_MCKR = (mckr & ~PMC_MCKR_PRES_Msk)
| (mck_setting & PMC_MCKR_PRES_Msk);
while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
/* Restore flash wait states */
EFC0->EEFC_FMR = fmr_setting;
#if defined(EFC1)
EFC1->EEFC_FMR = fmr_setting1;
#endif
/* Set CSS and others */
PMC->PMC_MCKR = mck_setting;
while (!(PMC->PMC_SR & PMC_SR_MCKRDY));
/* Waiting all restored PLLs ready */
while (!(PMC->PMC_SR & pll_sr));
}
/** If clocks are switched for some sleep mode */
static volatile bool b_is_sleep_clock_used = false;
/** Callback invoked once when clocks are restored */
static pmc_callback_wakeup_clocks_restored_t callback_clocks_restored = NULL;
void pmc_sleep(int sleep_mode)
{
switch (sleep_mode) {
#if (!(SAMG51 || SAMG53 || SAMG54))
case SAM_PM_SMODE_SLEEP_WFI:
case SAM_PM_SMODE_SLEEP_WFE:
#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAMS70 || SAME70)
SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP;
cpu_irq_enable();
__WFI();
break;
#else
PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM;
SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP;
cpu_irq_enable();
if (sleep_mode == SAM_PM_SMODE_SLEEP_WFI)
__WFI();
else
__WFE();
break;
#endif
#endif
case SAM_PM_SMODE_WAIT_FAST:
case SAM_PM_SMODE_WAIT: {
uint32_t mor, pllr0, pllr1, mckr;
uint32_t fmr;
#if defined(EFC1)
uint32_t fmr1;
#endif
#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAMS70 || SAME70)
(sleep_mode == SAM_PM_SMODE_WAIT_FAST) ?
pmc_set_flash_in_wait_mode(PMC_FSMR_FLPM_FLASH_STANDBY) :
pmc_set_flash_in_wait_mode(PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN);
#endif
cpu_irq_disable();
b_is_sleep_clock_used = true;
#if (SAM4C || SAM4CM || SAM4CP)
/* Backup the sub-system 1 status and stop sub-system 1 */
uint32_t cpclk_backup = PMC->PMC_SCSR &
(PMC_SCSR_CPCK | PMC_SCSR_CPBMCK);
PMC->PMC_SCDR = cpclk_backup | PMC_SCDR_CPKEY_PASSWD;
#endif
pmc_save_clock_settings(&mor, &pllr0, &pllr1, &mckr, &fmr,
#if defined(EFC1)
&fmr1,
#endif
(sleep_mode == SAM_PM_SMODE_WAIT));
/* Enter wait mode */
cpu_irq_enable();
pmc_enable_waitmode();
cpu_irq_disable();
pmc_restore_clock_setting(mor, pllr0, pllr1, mckr, fmr
#if defined(EFC1)
, fmr1
#endif
);
#if (SAM4C || SAM4CM || SAM4CP)
/* Restore the sub-system 1 */
PMC->PMC_SCER = cpclk_backup | PMC_SCER_CPKEY_PASSWD;
#endif
b_is_sleep_clock_used = false;
if (callback_clocks_restored) {
callback_clocks_restored();
callback_clocks_restored = NULL;
}
cpu_irq_enable();
break;
}
#if (!(SAMG51 || SAMG53 || SAMG54))
case SAM_PM_SMODE_BACKUP:
SCB->SCR |= SCR_SLEEPDEEP;
#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAMV70 || SAMS70 || SAME70)
SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG;
cpu_irq_enable();
__WFI() ;
#else
cpu_irq_enable();
__WFE() ;
#endif
break;
#endif
}
}
bool pmc_is_wakeup_clocks_restored(void)
{
return !b_is_sleep_clock_used;
}
void pmc_wait_wakeup_clocks_restore(
pmc_callback_wakeup_clocks_restored_t callback)
{
if (b_is_sleep_clock_used) {
cpu_irq_disable();
callback_clocks_restored = callback;
} else if (callback) {
callback();
}
}
#endif
@@ -0,0 +1,133 @@
/**
* \file
*
* \brief Sleep mode access
*
* Copyright (c) 2012-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef SLEEP_H
#define SLEEP_H
#ifdef __cplusplus
extern "C" {
#endif
#include <compiler.h>
/**
* \defgroup sleep_group Power Manager (PM)
*
* This is a stub on the SAM Power Manager Control (PMC) for the sleepmgr
* service.
*
* \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.
*
* @{
*/
#if defined(__DOXYGEN__)
/**
* \brief Sets the MCU in the specified sleep mode
* \param sleep_mode Sleep mode to set.
*/
#endif
/* SAM3,SAM4,SAMG,SAMV,SAME and SAMS series */
#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \
SAM4CM || SAM4CP || SAMG || SAMV71 || SAME70 || SAMS70)
#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \
SAM4CM || SAM4CP || SAMG55 || SAMV71 || SAME70 || SAMS70)
# define SAM_PM_SMODE_ACTIVE 0 /**< Active */
# define SAM_PM_SMODE_SLEEP_WFE 1 /**< Wait for Events */
# define SAM_PM_SMODE_SLEEP_WFI 2 /**< Wait for Interrupts */
# define SAM_PM_SMODE_WAIT_FAST 3 /**< Wait Mode, startup fast (in 3ms) */
# define SAM_PM_SMODE_WAIT 4 /**< Wait Mode */
# define SAM_PM_SMODE_BACKUP 5 /**< Backup Mode */
#else
# define SAM_PM_SMODE_ACTIVE 0 /**< Active */
# define SAM_PM_SMODE_WAIT_FAST 1 /**< Wait Mode, startup fast (in 3ms) */
# define SAM_PM_SMODE_WAIT 2 /**< Wait Mode */
#endif
/** (SCR) Sleep deep bit */
#define SCR_SLEEPDEEP (0x1 << 2)
/**
* Clocks restored callback function type.
* Registered by routine pmc_wait_wakeup_clocks_restore()
* Callback called when all clocks are restored.
*/
typedef void (*pmc_callback_wakeup_clocks_restored_t) (void);
/**
* Enter sleep mode
* \param sleep_mode Sleep mode to enter
*/
void pmc_sleep(int sleep_mode);
/**
* Check if clocks are restored after wakeup
* (For WAIT mode. In WAIT mode, clocks are switched to FASTRC.
* After wakeup clocks should be restored, before that some of the
* ISR should not be served, otherwise there may be timing or clock issue.)
*/
bool pmc_is_wakeup_clocks_restored(void);
/**
* \return true if start waiting
*/
void pmc_wait_wakeup_clocks_restore(
pmc_callback_wakeup_clocks_restored_t callback);
#endif
//! @}
#ifdef __cplusplus
}
#endif
#endif /* SLEEP_H */
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,455 @@
/**
* \file
*
* \brief SAM Timer Counter (TC) driver.
*
* Copyright (c) 2011-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef TC_H_INCLUDED
#define TC_H_INCLUDED
/**
* \defgroup asfdoc_sam_drivers_tc_group SAM3/4S/4L/4E/4N/4CM/4C/G Timer Counter (TC) Driver
*
* This driver for Atmel&reg; | SMART ARM&reg;-based microcontrollers
* provides an interface for the configuration and management of the
* device's Timer Counter functionality.
*
* The Timer Counter (TC) includes several identical 16-bit or 32-bit
* Timer Counter channels. Each channel can be independently programmed
* to perform a wide range of functions that includes frequency
* measurement, event counting, interval measurement, pulse generation,
* delay timing, and pulse width modulation.
*
* Devices from the following series can use this module:
* - Atmel | SMART SAM3
* - Atmel | SMART SAM4S
* - Atmel | SMART SAM4L
* - Atmel | SMART SAM4E
* - Atmel | SMART SAM4N
* - Atmel | SMART SAM4CM
* - Atmel | SMART SAM4C
* - Atmel | SMART SAMG
*
* The outline of this documentation is as follows:
* - \ref asfdoc_sam_drivers_tc_prerequisites
* - \ref asfdoc_sam_drivers_tc_module_overview
* - \ref asfdoc_sam_drivers_tc_special_considerations
* - \ref asfdoc_sam_drivers_tc_extra_info
* - \ref asfdoc_sam_drivers_tc_examples
* - \ref asfdoc_sam_drivers_tc_api_overview
*
*
* \section asfdoc_sam_drivers_tc_prerequisites Prerequisites
*
* There are no prerequisites for this module.
*
*
* \section asfdoc_sam_drivers_tc_module_overview Module Overview
* The Timer Counter (TC) includes several identical 16-bit or 32-bit Timer
* Counter channels. The number of TC channels is device specific, refer
* to the device-specific datasheet for more information.
*
* Each channel can be independently programmed to perform a wide range of
* functions that includes frequency measurement, event counting, interval measurement,
* pulse generation, delay timing, and pulse width modulation.
*
* Each channel has three external clock inputs, five internal clock inputs,
* and two multi-purpose input/output signals which can be configured by the user.
* Each channel drives an internal interrupt signal which can be programmed to
* generate processor interrupts.
*
* The Timer Counter (TC) embeds a quadrature decoder logic connected in front of
* the timers. When enabled, the quadrature decoder performs the input line
* filtering, decoding of quadrature signals and connects to the timers/counters
* in order to read the position and speed of the motor.
*
*
* \section asfdoc_sam_drivers_tc_special_considerations Special Considerations
* \subsection asfdoc_sam_drivers_tc_special_considerations_clock External Clock
* In all cases, if an external clock is used, the duration of each of its levels
* must be longer than the master clock (MCLK) period. The external clock frequency
* must be at least 2.5 times lower than the master clock.
*
* \subsection asfdoc_sam_drivers_tc_special_considerations_trigger External Trigger
* If an external trigger is used, the duration of its pulses must be longer than
* the master clock (MCLK) period in order to be detected.
*
*
* \section asfdoc_sam_drivers_tc_extra_info Extra Information
*
* For extra information, see \ref asfdoc_sam_drivers_tc_extra. This includes:
* - \ref asfdoc_sam_drivers_tc_extra_acronyms
* - \ref asfdoc_sam_drivers_tc_extra_dependencies
* - \ref asfdoc_sam_drivers_tc_extra_errata
* - \ref asfdoc_sam_drivers_tc_extra_history
*
* \section asfdoc_sam_drivers_tc_examples Examples
*
* For a list of examples related to this driver, see
* \ref asfdoc_sam_drivers_tc_exqsg.
*
*
* \section asfdoc_sam_drivers_tc_api_overview API Overview
* @{
*/
#include <compiler.h>
/// @cond
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
void tc_init(Tc *p_tc, uint32_t ul_Channel, uint32_t ul_Mode);
void tc_sync_trigger(Tc *p_tc);
void tc_set_block_mode(Tc *p_tc, uint32_t ul_blockmode);
#if (!SAM3U) || defined(__DOXYGEN__)
uint32_t tc_init_2bit_gray(Tc *p_tc, uint32_t ul_channel,
uint32_t ul_steppermode);
#endif /* (!SAM3U) || defined(__DOXYGEN__) */
void tc_start(Tc *p_tc, uint32_t ul_channel);
void tc_stop(Tc *p_tc, uint32_t ul_channel);
uint32_t tc_read_cv(Tc *p_tc, uint32_t ul_channel);
uint32_t tc_read_ra(Tc *p_tc, uint32_t ul_channel);
uint32_t tc_read_rb(Tc *p_tc, uint32_t ul_channel);
uint32_t tc_read_rc(Tc *p_tc, uint32_t ul_channel);
void tc_write_ra(Tc *p_tc, uint32_t ul_channel,
uint32_t ul_value);
void tc_write_rb(Tc *p_tc, uint32_t ul_channel,
uint32_t ul_value);
void tc_write_rc(Tc *p_tc, uint32_t ul_channel,
uint32_t ul_value);
uint32_t tc_find_mck_divisor(uint32_t ul_freq, uint32_t ul_mck,
uint32_t *p_uldiv, uint32_t *ul_tcclks, uint32_t ul_boardmck);
void tc_enable_interrupt(Tc *p_tc, uint32_t ul_channel,
uint32_t ul_sources);
void tc_disable_interrupt(Tc *p_tc, uint32_t ul_channel,
uint32_t ul_sources);
uint32_t tc_get_interrupt_mask(Tc *p_tc, uint32_t ul_channel);
uint32_t tc_get_status(Tc *p_tc, uint32_t ul_channel);
#if (!SAM4L && !SAMG) || defined(__DOXYGEN__)
void tc_enable_qdec_interrupt(Tc *p_tc, uint32_t ul_sources);
void tc_disable_qdec_interrupt(Tc *p_tc, uint32_t ul_sources);
uint32_t tc_get_qdec_interrupt_mask(Tc *p_tc);
uint32_t tc_get_qdec_interrupt_status(Tc *p_tc);
#endif /* (!SAM4L && !SAMG) || defined(__DOXYGEN__) */
#if (!SAM3U)
void tc_set_writeprotect(Tc *p_tc, uint32_t ul_enable);
#endif /* (!SAM3U) */
#if SAM4L || defined(__DOXYGEN__)
uint32_t tc_get_feature(Tc *p_tc);
uint32_t tc_get_version(Tc *p_tc);
#endif /* SAM4L || defined(__DOXYGEN__) */
/// @cond
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
/** @} */
/**
* \page asfdoc_sam_drivers_tc_extra Extra Information for Timer Counter Driver
*
* \section asfdoc_sam_drivers_tc_extra_acronyms Acronyms
* Below is a table listing the acronyms used in this module, along with their
* intended meanings.
*
* <table>
* <tr>
* <th>Acronym</th>
* <th>Definition</th>
* </tr>
* <tr>
* <td>MCK</td>
* <td>Master Clock</td>
* </tr>
* <tr>
* <td>PBA</td>
* <td>Peripheral Bus A clock</td>
* </tr>
* <tr>
* <td>PHA</td>
* <td>Quadrature Decoder input signal Phase A</td>
* </tr>
* <tr>
* <td>PHB</td>
* <td>Quadrature Decoder input signal Phase B</td>
* </tr>
* <tr>
* <td>QDEC</td>
* <td>Quadrature Decoder</td>
* </tr>
* <tr>
* <td>QSG</td>
* <td>Quick Start Guide</td>
* </tr>
* <tr>
* <td>RA</td>
* <td>Register A</td>
* </tr>
* <tr>
* <td>RB</td>
* <td>Register B</td>
* </tr>
* <tr>
* <td>RC</td>
* <td>Register C</td>
* </tr>
* <tr>
* <td>TIOB</td>
* <td>Timer Input Output B</td>
* </tr>
* </table>
*
*
* \section asfdoc_sam_drivers_tc_extra_dependencies Dependencies
* This driver has the following dependencies:
*
* - \ref clk_group "System Clock Management (sysclock)"
* - \ref asfdoc_sam_drivers_gpio_group "General Purpose I/O (GPIO) driver"
* - \ref asfdoc_sam_drivers_pmc_group "Power Manager Controller (PMC) driver"
*
*
* \section asfdoc_sam_drivers_tc_extra_errata Errata
* There are no errata related to this driver.
*
*
* \section asfdoc_sam_drivers_tc_extra_history Module History
* An overview of the module history is presented in the table below, with
* details on the enhancements and fixes made to the module since its first
* release. The current version of this corresponds to the newest version in
* the table.
*
* <table>
* <tr>
* <th>Changelog</th>
* </tr>
* <tr>
* <td>Initial document release</td>
* </tr>
* </table>
*/
/**
* \page asfdoc_sam_drivers_tc_exqsg Examples for Timer Counter
*
* This is a list of the available Quick Start Guides (QSGs) and example
* applications for \ref asfdoc_sam_drivers_tc_group. QSGs are simple examples with
* step-by-step instructions to configure and use this driver in a selection of
* use cases. Note that a QSG can be compiled as a standalone application or be
* added to the user application.
*
* - \subpage asfdoc_sam_drivers_tc_qsg
* - \subpage asfdoc_sam_drivers_tc_example
*
* \page asfdoc_sam_drivers_tc_document_revision_history Document Revision History
*
* <table>
* <tr>
* <th>Doc. Rev.</td>
* <th>Date</td>
* <th>Comments</td>
* </tr>
* <tr>
* <td>42301B</td>
* <td>07/2015</td>
* <td>Updated title of application note and added list of supported devices</td>
* </tr>
* <tr>
* <td>42301A</td>
* <td>05/2014</td>
* <td>Initial document release</td>
* </tr>
* </table>
*
*/
/**
* \page asfdoc_sam_drivers_tc_qsg Quick Start Guide for the TC driver
*
* This is the quick start guide for the \ref asfdoc_sam_drivers_tc_group, with
* step-by-step instructions on how to configure and use the driver for
* a specific use case. The code examples can be copied into the main
* application loop or any other function that will need to control the
* AST module.
*
* \section asfdoc_sam_drivers_tc_qsg_use_cases Use Cases
* - \ref asfdoc_sam_drivers_tc_qsg_basic_capture
* - \ref asfdoc_sam_drivers_tc_qsg_basic_waveform
*
* \section asfdoc_sam_drivers_tc_qsg_basic_capture TC Capture Mode Basic Usage
*
* This use case will demonstrate how to initialize the TC module to
* operate in capture mode using interrupts. Note, that the macros
* used to select the TC channel are device specific. Refer to the
* appropriate device-specific datasheet for more information.
*
*
* \section asfdoc_sam_drivers_tc_qsg_basic_capture_setup Setup Steps
*
* \subsection asfdoc_sam_tc_qsg_basic_capture_prereq Prerequisites
*
* This module requires the following services:
* - \ref clk_group "System Clock Management (sysclock)"
* - \ref asfdoc_sam_drivers_gpio_group "General Purpose I/O (GPIO) driver"
*
* \subsection asfdoc_sam_drivers_tc_qsg_basic_capture_setup_code Setup Code
*
* Add these macros to the top of your main application C-file:
* \snippet conf_board.h tc_define_peripheral
* \snippet conf_board.h tc_define_ch2
* \snippet conf_board.h tc_define_irq_handler
*
* Add this macro and functions to your main application C-file:
* \snippet tc_capture_waveform_example.c tc_capture_selection
* \snippet tc_capture_waveform_example.c tc_capture_init
* \snippet tc_capture_waveform_example.c tc_capture_irq_handler_start
* \snippet tc_capture_waveform_example.c tc_capture_irq_handler_end
*
* \subsection asfdoc_sam_drivers_tc_qsg_basic_capture_setup_workflow Workflow
*
* -# Enable the TC module's capture pin:
* \snippet tc_capture_waveform_example.c tc_capture_gpio
* -# Initialize the capture channel to the following:
* - Load RA on the rising edge of TIOA
* - Load RB on the falling edge of TIOA
* - Set the external trigger to TIOA
* - Set the external trigger to falling edge
* \snippet tc_capture_waveform_example.c tc_capture_init_call
* -# Enable the TC interrupt using NVIC:
* \snippet tc_capture_waveform_example.c tc_capture_init_irq
* -# Enable the capture channel interrupt:
* \snippet tc_capture_waveform_example.c tc_capture_init_module_irq
* -# In the \ref TC_Handler_null "TC_Handler()" function, the load.
* RB interrupt can be checked by:
* \snippet tc_capture_waveform_example.c tc_capture_irq_handler_status
* \code } \endcode
* -# In the \ref TC_Handler_null "TC_Handler()" function, the RA value.
* can be read by:
* \code uint32_t gs_ul_captured_ra; \endcode
* \snippet tc_capture_waveform_example.c tc_capture_irq_handler_read_ra
* -# In the \ref TC_Handler_null "TC_Handler()" function, the RB value.
* can be read by:
* \code uint32_t gs_ul_captured_rb; \endcode
* \snippet tc_capture_waveform_example.c tc_capture_irq_handler_read_rb
*
* \section asfdoc_sam_drivers_tc_qsg_basic_waveform TC Waveform Mode Basic Usage
*
* This use case will demonstrate how to initialize the TC module to
* operate in waveform mode. Note, that the macros used to select
* the TC channel are device specific. Refer to the appropriate
* device-specific datasheet for more information.
*
*
* \section asfdoc_sam_drivers_tc_qsg_basic_waveform_setup Setup Steps
*
* \subsection asfdoc_sam_tc_qsg_basic_waveform_prereq Prerequisites
*
* This module requires the following services:
* - \ref clk_group "System Clock Management (sysclock)"
* - \ref asfdoc_sam_drivers_gpio_group "General Purpose I/O (GPIO) driver"
*
* \subsection asfdoc_sam_drivers_tc_qsg_basic_waveform_setup_code Setup Code
*
* Add these macros to the top of your main application C-file:
* \snippet conf_board.h tc_define_peripheral
* \snippet conf_board.h tc_define_ch1
*
* Add these macros and function to your main application C-file:
* \code #define TC_WAVEFORM_TIMER_SELECTION TC_CMR_TCCLKS_TIMER_CLOCK4 \endcode
* \code #define TC_WAVEFORM_DIVISOR 128 \endcode
* \code #define TC_WAVEFORM_FREQUENCY 178 \endcode
* \code #define TC_WAVEFORM_DUTY_CYCLE 30 \endcode
* \code
* static void tc_waveform_initialize(void)
* {
* uint32_t ra, rc;
*
* // Configure the PMC to enable the TC module.
* sysclk_enable_peripheral_clock(ID_TC_WAVEFORM);
*
* // Init TC to waveform mode.
* tc_init(TC, TC_CHANNEL_WAVEFORM,
* TC_WAVEFORM_TIMER_SELECTION // Waveform Clock Selection
* | TC_CMR_WAVE // Waveform mode is enabled
* | TC_CMR_ACPA_SET // RA Compare Effect: set
* | TC_CMR_ACPC_CLEAR // RC Compare Effect: clear
* | TC_CMR_CPCTRG // UP mode with automatic trigger on RC Compare
* );
*
* // Configure waveform frequency and duty cycle.
* rc = (sysclk_get_peripheral_bus_hz(TC) /
* TC_WAVEFORM_DIVISOR /
* TC_WAVEFORM_FREQUENCY;
* tc_write_rc(TC, TC_CHANNEL_WAVEFORM, rc);
* ra = (100 - TC_WAVEFORM_FREQUENCY_DUTY_CYCLE * rc / 100;
* tc_write_ra(TC, TC_CHANNEL_WAVEFORM, ra);
*
* // Enable TC TC_CHANNEL_WAVEFORM.
* tc_start(TC, TC_CHANNEL_WAVEFORM);
* } \endcode
*
* \subsection asfdoc_sam_drivers_tc_qsg_basic_waveform_setup_workflow Workflow
*
* -# Enable the TC module's waveform pin:
* \snippet tc_capture_waveform_example.c tc_waveform_gpio
* -# Initialize the waveform channel to the following:
* - Output frequency of 178Hz, with a duty-cycle of 30%
* - Use TC_CMR_TCCLKS_TIMER_CLOCK4, with a divisor of 128
* \snippet tc_capture_waveform_example.c tc_waveform_init_call
*/
#endif /* TC_H_INCLUDED */
@@ -0,0 +1,160 @@
/**
* \file
*
* \brief Universal Asynchronous Receiver Transceiver (UART) driver for SAM.
*
* Copyright (c) 2011-2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef UART_H_INCLUDED
#define UART_H_INCLUDED
#include "compiler.h"
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
extern "C" {
#endif
/**INDENT-ON**/
/// @endcond
/* UART internal div factor for sampling */
#define UART_MCK_DIV 16
/* Div factor to get the maximum baud rate */
#define UART_MCK_DIV_MIN_FACTOR 1
/* Div factor to get the minimum baud rate */
#define UART_MCK_DIV_MAX_FACTOR 65535
/*! \brief Option list for UART peripheral initialization */
typedef struct sam_uart_opt {
/** MCK for UART */
uint32_t ul_mck;
/** Expected baud rate */
uint32_t ul_baudrate;
/** Initialize value for UART mode register */
uint32_t ul_mode;
} sam_uart_opt_t;
uint32_t uart_init(Uart *p_uart, const sam_uart_opt_t *p_uart_opt);
void uart_enable_tx(Uart *p_uart);
void uart_disable_tx(Uart *p_uart);
void uart_reset_tx(Uart *p_uart);
void uart_enable_rx(Uart *p_uart);
void uart_disable_rx(Uart *p_uart);
void uart_reset_rx(Uart *p_uart);
void uart_enable(Uart *p_uart);
void uart_disable(Uart *p_uart);
void uart_reset(Uart *p_uart);
void uart_enable_interrupt(Uart *p_uart, uint32_t ul_sources);
void uart_disable_interrupt(Uart *p_uart, uint32_t ul_sources);
uint32_t uart_get_interrupt_mask(Uart *p_uart);
uint32_t uart_get_status(Uart *p_uart);
void uart_reset_status(Uart *p_uart);
uint32_t uart_is_tx_ready(Uart *p_uart);
uint32_t uart_is_tx_empty(Uart *p_uart);
uint32_t uart_is_rx_ready(Uart *p_uart);
uint32_t uart_is_tx_buf_empty(Uart *p_uart);
void uart_set_clock_divisor(Uart *p_uart, uint16_t us_divisor);
uint32_t uart_write(Uart *p_uart, const uint8_t uc_data);
uint32_t uart_read(Uart *p_uart, uint8_t *puc_data);
#if (!SAMV71 && !SAMV70 && !SAME70 && !SAMS70)
uint32_t uart_is_rx_buf_end(Uart *p_uart);
uint32_t uart_is_tx_buf_end(Uart *p_uart);
uint32_t uart_is_rx_buf_full(Uart *p_uart);
Pdc *uart_get_pdc_base(Uart *p_uart);
#endif
#if (SAMG53 || SAMG54 || SAMV71 || SAMV70 || SAME70 || SAMS70)
void uart_set_sleepwalking(Uart *p_uart, uint8_t ul_low_value,
bool cmpmode, bool cmppar, uint8_t ul_high_value);
void uart_set_write_protection(Uart *p_uart, bool flag);
#endif
#if (SAM4C || SAM4CP || SAM4CM)
enum uart_optical_duty_cycle {
UART_MOD_CLK_DUTY_50_00 = UART_MR_OPT_DUTY_DUTY_50,
UART_MOD_CLK_DUTY_43_75 = UART_MR_OPT_DUTY_DUTY_43P75,
UART_MOD_CLK_DUTY_37_50 = UART_MR_OPT_DUTY_DUTY_37P5,
UART_MOD_CLK_DUTY_31_25 = UART_MR_OPT_DUTY_DUTY_31P25,
UART_MOD_CLK_DUTY_25_00 = UART_MR_OPT_DUTY_DUTY_25,
UART_MOD_CLK_DUTY_18_75 = UART_MR_OPT_DUTY_DUTY_18P75,
UART_MOD_CLK_DUTY_12_50 = UART_MR_OPT_DUTY_DUTY_12P5,
UART_MOD_CLK_DUTY_06_25 = UART_MR_OPT_DUTY_DUTY_6P25,
};
enum uart_optical_cmp_threshold {
UART_RX_CMP_THRESHOLD_VDDIO_DIV_10_0 = UART_MR_OPT_CMPTH_VDDIO_DIV10,
UART_RX_CMP_THRESHOLD_VDDIO_DIV_5_0 = UART_MR_OPT_CMPTH_VDDIO_DIV5,
UART_RX_CMP_THRESHOLD_VDDIO_DIV_3_3 = UART_MR_OPT_CMPTH_VDDIO_DIV3P3,
UART_RX_CMP_THRESHOLD_VDDIO_DIV_2_5 = UART_MR_OPT_CMPTH_VDDIO_DIV2P5,
UART_RX_CMP_THRESHOLD_VDDIO_DIV_2_0 = UART_MR_OPT_CMPTH_VDDIO_DIV2,
};
struct uart_config_optical {
/* UART Receive Data Inverted */
bool rx_inverted;
/* UART Modulated Data Inverted */
bool tx_inverted;
/* UART Receiver Digital Filter */
bool rx_filter;
/* Optical Link Clock Divider */
uint8_t clk_div;
/* Optical Link Modulation Clock Duty Cycle */
enum uart_optical_duty_cycle duty;
/* Receive Path Comparator Threshold */
enum uart_optical_cmp_threshold threshold;
};
void uart_enable_optical_interface(Uart *p_uart);
void uart_disable_optical_interface(Uart *p_uart);
void uart_config_optical_interface(Uart *p_uart,
struct uart_config_optical *cfg);
#endif
/// @cond 0
/**INDENT-OFF**/
#ifdef __cplusplus
}
#endif
/**INDENT-ON**/
/// @endcond
#endif /* UART_H_INCLUDED */
@@ -0,0 +1,143 @@
/**
* \file
*
* Copyright (c) 2015 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
*
*/
/*
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _SAME70_ACC_COMPONENT_
#define _SAME70_ACC_COMPONENT_
/* ============================================================================= */
/** SOFTWARE API DEFINITION FOR Analog Comparator Controller */
/* ============================================================================= */
/** \addtogroup SAME70_ACC Analog Comparator Controller */
/*@{*/
#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
/** \brief Acc hardware registers */
typedef struct {
__O uint32_t ACC_CR; /**< \brief (Acc Offset: 0x00) Control Register */
__IO uint32_t ACC_MR; /**< \brief (Acc Offset: 0x04) Mode Register */
__I uint32_t Reserved1[7];
__O uint32_t ACC_IER; /**< \brief (Acc Offset: 0x24) Interrupt Enable Register */
__O uint32_t ACC_IDR; /**< \brief (Acc Offset: 0x28) Interrupt Disable Register */
__I uint32_t ACC_IMR; /**< \brief (Acc Offset: 0x2C) Interrupt Mask Register */
__I uint32_t ACC_ISR; /**< \brief (Acc Offset: 0x30) Interrupt Status Register */
__I uint32_t Reserved2[24];
__IO uint32_t ACC_ACR; /**< \brief (Acc Offset: 0x94) Analog Control Register */
__I uint32_t Reserved3[19];
__IO uint32_t ACC_WPMR; /**< \brief (Acc Offset: 0xE4) Write Protection Mode Register */
__I uint32_t ACC_WPSR; /**< \brief (Acc Offset: 0xE8) Write Protection Status Register */
} Acc;
#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
/* -------- ACC_CR : (ACC Offset: 0x00) Control Register -------- */
#define ACC_CR_SWRST (0x1u << 0) /**< \brief (ACC_CR) Software Reset */
/* -------- ACC_MR : (ACC Offset: 0x04) Mode Register -------- */
#define ACC_MR_SELMINUS_Pos 0
#define ACC_MR_SELMINUS_Msk (0x7u << ACC_MR_SELMINUS_Pos) /**< \brief (ACC_MR) Selection for Minus Comparator Input */
#define ACC_MR_SELMINUS(value) ((ACC_MR_SELMINUS_Msk & ((value) << ACC_MR_SELMINUS_Pos)))
#define ACC_MR_SELMINUS_TS (0x0u << 0) /**< \brief (ACC_MR) Select TS */
#define ACC_MR_SELMINUS_ADVREFP (0x1u << 0) /**< \brief (ACC_MR) Select ADVREFP */
#define ACC_MR_SELMINUS_DAC0 (0x2u << 0) /**< \brief (ACC_MR) Select DAC0 */
#define ACC_MR_SELMINUS_DAC1 (0x3u << 0) /**< \brief (ACC_MR) Select DAC1 */
#define ACC_MR_SELMINUS_AFE0_AD0 (0x4u << 0) /**< \brief (ACC_MR) Select AFE0_AD0 */
#define ACC_MR_SELMINUS_AFE0_AD1 (0x5u << 0) /**< \brief (ACC_MR) Select AFE0_AD1 */
#define ACC_MR_SELMINUS_AFE0_AD2 (0x6u << 0) /**< \brief (ACC_MR) Select AFE0_AD2 */
#define ACC_MR_SELMINUS_AFE0_AD3 (0x7u << 0) /**< \brief (ACC_MR) Select AFE0_AD3 */
#define ACC_MR_SELPLUS_Pos 4
#define ACC_MR_SELPLUS_Msk (0x7u << ACC_MR_SELPLUS_Pos) /**< \brief (ACC_MR) Selection For Plus Comparator Input */
#define ACC_MR_SELPLUS(value) ((ACC_MR_SELPLUS_Msk & ((value) << ACC_MR_SELPLUS_Pos)))
#define ACC_MR_SELPLUS_AFE0_AD0 (0x0u << 4) /**< \brief (ACC_MR) Select AFE0_AD0 */
#define ACC_MR_SELPLUS_AFE0_AD1 (0x1u << 4) /**< \brief (ACC_MR) Select AFE0_AD1 */
#define ACC_MR_SELPLUS_AFE0_AD2 (0x2u << 4) /**< \brief (ACC_MR) Select AFE0_AD2 */
#define ACC_MR_SELPLUS_AFE0_AD3 (0x3u << 4) /**< \brief (ACC_MR) Select AFE0_AD3 */
#define ACC_MR_SELPLUS_AFE0_AD4 (0x4u << 4) /**< \brief (ACC_MR) Select AFE0_AD4 */
#define ACC_MR_SELPLUS_AFE0_AD5 (0x5u << 4) /**< \brief (ACC_MR) Select AFE0_AD5 */
#define ACC_MR_SELPLUS_AFE1_AD0 (0x6u << 4) /**< \brief (ACC_MR) Select AFE1_AD0 */
#define ACC_MR_SELPLUS_AFE1_AD1 (0x7u << 4) /**< \brief (ACC_MR) Select AFE1_AD1 */
#define ACC_MR_ACEN (0x1u << 8) /**< \brief (ACC_MR) Analog Comparator Enable */
#define ACC_MR_ACEN_DIS (0x0u << 8) /**< \brief (ACC_MR) Analog comparator disabled. */
#define ACC_MR_ACEN_EN (0x1u << 8) /**< \brief (ACC_MR) Analog comparator enabled. */
#define ACC_MR_EDGETYP_Pos 9
#define ACC_MR_EDGETYP_Msk (0x3u << ACC_MR_EDGETYP_Pos) /**< \brief (ACC_MR) Edge Type */
#define ACC_MR_EDGETYP(value) ((ACC_MR_EDGETYP_Msk & ((value) << ACC_MR_EDGETYP_Pos)))
#define ACC_MR_EDGETYP_RISING (0x0u << 9) /**< \brief (ACC_MR) Only rising edge of comparator output */
#define ACC_MR_EDGETYP_FALLING (0x1u << 9) /**< \brief (ACC_MR) Falling edge of comparator output */
#define ACC_MR_EDGETYP_ANY (0x2u << 9) /**< \brief (ACC_MR) Any edge of comparator output */
#define ACC_MR_INV (0x1u << 12) /**< \brief (ACC_MR) Invert Comparator Output */
#define ACC_MR_INV_DIS (0x0u << 12) /**< \brief (ACC_MR) Analog comparator output is directly processed. */
#define ACC_MR_INV_EN (0x1u << 12) /**< \brief (ACC_MR) Analog comparator output is inverted prior to being processed. */
#define ACC_MR_SELFS (0x1u << 13) /**< \brief (ACC_MR) Selection Of Fault Source */
#define ACC_MR_SELFS_CE (0x0u << 13) /**< \brief (ACC_MR) The CE flag is used to drive the FAULT output. */
#define ACC_MR_SELFS_OUTPUT (0x1u << 13) /**< \brief (ACC_MR) The output of the analog comparator flag is used to drive the FAULT output. */
#define ACC_MR_FE (0x1u << 14) /**< \brief (ACC_MR) Fault Enable */
#define ACC_MR_FE_DIS (0x0u << 14) /**< \brief (ACC_MR) The FAULT output is tied to 0. */
#define ACC_MR_FE_EN (0x1u << 14) /**< \brief (ACC_MR) The FAULT output is driven by the signal defined by SELFS. */
/* -------- ACC_IER : (ACC Offset: 0x24) Interrupt Enable Register -------- */
#define ACC_IER_CE (0x1u << 0) /**< \brief (ACC_IER) Comparison Edge */
/* -------- ACC_IDR : (ACC Offset: 0x28) Interrupt Disable Register -------- */
#define ACC_IDR_CE (0x1u << 0) /**< \brief (ACC_IDR) Comparison Edge */
/* -------- ACC_IMR : (ACC Offset: 0x2C) Interrupt Mask Register -------- */
#define ACC_IMR_CE (0x1u << 0) /**< \brief (ACC_IMR) Comparison Edge */
/* -------- ACC_ISR : (ACC Offset: 0x30) Interrupt Status Register -------- */
#define ACC_ISR_CE (0x1u << 0) /**< \brief (ACC_ISR) Comparison Edge (cleared on read) */
#define ACC_ISR_SCO (0x1u << 1) /**< \brief (ACC_ISR) Synchronized Comparator Output */
#define ACC_ISR_MASK (0x1u << 31) /**< \brief (ACC_ISR) Flag Mask */
/* -------- ACC_ACR : (ACC Offset: 0x94) Analog Control Register -------- */
#define ACC_ACR_ISEL (0x1u << 0) /**< \brief (ACC_ACR) Current Selection */
#define ACC_ACR_ISEL_LOPW (0x0u << 0) /**< \brief (ACC_ACR) Low-power option. */
#define ACC_ACR_ISEL_HISP (0x1u << 0) /**< \brief (ACC_ACR) High-speed option. */
#define ACC_ACR_HYST_Pos 1
#define ACC_ACR_HYST_Msk (0x3u << ACC_ACR_HYST_Pos) /**< \brief (ACC_ACR) Hysteresis Selection */
#define ACC_ACR_HYST(value) ((ACC_ACR_HYST_Msk & ((value) << ACC_ACR_HYST_Pos)))
/* -------- ACC_WPMR : (ACC Offset: 0xE4) Write Protection Mode Register -------- */
#define ACC_WPMR_WPEN (0x1u << 0) /**< \brief (ACC_WPMR) Write Protection Enable */
#define ACC_WPMR_WPKEY_Pos 8
#define ACC_WPMR_WPKEY_Msk (0xffffffu << ACC_WPMR_WPKEY_Pos) /**< \brief (ACC_WPMR) Write Protection Key */
#define ACC_WPMR_WPKEY(value) ((ACC_WPMR_WPKEY_Msk & ((value) << ACC_WPMR_WPKEY_Pos)))
#define ACC_WPMR_WPKEY_PASSWD (0x414343u << 8) /**< \brief (ACC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */
/* -------- ACC_WPSR : (ACC Offset: 0xE8) Write Protection Status Register -------- */
#define ACC_WPSR_WPVS (0x1u << 0) /**< \brief (ACC_WPSR) Write Protection Violation Status */
/*@}*/
#endif /* _SAME70_ACC_COMPONENT_ */

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