subrepo:
  subdir:   "libopencm3"
  merged:   "88e91c9a7cce"
upstream:
  origin:   "https://github.com/libopencm3/libopencm3.git"
  branch:   "master"
  commit:   "88e91c9a7cce"
git-subrepo:
  version:  "0.4.3"
  origin:   "???"
  commit:   "???"
This commit is contained in:
2023-01-21 21:54:42 +02:00
parent f01f2a30fa
commit 054740c5de
1205 changed files with 191912 additions and 0 deletions

View File

@@ -0,0 +1,15 @@
/** @addtogroup acmp_file ACMP peripheral API
* @ingroup peripheral_apis
* @brief Analog Comparator helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/acmp.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,678 @@
/** @addtogroup adc_file ADC peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/adc.h>
/**@{*/
/**
* Set ADC over sampling
* @param[in] adc ADC (use ADCx)
* @param[in] oversamp Oversampling (use ADC_CTRL_OVERSEL_Xx)
*/
void adc_set_oversampling(uint32_t adc, uint32_t oversamp)
{
ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_OVERSEL_MASK) | oversamp;
}
/**
* Set ADC warm up
* @param[in] adc ADC (use ADCx)
* @param[in] clocks Clock cycles (1 - 128)
* @note warm-up-time = (@a clocks / HFPERCLK)
*/
void adc_set_warm_up(uint32_t adc, uint8_t clocks)
{
uint32_t timebase = ADC_CTRL_TIMEBASE(clocks - 1);
ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_TIMEBASE_MASK) | timebase;
}
/** Clock division factor
* @param[in] adc ADC (use ADCx)
* @param[in] factor Factor (1 - 128)
* @note output-clock = input-clock / @a factor
*/
void adc_set_clock_prescaler(uint32_t adc, uint8_t factor)
{
uint32_t presc = ADC_CTRL_PRESC(factor - 1);
ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_PRESC_MASK) | presc;
}
/**
* Set low pass filter mode
* @param[in] adc ADC (use ADCx)
* @param[in] lpfmode Low pass filter mode (use ADC_CTRL_LPFMODE_*)
*/
void adc_set_lowpass_filter(uint32_t adc, uint32_t lpfmode)
{
ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_LPFMODE_MASK) | lpfmode;
}
/**
* Enable tail gating
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_tailgating(uint32_t adc)
{
ADC_CTRL(adc) |= ADC_CTRL_TAILGATE;
}
/**
* Disable tail gating
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_tailgating(uint32_t adc)
{
ADC_CTRL(adc) &= ~ADC_CTRL_TAILGATE;
}
/**
* Set warm up mode
* @param[in] adc ADC (use ADCx)
* @param[in] warmupmode Warm Up Mode (use ADC_CTRL_WARMUPMODE_*)
*/
void adc_set_warm_up_mode(uint32_t adc, uint32_t warmupmode)
{
ADC_CTRL(adc) = (ADC_CTRL(adc) & ~ADC_CTRL_WARMUPMODE_MASK)
| warmupmode;
}
/**
* Start ADC in single acquisition
* @param[in] adc ADC (use ADCx)
*/
void adc_single_start(uint32_t adc)
{
ADC_CMD(adc) = ADC_CMD_SINGLESTART;
}
/**
* Stop ADC in single acquisition
* @param[in] adc ADC (use ADCx)
*/
void adc_single_stop(uint32_t adc)
{
ADC_CMD(adc) = ADC_CMD_SINGLESTOP;
}
/**
* Start ADC in scan acquisition
* @param[in] adc ADC (use ADCx)
*/
void adc_scan_start(uint32_t adc)
{
ADC_CMD(adc) = ADC_CMD_SCANSTART;
}
/**
* Stop ADC in scan acquisition
* @param[in] adc ADC (use ADCx)
*/
void adc_scan_stop(uint32_t adc)
{
ADC_CMD(adc) = ADC_CMD_SCANSTOP;
}
/* Single ----------------------------------------------------------- */
/**
* Set single PRS trigger
* @param[in] adc ADC (use ADCx)
* @param[in] prssel PRS Selected (use PRS_CHx)
*/
void adc_set_single_prs_trigger(uint32_t adc, uint8_t prssel)
{
ADC_SINGLECTRL(adc) =
(ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_PRSSEL_MASK) |
(ADC_SINGLECTRL_PRSSEL_PRSCHx(prssel));
}
/**
* Enable single PRS Triggering
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_single_prs_trigger(uint32_t adc)
{
ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_PRSEN;
}
/**
* Disable single PRS Triggering
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_single_prs_trigger(uint32_t adc)
{
ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_PRSEN;
}
/**
* Set single acquisition cycle
* @param[in] adc ADC (use ADCx)
* @param[in] at Acquisition time (use ADC_SINGLECTRL_AT_x)
*/
void adc_set_single_acquisition_cycle(uint32_t adc, uint32_t at)
{
ADC_SINGLECTRL(adc) =
(ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_AT_MASK) | at;
}
/**
* Set single reference for acquisition
* @param[in] adc ADC (use ADCx)
* @param[in] ref Reference (use ADC_SINGLECTRL_REF_x)
*/
void adc_set_single_reference(uint32_t adc, uint32_t ref)
{
ADC_SINGLECTRL(adc) =
(ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_REF_MASK) | ref;
}
/**
* Set single channel
* @param[in] adc ADC (use ADCx)
* @param[in] ch Channel (use ADC_CHx and ADC_CH_*)
*/
void adc_set_single_channel(uint32_t adc, uint8_t ch)
{
ADC_SINGLECTRL(adc) =
(ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_INPUTSEL_MASK) |
ADC_SINGLECTRL_INPUTSEL(ch);
}
/**
* Set single resolution of conversion
* @param[in] adc ADC (use ADCx)
* @param[in] res Resolution (use ADC_SINGLECTRL_RES_*)
*/
void adc_set_single_resolution(uint32_t adc, uint32_t res)
{
ADC_SINGLECTRL(adc) =
(ADC_SINGLECTRL(adc) & ~ADC_SINGLECTRL_RES_MASK) | res;
}
/**
* Set single left aligned output
* @param[in] adc ADC (use ADCx)
*/
void adc_set_single_left_aligned(uint32_t adc)
{
ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_ADJ;
}
/**
* Set single right aligned output
* @param[in] adc ADC (use ADCx)
*/
void adc_set_single_right_aligned(uint32_t adc)
{
ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_ADJ;
}
/**
* Set single single-ended conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_set_single_single_ended(uint32_t adc)
{
ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_DIFF;
}
/**
* Set single differential conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_set_single_differential(uint32_t adc)
{
ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_DIFF;
}
/**
* Enable single channel repeated conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_single_repeat_conv(uint32_t adc)
{
ADC_SINGLECTRL(adc) |= ADC_SINGLECTRL_REP;
}
/**
* Disable single repeated conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_single_repeat_conv(uint32_t adc)
{
ADC_SINGLECTRL(adc) &= ~ADC_SINGLECTRL_REP;
}
/* Scan ------------------------------------------------------------- */
/**
* Set scan PRS trigger
* @param[in] adc ADC (use ADCx)
* @param[in] prssel PRS Selected (use PRS_CHx)
*/
void adc_set_scan_prs_trigger(uint32_t adc, uint8_t prssel)
{
ADC_SCANCTRL(adc) =
(ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_PRSSEL_MASK) |
ADC_SCANCTRL_PRSSEL_PRSCHx(prssel);
}
/**
* Enable scan PRS Triggering
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_scan_prs_trigger(uint32_t adc)
{
ADC_SCANCTRL(adc) |= ADC_SCANCTRL_PRSEN;
}
/**
* Disable scan PRS Triggering
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_scan_prs_trigger(uint32_t adc)
{
ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_PRSEN;
}
/**
* Set scan acquisition cycle
* @param[in] adc ADC (use ADCx)
* @param[in] at Acquisition time (use ADC_SCANCTRL_AT_x)
*/
void adc_set_scan_acquisition_cycle(uint32_t adc, uint32_t at)
{
ADC_SCANCTRL(adc) =
(ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_AT_MASK) | at;
}
/**
* Set scan reference for acquisition
* @param[in] adc ADC (use ADCx)
* @param[in] ref Reference (use ADC_SCANCTRL_REF_x)
*/
void adc_set_scan_reference(uint32_t adc, uint32_t ref)
{
ADC_SCANCTRL(adc) =
(ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_REF_MASK) | ref;
}
/**
* Set scan channel list
* @param[in] adc ADC (use ADCx)
* @param[in] length Length of @a channel
* @param[in] channel channel list (use ADC_CHx)
* @note channel[0] is used as single acuqisition
*/
void adc_set_scan_channel(uint32_t adc, uint8_t length, uint8_t channel[])
{
unsigned i;
uint32_t val = 0;
for (i = 0; i < length; i++) {
val |= 1 << (channel[i] + ADC_SCANCTRL_INPUTSEL_SHIFT);
}
ADC_SCANCTRL(adc) =
(ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_INPUTSEL_MASK) |
(val & ADC_SCANCTRL_INPUTSEL_MASK);
}
/**
* Set scan resolution of conversion
* @param[in] adc ADC (use ADCx)
* @param[in] res Resolution (use ADC_SCANCTRL_RES_*)
*/
void adc_set_scan_resolution(uint32_t adc, uint32_t res)
{
ADC_SCANCTRL(adc) =
(ADC_SCANCTRL(adc) & ~ADC_SCANCTRL_RES_MASK) | res;
}
/**
* Set scan left aligned output
* @param[in] adc ADC (use ADCx)
*/
void adc_set_scan_left_aligned(uint32_t adc)
{
ADC_SCANCTRL(adc) |= ADC_SCANCTRL_ADJ;
}
/**
* Set scan right aligned output
* @param[in] adc ADC (use ADCx)
*/
void adc_set_scan_right_aligned(uint32_t adc)
{
ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_ADJ;
}
/**
* Set scan single ended conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_set_scan_single_ended(uint32_t adc)
{
ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_DIFF;
}
/**
* Set scan differential conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_set_scan_differential(uint32_t adc)
{
ADC_SCANCTRL(adc) |= ADC_SCANCTRL_DIFF;
}
/**
* Enable scan repeated conversion
* @param[in] adc ADC (use ADCx)
* @note In SINGLE mode, channel is repeated
* @note In SCAN mode, channel sequence is repeated
*/
void adc_enable_scan_repeat_conv(uint32_t adc)
{
ADC_SCANCTRL(adc) |= ADC_SCANCTRL_REP;
}
/**
* Disable scan repeated conversion
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_scan_repeat_conv(uint32_t adc)
{
ADC_SCANCTRL(adc) &= ~ADC_SCANCTRL_REP;
}
/**
* Enable single result overflow interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_single_result_overflow_interrupt(uint32_t adc)
{
ADC_IEN(adc) |= ADC_IEN_SINGLEOF;
}
/**
* Disable single result overflow interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_single_result_overflow_interrupt(uint32_t adc)
{
ADC_IEN(adc) &= ~ADC_IEN_SINGLEOF;
}
/**
* Enable single conversion complete interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_single_conversion_complete_interrupt(uint32_t adc)
{
ADC_IEN(adc) |= ADC_IEN_SINGLE;
}
/**
* Disable single conversion complete interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_single_conversion_complete_interrupt(uint32_t adc)
{
ADC_IEN(adc) &= ~ADC_IEN_SINGLE;
}
/**
* Enable scan result overflow interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_scan_result_overflow_interrupt(uint32_t adc)
{
ADC_IEN(adc) |= ADC_IEN_SCANOF;
}
/**
* Disable scan result overflow interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_scan_result_overflow_interrupt(uint32_t adc)
{
ADC_IEN(adc) &= ~ADC_IEN_SCANOF;
}
/**
* Disable scan conversion complete interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_enable_scan_conversion_complete_interrupt(uint32_t adc)
{
ADC_IEN(adc) |= ADC_IEN_SCAN;
}
/**
* Disable scan conversion complete interrupt
* @param[in] adc ADC (use ADCx)
*/
void adc_disable_scan_conversion_complete_interrupt(uint32_t adc)
{
ADC_IEN(adc) &= ~ADC_IEN_SCAN;
}
/**
* Get single result overflow flag
* @param[in] adc ADC (use ADCx)
* @retval true if flag set
* @retval false if flag is not set
*/
bool adc_get_single_result_overflow_flag(uint32_t adc)
{
return (ADC_IF(adc) & ADC_IF_SCANOF) != 0;
}
/**
* Get single conversion complete flag
* @param[in] adc ADC (use ADCx)
* @retval true if flag set
* @retval false if flag is not set
*/
bool adc_get_single_conversion_complete_flag(uint32_t adc)
{
return (ADC_IF(adc) & ADC_IF_SINGLE) != 0;
}
/**
* Get scan result overflow flag
* @param[in] adc ADC (use ADCx)
* @retval true if flag set
* @retval false if flag is not set
*/
bool adc_get_scan_result_overflow_flag(uint32_t adc)
{
return (ADC_IF(adc) & ADC_IF_SCANOF) != 0;
}
/**
* Get scan conversion complete flag
* @param[in] adc ADC (use ADCx)
* @retval true if flag is set
* @retval false if flag is not set
*/
bool adc_get_scan_conversion_complete_flag(uint32_t adc)
{
return (ADC_IF(adc) & ADC_IF_SCAN) != 0;
}
/**
* Set single result overflow flag
* @param[in] adc ADC (use ADCx)
*/
void adc_set_single_result_overflow_flag(uint32_t adc)
{
ADC_IFS(adc) = ADC_IFS_SINGLEOF;
}
/**
* Set single conversion complete flag
* @param[in] adc ADC (use ADCx)
*/
void adc_set_single_conversion_complete_flag(uint32_t adc)
{
ADC_IFS(adc) = ADC_IFS_SINGLE;
}
/**
* Set scan result overflow flag
* @param[in] adc ADC (use ADCx)
*/
void adc_set_scan_result_overflow_flag(uint32_t adc)
{
ADC_IFS(adc) = ADC_IFS_SCANOF;
}
/**
* Set scan conversion complete flag
* @param[in] adc ADC (use ADCx)
*/
void adc_set_scan_conversion_complete_flag(uint32_t adc)
{
ADC_IFS(adc) = ADC_IFS_SCAN;
}
/**
* Clear single result overflow flag
* @param[in] adc ADC (use ADCx)
*/
void adc_clear_single_result_overflow_flag(uint32_t adc)
{
ADC_IFC(adc) = ADC_IFC_SINGLEOF;
}
/**
* Clear single conversion complete flag
* @param[in] adc ADC (use ADCx)
*/
void adc_clear_single_conversion_complete_flag(uint32_t adc)
{
ADC_IFC(adc) = ADC_IFC_SINGLE;
}
/**
* Clear scan result overflow flag
* @param[in] adc ADC (use ADCx)
*/
void adc_clear_scan_result_overflow_flag(uint32_t adc)
{
ADC_IFC(adc) = ADC_IFC_SCANOF;
}
/**
* Clear scan conversion complete flag
* @param[in] adc ADC (use ADCx)
*/
void adc_clear_scan_conversion_complete_flag(uint32_t adc)
{
ADC_IFC(adc) = ADC_IFC_SCAN;
}
/**
* Get result from last scan conversion
* @param[in] adc ADC (use ADCx)
* @return result
*/
uint32_t adc_single_data(uint32_t adc)
{
return ADC_SINGLEDATA(adc);
}
/**
* Get result from last scan conversion
* @param[in] adc ADC (use ADCx)
* @return result
*/
uint32_t adc_scan_data(uint32_t adc)
{
return ADC_SCANDATA(adc);
}
/**
* Get result from last single conversion (peak)
* Reading result using this function will not clear
* SINGLEDV in ADC_STATUS or SINGLE DMA request.
* @param[in] adc ADC (use ADCx)
* @return result
*/
uint32_t adc_single_data_peak(uint32_t adc)
{
return ADC_SINGLEDATAP(adc);
}
/**
* Get result from last scan conversion (peak)
* Reading result using this function will not clear
* SCANDV in ADC_STATUS or SCAN DMA request.
* @param[in] adc ADC (use ADCx)
* @return result
*/
uint32_t adc_scan_data_peak(uint32_t adc)
{
return ADC_SCANDATAP(adc);
}
/**
* Set ADC scan gain calibration
* @param[in] adc ADC (use ADCx)
* @param scan_gain calibration of gain for internal ref
*/
void adc_set_calibration_scan_gain(uint32_t adc, uint8_t scan_gain)
{
ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SCANGAIN_MASK) | scan_gain;
}
/**
* Set ADC scan offset calibration
* @param[in] adc ADC (use ADCx)
* @param scan_offset calibration of offset for internal ref
*/
void adc_set_calibration_scan_offset(uint32_t adc, uint8_t scan_offset)
{
ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SCANOFF_MASK) | scan_offset;
}
/**
* Set ADC single gain calibration
* @param[in] adc ADC (use ADCx)
* @param single_gain calibration of gain for internal ref
*/
void adc_set_calibration_single_gain(uint32_t adc, uint8_t single_gain)
{
ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SINGLEGAIN_MASK) | single_gain;
}
/**
* Set ADC single offset calibration
* @param[in] adc ADC (use ADCx)
* @param single_offset calibration of offset for internal ref
*/
void adc_set_calibration_single_offset(uint32_t adc, uint8_t single_offset)
{
ADC_CAL(adc) = (ADC_CAL(adc) & ADC_CAL_SINGLEOFF_MASK) | single_offset;
}
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup burtc_file BURTC peripheral API
* @ingroup peripheral_apis
* @brief Backup RTC helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/burtc.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,279 @@
/** @addtogroup cmu_file CMU peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/cmu.h>
#include <libopencm3/efm32/msc.h>
/**@{*/
/**
* Enable CMU registers lock.
*/
void cmu_enable_lock(void)
{
CMU_LOCK = CMU_LOCK_LOCKKEY_LOCK;
}
/**
* Disable CMU registers lock
*/
void cmu_disable_lock(void)
{
CMU_LOCK = CMU_LOCK_LOCKKEY_UNLOCK;
}
/**
* Get CMU register lock flag
* @retval true if flag is set
* @retval false if flag is not set
*/
bool cmu_get_lock_flag(void)
{
return (CMU_LOCK & CMU_LOCK_LOCKKEY_MASK) == CMU_LOCK_LOCKKEY_LOCKED;
}
#define _CMU_REG(i) MMIO32(CMU_BASE + ((i) >> 5))
#define _CMU_BIT(i) (1 << ((i) & 0x1f))
/**
* @brief Enable Peripheral Clock in running mode.
*
* Enable the clock on particular peripheral.
*
* @param[in] clken Peripheral Name
*
* For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for
* example)
*/
void cmu_periph_clock_enable(enum cmu_periph_clken clken)
{
_CMU_REG(clken) |= _CMU_BIT(clken);
}
/**
* @brief Disable Peripheral Clock in running mode.
* Disable the clock on particular peripheral.
*
* @param[in] clken Peripheral Name
*
* For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for
* example)
*/
void cmu_periph_clock_disable(enum cmu_periph_clken clken)
{
_CMU_REG(clken) &= ~_CMU_BIT(clken);
}
/**
* Turn on Oscillator
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_osc_on(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_HFRCOEN;
break;
case LFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_LFRCOEN;
break;
case ULFRCO:
/* TODO: but how? */
break;
case HFXO:
CMU_OSCENCMD = CMU_OSCENCMD_HFXOEN;
break;
case LFXO:
CMU_OSCENCMD = CMU_OSCENCMD_LFXOEN;
break;
case AUXHFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
break;
}
}
/**
* Turn off Oscillator
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_osc_off(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS;
break;
case LFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_LFRCODIS;
break;
case ULFRCO:
/* TODO: but how? */
break;
case HFXO:
CMU_OSCENCMD = CMU_OSCENCMD_HFXODIS;
break;
case LFXO:
CMU_OSCENCMD = CMU_OSCENCMD_LFXODIS;
break;
case AUXHFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCODIS;
break;
}
}
/**
* Get Oscillator read flag
* @param[in] osc enum cmu_osc Oscillator name
* @retval true if flag is set
* @retval false if flag is not set
*/
bool cmu_osc_ready_flag(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
return (CMU_STATUS & CMU_STATUS_HFRCORDY) != 0;
break;
case LFRCO:
return (CMU_STATUS & CMU_STATUS_LFRCORDY) != 0;
break;
case ULFRCO:
/* TODO: but how? */
break;
case HFXO:
return (CMU_STATUS & CMU_STATUS_HFXORDY) != 0;
break;
case LFXO:
return (CMU_STATUS & CMU_STATUS_LFXORDY) != 0;
break;
case AUXHFRCO:
return (CMU_STATUS & CMU_STATUS_AUXHFRCORDY) != 0;
break;
}
return false;
}
/**
* Wait till oscillator is not ready
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_wait_for_osc_ready(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
while ((CMU_STATUS & CMU_STATUS_HFRCORDY) == 0);
break;
case LFRCO:
while ((CMU_STATUS & CMU_STATUS_LFRCORDY) == 0);
break;
case ULFRCO:
/* TODO: but how? */
break;
case HFXO:
while ((CMU_STATUS & CMU_STATUS_HFXORDY) == 0);
break;
case LFXO:
while ((CMU_STATUS & CMU_STATUS_LFXORDY) == 0);
break;
case AUXHFRCO:
while ((CMU_STATUS & CMU_STATUS_AUXHFRCORDY) == 0);
break;
}
}
/**
* Set HFCLK clock source
* @param[in] osc enum cmu_osc Oscillator name
* @note calling cmu_set_hfclk_source() do not set source immediately, use
* @a cmu_get_hfclk_source() to verify that the source has been set.
* @see cmu_get_hfclk_source()
*/
void cmu_set_hfclk_source(enum cmu_osc osc)
{
switch (osc) {
case HFXO:
CMU_CMD = CMU_CMD_HFCLKSEL_HFXO;
break;
case HFRCO:
CMU_CMD = CMU_CMD_HFCLKSEL_HFRCO;
break;
case LFXO:
CMU_CMD = CMU_CMD_HFCLKSEL_LFXO;
break;
case LFRCO:
CMU_CMD = CMU_CMD_HFCLKSEL_LFRCO;
break;
default:
/* not applicable */
return;
}
}
enum cmu_osc cmu_get_hfclk_source(void)
{
uint32_t status = CMU_STATUS;
if (status & CMU_STATUS_LFXOSEL) {
return LFXO;
} else if (status & CMU_STATUS_LFRCOSEL) {
return LFRCO;
} else if (status & CMU_STATUS_HFXOSEL) {
return HFXO;
} else if (status & CMU_STATUS_HFRCOSEL) {
return HFRCO;
}
/* never reached */
return (enum cmu_osc) -1;
}
/**
* HFXO output 48Mhz and core running at 48Mhz
*/
void cmu_clock_setup_in_hfxo_out_48mhz(void)
{
/* configure HFXO and prescaler */
CMU_HFCORECLKDIV = CMU_HFCORECLKDIV_HFCORECLKDIV_NODIV
| CMU_HFCORECLKDIV_HFCORECLKLEDIV;
CMU_CTRL = (CMU_CTRL
& ~(CMU_CTRL_HFCLKDIV_MASK | CMU_CTRL_HFXOBUFCUR_MASK))
| (CMU_CTRL_HFCLKDIV_NODIV
| CMU_CTRL_HFXOBUFCUR_BOOSTABOVE32MHZ);
/* enable HFXO */
cmu_osc_on(HFXO);
/* wait for HFXO */
cmu_wait_for_osc_ready(HFXO);
/* set flash wait state */
MSC_READCTRL = (MSC_READCTRL & ~MSC_READCTRL_MODE_MASK)
| MSC_READCTRL_MODE_WS2;
/* switch to HFXO */
cmu_set_hfclk_source(HFXO);
/* wait till HFXO not selected */
while (cmu_get_hfclk_source() != HFXO);
}
/**@}*/

