Skip to content

Flex Glove implementado #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 10 additions & 10 deletions Sensores/IMU-MCU6050-I2C/IMU-MCU6050-I2C/src/main.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
/**
* Computa��o Embarcada
* Computação Embarcada
* Insper
* Rafael Corsi - rafael.corsi@insper.edu.br
* C�digo exemplo uso I2C
* Código exemplo uso I2C
* Abril - 2017
*
* Bug conhecido : spi read deve ser executado duas vezes ?
@@ -23,7 +23,7 @@

#include "asf.h"
#include "mpu6050.h"
#include "Fusion/Fusion.h"
#include "fusion/fusion.h"

/************************************************************************/
/* VAR globais */
@@ -197,7 +197,7 @@ int main(void){
/* Inicializa funcao de delay */
delay_init( sysclk_get_cpu_hz());

/* Inicializa Fun��o de fus�o */
/* Inicializa Função de fusão */
FusionAhrs ahrs;
FusionAhrsInitialise(&ahrs);

@@ -215,7 +215,7 @@ int main(void){
printf("[ERRO] [i2c] [read] \n");
}

// Por algum motivo a primeira leitura errada.
// Por algum motivo a primeira leitura é errada.
if(bufferRX[0] != 0x68){
printf("[ERRO] [mcu] [Wrong device] [0x%2X] \n", bufferRX[0]);
}
@@ -246,16 +246,16 @@ int main(void){
rtn = mcu6050_i2c_bus_read(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_ZOUT_H, &raw_acc_zHigh, 1);
rtn = mcu6050_i2c_bus_read(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_ZOUT_L, &raw_acc_zLow, 1);

// Dados s�o do tipo complemento de dois
// Dados são do tipo complemento de dois
raw_acc_x = (raw_acc_xHigh << 8) | (raw_acc_xLow << 0);
raw_acc_y = (raw_acc_yHigh << 8) | (raw_acc_yLow << 0);
raw_acc_z = (raw_acc_zHigh << 8) | (raw_acc_zLow << 0);
proc_acc_x = (float)raw_acc_x/16384;
proc_acc_y = (float)raw_acc_y/16384;
proc_acc_z = (float)raw_acc_z/16384;

// Configura range gyroscopio para operar com 250 /s
bufferTX[0] = 0x00; // 250 /s
// Configura range gyroscopio para operar com 250 °/s
bufferTX[0] = 0x00; // 250 °/s
rtn = mcu6050_i2c_bus_write(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_CONFIG, bufferTX, 1);

// Le valor do gyr X High e Low
@@ -270,7 +270,7 @@ int main(void){
rtn = mcu6050_i2c_bus_read(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_ZOUT_H, &raw_gyr_zHigh, 1);
rtn = mcu6050_i2c_bus_read(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_ZOUT_L, &raw_gyr_zLow, 1);

// Dados s�o do tipo complemento de dois
// Dados são do tipo complemento de dois
raw_gyr_x = (raw_gyr_xHigh << 8) | (raw_gyr_xLow << 0);
raw_gyr_y = (raw_gyr_yHigh << 8) | (raw_gyr_yLow << 0);
raw_gyr_z = (raw_gyr_zHigh << 8) | (raw_gyr_zLow << 0);
@@ -283,7 +283,7 @@ int main(void){
// replace this with actual accelerometer data in g
const FusionVector accelerometer = {proc_acc_x, proc_acc_y, proc_acc_z};

// calcula runtime do c�digo acima para definir delta t do programa
// calcula runtime do código acima para definir delta t do programa
int tick = rtt_read_timer_value(RTT);
float delta_time = (tick - tick_old)/1000.0;
tick_old = tick;
22 changes: 22 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## Ignore Atmel Studio temporary files and build results
# https://www.microchip.com/mplab/avr-support/atmel-studio-7

# Atmel Studio is powered by an older version of Visual Studio,
# so most of the project and solution files are the same as VS files,
# only prefixed by an `at`.

#Build Directories
[Dd]ebug/
[Rr]elease/

#Build Results
*.o
*.d
*.eep
*.elf
*.hex
*.map
*.srec

#User Specific Files
*.atsuo
22 changes: 22 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/bme280-i2c.atsln
Original file line number Diff line number Diff line change
@@ -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}") = "bme280-i2c", "bme280-i2c.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
4 changes: 4 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/bme280-i2c.componentinfo.xml
Original file line number Diff line number Diff line change
@@ -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>
1,380 changes: 1,380 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/bme280-i2c.cproj

Large diffs are not rendered by default.

445 changes: 445 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/boards/board.h

Large diffs are not rendered by default.

199 changes: 199 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/clock/genclk.h
Original file line number Diff line number Diff line change
@@ -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 */
185 changes: 185 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/clock/osc.h
Original file line number Diff line number Diff line change
@@ -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 */
341 changes: 341 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/clock/pll.h
Original file line number Diff line number Diff line change
@@ -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 */
Original file line number Diff line number Diff line change
@@ -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 */
Original file line number Diff line number Diff line change
@@ -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 */
Original file line number Diff line number Diff line change
@@ -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 */
Original file line number Diff line number Diff line change
@@ -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

Large diffs are not rendered by default.

194 changes: 194 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/clock/sysclk.h
Original file line number Diff line number Diff line change
@@ -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 */
139 changes: 139 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/delay/delay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/**
* \file
*
* \brief Common Delay Service
*
* Copyright (c) 2014-2016 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 _DELAY_H_
#define _DELAY_H_

#ifdef __cplusplus
extern "C" {
#endif

#include <sysclk.h>

#if UC3
# include <cycle_counter.h>
#elif XMEGA
# include "xmega/cycle_counter.h"
#elif MEGA
# include "mega/cycle_counter.h"
#elif SAM
# include "sam/cycle_counter.h"
#endif

/**
* @defgroup group_common_services_delay Busy-Wait Delay Routines
*
* This module provides simple loop-based delay routines for those
* applications requiring a brief wait during execution. Common API
* for UC3, XMEGA, and AVR MEGA.
*
* @{
*/

/**
* @def F_CPU
* @brief MCU Clock Frequency (Hertz)
*
* @deprecated
* The \ref F_CPU configuration constant is used for compatibility with the
* \ref group_common_services_delay routines. The common loop-based delay
* routines are designed to use the \ref clk_group modules while anticipating
* support for legacy applications assuming a statically defined clock
* frequency. Applications using a statically configured MCU clock frequency
* can define \ref F_CPU (Hertz), in which case the common delay routines will
* use this value rather than calling sysclk_get_cpu_hz() to get the current
* MCU clock frequency.
*/
#ifndef F_CPU
# define F_CPU sysclk_get_cpu_hz()
#endif

/**
* @def delay_init
*
* @brief Initialize the delay driver.
* @param fcpu_hz CPU frequency in Hz
*
* @deprecated
* This function is provided for compatibility with ASF applications that
* may not have been updated to configure the system clock via the common
* clock service; e.g. sysclk_init() and a configuration header file are
* used to configure clocks.
*
* The functions in this module call \ref sysclk_get_cpu_hz() function to
* obtain the system clock frequency.
*/
#define delay_init(fcpu_hz)

/**
* @def delay_s
* @brief Delay in seconds.
* @param delay Delay in seconds
*/
#define delay_s(delay) ((delay) ? cpu_delay_ms(1000 * delay, F_CPU) : cpu_delay_us(1, F_CPU))

/**
* @def delay_ms
* @brief Delay in milliseconds.
* @param delay Delay in milliseconds
*/
#define delay_ms(delay) ((delay) ? cpu_delay_ms(delay, F_CPU) : cpu_delay_us(1, F_CPU))

/**
* @def delay_us
* @brief Delay in microseconds.
* @param delay Delay in microseconds
*/
#define delay_us(delay) ((delay) ? cpu_delay_us(delay, F_CPU) : cpu_delay_us(1, F_CPU))

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* _DELAY_H_ */
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* \file
*
* \brief ARM functions for busy-wait delay loops
*
* 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 "cycle_counter.h"

// Delay loop is put to SRAM so that FWS will not affect delay time
OPTIMIZE_HIGH
RAMFUNC
void portable_delay_cycles(unsigned long n)
{
UNUSED(n);

__asm (
"loop: DMB \n"
"SUBS R0, R0, #1 \n"
"BNE.N loop "
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/**
* \file
*
* \brief ARM functions for busy-wait delay loops
*
* Copyright (c) 2014-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 _cycle_counter_h_
#define _cycle_counter_h_

#ifdef __cplusplus
extern "C" {
#endif


#include <compiler.h>

/**
* @name Convenience functions for busy-wait delay loops
*
* @def delay_cycles
* @brief Delay program execution for a specified number of CPU cycles.
* @param n number of CPU cycles to wait
*
* @def cpu_delay_ms
* @brief Delay program execution for a specified number of milliseconds.
* @param delay number of milliseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_delay_us
* @brief Delay program execution for a specified number of microseconds.
* @param delay number of microseconds to wait
* @param f_cpu CPU frequency in Hertz
*
* @def cpu_ms_2_cy
* @brief Convert milli-seconds into CPU cycles.
* @param ms number of milliseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @def cpu_us_2_cy
* @brief Convert micro-seconds into CPU cycles.
* @param ms number of microseconds
* @param f_cpu CPU frequency in Hertz
* @return the converted number of CPU cycles
*
* @{
*/

/**
* \brief Delay loop to delay n number of cycles
*
* \note The function runs in internal RAM so that flash wait states
* will not affect the delay time.
*
* \param n Number of cycles
*/
void portable_delay_cycles(unsigned long n);

/* Cortex-M7 is faster than Cortex-M3/M4/M0+ */
#ifdef __CM7_REV

# define cpu_ms_2_cy(ms, f_cpu) \
(((uint64_t)(ms) * (f_cpu) + (uint64_t)(5.932e3 - 1ul)) / (uint64_t)5.932e3)
# define cpu_us_2_cy(us, f_cpu) \
(((uint64_t)(us) * (f_cpu) + (uint64_t)(5.932e6 - 1ul)) / (uint64_t)5.932e6)

#else

# define cpu_ms_2_cy(ms, f_cpu) \
(((uint64_t)(ms) * (f_cpu) + (uint64_t)(14e3 - 1ul)) / (uint64_t)14e3)
# define cpu_us_2_cy(us, f_cpu) \
(((uint64_t)(us) * (f_cpu) + (uint64_t)(14e6 - 1ul)) / (uint64_t)14e6)

#endif

#define delay_cycles portable_delay_cycles

#define cpu_delay_ms(delay, f_cpu) delay_cycles(cpu_ms_2_cy(delay, f_cpu))
#define cpu_delay_us(delay, f_cpu) delay_cycles(cpu_us_2_cy(delay, f_cpu))
//! @}


#ifdef __cplusplus
}
#endif

#endif /* _cycle_counter_h_ */
86 changes: 86 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/gpio/gpio.h
Original file line number Diff line number Diff line change
@@ -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_ */
Original file line number Diff line number Diff line change
@@ -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 */
541 changes: 541 additions & 0 deletions Sensores/QWIIC-FLEX-GLOVE-I2C/src/ASF/common/services/ioport/ioport.h

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -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 */
Loading