View File

@@ -0,0 +1,175 @@
/** @addtogroup dac_file DAC peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY
{
} without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/dac.h>
/**@{*/
/**
* Set DAC refresh cycle
* @param[in] dac DAC (use DACx)
* @param[in] refrsel (use DAC_CTRL_REFRSEL_*CYCLES)
* @see dac_disable_auto_refresh()
* @see dac_enable_auto_refresh()
*/
void dac_set_refresh_cycle(uint32_t dac, uint32_t refrsel)
{
DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_REFRSEL_MASK) | refrsel;
}
/**
* Set DAC clock prescaler
* @param[in] dac DAC (use DACx)
* @param[in] presc Prescaler (use DAC_CTRL_PRESC_*)
*/
void dac_set_clock_prescaler(uint32_t dac, uint32_t presc)
{
DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_PRESC_MASK) | presc;
}
/**
* Set DAC reference
* @param[in] dac DAC (use DACx)
* @param[in] refsel Reference (DAC_CTRL_REFSEL_*)
*/
void dac_set_reference(uint32_t dac, uint32_t refsel)
{
DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_REFSEL_MASK) | refsel;
}
/**
* Set DAC output mode
* @param[in] dac DAC (use DACx)
* @param[in] outmode Output mode (DAC_CTRL_OUTMODE_*)
*/
void dac_set_out_mode(uint32_t dac, uint32_t outmode)
{
DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_OUTMODE_MASK) | outmode;
}
/**
* Set conversion mode
* @param[in] dac DAC (use DACx)
* @param[in] convmode Conversion mode (use DAC_CTRL_CONVMODE_*)
*/
void dac_set_conversion_mode(uint32_t dac, uint32_t convmode)
{
DAC_CTRL(dac) = (DAC_CTRL(dac) & ~DAC_CTRL_CONVMODE_MASK) | convmode;
}
/**
* Enable Sine wave on output
* @param[in] dac DAC (use DACx)
*/
void dac_enable_sine(uint32_t dac)
{
DAC_CTRL(dac) |= DAC_CTRL_SINMODE;
}
/**
* Disable Sine wave on output
* @param[in] dac DAC (use DACx)
*/
void dac_disable_sine(uint32_t dac)
{
DAC_CTRL(dac) &= ~DAC_CTRL_SINMODE;
}
/**
* Set PRS trigger source on DAC channel
* @param[in] dac DAC (use DACx)
* @param[in] dac_chan DAC Channel (use DAC_CHx)
* @param[in] prs_chan PRS Channel (use PRS_CHx)
*/
void dac_set_prs_trigger(uint32_t dac, enum dac_ch dac_chan,
enum prs_ch prs_chan)
{
uint32_t ch_ctrl = DAC_CHx_CTRL(dac, dac_chan);
ch_ctrl &= DAC_CH_CTRL_PRSSEL_MASK;
ch_ctrl |= DAC_CH_CTRL_PRSSEL(prs_chan);
DAC_CHx_CTRL(dac, dac_chan) = ch_ctrl;
}
/**
* Enable PRS triggerring
* @param[in] dac DAC (use DACx)
* @param[in] ch DAC Channel (use DAC_CHx)
*/
void dac_enable_prs_trigger(uint32_t dac, enum dac_ch ch)
{
DAC_CHx_CTRL(dac, ch) |= DAC_CH_CTRL_PRSEN;
}
/**
* Disable PRS triggerring
* @param[in] dac DAC (use DACx)
* @param[in] ch DAC Channel (use DAC_CHx)
*/
void dac_disable_prs_trigger(uint32_t dac, enum dac_ch ch)
{
DAC_CHx_CTRL(dac, ch) &= ~DAC_CH_CTRL_PRSEN;
}
/**
* Enable auto refresh
* @param[in] dac DAC (use DACx)
* @param[in] ch DAC Channel (use DAC_CHx)
*/
void dac_enable_auto_refresh(uint32_t dac, enum dac_ch ch)
{
DAC_CHx_CTRL(dac, ch) |= DAC_CH_CTRL_REFREN;
}
/**
* Disable auto refresh
* @param[in] dac DAC (use DACx)
* @param[in] ch DAC Channel (use DAC_CHx)
*/
void dac_disable_auto_refresh(uint32_t dac, enum dac_ch ch)
{
DAC_CHx_CTRL(dac, ch) &= ~DAC_CH_CTRL_REFREN;
}
/**
* Enable channel
* @param[in] dac DAC (use DACx)
* @param[in] ch DAC Channel (use DAC_CHx)
*/
void dac_enable_channel(uint32_t dac, enum dac_ch ch)
{
DAC_CHx_CTRL(dac, ch) |= DAC_CH_CTRL_EN;
}
/**
* Disable channel
* @param[in] dac DAC (use DACx)
* @param[in] ch DAC Channel (use DAC_CHx)
*/
void dac_disable_channel(uint32_t dac, enum dac_ch ch)
{
DAC_CHx_CTRL(dac, ch) &= ~DAC_CH_CTRL_REFREN;
}
/**@}*/

View File

@@ -0,0 +1,627 @@
/** @addtogroup dma_file DMA peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/dma.h>
/**@{*/
#define CHANNEL_SUPPORT_LOOP(ch) (((ch) == DMA_CH0) || ((ch) == DMA_CH1))
/**
* Enable DMA with privileged access
* @see dma_enable_with_unprivileged_access()
*/
void dma_enable_with_privileged_access(void)
{
DMA_CONFIG = DMA_CONFIG_EN | DMA_CONFIG_CHPROT;
}
/**
* Enable DMA with un-privileged access
* @see dma_enable_with_privileged_access()
*/
void dma_enable_with_unprivileged_access(void)
{
DMA_CONFIG = DMA_CONFIG_EN;
}
/**
* same as @a dma_enable_with_unprivileged_access()
* @see dma_enable_with_unprivileged_access()
*/
void dma_enable(void)
{
dma_enable_with_unprivileged_access();
}
/**
* Disable DMA
*/
void dma_disable(void)
{
DMA_CONFIG = 0;
}
/**
* Set channel's descriptor address
* @param[in] desc_base Address of channel's descriptor address
* @note @a desc_base 8LSB's should be 0x00
*/
void dma_set_desc_address(uint32_t desc_base)
{
if (desc_base & 0xFF) {
return;
}
DMA_CTRLBASE = desc_base;
}
/**
* Get channel wait on request status flag
* @retval true if flag is set
* @retval false if flag is not set
*/
bool dma_get_wait_on_request_flag(enum dma_ch ch)
{
uint32_t mask = DMA_CHWAITSTATUS_CHxWAITSTATUS(ch);
return (DMA_CHWAITSTATUS & mask) != 0;
}
/**
* Generate a software request on channel
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_generate_software_request(enum dma_ch ch)
{
DMA_CHSWREQ = DMA_CHSWREQ_CHxSWREQ(ch);
}
/**
* Enable channel burst only
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_burst_only(enum dma_ch ch)
{
DMA_CHUSEBURSTS = DMA_CHUSEBURSTS_CHxSUSEBURSTS(ch);
}
/**
* Enable channel single and burst
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_single_and_burst(enum dma_ch ch)
{
DMA_CHUSEBURSTC = DMA_CHUSEBURSTC_CHxSUSEBURSTC(ch);
}
/**
* Enable channel peripherial request
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_periph_request(enum dma_ch ch)
{
DMA_CHREQMASKC = DMA_CHREQMASKC_CHxSREQMASKC(ch);
}
/**
* Disable channel peripherial request
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_disable_periph_request(enum dma_ch ch)
{
DMA_CHREQMASKS = DMA_CHREQMASKS_CHxSREQMASKS(ch);
}
/**
* Enable channel
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_channel(enum dma_ch ch)
{
DMA_CHENS = DMA_CHENS_CHxSENS(ch);
}
/**
* Disable channel
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_disable_channel(enum dma_ch ch)
{
DMA_CHENC = DMA_CHENC_CHxSENC(ch);
}
/**
* Disable channel alternate structure
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_disable_alternate_structure(enum dma_ch ch)
{
DMA_CHALTC = DMA_CHALTC_CHxSALTC(ch);
}
/**
* Enable channel alternate structure
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_alternate_structure(enum dma_ch ch)
{
DMA_CHALTS = DMA_CHALTS_CHxSALTS(ch);
}
/**
* Enable channel high priority
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_priority(enum dma_ch ch)
{
DMA_CHPRIS = DMA_CHPRIS_CHxSPRIC(ch);
}
/**
* Disable channel high priority
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_disable_priority(enum dma_ch ch)
{
DMA_CHPRIC = DMA_CHPRIC_CHxSPRIC(ch);
}
/**
* Get bus error flag
* @retval true if flag is set
* @retval false if flag is not set
*/
bool dma_get_bus_error_flag(void)
{
return (DMA_ERRORC & DMA_ERRORC_ERRORC) != 0;
}
/**
* Clear bus error flag
*/
void dma_clear_bus_error_flag(void)
{
DMA_ERRORC = DMA_ERRORC_ERRORC;
}
/**
* Get channel request flag
* @param[in] ch Channel (use DMA_CHx)
* @retval true if flag is set
* @retval false if flag is not set
*/
bool dma_get_request_flag(enum dma_ch ch)
{
uint32_t mask = DMA_CHREQSTATUS_CHxSREQSTATUS(ch);
return (DMA_CHREQSTATUS & mask) != 0;
}
/**
* Get bus error interrupt flag
* @retval true if flag is set
* @retval false if flag is not set
*/
bool dma_get_bus_error_interrupt_flag(void)
{
return (DMA_IF & DMA_IF_ERR) != 0;
}
/**
* Get channel done interrupt flag
* @param[in] ch Channel (use DMA_CHx)
* @retval true if flag is set
* @retval false if flag is not set
*
*/
bool dma_get_done_interrupt_flag(enum dma_ch ch)
{
return (DMA_IF & DMA_IF_CHxDONE(ch)) != 0;
}
/**
* Set bus error interrupt flag
*/
void dma_set_bus_error_interrupt_flag(void)
{
DMA_IFS = DMA_IFS_ERR;
}
/**
* Set channel done interrupt flag
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_set_done_interrupt_flag(enum dma_ch ch)
{
DMA_IFS = DMA_IFS_CHxDONE(ch);
}
/**
* Clear bus error interrupt flag
*/
void dma_clear_bus_error_interrupt_flag(void)
{
DMA_IFC = DMA_IFC_ERR;
}
/**
* Clear channel done interrupt flag
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_clear_done_interrupt_flag(enum dma_ch ch)
{
DMA_IFC = DMA_IFC_CHxDONE(ch);
}
/**
* Enable bus error interrupt
*/
void dma_enable_bus_error_interrupt(void)
{
DMA_IEN |= DMA_IEN_ERR;
}
/**
* Disable bus error interrupt
*/
void dma_disable_bus_error_interrupt(void)
{
DMA_IEN &= ~DMA_IEN_ERR;
}
/**
* Enable channel done interrupt
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_done_interrupt(enum dma_ch ch)
{
DMA_IEN |= DMA_IEN_CHxDONE(ch);
}
/**
* Disable channel done interrupt
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_disable_done_interrupt(enum dma_ch ch)
{
DMA_IEN &= ~DMA_IEN_CHxDONE(ch);
}
/**
* Set channel source
* @param[in] ch Channel (use DMA_CHx)
* @param[in] source Source (use DMA_CH_CTRL_SOURCESEL_*)
*/
void dma_set_source(enum dma_ch ch, uint32_t source)
{
DMA_CHx_CTRL(ch) = (DMA_CHx_CTRL(ch) & ~DMA_CH_CTRL_SOURCESEL_MASK)
| source;
}
/**
* Set channel source signal
* @param[in] ch Channel (use DMA_CHx)
* @param[in] signal Signal (use DMA_CH_CTRL_SIGSEL_*)
*/
void dma_set_signal(enum dma_ch ch, uint32_t signal)
{
DMA_CHx_CTRL(ch) = (DMA_CHx_CTRL(ch) & ~DMA_CH_CTRL_SIGSEL_MASK)
| signal;
}
/**
* Reset channel
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_channel_reset(enum dma_ch ch)
{
/* Disable channel */
DMA_CHENC = DMA_CHENC_CHxSENC(ch);
/* reset channel alternate desc */
DMA_CHALTC = DMA_CHALTC_CHxSALTC(ch);
/* reset channel priority */
DMA_CHPRIC = DMA_CHPRIC_CHxSPRIC(ch);
/* clear channel interrupt */
DMA_IFC = DMA_IFC_CHxDONE(ch);
/* disable loop */
if (CHANNEL_SUPPORT_LOOP(ch)) {
DMA_LOOPx(ch) = 0;
}
/* reset signal {source, select} */
DMA_CHx_CTRL(ch) = 0;
}
/**
* Set channel loop width to ( @a count + 1)
* @param[in] ch Channel (use DMA_CHx)
* @param[in] count Count
* @note @a count is expected to be equal to (n_minus_1 + 1)
*/
void dma_set_loop_count(enum dma_ch ch, uint16_t count)
{
if (!CHANNEL_SUPPORT_LOOP(ch)) {
return;
}
DMA_LOOPx(ch) = (DMA_LOOPx(ch) & ~DMA_LOOP_WIDTH_MASK)
| DMA_LOOP_WIDTH(count - 1);
}
/**
* Enable channel loop
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_enable_loop(enum dma_ch ch)
{
if (!CHANNEL_SUPPORT_LOOP(ch)) {
return;
}
DMA_LOOPx(ch) |= DMA_LOOP_EN;
}
/**
* Disable channel loop
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_disable_loop(enum dma_ch ch)
{
if (!CHANNEL_SUPPORT_LOOP(ch)) {
return;
}
DMA_LOOPx(ch) &= ~DMA_LOOP_EN;
}
/**
* Set desination size
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] size Size (use DMA_MEM_*)
*/
void dma_desc_set_dest_size(uint32_t desc_base, enum dma_ch ch,
enum dma_mem size)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_DEST_SIZE_MASK;
cfg |= DMA_DESC_CH_CFG_DEST_SIZE(size);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**
* Set destination increment
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] inc Increment (use DMA_MEM_*)
*/
void dma_desc_set_dest_inc(uint32_t desc_base, enum dma_ch ch,
enum dma_mem inc)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_DEST_INC_MASK;
cfg |= DMA_DESC_CH_CFG_DEST_INC(inc);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**
* Set source size
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] size Size (use DMA_MEM_*)
*/
void dma_desc_set_src_size(uint32_t desc_base, enum dma_ch ch,
enum dma_mem size)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_SRC_SIZE_MASK;
cfg |= DMA_DESC_CH_CFG_SRC_SIZE(size);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**
* Set source increment
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] inc Increment (use DMA_MEM_*)
*/
void dma_desc_set_src_inc(uint32_t desc_base, enum dma_ch ch, enum dma_mem inc)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_SRC_INC_MASK;
cfg |= DMA_DESC_CH_CFG_SRC_INC(inc);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**
* Set R Power
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] r_power R Power (Use DMA_R_POWER_*)
*/
void dma_desc_set_r_power(uint32_t desc_base, enum dma_ch ch,
enum dma_r_power r_power)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_R_POWER_MASK;
cfg |= DMA_DESC_CH_CFG_R_POWER(r_power);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**
* Enable next useburst
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_desc_enable_next_useburst(uint32_t desc_base, enum dma_ch ch)
{
DMA_DESC_CHx_CFG(desc_base, ch) &= ~DMA_DESC_CH_CFG_NEXT_USEBURST;
}
/**
* Disable next useburst
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
*/
void dma_desc_disable_next_useburst(uint32_t desc_base, enum dma_ch ch)
{
DMA_DESC_CHx_CFG(desc_base, ch) |= DMA_DESC_CH_CFG_NEXT_USEBURST;
}
/**
* Set number (count) of transfer to be performed
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] count Count
*/
void dma_desc_set_count(uint32_t desc_base, enum dma_ch ch, uint16_t count)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_N_MINUS_1_MASK;
cfg |= DMA_DESC_CH_CFG_N_MINUS_1(count - 1);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**
* Store user data field in channel descriptor
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] user_data User data
*/
void dma_desc_set_user_data(uint32_t desc_base, enum dma_ch ch,
uint32_t user_data)
{
DMA_DESC_CHx_USER_DATA(desc_base, ch) = user_data;
}
/**
* Extract user data field from channel descriptor
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @return user data
*/
uint32_t dma_desc_get_user_data(uint32_t desc_base, enum dma_ch ch)
{
return DMA_DESC_CHx_USER_DATA(desc_base, ch);
}
/**
* Calculate end from start address.
*
* @details
* See "8.4.3.4 Address calculation" p68, EFM32LG-RM "d0183_Rev1.10"
*
* @param[in] start address to start of memory
* @param[in] inc Increment (use DMA_MEM_*)
* @param[in] n_minus_1 the number of transfers minus 1 (ie count - 1)
* @return the calculate end address
* @note can be used to calculate {source, destination} end address
*/
static inline uint32_t dma_calc_end_from_start(uint32_t start, uint8_t inc,
uint16_t n_minus_1)
{
switch (inc) {
case DMA_MEM_BYTE:
return start + n_minus_1;
case DMA_MEM_HALF_WORD:
return start + (n_minus_1 << 1);
case DMA_MEM_WORD:
return start + (n_minus_1 << 2);
case DMA_MEM_NONE:
return start;
}
return 0;
}
/**
* Assign Source address to DMA Channel
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] src_start Source data start address
* this function uses @ref dma_calc_end_from_start to calculate the
* src data end address from @a src_start
* @note dma_desc_set_count() should be called first.
* @note dma_desc_set_src_inc() should be called first.
*/
void dma_desc_set_src_address(uint32_t desc_base, enum dma_ch ch,
uint32_t src_start)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
uint8_t inc = (cfg & DMA_DESC_CH_CFG_SRC_INC_MASK)
>> DMA_DESC_CH_CFG_SRC_INC_SHIFT;
uint16_t n_minus_1 = (cfg & DMA_DESC_CH_CFG_N_MINUS_1_MASK)
>> DMA_DESC_CH_CFG_N_MINUS_1_SHIFT;
uint32_t src_end = dma_calc_end_from_start(src_start, inc, n_minus_1);
DMA_DESC_CHx_SRC_DATA_END_PTR(desc_base, ch) = src_end;
}
/**
* Assign Destination address to DMA Channel
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] dest_start Destination data start address
* this function uses @ref dma_calc_end_from_start to calculate the
* dest data end address from @a dest_start
* @note dma_desc_set_count() should be called first.
* @note dma_desc_set_dest_inc() should be called first.
*/
void dma_desc_set_dest_address(uint32_t desc_base, enum dma_ch ch,
uint32_t dest_start)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
uint8_t inc = (cfg & DMA_DESC_CH_CFG_DEST_INC_MASK)
>> DMA_DESC_CH_CFG_DEST_INC_SHIFT;
uint16_t n_minus_1 = (cfg & DMA_DESC_CH_CFG_N_MINUS_1_MASK)
>> DMA_DESC_CH_CFG_N_MINUS_1_SHIFT;
uint32_t dest_end = dma_calc_end_from_start(dest_start, inc,
n_minus_1);
DMA_DESC_CHx_DEST_DATA_END_PTR(desc_base, ch) = dest_end;
}
/**
* Set the channel mode ("Cycle control")
* @param[in] desc_base start of memory location that contain channel
* descriptor
* @param[in] ch Channel (use DMA_CHx)
* @param[in] mode Mode (use DMA_MODE_*)
*/
void dma_desc_set_mode(uint32_t desc_base, enum dma_ch ch, enum dma_mode mode)
{
uint32_t cfg = DMA_DESC_CHx_CFG(desc_base, ch);
cfg &= ~DMA_DESC_CH_CFG_CYCLE_CTRL_MASK;
cfg |= DMA_DESC_CH_CFG_CYCLE_CTRL(mode);
DMA_DESC_CHx_CFG(desc_base, ch) = cfg;
}
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup emu_file EMU peripheral API
* @ingroup peripheral_apis
* @brief Energy Management Unit helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/emu.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,182 @@
/** @addtogroup gpio_file GPIO peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/gpio.h>
/**@{*/
/**
* Enable GPIO registers lock.
* @see gpio_disable_lock()
* @see gpio_get_lock_flag()
*/
void gpio_enable_lock(void)
{
GPIO_LOCK = GPIO_LOCK_LOCKKEY_LOCK;
}
/**
* Disable GPIO registers lock.
* @see gpio_enable_lock()
* @see gpio_get_lock_flag()
*/
void gpio_disable_lock(void)
{
GPIO_LOCK = GPIO_LOCK_LOCKKEY_UNLOCK;
}
/**
* Get GPIO register lock flag
* @retval true if flag is set
* @retval false if flag is not set
* @see gpio_enable_lock()
* @see gpio_disable_lock()
*/
bool gpio_get_lock_flag(void)
{
return (GPIO_LOCK & GPIO_LOCK_LOCKKEY_MASK)
== GPIO_LOCK_LOCKKEY_LOCKED;
}
/**
* Set port pins drive strength
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] drive_stength Driver Stength (use GPIO_STENGTH_*)
*/
void gpio_set_drive_strength(uint32_t gpio_port,
enum gpio_drive_strength drive_stength)
{
GPIO_P_CTRL(gpio_port) = GPIO_P_CTRL_DRIVEMODE(drive_stength);
}
/**
* Set port pins mode
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] mode Mode (use GPIO_MODE_*)
* @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL,
* use bitwise OR '|' to separate)
*/
void gpio_mode_setup(uint32_t gpio_port, enum gpio_mode mode, uint16_t gpios)
{
unsigned i;
uint32_t high = GPIO_P_MODEH(gpio_port);
uint32_t low = GPIO_P_MODEL(gpio_port);
for (i = 0; i < 8; i++) {
if (gpios & (1 << i)) {
low &= ~GPIO_P_MODE_MODEx_MASK(i);
low |= GPIO_P_MODE_MODEx(i, mode);
}
if (gpios & (1 << (i + 8))) {
high &= ~GPIO_P_MODE_MODEx_MASK(i);
high |= GPIO_P_MODE_MODEx(i, mode);
}
}
GPIO_P_MODEL(gpio_port) = low;
GPIO_P_MODEH(gpio_port) = high;
}
/**
* Set port pins output value (Atomic)
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL,
* use bitwise OR '|' to separate)
*/
void gpio_set(uint32_t gpio_port, uint16_t gpios)
{
GPIO_P_DOUTSET(gpio_port) = gpios;
}
/**
* Set port pins output value (Atomic)
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL,
* use bitwise OR '|' to separate)
*/
void gpio_clear(uint32_t gpio_port, uint16_t gpios)
{
GPIO_P_DOUTCLR(gpio_port) = gpios;
}
/**
* Get port pins input value
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL,
* use bitwise OR '|' to separate)
* @return masked pins value (separated by bitwise OR '|')
*/
uint16_t gpio_get(uint32_t gpio_port, uint16_t gpios)
{
return GPIO_P_DIN(gpio_port) & gpios;
}
/**
* Toggle port pins output value (Atomic)
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL,
* use bitwise OR '|' to separate)
*/
void gpio_toggle(uint32_t gpio_port, uint16_t gpios)
{
GPIO_P_DOUTTGL(gpio_port) = gpios;
}
/**
* Get port (all) input value's
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @return all pins input value
*/
uint16_t gpio_port_read(uint32_t gpio_port)
{
return GPIO_P_DIN(gpio_port);
}
/**
* Set port (all) output value's
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] data Data (all pins output value)
*/
void gpio_port_write(uint32_t gpio_port, uint16_t data)
{
GPIO_P_DOUT(gpio_port) = data;
}
/**
* @brief Lock the Configuration of a Group of Pins
*
* The configuration of one or more pins of the given GPIO port is locked.
* There is no mechanism to unlock these via software. Unlocking occurs at the
* next reset.
*
* @param[in] gpio_port GPIO Port (use GPIO* ex. GPIOA, GPIOB, ....)
* @param[in] gpios (pins mask (use GPIO* ex . GPIO0, GPIO1 .... GPIO_ALL,
* use bitwise OR '|' to separate)
*/
void gpio_port_config_lock(uint32_t gpio_port, uint16_t gpios)
{
GPIO_P_PINLOCKN(gpio_port) = ~gpios;
}
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup i2c_file I2C peripheral API
* @ingroup peripheral_apis
* @brief I²C helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/i2c.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup letimer_file LETIMER peripheral API
* @ingroup peripheral_apis
* @brief Low Energy Timer helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/letimer.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup msc_file MSC peripheral API
* @ingroup peripheral_apis
* @brief Memory Systems Controller helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/msc.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,151 @@
/** @addtogroup prs_file PRS peripheral API
* @ingroup peripheral_apis
* @brief EFM32 Peripheral Reflex System (PRS).
* The Peripheral Reflex System (PRS) system is a network which allows the
* different peripheral modules to communicate directly with each other
* without involving the CPU.
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/prs.h>
/**@{*/
/**
* Enable PRS output to GPIO.
* @param[in] ch Channel (use PRS_CHx)
* @see prs_set_output_loc()
*/
void prs_enable_gpio_output(enum prs_ch ch)
{
PRS_ROUTE |= PRS_ROUTE_CHxPEN(ch);
}
/**
* Disable PRS output to GPIO.
* @param[in] ch Channel (use PRS_CHx)
* @see prs_set_output_loc()
*/
void prs_disable_gpio_output(enum prs_ch ch)
{
PRS_ROUTE &= ~PRS_ROUTE_CHxPEN(ch);
}
/**
* Location of the PRS to be output on GPIO.
* @param[in] loc location (use PRS_ROUTE_LOCATION_LOCx)
* @see prs_set_output_loc()
*/
void prs_set_output_loc(uint32_t loc)
{
PRS_ROUTE = (PRS_ROUTE & ~PRS_ROUTE_LOCATION_MASK) | loc;
}
/**
* Generate software pulse.
* @param[in] ch Channel (use PRS_CHx)
* @note the final output is dependent on "software level" value of the channel
* @see prs_software_level_high()
* @see prs_software_level_low()
*/
void prs_software_pulse(enum prs_ch ch)
{
PRS_SWPULSE = PRS_SWPULSE_CHxPULSE(ch);
}
/**
* HIGH is XOR'ed with the corresponding bit in the software-pulse and
* the PRS input signal to generate.
* @param[in] ch Channel (use PRS_CHx)
* @see prs_software_level_low()
* @see prs_software_pulse()
*/
void prs_software_level_high(enum prs_ch ch)
{
PRS_SWLEVEL |= PRS_SWLEVEL_CHxLEVEL(ch);
}
/**
* LOW is XOR'ed with the corresponding bit in the software-pulse and
* the PRS input signal to generate.
* @param[in] ch Channel (use PRS_CHx)
* @see prs_software_level_high()
* @see prs_software_pulse()
*/
void prs_software_level_low(enum prs_ch ch)
{
PRS_SWLEVEL &= ~PRS_SWLEVEL_CHxLEVEL(ch);
}
/**
* disable synchronization of this channel reflex signal
* @param[in] ch Channel (use PRS_CHx)
* @see prs_disable_async()
*/
void prs_enable_async(enum prs_ch ch)
{
PRS_CHx_CTRL(ch) |= PRS_CH_CTRL_ASYNC;
}
/**
* enable synchronization of this channel reflex signal
* @param[in] ch Channel (use PRS_CHx)
* @see prs_disable_async()
*/
void prs_disable_async(enum prs_ch ch)
{
PRS_CHx_CTRL(ch) &= ~PRS_CH_CTRL_ASYNC;
}
/**
* Edge detection for the channel
* @param[in] ch Channel (use PRS_CHx)
* @param[in] edge Edge (use PRS_CH_CTRL_EDSEL_*)
*/
void prs_set_edge(enum prs_ch ch, uint32_t edge)
{
PRS_CHx_CTRL(ch) = (PRS_CHx_CTRL(ch) & ~PRS_CH_CTRL_EDSEL_MASK) | edge;
}
/**
* Source for the channel
* @param[in] ch Channel (use PRS_CHx)
* @param[in] source Source (use PRS_CH_CTRL_SOURCESEL_*)
* @see prs_set_signal()
*/
void prs_set_source(enum prs_ch ch, uint32_t source)
{
PRS_CHx_CTRL(ch) = (PRS_CHx_CTRL(ch) & ~PRS_CH_CTRL_SOURCESEL_MASK)
| source;
}
/**
* Source for the channel
* @param[in] ch Channel (use PRS_CHx)
* @param[in] signal Signal (use PRS_CH_CTRL_SIGSEL_*)
* @see prs_set_source()
*/
void prs_set_signal(enum prs_ch ch, uint32_t signal)
{
PRS_CHx_CTRL(ch) = (PRS_CHx_CTRL(ch) & ~PRS_CH_CTRL_SIGSEL_MASK)
| signal;
}
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup rmu_file RMU peripheral API
* @ingroup peripheral_apis
* @brief Reset Management Unit helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/rmu.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,16 @@
/** @addtogroup rtc_file RTC peripheral API
* @ingroup peripheral_apis
* @brief Real Time Clock helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @sa rtc_defines
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/rtc.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,69 @@
/** @addtogroup timer_file TIMER peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/timer.h>
/**@{*/
#define HAS_DEAD_TIME_INSERTION(timer) (timer == TIMER0)
/**
* Start timer
* @param[in] timer Timer (use TIMERx)
*/
void timer_start(uint32_t timer)
{
TIMER_CMD(timer) = TIMER_CMD_START;
}
/**
* Stop timer
* @param[in] timer Timer (use TIMERx)
*/
void timer_stop(uint32_t timer)
{
TIMER_CMD(timer) = TIMER_CMD_STOP;
}
/** Clock division factor
* @param[in] timer Timer (use TIMERx)
* @param[in] presc Factor (use TIMER_CTRL_PRESC_DIV*)
* @note output-clock = input-clock / @a presc
*/
void timer_set_clock_prescaler(uint32_t timer, uint32_t presc)
{
TIMER_CTRL(timer) = (TIMER_CTRL(timer) & ~TIMER_CTRL_PRESC_MASK)
| TIMER_CTRL_PRESC(presc);
}
/**
* Start timer top value
* the timer reload after it reaches top value
* @param[in] timer Timer (use TIMERx)
* @param[in] top Top value
*/
void timer_set_top(uint32_t timer, uint32_t top)
{
TIMER_TOP(timer) = top;
}
/**@}*/

View File

@@ -0,0 +1,18 @@
/** @addtogroup usart_file UART/USART peripheral API
* @ingroup peripheral_apis
* @brief UART/USART helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @sa usart_defines
* @sa uart_defines
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/uart.h>
#include <libopencm3/efm32/usart.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,15 @@
/** @addtogroup wdog_file WDOG peripheral API
* @ingroup peripheral_apis
* @brief Watchdog Module helper functions.
*
* <b>NO</b> helper functions exist. Only header definitions are available.
* Delete these lines if/when you add actual helper APIs.
* @copyright See @ref lgpl_license
*/
#include <libopencm3/efm32/wdog.h>
/**@{*/
/**@}*/

View File

@@ -0,0 +1,65 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
## Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_ezr32wg
SRCLIBDIR ?= ../..
FAMILY = EZR32WG
FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m4 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS += acmp_common.o
OBJS += adc_common.o
OBJS += burtc_common.o
OBJS += cmu_common.o
OBJS += dac_common.o
OBJS += dma_common.o
OBJS += emu_common.o
OBJS += gpio_common.o
OBJS += i2c_common.o
OBJS += letimer_common.o
OBJS += msc_common.o
OBJS += prs_common.o
OBJS += rmu_common.o
OBJS += rtc_common.o
OBJS += timer_common.o
OBJS += usart_common.o
OBJS += wdog_common.o
OBJS += usb.o usb_control.o usb_standard.o usb_msc.o
OBJS += usb_hid.o
OBJS += usb_audio.o usb_cdc.o usb_midi.o
OBJS += usb_efm32.o
VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include

View File

@@ -0,0 +1,27 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/scb.h>
static void pre_main(void)
{
/* Enable access to Floating-Point coprocessor. */
SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11);
}

View File

@@ -0,0 +1,43 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_efm32g
SRCLIBDIR ?= ../..
FAMILY = EFM32G
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
TGT_CFLAGS += $(STANDARD_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS =
VPATH += ../:../../cm3
include ../../Makefile.include

View File

@@ -0,0 +1,43 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_efm32gg
SRCLIBDIR ?= ../..
FAMILY = EFM32GG
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
TGT_CFLAGS += $(STANDARD_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS =
VPATH += ../:../../cm3
include ../../Makefile.include

View File

@@ -0,0 +1,52 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
## Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
## Copyright (C) 2018 Seb Holzapfel <schnommus@gmail.com>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_efm32hg
SRCLIBDIR ?= ../..
FAMILY = EFM32HG
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m0plus $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
TGT_CFLAGS += $(STANDARD_FLAGS)
ARFLAGS = rcs
OBJS += cmu.o
OBJS += gpio_common.o
OBJS += timer_common.o
OBJS += usb.o usb_control.o usb_standard.o usb_msc.o
OBJS += usb_hid.o
OBJS += usb_audio.o usb_cdc.o usb_midi.o
OBJS += usb_dwc_common.o usb_efm32hg.o
VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include

View File

@@ -0,0 +1,314 @@
/** @addtogroup cmu_file CMU peripheral API
* @ingroup peripheral_apis
*/
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
* Copyright (C) 2018 Seb Holzapfel <schnommus@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/efm32/cmu.h>
/**@{*/
/**
* Enable CMU registers lock.
*/
void cmu_enable_lock(void)
{
CMU_LOCK = CMU_LOCK_LOCKKEY_LOCK;
}
/**
* Disable CMU registers lock
*/
void cmu_disable_lock(void)
{
CMU_LOCK = CMU_LOCK_LOCKKEY_UNLOCK;
}
/**
* Get CMU register lock flag
* @retval true if flag is set
* @retval false if flag is not set
*/
bool cmu_get_lock_flag(void)
{
return (CMU_LOCK & CMU_LOCK_LOCKKEY_MASK) == CMU_LOCK_LOCKKEY_LOCKED;
}
#define _CMU_REG(i) MMIO32(CMU_BASE + ((i) >> 5))
#define _CMU_BIT(i) (1 << ((i) & 0x1f))
/**
* @brief Enable Peripheral Clock in running mode.
*
* Enable the clock on particular peripheral.
*
* @param[in] clken Peripheral Name
*
* For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for
* example)
*/
void cmu_periph_clock_enable(enum cmu_periph_clken clken)
{
_CMU_REG(clken) |= _CMU_BIT(clken);
}
/**
* @brief Disable Peripheral Clock in running mode.
* Disable the clock on particular peripheral.
*
* @param[in] clken Peripheral Name
*
* For available constants, see @a enum::cmu_periph_clken (CMU_LEUART1 for
* example)
*/
void cmu_periph_clock_disable(enum cmu_periph_clken clken)
{
_CMU_REG(clken) &= ~_CMU_BIT(clken);
}
/**
* Turn on Oscillator
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_osc_on(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_HFRCOEN;
break;
case LFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_LFRCOEN;
break;
case USHFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_USHFRCOEN;
break;
case HFXO:
CMU_OSCENCMD = CMU_OSCENCMD_HFXOEN;
break;
case LFXO:
CMU_OSCENCMD = CMU_OSCENCMD_LFXOEN;
break;
case AUXHFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
break;
default:
/* not applicable */
break;
}
}
/**
* Turn off Oscillator
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_osc_off(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_HFRCODIS;
break;
case LFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_LFRCODIS;
break;
case USHFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_USHFRCODIS;
break;
case HFXO:
CMU_OSCENCMD = CMU_OSCENCMD_HFXODIS;
break;
case LFXO:
CMU_OSCENCMD = CMU_OSCENCMD_LFXODIS;
break;
case AUXHFRCO:
CMU_OSCENCMD = CMU_OSCENCMD_AUXHFRCODIS;
break;
default:
/* not applicable */
break;
}
}
/**
* Get Oscillator read flag
* @param[in] osc enum cmu_osc Oscillator name
* @retval true if flag is set
* @retval false if flag is not set
*/
bool cmu_osc_ready_flag(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
return (CMU_STATUS & CMU_STATUS_HFRCORDY) != 0;
break;
case LFRCO:
return (CMU_STATUS & CMU_STATUS_LFRCORDY) != 0;
break;
case USHFRCO:
return (CMU_STATUS & CMU_STATUS_USHFRCORDY) != 0;
break;
case HFXO:
return (CMU_STATUS & CMU_STATUS_HFXORDY) != 0;
break;
case LFXO:
return (CMU_STATUS & CMU_STATUS_LFXORDY) != 0;
break;
case AUXHFRCO:
return (CMU_STATUS & CMU_STATUS_AUXHFRCORDY) != 0;
break;
default:
/* not applicable */
break;
}
return false;
}
/**
* Wait while oscillator is not ready
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_wait_for_osc_ready(enum cmu_osc osc)
{
switch (osc) {
case HFRCO:
while ((CMU_STATUS & CMU_STATUS_HFRCORDY) == 0);
break;
case LFRCO:
while ((CMU_STATUS & CMU_STATUS_LFRCORDY) == 0);
break;
case USHFRCO:
while ((CMU_STATUS & CMU_STATUS_USHFRCORDY) == 0);
break;
case HFXO:
while ((CMU_STATUS & CMU_STATUS_HFXORDY) == 0);
break;
case LFXO:
while ((CMU_STATUS & CMU_STATUS_LFXORDY) == 0);
break;
case AUXHFRCO:
while ((CMU_STATUS & CMU_STATUS_AUXHFRCORDY) == 0);
break;
default:
/* not applicable */
break;
}
}
/**
* Set HFCLK clock source
* @param[in] osc enum cmu_osc Oscillator name
* @note calling cmu_set_hfclk_source() do not set source immediately, use
* @a cmu_get_hfclk_source() to verify that the source has been set.
* @see cmu_get_hfclk_source()
*/
void cmu_set_hfclk_source(enum cmu_osc osc)
{
switch (osc) {
case HFXO:
CMU_CMD = CMU_CMD_HFCLKSEL_HFXO;
break;
case HFRCO:
CMU_CMD = CMU_CMD_HFCLKSEL_HFRCO;
break;
case LFXO:
CMU_CMD = CMU_CMD_HFCLKSEL_LFXO;
break;
case LFRCO:
CMU_CMD = CMU_CMD_HFCLKSEL_LFRCO;
break;
case USHFRCODIV2:
CMU_CMD = CMU_CMD_HFCLKSEL_USHFRCODIV2;
break;
default:
/* not applicable */
return;
}
}
/**
* Get HFCLK clock source
* @retval enum cmu_osc Oscillator name
*/
enum cmu_osc cmu_get_hfclk_source(void)
{
uint32_t status = CMU_STATUS;
if (status & CMU_STATUS_LFXOSEL) {
return LFXO;
} else if (status & CMU_STATUS_LFRCOSEL) {
return LFRCO;
} else if (status & CMU_STATUS_HFXOSEL) {
return HFXO;
} else if (status & CMU_STATUS_HFRCOSEL) {
return HFRCO;
} else if (status & CMU_STATUS_USHFRCODIV2SEL) {
return USHFRCODIV2;
}
/* never reached */
return (enum cmu_osc) -1;
}
/**
* Set USBCLK clock source
* @param osc Oscillator name
*/
void cmu_set_usbclk_source(enum cmu_osc osc)
{
switch (osc) {
case LFXO:
CMU_CMD = CMU_CMD_USBCCLKSEL_LFXO;
break;
case LFRCO:
CMU_CMD = CMU_CMD_USBCCLKSEL_LFRCO;
break;
case USHFRCO:
CMU_CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
break;
default:
/* not applicable */
return;
}
}
/**
* Wait while USBCLK is not selected
* @param[in] osc enum cmu_osc Oscillator name
*/
void cmu_wait_for_usbclk_selected(enum cmu_osc osc)
{
switch (osc) {
case LFXO:
while ((CMU_STATUS & CMU_STATUS_USBCLFXOSEL) == 0);
break;
case LFRCO:
while ((CMU_STATUS & CMU_STATUS_USBCLFRCOSEL) == 0);
break;
case USHFRCO:
while ((CMU_STATUS & CMU_STATUS_USBCUSHFRCOSEL) == 0);
break;
default:
/* not applicable */
return;
}
}
/**@}*/

View File

@@ -0,0 +1,66 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
## Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_efm32lg
SRCLIBDIR ?= ../..
FAMILY = EFM32LG
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
TGT_CFLAGS += $(STANDARD_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS += acmp_common.o
OBJS += adc_common.o
OBJS += burtc_common.o
OBJS += cmu_common.o
OBJS += dac_common.o
OBJS += dma_common.o
OBJS += emu_common.o
OBJS += gpio_common.o
OBJS += i2c_common.o
OBJS += letimer_common.o
OBJS += msc_common.o
OBJS += prs_common.o
OBJS += rmu_common.o
OBJS += rtc_common.o
OBJS += timer_common.o
OBJS += usart_common.o
OBJS += wdog_common.o
OBJS += usb.o usb_control.o usb_standard.o usb_msc.o
OBJS += usb_hid.o
OBJS += usb_audio.o usb_cdc.o usb_midi.o
OBJS += usb_efm32.o
VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include

View File

@@ -0,0 +1,43 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_efm32tg
SRCLIBDIR ?= ../..
FAMILY = EFM32TG
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m3 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
TGT_CFLAGS += $(STANDARD_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS =
VPATH += ../:../../cm3
include ../../Makefile.include

View File

@@ -0,0 +1,65 @@
##
## This file is part of the libopencm3 project.
##
## Copyright (C) 2009 Uwe Hermann <uwe@hermann-uwe.de>
## Copyright (C) 2012 chrysn <chrysn@fsfe.org>
## Copyright (C) 2015 Kuldeep Singh Dhaka <kuldeepdhaka9@gmail.com>
##
## This library is free software: you can redistribute it and/or modify
## it under the terms of the GNU Lesser General Public License as published by
## the Free Software Foundation, either version 3 of the License, or
## (at your option) any later version.
##
## This library is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
## GNU Lesser General Public License for more details.
##
## You should have received a copy of the GNU Lesser General Public License
## along with this library. If not, see <http://www.gnu.org/licenses/>.
##
LIBNAME = libopencm3_efm32wg
SRCLIBDIR ?= ../..
FAMILY = EFM32WG
FP_FLAGS ?= -mfloat-abi=hard -mfpu=fpv4-sp-d16
CC = $(PREFIX)gcc
AR = $(PREFIX)ar
TGT_CFLAGS = -Os \
-Wall -Wextra -Wimplicit-function-declaration \
-Wredundant-decls -Wmissing-prototypes -Wstrict-prototypes \
-Wundef -Wshadow \
-I../../../include -fno-common \
-mcpu=cortex-m4 $(FP_FLAGS) -mthumb -Wstrict-prototypes \
-ffunction-sections -fdata-sections -MD -D$(FAMILY)
TGT_CFLAGS += $(DEBUG_FLAGS)
# ARFLAGS = rcsv
ARFLAGS = rcs
OBJS += acmp_common.o
OBJS += adc_common.o
OBJS += burtc_common.o
OBJS += cmu_common.o
OBJS += dac_common.o
OBJS += dma_common.o
OBJS += emu_common.o
OBJS += gpio_common.o
OBJS += i2c_common.o
OBJS += letimer_common.o
OBJS += msc_common.o
OBJS += prs_common.o
OBJS += rmu_common.o
OBJS += rtc_common.o
OBJS += timer_common.o
OBJS += usart_common.o
OBJS += wdog_common.o
OBJS += usb.o usb_control.o usb_standard.o usb_msc.o
OBJS += usb_hid.o
OBJS += usb_audio.o usb_cdc.o usb_midi.o
OBJS += usb_efm32.o
VPATH += ../../usb:../:../../cm3:../common
include ../../Makefile.include

View File

@@ -0,0 +1,27 @@
/*
* This file is part of the libopencm3 project.
*
* Copyright (C) 2010 Piotr Esden-Tempski <piotr@esden.net>
* Copyright (C) 2011 Fergus Noble <fergusnoble@gmail.com>
*
* This library is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include <libopencm3/cm3/scb.h>
static void pre_main(void)
{
/* Enable access to Floating-Point coprocessor. */
SCB_CPACR |= SCB_CPACR_FULL * (SCB_CPACR_CP10 | SCB_CPACR_CP11);
}