summaryrefslogtreecommitdiff
path: root/atmel-samd/asf4/samd21/hpl
diff options
context:
space:
mode:
authorDan Halbert <halbert@halwitz.org>2017-10-11 18:30:01 -0400
committerScott Shawcroft <scott@tannewt.org>2017-10-12 10:55:15 -0700
commitb7591cfd19d308091dc67ae698c112cdb52a044f (patch)
treee0138f82640a0e582baa87e6b041f497a8a5036c /atmel-samd/asf4/samd21/hpl
parent80654779e1ad98f5818186746e00b6b642dca3db (diff)
Replace asf4 tree with submodule repo adafruit/asf4, branch circuitpython.
Diffstat (limited to 'atmel-samd/asf4/samd21/hpl')
-rw-r--r--atmel-samd/asf4/samd21/hpl/adc/hpl_adc.c761
-rw-r--r--atmel-samd/asf4/samd21/hpl/adc/hpl_adc_base.h82
-rw-r--r--atmel-samd/asf4/samd21/hpl/core/hpl_core_m0plus_base.c210
-rw-r--r--atmel-samd/asf4/samd21/hpl/core/hpl_core_port.h71
-rw-r--r--atmel-samd/asf4/samd21/hpl/core/hpl_init.c69
-rw-r--r--atmel-samd/asf4/samd21/hpl/dac/hpl_dac.c248
-rw-r--r--atmel-samd/asf4/samd21/hpl/dmac/hpl_dmac.c226
-rw-r--r--atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk.c162
-rw-r--r--atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk_base.h91
-rw-r--r--atmel-samd/asf4/samd21/hpl/nvmctrl/hpl_nvmctrl.c684
-rw-r--r--atmel-samd/asf4/samd21/hpl/pm/hpl_pm.c87
-rw-r--r--atmel-samd/asf4/samd21/hpl/pm/hpl_pm_base.h213
-rw-r--r--atmel-samd/asf4/samd21/hpl/port/hpl_gpio_base.h172
-rw-r--r--atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc.c201
-rw-r--r--atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc_base.h62
-rw-r--r--atmel-samd/asf4/samd21/hpl/sercom/hpl_sercom.c2897
-rw-r--r--atmel-samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c265
-rw-r--r--atmel-samd/asf4/samd21/hpl/systick/hpl_systick.c113
-rw-r--r--atmel-samd/asf4/samd21/hpl/tc/hpl_tc.c369
-rw-r--r--atmel-samd/asf4/samd21/hpl/tc/hpl_tc_base.h87
-rw-r--r--atmel-samd/asf4/samd21/hpl/usb/hpl_usb.c2051
21 files changed, 0 insertions, 9121 deletions
diff --git a/atmel-samd/asf4/samd21/hpl/adc/hpl_adc.c b/atmel-samd/asf4/samd21/hpl/adc/hpl_adc.c
deleted file mode 100644
index 7f2e9fca1..000000000
--- a/atmel-samd/asf4/samd21/hpl/adc/hpl_adc.c
+++ /dev/null
@@ -1,761 +0,0 @@
-/**
- * \file
- *
- * \brief SAM Analog Digital Converter
- *
- * Copyright (C) 2015-2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_adc_async.h>
-#include <hpl_adc_dma.h>
-#include <hpl_adc_sync.h>
-#include <utils_assert.h>
-#include <utils_repeat_macro.h>
-#include <hpl_adc_config.h>
-
-#define ADC_CONFIGURATION(n) \
- { \
- (n), (CONF_ADC_##n##_RUNSTDBY << ADC_CTRLA_RUNSTDBY_Pos) | (CONF_ADC_##n##_ENABLE << ADC_CTRLA_ENABLE_Pos), \
- (CONF_ADC_##n##_REFCOMP << ADC_REFCTRL_REFCOMP_Pos) | ADC_REFCTRL_REFSEL(CONF_ADC_##n##_REFSEL), \
- ADC_AVGCTRL_ADJRES(CONF_ADC_##n##_ADJRES) | ADC_AVGCTRL_SAMPLENUM(CONF_ADC_##n##_SAMPLENUM), \
- ADC_SAMPCTRL_SAMPLEN(CONF_ADC_##n##_SAMPLEN), \
- ADC_CTRLB_PRESCALER(CONF_ADC_##n##_PRESCALER) | (CONF_ADC_##n##_RESSEL << ADC_CTRLB_RESSEL_Pos) \
- | (CONF_ADC_##n##_CORREN << ADC_CTRLB_CORREN_Pos) | (CONF_ADC_##n##_FREERUN << ADC_CTRLB_FREERUN_Pos) \
- | (CONF_ADC_##n##_LEFTADJ << ADC_CTRLB_LEFTADJ_Pos) \
- | (CONF_ADC_##n##_DIFFMODE << ADC_CTRLB_DIFFMODE_Pos), \
- CONF_ADC_##n##_WINMODE, \
- ADC_INPUTCTRL_GAIN(CONF_ADC_##n##_GAIN) | ADC_INPUTCTRL_INPUTOFFSET(CONF_ADC_##n##_INPUTOFFSET) \
- | ADC_INPUTCTRL_INPUTSCAN(CONF_ADC_##n##_INPUTSCAN) \
- | (CONF_ADC_##n##_MUXNEG << ADC_INPUTCTRL_MUXNEG_Pos) \
- | (CONF_ADC_##n##_MUXPOS << ADC_INPUTCTRL_MUXPOS_Pos), \
- (CONF_ADC_##n##_WINMONEO << ADC_EVCTRL_WINMONEO_Pos) \
- | (CONF_ADC_##n##_RESRDYEO << ADC_EVCTRL_RESRDYEO_Pos) \
- | (CONF_ADC_##n##_SYNCEI << ADC_EVCTRL_SYNCEI_Pos) \
- | (CONF_ADC_##n##_STARTEI << ADC_EVCTRL_STARTEI_Pos), \
- CONF_ADC_##n##_WINLT, CONF_ADC_##n##_WINUT, ADC_GAINCORR_GAINCORR(CONF_ADC_##n##_GAINCORR), \
- ADC_OFFSETCORR_OFFSETCORR(CONF_ADC_##n##_OFFSETCORR), (CONF_ADC_##n##_DBGRUN << ADC_DBGCTRL_DBGRUN_Pos), \
- }
-
-/**
- * \brief ADC configuration type
- */
-struct adc_configuration {
- uint8_t number;
- hri_adc_ctrla_reg_t ctrl_a;
- hri_adc_refctrl_reg_t ref_ctrl;
- hri_adc_avgctrl_reg_t avg_ctrl;
- hri_adc_sampctrl_reg_t samp_ctrl;
- hri_adc_ctrlb_reg_t ctrl_b;
- hri_adc_winctrl_reg_t win_ctrl;
- hri_adc_inputctrl_reg_t input_ctrl;
- hri_adc_evctrl_reg_t ev_ctrl;
- hri_adc_winlt_reg_t win_lt;
- hri_adc_winut_reg_t win_ut;
- hri_adc_gaincorr_reg_t gain_corr;
- hri_adc_offsetcorr_reg_t offset_corr;
- hri_adc_dbgctrl_reg_t dbg_ctrl;
-};
-
-#define ADC_AMOUNT (CONF_ADC_0_ENABLE)
-
-/**
- * \brief Array of ADC configurations
- */
-static struct adc_configuration _adcs[] = {
-#if CONF_ADC_0_ENABLE == 1
- ADC_CONFIGURATION(0),
-#endif
-};
-
-/*!< Pointer to hpl device */
-static struct _adc_async_device *_adc_dev = NULL;
-
-static void _adc_set_resolution(void *const hw, const adc_resolution_t resolution);
-static void _adc_set_conversion_mode(void *const hw, const enum adc_conversion_mode mode);
-static void _adc_set_channel_differential_mode(void *const hw, const uint8_t channel,
- const enum adc_differential_mode mode);
-
-/**
- * \brief Retrieve ordinal number of the given adc hardware instance
- */
-static uint8_t _adc_get_hardware_index(const void *const hw)
-{
- (void)hw;
- return 0;
-}
-
-/** \brief Return the pointer to register settings of specific ADC
- * \param[in] hw_addr The hardware register base address.
- * \return Pointer to register settings of specific ADC.
- */
-static uint8_t _adc_get_regs(const uint32_t hw_addr)
-{
- uint8_t n = _adc_get_hardware_index((const void *)hw_addr);
- uint8_t i;
-
- for (i = 0; i < sizeof(_adcs) / sizeof(struct adc_configuration); i++) {
- if (_adcs[i].number == n) {
- return i;
- }
- }
-
- ASSERT(false);
- return 0;
-}
-
-/**
- * \brief Retrieve IRQ number for the given hardware instance
- */
-static uint8_t _adc_get_irq_num(const struct _adc_async_device *const device)
-{
- (void)device;
- return ADC_IRQn;
-}
-
-/**
- * \brief Initialize ADC
- *
- * \param[in] hw The pointer to hardware instance
- * \param[in] i The number of hardware instance
- */
-static int32_t _adc_init(void *const hw, const uint8_t i)
-{
- ASSERT(hw == ADC);
-
- hri_adc_wait_for_sync(hw);
- if (hri_adc_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_adc_set_CTRLA_SWRST_bit(hw);
- hri_adc_wait_for_sync(hw);
-
- hri_adc_write_REFCTRL_reg(hw, _adcs[i].ref_ctrl);
- hri_adc_write_AVGCTRL_reg(hw, _adcs[i].avg_ctrl);
- hri_adc_write_SAMPCTRL_reg(hw, _adcs[i].samp_ctrl);
- hri_adc_write_EVCTRL_reg(hw, _adcs[i].ev_ctrl);
- hri_adc_write_GAINCORR_reg(hw, _adcs[i].gain_corr);
- hri_adc_write_OFFSETCORR_reg(hw, _adcs[i].offset_corr);
- hri_adc_write_DBGCTRL_reg(hw, _adcs[i].dbg_ctrl);
- hri_adc_write_CTRLB_reg(hw, _adcs[i].ctrl_b);
- hri_adc_write_INPUTCTRL_reg(hw, _adcs[i].input_ctrl);
- hri_adc_write_WINCTRL_reg(hw, _adcs[i].win_ctrl);
- hri_adc_write_WINLT_reg(hw, _adcs[i].win_lt);
- hri_adc_write_WINUT_reg(hw, _adcs[i].win_ut);
- hri_adc_write_CTRLA_reg(hw, _adcs[i].ctrl_a);
-
- return ERR_NONE;
-}
-
-/**
- * \brief De-initialize ADC
- *
- * \param[in] hw The pointer to hardware instance
- */
-static inline void _adc_deinit(void *const hw)
-{
- hri_adc_clear_CTRLA_ENABLE_bit(hw);
- hri_adc_set_CTRLA_SWRST_bit(hw);
-}
-
-/**
- * \brief Initialize ADC
- */
-int32_t _adc_sync_init(struct _adc_sync_device *const device, void *const hw)
-{
- ASSERT(device);
-
- device->hw = hw;
-
- return _adc_init(hw, _adc_get_regs((uint32_t)hw));
-}
-
-/**
- * \brief Initialize ADC
- */
-int32_t _adc_async_init(struct _adc_async_device *const device, void *const hw)
-{
- int32_t init_status;
-
- ASSERT(device);
-
- init_status = _adc_init(hw, _adc_get_regs((uint32_t)hw));
- if (init_status) {
- return init_status;
- }
- device->hw = hw;
- _adc_dev = device;
-
- NVIC_DisableIRQ(ADC_IRQn);
- NVIC_ClearPendingIRQ(ADC_IRQn);
- NVIC_EnableIRQ(ADC_IRQn);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Initialize ADC
- */
-int32_t _adc_dma_init(struct _adc_dma_device *const device, void *const hw)
-{
- ASSERT(device);
-
- device->hw = hw;
-
- return _adc_init(hw, _adc_get_regs((uint32_t)hw));
-}
-
-/**
- * \brief De-initialize ADC
- */
-void _adc_sync_deinit(struct _adc_sync_device *const device)
-{
- _adc_deinit(device->hw);
-}
-
-/**
- * \brief De-initialize ADC
- */
-void _adc_async_deinit(struct _adc_async_device *const device)
-{
- NVIC_DisableIRQ(_adc_get_irq_num(device));
- NVIC_ClearPendingIRQ(_adc_get_irq_num(device));
-
- _adc_deinit(device->hw);
-}
-
-/**
- * \brief De-initialize ADC
- */
-void _adc_dma_deinit(struct _adc_dma_device *const device)
-{
- _adc_deinit(device->hw);
-}
-
-/**
- * \brief Enable ADC
- */
-void _adc_sync_enable_channel(struct _adc_sync_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Enable ADC
- */
-void _adc_async_enable_channel(struct _adc_async_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Enable ADC
- */
-void _adc_dma_enable_channel(struct _adc_dma_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable ADC
- */
-void _adc_sync_disable_channel(struct _adc_sync_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable ADC
- */
-void _adc_async_disable_channel(struct _adc_async_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable ADC
- */
-void _adc_dma_disable_channel(struct _adc_dma_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Return address of ADC DMA source
- */
-uint32_t _adc_get_source_for_dma(struct _adc_dma_device *const device)
-{
- return (uint32_t) & (((Adc *)(device->hw))->RESULT.reg);
-}
-
-/**
- * \brief Retrieve ADC conversion data size
- */
-uint8_t _adc_sync_get_data_size(const struct _adc_sync_device *const device)
-{
- return hri_adc_read_CTRLB_RESSEL_bf(device->hw) == ADC_CTRLB_RESSEL_8BIT_Val ? 1 : 2;
-}
-
-/**
- * \brief Retrieve ADC conversion data size
- */
-uint8_t _adc_async_get_data_size(const struct _adc_async_device *const device)
-{
- return hri_adc_read_CTRLB_RESSEL_bf(device->hw) == ADC_CTRLB_RESSEL_8BIT_Val ? 1 : 2;
-}
-
-/**
- * \brief Retrieve ADC conversion data size
- */
-uint8_t _adc_dma_get_data_size(const struct _adc_dma_device *const device)
-{
- return hri_adc_read_CTRLB_RESSEL_bf(device->hw) == ADC_CTRLB_RESSEL_8BIT_Val ? 1 : 2;
-}
-
-/**
- * \brief Check if conversion is done
- */
-bool _adc_sync_is_channel_conversion_done(const struct _adc_sync_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- return hri_adc_get_interrupt_RESRDY_bit(device->hw);
-}
-
-/**
- * \brief Check if conversion is done
- */
-bool _adc_async_is_channel_conversion_done(const struct _adc_async_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- return hri_adc_get_interrupt_RESRDY_bit(device->hw);
-}
-
-/**
- * \brief Check if conversion is done
- */
-bool _adc_dma_is_conversion_done(const struct _adc_dma_device *const device)
-{
- return hri_adc_get_interrupt_RESRDY_bit(device->hw);
-}
-
-/**
- * \brief Make conversion
- */
-void _adc_sync_convert(struct _adc_sync_device *const device)
-{
- hri_adc_set_SWTRIG_START_bit(device->hw);
-}
-
-/**
- * \brief Make conversion
- */
-void _adc_async_convert(struct _adc_async_device *const device)
-{
- hri_adc_set_SWTRIG_START_bit(device->hw);
-}
-
-/**
- * \brief Make conversion
- */
-void _adc_dma_convert(struct _adc_dma_device *const device)
-{
- hri_adc_set_SWTRIG_START_bit(device->hw);
-}
-
-/**
- * \brief Retrieve the conversion result
- */
-uint16_t _adc_sync_read_channel_data(const struct _adc_sync_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- return hri_adc_read_RESULT_reg(device->hw);
-}
-
-/**
- * \brief Retrieve the conversion result
- */
-uint16_t _adc_async_read_channel_data(const struct _adc_async_device *const device, const uint8_t channel)
-{
- (void)channel;
-
- return hri_adc_read_RESULT_reg(device->hw);
-}
-
-/**
- * \brief Set reference source
- */
-void _adc_sync_set_reference_source(struct _adc_sync_device *const device, const adc_reference_t reference)
-{
- hri_adc_write_REFCTRL_REFSEL_bf(device->hw, reference);
-}
-
-/**
- * \brief Set reference source
- */
-void _adc_async_set_reference_source(struct _adc_async_device *const device, const adc_reference_t reference)
-{
- hri_adc_write_REFCTRL_REFSEL_bf(device->hw, reference);
-}
-
-/**
- * \brief Set reference source
- */
-void _adc_dma_set_reference_source(struct _adc_dma_device *const device, const adc_reference_t reference)
-{
- hri_adc_write_REFCTRL_REFSEL_bf(device->hw, reference);
-}
-
-/**
- * \brief Set resolution
- */
-void _adc_sync_set_resolution(struct _adc_sync_device *const device, const adc_resolution_t resolution)
-{
- _adc_set_resolution(device->hw, resolution);
-}
-
-/**
- * \brief Set resolution
- */
-void _adc_async_set_resolution(struct _adc_async_device *const device, const adc_resolution_t resolution)
-{
- _adc_set_resolution(device->hw, resolution);
-}
-
-/**
- * \brief Set resolution
- */
-void _adc_dma_set_resolution(struct _adc_dma_device *const device, const adc_resolution_t resolution)
-{
- hri_adc_write_CTRLB_RESSEL_bf(device->hw, resolution);
-}
-
-/**
- * \brief Set channels input sources
- */
-void _adc_sync_set_inputs(struct _adc_sync_device *const device, const adc_pos_input_t pos_input,
- const adc_neg_input_t neg_input, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_write_INPUTCTRL_MUXPOS_bf(device->hw, pos_input);
- hri_adc_write_INPUTCTRL_MUXNEG_bf(device->hw, neg_input);
-}
-
-/**
- * \brief Set channels input sources
- */
-void _adc_async_set_inputs(struct _adc_async_device *const device, const adc_pos_input_t pos_input,
- const adc_neg_input_t neg_input, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_write_INPUTCTRL_MUXPOS_bf(device->hw, pos_input);
- hri_adc_write_INPUTCTRL_MUXNEG_bf(device->hw, neg_input);
-}
-
-/**
- * \brief Set channels input source
- */
-void _adc_dma_set_inputs(struct _adc_dma_device *const device, const adc_pos_input_t pos_input,
- const adc_neg_input_t neg_input, const uint8_t channel)
-{
- (void)channel;
-
- hri_adc_write_INPUTCTRL_MUXPOS_bf(device->hw, pos_input);
- hri_adc_write_INPUTCTRL_MUXNEG_bf(device->hw, neg_input);
-}
-
-/**
- * \brief Set thresholds
- */
-void _adc_sync_set_thresholds(struct _adc_sync_device *const device, const adc_threshold_t low_threshold,
- const adc_threshold_t up_threshold)
-{
- hri_adc_write_WINLT_reg(device->hw, low_threshold);
- hri_adc_write_WINUT_reg(device->hw, up_threshold);
-}
-
-/**
- * \brief Set threshold
- */
-void _adc_async_set_thresholds(struct _adc_async_device *const device, const adc_threshold_t low_threshold,
- const adc_threshold_t up_threshold)
-{
- hri_adc_write_WINLT_reg(device->hw, low_threshold);
- hri_adc_write_WINUT_reg(device->hw, up_threshold);
-}
-
-/**
- * \brief Set thresholds
- */
-void _adc_dma_set_thresholds(struct _adc_dma_device *const device, const adc_threshold_t low_threshold,
- const adc_threshold_t up_threshold)
-{
- hri_adc_write_WINLT_reg(device->hw, low_threshold);
- hri_adc_write_WINUT_reg(device->hw, up_threshold);
-}
-
-/**
- * \brief Set gain
- */
-void _adc_sync_set_channel_gain(struct _adc_sync_device *const device, const uint8_t channel, const adc_gain_t gain)
-{
- (void)channel;
-
- hri_adc_write_INPUTCTRL_GAIN_bf(device->hw, gain);
-}
-
-/**
- * \brief Set gain
- */
-void _adc_async_set_channel_gain(struct _adc_async_device *const device, const uint8_t channel, const adc_gain_t gain)
-{
- (void)channel;
-
- hri_adc_write_INPUTCTRL_GAIN_bf(device->hw, gain);
-}
-
-/**
- * \brief Set gain
- */
-void _adc_dma_set_channel_gain(struct _adc_dma_device *const device, const uint8_t channel, const adc_gain_t gain)
-{
- (void)channel;
-
- hri_adc_write_INPUTCTRL_GAIN_bf(device->hw, gain);
-}
-
-/**
- * \brief Set conversion mode
- */
-void _adc_sync_set_conversion_mode(struct _adc_sync_device *const device, const enum adc_conversion_mode mode)
-{
- _adc_set_conversion_mode(device->hw, mode);
-}
-
-/**
- * \brief Set conversion mode
- */
-void _adc_async_set_conversion_mode(struct _adc_async_device *const device, const enum adc_conversion_mode mode)
-{
- _adc_set_conversion_mode(device->hw, mode);
-}
-
-/**
- * \brief Set conversion mode
- */
-void _adc_dma_set_conversion_mode(struct _adc_dma_device *const device, const enum adc_conversion_mode mode)
-{
- _adc_set_conversion_mode(device->hw, mode);
-}
-
-/**
- * \brief Set differential mode
- */
-void _adc_sync_set_channel_differential_mode(struct _adc_sync_device *const device, const uint8_t channel,
- const enum adc_differential_mode mode)
-{
- _adc_set_channel_differential_mode(device->hw, channel, mode);
-}
-
-/**
- * \brief Set differential mode
- */
-void _adc_async_set_channel_differential_mode(struct _adc_async_device *const device, const uint8_t channel,
- const enum adc_differential_mode mode)
-{
- _adc_set_channel_differential_mode(device->hw, channel, mode);
-}
-
-/**
- * \brief Set differential mode
- */
-void _adc_dma_set_channel_differential_mode(struct _adc_dma_device *const device, const uint8_t channel,
- const enum adc_differential_mode mode)
-{
- (void)channel;
-
- _adc_set_channel_differential_mode(device->hw, channel, mode);
-}
-
-/**
- * \brief Set window mode
- */
-void _adc_sync_set_window_mode(struct _adc_sync_device *const device, const adc_window_mode_t mode)
-{
- hri_adc_write_WINCTRL_WINMODE_bf(device->hw, mode);
-}
-
-/**
- * \brief Set window mode
- */
-void _adc_async_set_window_mode(struct _adc_async_device *const device, const adc_window_mode_t mode)
-{
- hri_adc_write_WINCTRL_WINMODE_bf(device->hw, mode);
-}
-
-/**
- * \brief Set window mode
- */
-void _adc_dma_set_window_mode(struct _adc_dma_device *const device, const adc_window_mode_t mode)
-{
- hri_adc_write_WINCTRL_WINMODE_bf(device->hw, mode);
-}
-
-/**
- * \brief Retrieve threshold state
- */
-void _adc_sync_get_threshold_state(const struct _adc_sync_device *const device, adc_threshold_status_t *const state)
-{
- *state = hri_adc_get_interrupt_WINMON_bit(device->hw);
-}
-
-/**
- * \brief Retrieve threshold state
- */
-void _adc_async_get_threshold_state(const struct _adc_async_device *const device, adc_threshold_status_t *const state)
-{
- *state = hri_adc_get_interrupt_WINMON_bit(device->hw);
-}
-
-/**
- * \brief Retrieve threshold state
- */
-void _adc_dma_get_threshold_state(const struct _adc_dma_device *const device, adc_threshold_status_t *const state)
-{
- *state = hri_adc_get_interrupt_WINMON_bit(device->hw);
-}
-
-/**
- * \brief Enable/disable ADC interrupt
- *
- * param[in] device The pointer to ADC device instance
- * param[in] type The type of interrupt to disable/enable if applicable
- * param[in] state Enable or disable
- */
-void _adc_async_set_irq_state(struct _adc_async_device *const device, const uint8_t channel,
- const enum _adc_async_callback_type type, const bool state)
-{
- (void)channel;
-
- void *const hw = device->hw;
-
- if (ADC_ASYNC_DEVICE_MONITOR_CB == type) {
- hri_adc_write_INTEN_WINMON_bit(hw, state);
- } else if (ADC_ASYNC_DEVICE_ERROR_CB == type) {
- hri_adc_write_INTEN_OVERRUN_bit(hw, state);
- } else if (ADC_ASYNC_DEVICE_CONVERT_CB == type) {
- hri_adc_write_INTEN_RESRDY_bit(hw, state);
- }
-}
-
-/**
- * \brief SetADC resolution
- *
- * \param[in] hw The pointer to hardware instance
- * \param[in] resolution The resolution to set
- */
-static void _adc_set_resolution(void *const hw, const adc_resolution_t resolution)
-{
- bool enabled = hri_adc_get_CTRLA_ENABLE_bit(hw);
-
- hri_adc_clear_CTRLA_ENABLE_bit(hw);
- hri_adc_write_CTRLB_RESSEL_bf(hw, resolution);
-
- if (enabled) {
- hri_adc_set_CTRLA_ENABLE_bit(hw);
- }
-}
-
-/**
- * \brief SetADC resolution
- *
- * \param[in] hw The pointer to hardware instance
- * \param[in] mode The mode to set
- */
-static void _adc_set_conversion_mode(void *const hw, const enum adc_conversion_mode mode)
-{
- bool enabled = hri_adc_get_CTRLA_ENABLE_bit(hw);
-
- hri_adc_clear_CTRLA_ENABLE_bit(hw);
- hri_adc_clear_CTRLB_FREERUN_bit(hw);
- if (ADC_CONVERSION_MODE_FREERUN == mode) {
- hri_adc_set_CTRLB_FREERUN_bit(hw);
- }
-
- if (enabled) {
- hri_adc_set_CTRLA_ENABLE_bit(hw);
- }
-}
-
-/**
- * \brief SetADC resolution
- *
- * \param[in] hw The pointer to hardware instance
- * \param[in] mode The mode to set
- */
-static void _adc_set_channel_differential_mode(void *const hw, const uint8_t channel,
- const enum adc_differential_mode mode)
-{
- (void)channel;
- bool enabled = hri_adc_get_CTRLA_ENABLE_bit(hw);
-
- hri_adc_clear_CTRLA_ENABLE_bit(hw);
- hri_adc_clear_CTRLB_DIFFMODE_bit(hw);
- if (ADC_DIFFERENTIAL_MODE_DIFFERENTIAL == mode) {
- hri_adc_set_CTRLB_DIFFMODE_bit(hw);
- }
-
- if (enabled) {
- hri_adc_set_CTRLA_ENABLE_bit(hw);
- }
-}
diff --git a/atmel-samd/asf4/samd21/hpl/adc/hpl_adc_base.h b/atmel-samd/asf4/samd21/hpl/adc/hpl_adc_base.h
deleted file mode 100644
index 2f9a333c9..000000000
--- a/atmel-samd/asf4/samd21/hpl/adc/hpl_adc_base.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * \file
- *
- * \brief ADC related functionality declaration.
- *
- * Copyright (C) 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
- *
- */
-
-#ifndef _HPL_ADC_ADC_H_INCLUDED
-#define _HPL_ADC_ADC_H_INCLUDED
-
-#include <hpl_adc_sync.h>
-#include <hpl_adc_async.h>
-
-/**
- * \addtogroup HPL ADC
- *
- * \section hpl_adc_rev Revision History
- * - v1.0.0 Initial Release
- *
- *@{
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \name HPL functions
- */
-//@{
-
-/**
- * \brief Retrieve ADC helper functions
- *
- * \return A pointer to set of ADC helper functions
- */
-void *_adc_get_adc_sync(void);
-void *_adc_get_adc_async(void);
-
-//@}
-
-#ifdef __cplusplus
-}
-#endif
-/**@}*/
-#endif /* _HPL_USART_UART_H_INCLUDED */
diff --git a/atmel-samd/asf4/samd21/hpl/core/hpl_core_m0plus_base.c b/atmel-samd/asf4/samd21/hpl/core/hpl_core_m0plus_base.c
deleted file mode 100644
index 8b2ecbff3..000000000
--- a/atmel-samd/asf4/samd21/hpl/core/hpl_core_m0plus_base.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/**
- * \file
- *
- * \brief Core related functionality implementation.
- *
- * 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
- *
- */
-
-#include <hpl_core.h>
-#include <hpl_irq.h>
-#include <hpl_reset.h>
-#include <hpl_sleep.h>
-#include <hpl_delay.h>
-#ifndef _UNIT_TEST_
-#include <utils.h>
-#endif
-#include <utils_assert.h>
-#include <peripheral_clk_config.h>
-
-#ifndef CONF_CPU_FREQUENCY
-#define CONF_CPU_FREQUENCY 1000000
-#endif
-
-#if CONF_CPU_FREQUENCY < 1000
-#define CPU_FREQ_POWER 3
-#elif CONF_CPU_FREQUENCY < 10000
-#define CPU_FREQ_POWER 4
-#elif CONF_CPU_FREQUENCY < 100000
-#define CPU_FREQ_POWER 5
-#elif CONF_CPU_FREQUENCY < 1000000
-#define CPU_FREQ_POWER 6
-#elif CONF_CPU_FREQUENCY < 10000000
-#define CPU_FREQ_POWER 7
-#elif CONF_CPU_FREQUENCY < 100000000
-#define CPU_FREQ_POWER 8
-#endif
-
-/**
- * \brief The array of interrupt handlers
- */
-struct _irq_descriptor *_irq_table[PERIPH_COUNT_IRQn];
-
-/**
- * \brief Reset MCU
- */
-void _reset_mcu(void)
-{
- NVIC_SystemReset();
-}
-
-/**
- * \brief Put MCU to sleep
- */
-void _go_to_sleep(void)
-{
- __DSB();
- __WFI();
-}
-
-/**
- * \brief Retrieve current IRQ number
- */
-uint8_t _irq_get_current(void)
-{
- return (uint8_t)__get_IPSR() - 16;
-}
-
-/**
- * \brief Disable the given IRQ
- */
-void _irq_disable(uint8_t n)
-{
- NVIC_DisableIRQ((IRQn_Type)n);
-}
-
-/**
- * \brief Set the given IRQ
- */
-void _irq_set(uint8_t n)
-{
- NVIC_SetPendingIRQ((IRQn_Type)n);
-}
-
-/**
- * \brief Clear the given IRQ
- */
-void _irq_clear(uint8_t n)
-{
- NVIC_ClearPendingIRQ((IRQn_Type)n);
-}
-
-/**
- * \brief Enable the given IRQ
- */
-void _irq_enable(uint8_t n)
-{
- NVIC_EnableIRQ((IRQn_Type)n);
-}
-
-/**
- * \brief Register IRQ handler
- */
-void _irq_register(const uint8_t n, struct _irq_descriptor *const irq)
-{
- ASSERT(n < PERIPH_COUNT_IRQn);
-
- _irq_table[n] = irq;
-}
-
-/**
- * \brief Default interrupt handler for unused IRQs.
- */
-void Default_Handler(void)
-{
- while (1) {
- }
-}
-
-/**
- * \brief Retrieve the amount of cycles to delay for the given amount of us
- */
-static inline uint32_t _get_cycles_for_us_internal(const uint16_t us, const uint32_t freq, const uint8_t power)
-{
- switch (power) {
- case 8:
- return (us * (freq / 100000) - 1) / 10 + 1;
- case 7:
- return (us * (freq / 10000) - 1) / 100 + 1;
- case 6:
- return (us * (freq / 1000) - 1) / 1000 + 1;
- case 5:
- return (us * (freq / 100) - 1) / 10000 + 1;
- case 4:
- return (us * (freq / 10) - 1) / 100000 + 1;
- default:
- return (us * freq - 1) / 1000000 + 1;
- }
-}
-
-/**
- * \brief Retrieve the amount of cycles to delay for the given amount of us
- */
-uint32_t _get_cycles_for_us(const uint16_t us)
-{
- return _get_cycles_for_us_internal(us, CONF_CPU_FREQUENCY, CPU_FREQ_POWER);
-}
-
-/**
- * \brief Retrieve the amount of cycles to delay for the given amount of ms
- */
-static inline uint32_t _get_cycles_for_ms_internal(const uint16_t ms, const uint32_t freq, const uint8_t power)
-{
- switch (power) {
- case 8:
- return (ms * (freq / 100000)) * 100;
- case 7:
- return (ms * (freq / 10000)) * 10;
- case 6:
- return (ms * (freq / 1000));
- case 5:
- return (ms * (freq / 100) - 1) / 10 + 1;
- case 4:
- return (ms * (freq / 10) - 1) / 100 + 1;
- default:
- return (ms * freq - 1) / 1000 + 1;
- }
-}
-
-/**
- * \brief Retrieve the amount of cycles to delay for the given amount of ms
- */
-uint32_t _get_cycles_for_ms(const uint16_t ms)
-{
- return _get_cycles_for_ms_internal(ms, CONF_CPU_FREQUENCY, CPU_FREQ_POWER);
-}
diff --git a/atmel-samd/asf4/samd21/hpl/core/hpl_core_port.h b/atmel-samd/asf4/samd21/hpl/core/hpl_core_port.h
deleted file mode 100644
index b068af839..000000000
--- a/atmel-samd/asf4/samd21/hpl/core/hpl_core_port.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/**
- * \file
- *
- * \brief Core related functionality implementation.
- *
- * Copyright (C) 2015 - 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
- *
- */
-
-#ifndef _HPL_CORE_PORT_H_INCLUDED
-#define _HPL_CORE_PORT_H_INCLUDED
-
-#include <peripheral_clk_config.h>
-
-/* It's possible to include this file in ARM ASM files (e.g., in FreeRTOS IAR
- * portable implement, portasm.s -> FreeRTOSConfig.h -> hpl_core_port.h),
- * there will be assembling errors.
- * So the following things are not included for assembling.
- */
-#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
-
-#ifndef _UNIT_TEST_
-#include <compiler.h>
-#endif
-
-/**
- * \brief Check if it's in ISR handling
- * \return \c true if it's in ISR
- */
-static inline bool _is_in_isr(void)
-{
- return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk);
-}
-
-#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
-
-#endif /* _HPL_CORE_PORT_H_INCLUDED */
diff --git a/atmel-samd/asf4/samd21/hpl/core/hpl_init.c b/atmel-samd/asf4/samd21/hpl/core/hpl_init.c
deleted file mode 100644
index e567b5d22..000000000
--- a/atmel-samd/asf4/samd21/hpl/core/hpl_init.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * \file
- *
- * \brief HPL initialization related functionality implementation.
- *
- * Copyright (C) 2014-2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_gpio.h>
-#include <hpl_init.h>
-#include <hpl_pm_config.h>
-#include <hpl_pm_base.h>
-
-#include <hpl_dma.h>
-#include <hpl_dmac_config.h>
-
-/**
- * \brief Initialize the hardware abstraction layer
- */
-void _init_chip(void)
-{
- hri_nvmctrl_set_CTRLB_RWS_bf(NVMCTRL, CONF_NVM_WAIT_STATE);
-
- _pm_init();
- _sysctrl_init_sources();
- _gclk_init_generators();
- _sysctrl_init_referenced_generators();
-
-#if CONF_DMAC_ENABLE
- _pm_enable_bus_clock(PM_BUS_AHB, DMAC);
- _pm_enable_bus_clock(PM_BUS_APBB, DMAC);
- _dma_init();
-#endif
-}
diff --git a/atmel-samd/asf4/samd21/hpl/dac/hpl_dac.c b/atmel-samd/asf4/samd21/hpl/dac/hpl_dac.c
deleted file mode 100644
index 2896b0eee..000000000
--- a/atmel-samd/asf4/samd21/hpl/dac/hpl_dac.c
+++ /dev/null
@@ -1,248 +0,0 @@
-
-/**
-* \file
-*
-* \brief SAM Digital to Analog Converter
-*
-* Copyright (C) 2016 -2017 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 LIMIT ED TO, PROCUREMENT OF SUBSTITUTE GOODS
-* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-*
-* \asf_license_stop
-*
-*/
-
-#include <hpl_dac_async.h>
-#include <hpl_dac_config.h>
-#include <hpl_dac_sync.h>
-#include <utils_assert.h>
-
-/** \conf INTERNAL */
-static int32_t _dac_init(void *const hw);
-static inline void _dac_deinit(void *const hw);
-/** \endcond */
-
-/**
- * \brief DAC configuration type
- */
-struct dac_configuration {
- hri_dac_ctrla_reg_t ctrla; /*!< Control A Register */
- hri_dac_ctrlb_reg_t ctrlb; /*!< Control B Register */
- hri_dac_evctrl_reg_t ev_ctrl; /*!< Event Control Register */
-};
-
-/**
- * \brief Array of DAC configurations
- */
-static struct dac_configuration _dac = {
- (CONF_DAC_RUNSTDBY << DAC_CTRLA_RUNSTDBY_Pos),
- (CONF_DAC_REFSEL << DAC_CTRLB_REFSEL_Pos) | (CONF_DAC_BDWP << DAC_CTRLB_BDWP_Pos)
- | (CONF_DAC_VPD << DAC_CTRLB_VPD_Pos)
- | (CONF_DAC_LEFTADJ << DAC_CTRLB_LEFTADJ_Pos)
- | (CONF_DAC_IOEN << DAC_CTRLB_IOEN_Pos)
- | (CONF_DAC_EOEN << DAC_CTRLB_EOEN_Pos),
- (CONF_DAC_EMPTYEO << DAC_EVCTRL_EMPTYEO_Pos) | (CONF_DAC_STARTEI << DAC_EVCTRL_STARTEI_Pos),
-};
-
-/*!< Pointer to hpl device */
-static struct _dac_async_device *_dac_dev = NULL;
-
-/**
- * \brief Initialize synchronous DAC
- */
-int32_t _dac_sync_init(struct _dac_sync_device *const device, void *const hw)
-{
- ASSERT(device);
-
- device->hw = hw;
-
- return _dac_init(device->hw);
-}
-
-/**
- * \brief Initialize DAC
- *
- * param[in] hw The pointer to DAC hardware instance
- */
-static int32_t _dac_init(void *const hw)
-{
- hri_dac_wait_for_sync(hw);
-
- if (hri_dac_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_dac_set_CTRLA_SWRST_bit(hw);
- hri_dac_wait_for_sync(hw);
-
- hri_dac_write_EVCTRL_reg(hw, _dac.ev_ctrl);
- hri_dac_write_CTRLB_reg(hw, _dac.ctrlb);
- hri_dac_write_CTRLA_reg(hw, _dac.ctrla);
- return ERR_NONE;
-}
-
-/**
- * \brief De-initialize DAC
- *
- * param[in] hw The pointer to DAC hardware instance
- */
-static inline void _dac_deinit(void *const hw)
-{
- hri_dac_clear_CTRLA_ENABLE_bit(hw);
- hri_dac_set_CTRLA_SWRST_bit(hw);
-}
-
-/**
- * \brief Initialize DAC
- */
-int32_t _dac_async_init(struct _dac_async_device *const device, void *const hw)
-{
- int32_t init_status;
-
- ASSERT(device);
-
- init_status = _dac_init(hw);
- if (init_status) {
- return init_status;
- }
- device->hw = hw;
-
- _dac_dev = device;
- NVIC_DisableIRQ(DAC_IRQn);
- NVIC_ClearPendingIRQ(DAC_IRQn);
- NVIC_EnableIRQ(DAC_IRQn);
-
- return ERR_NONE;
-}
-
-/**
- * \brief De-initialize DAC
- */
-void _dac_sync_deinit(struct _dac_sync_device *const device)
-{
- _dac_deinit(device->hw);
-}
-
-/**
- * \brief De-initialize DAC
- */
-void _dac_async_deinit(struct _dac_async_device *const device)
-{
- NVIC_DisableIRQ(DAC_IRQn);
-
- _dac_deinit(device->hw);
-}
-
-/**
- * \brief Enable DAC Channel
- */
-void _dac_sync_enable_channel(struct _dac_sync_device *const device, const uint8_t ch)
-{
- (void)ch;
- hri_dac_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Enable DAC Channel
- */
-void _dac_async_enable_channel(struct _dac_async_device *const device, const uint8_t ch)
-{
- (void)ch;
- hri_dac_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable DAC Channel
- */
-void _dac_sync_disable_channel(struct _dac_sync_device *const device, const uint8_t ch)
-{
- (void)ch;
- hri_dac_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable DAC Channel
- */
-void _dac_async_disable_channel(struct _dac_async_device *const device, const uint8_t ch)
-{
- (void)ch;
- hri_dac_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-bool _dac_sync_is_channel_enable(struct _dac_sync_device *const device, const uint8_t ch)
-{
- (void)ch;
- return hri_dac_get_CTRLA_ENABLE_bit(device->hw);
-}
-
-bool _dac_async_is_channel_enable(struct _dac_async_device *const device, const uint8_t ch)
-{
- (void)ch;
- return hri_dac_get_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief write synchronous DAC data for output
- */
-void _dac_sync_write_data(struct _dac_sync_device *const device, const uint16_t data, const uint8_t ch)
-{
- (void)ch;
- hri_dac_write_DATA_reg(device->hw, data);
-}
-
-/**
- * \brief write DAC data for output
- */
-void _dac_async_write_data(struct _dac_async_device *const device, const uint16_t data, const uint8_t ch)
-{
- (void)ch;
- hri_dac_write_DATABUF_reg(device->hw, data);
-}
-
-/**
- * \brief Enable/disable DAC interrupt
- *
- * param[in] device The pointer to DAC device instance
- * param[in] type The type of interrupt to disable/enable if applicable
- * param[in] state Enable or disable
- */
-void _dac_async_set_irq_state(struct _dac_async_device *const device, const enum _dac_callback_type type,
- const bool state)
-{
- void *hw = device->hw;
-
- if (DAC_DEVICE_CONVERSION_DONE_CB == type) {
- hri_dac_write_INTEN_EMPTY_bit(hw, state);
- } else if (DAC_DEVICE_ERROR_CB == type) {
- hri_dac_write_INTEN_UNDERRUN_bit(hw, state);
- }
-}
diff --git a/atmel-samd/asf4/samd21/hpl/dmac/hpl_dmac.c b/atmel-samd/asf4/samd21/hpl/dmac/hpl_dmac.c
deleted file mode 100644
index 5af9abaf3..000000000
--- a/atmel-samd/asf4/samd21/hpl/dmac/hpl_dmac.c
+++ /dev/null
@@ -1,226 +0,0 @@
-
-/**
- * \file
- *
- * \brief Generic DMAC related functionality.
- *
- * Copyright (C) 2016 - 2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-#include <compiler.h>
-#include <hpl_dma.h>
-#include <hpl_dmac_config.h>
-#include <utils.h>
-#include <utils_assert.h>
-#include <utils_repeat_macro.h>
-
-#if CONF_DMAC_ENABLE
-
-/* Section containing first descriptors for all DMAC channels */
-COMPILER_ALIGNED(16)
-static DmacDescriptor _descriptor_section[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR;
-
-/* Section containing current descriptors for all DMAC channels */
-COMPILER_ALIGNED(16)
-static DmacDescriptor _write_back_section[DMAC_CH_NUM] SECTION_DMAC_DESCRIPTOR;
-
-/* Array containing callbacks for DMAC channels */
-static struct _dma_resource _resources[DMAC_CH_NUM];
-
-/* This macro DMAC configuration */
-#define DMAC_CHANNEL_CFG(i, n) \
- {(CONF_DMAC_ENABLE_##n << DMAC_CHCTRLA_ENABLE_Pos), \
- DMAC_CHCTRLB_TRIGACT(CONF_DMAC_TRIGACT_##n) | DMAC_CHCTRLB_TRIGSRC(CONF_DMAC_TRIGSRC_##n) \
- | DMAC_CHCTRLB_LVL(CONF_DMAC_LVL_##n) \
- | (CONF_DMAC_EVOE_##n << DMAC_CHCTRLB_EVOE_Pos) \
- | (CONF_DMAC_EVIE_##n << DMAC_CHCTRLB_EVIE_Pos) \
- | DMAC_CHCTRLB_EVACT(CONF_DMAC_EVACT_##n), \
- DMAC_BTCTRL_STEPSIZE(CONF_DMAC_STEPSIZE_##n) | (CONF_DMAC_STEPSEL_##n << DMAC_BTCTRL_STEPSEL_Pos) \
- | (CONF_DMAC_DSTINC_##n << DMAC_BTCTRL_DSTINC_Pos) \
- | (CONF_DMAC_SRCINC_##n << DMAC_BTCTRL_SRCINC_Pos) \
- | DMAC_BTCTRL_BEATSIZE(CONF_DMAC_BEATSIZE_##n) \
- | DMAC_BTCTRL_BLOCKACT(CONF_DMAC_BLOCKACT_##n) \
- | DMAC_BTCTRL_EVOSEL(CONF_DMAC_EVOSEL_##n)},
-
-/* DMAC channel configuration */
-struct dmac_channel_cfg {
- uint8_t ctrla;
- uint32_t ctrlb;
- uint16_t btctrl;
-};
-
-/* DMAC channel configurations */
-const static struct dmac_channel_cfg _cfgs[] = {REPEAT_MACRO(DMAC_CHANNEL_CFG, i, DMAC_CH_NUM)};
-
-/**
- * \brief Initialize DMAC
- */
-int32_t _dma_init(void)
-{
- uint8_t i = 0;
-
- hri_dmac_clear_CTRL_DMAENABLE_bit(DMAC);
- hri_dmac_clear_CTRL_CRCENABLE_bit(DMAC);
- hri_dmac_set_CHCTRLA_SWRST_bit(DMAC);
-
- hri_dmac_write_CTRL_reg(DMAC,
- (CONF_DMAC_LVLEN0 << DMAC_CTRL_LVLEN0_Pos) | (CONF_DMAC_LVLEN1 << DMAC_CTRL_LVLEN1_Pos)
- | (CONF_DMAC_LVLEN2 << DMAC_CTRL_LVLEN2_Pos)
- | (CONF_DMAC_LVLEN3 << DMAC_CTRL_LVLEN3_Pos));
- hri_dmac_write_DBGCTRL_DBGRUN_bit(DMAC, CONF_DMAC_DBGRUN);
-
- hri_dmac_write_PRICTRL0_reg(DMAC,
- DMAC_PRICTRL0_LVLPRI0(CONF_DMAC_LVLPRI0) | DMAC_PRICTRL0_LVLPRI1(CONF_DMAC_LVLPRI1)
- | DMAC_PRICTRL0_LVLPRI2(CONF_DMAC_LVLPRI2)
- | DMAC_PRICTRL0_LVLPRI3(CONF_DMAC_LVLPRI3)
- | (CONF_DMAC_RRLVLEN0 << DMAC_PRICTRL0_RRLVLEN0_Pos)
- | (CONF_DMAC_RRLVLEN1 << DMAC_PRICTRL0_RRLVLEN1_Pos)
- | (CONF_DMAC_RRLVLEN2 << DMAC_PRICTRL0_RRLVLEN2_Pos)
- | (CONF_DMAC_RRLVLEN3 << DMAC_PRICTRL0_RRLVLEN3_Pos));
- hri_dmac_write_BASEADDR_reg(DMAC, (uint32_t)_descriptor_section);
- hri_dmac_write_WRBADDR_reg(DMAC, (uint32_t)_write_back_section);
-
- for (; i < DMAC_CH_NUM; i++) {
- hri_dmac_write_CHID_reg(DMAC, i);
-
- hri_dmac_write_CHCTRLB_reg(DMAC, _cfgs[i].ctrlb);
- hri_dmacdescriptor_write_BTCTRL_reg(&_descriptor_section[i], _cfgs[i].btctrl);
- }
-
- NVIC_DisableIRQ(DMAC_IRQn);
- NVIC_ClearPendingIRQ(DMAC_IRQn);
- NVIC_EnableIRQ(DMAC_IRQn);
-
- hri_dmac_set_CTRL_DMAENABLE_bit(DMAC);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable/disable DMA interrupt
- */
-void _dma_set_irq_state(const uint8_t channel, const enum _dma_callback_type type, const bool state)
-{
- hri_dmac_write_CHID_reg(DMAC, channel);
-
- if (DMA_TRANSFER_COMPLETE_CB == type) {
- hri_dmac_write_CHINTEN_TCMPL_bit(DMAC, state);
- } else if (DMA_TRANSFER_ERROR_CB == type) {
- hri_dmac_write_CHINTEN_TERR_bit(DMAC, state);
- }
-}
-
-int32_t _dma_set_destination_address(const uint8_t channel, const void *const dst)
-{
- hri_dmacdescriptor_write_DSTADDR_reg(&_descriptor_section[channel], (uint32_t)dst);
-
- return ERR_NONE;
-}
-
-int32_t _dma_set_source_address(const uint8_t channel, const void *const src)
-{
- hri_dmacdescriptor_write_SRCADDR_reg(&_descriptor_section[channel], (uint32_t)src);
-
- return ERR_NONE;
-}
-
-int32_t _dma_srcinc_enable(const uint8_t channel, const bool enable)
-{
- hri_dmacdescriptor_write_BTCTRL_SRCINC_bit(&_descriptor_section[channel], enable);
-
- return ERR_NONE;
-}
-
-int32_t _dma_set_data_amount(const uint8_t channel, const uint32_t amount)
-{
- uint32_t address = hri_dmacdescriptor_read_DSTADDR_reg(&_descriptor_section[channel]);
- uint8_t beat_size = hri_dmacdescriptor_read_BTCTRL_BEATSIZE_bf(&_descriptor_section[channel]);
-
- if (hri_dmacdescriptor_get_BTCTRL_DSTINC_bit(&_descriptor_section[channel])) {
- hri_dmacdescriptor_write_DSTADDR_reg(&_descriptor_section[channel], address + amount * (1 << beat_size));
- }
-
- address = hri_dmacdescriptor_read_SRCADDR_reg(&_descriptor_section[channel]);
-
- if (hri_dmacdescriptor_get_BTCTRL_SRCINC_bit(&_descriptor_section[channel])) {
- hri_dmacdescriptor_write_SRCADDR_reg(&_descriptor_section[channel], address + amount * (1 << beat_size));
- }
-
- hri_dmacdescriptor_write_BTCNT_reg(&_descriptor_section[channel], amount);
-
- return ERR_NONE;
-}
-
-int32_t _dma_enable_transaction(const uint8_t channel, const bool software_trigger)
-{
- hri_dmac_write_CHID_reg(DMAC, channel);
- hri_dmacdescriptor_set_BTCTRL_VALID_bit(&_descriptor_section[channel]);
- hri_dmac_set_CHCTRLA_ENABLE_bit(DMAC);
- if (software_trigger) {
- hri_dmac_set_SWTRIGCTRL_reg(DMAC, 1 << channel);
- }
-
- return ERR_NONE;
-}
-
-int32_t _dma_get_channel_resource(struct _dma_resource **resource, const uint8_t channel)
-{
- *resource = &_resources[channel];
-
- return ERR_NONE;
-}
-
-/**
- * \internal DMAC interrupt handler
- */
-void DMAC_Handler(void)
-{
- uint8_t channel = hri_dmac_read_INTPEND_ID_bf(DMAC);
- struct _dma_resource *tmp_resource = &_resources[channel];
-
- hri_dmac_write_CHID_reg(DMAC, channel);
-
- if (hri_dmac_get_CHINTFLAG_TERR_bit(DMAC)) {
- hri_dmac_clear_CHINTFLAG_TERR_bit(DMAC);
- tmp_resource->dma_cb.error(tmp_resource);
- } else if (hri_dmac_get_CHINTFLAG_TCMPL_bit(DMAC)) {
- hri_dmac_clear_CHINTFLAG_TCMPL_bit(DMAC);
- tmp_resource->dma_cb.transfer_done(tmp_resource);
- }
-}
-
-#endif /* CONF_DMAC_ENABLE */
diff --git a/atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk.c b/atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk.c
deleted file mode 100644
index 1012da0a2..000000000
--- a/atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk.c
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * \file
- *
- * \brief Generic Clock Controller v210 related functionality.
- *
- * Copyright (C) 2014 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_gclk_config.h>
-#include <hpl_init.h>
-#include <utils_assert.h>
-
-/**
- * \brief Initializes generators
-
- */
-void _gclk_init_generators(void)
-{
-#if CONF_GCLK_GEN_0_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_0_DIV) | GCLK_GENDIV_ID(0));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_0_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_0_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_0_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_0_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_0_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_0_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_0_SRC
- | GCLK_GENCTRL_ID(0));
-#endif
-#if CONF_GCLK_GEN_1_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_1_DIV) | GCLK_GENDIV_ID(1));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_1_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_1_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_1_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_1_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_1_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_1_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_1_SRC
- | GCLK_GENCTRL_ID(1));
-#endif
-#if CONF_GCLK_GEN_2_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_2_DIV) | GCLK_GENDIV_ID(2));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_2_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_2_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_2_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_2_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_2_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_2_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_2_SRC
- | GCLK_GENCTRL_ID(2));
-#endif
-#if CONF_GCLK_GEN_3_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_3_DIV) | GCLK_GENDIV_ID(3));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_3_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_3_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_3_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_3_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_3_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_3_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_3_SRC
- | GCLK_GENCTRL_ID(3));
-#endif
-#if CONF_GCLK_GEN_4_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_4_DIV) | GCLK_GENDIV_ID(4));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_4_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_4_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_4_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_4_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_4_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_4_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_4_SRC
- | GCLK_GENCTRL_ID(4));
-#endif
-#if CONF_GCLK_GEN_5_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_5_DIV) | GCLK_GENDIV_ID(5));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_5_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_5_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_5_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_5_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_5_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_5_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_5_SRC
- | GCLK_GENCTRL_ID(5));
-#endif
-#if CONF_GCLK_GEN_6_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_6_DIV) | GCLK_GENDIV_ID(6));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_6_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_6_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_6_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_6_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_6_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_6_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_6_SRC
- | GCLK_GENCTRL_ID(6));
-#endif
-#if CONF_GCLK_GEN_7_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_7_DIV) | GCLK_GENDIV_ID(7));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_7_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_7_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_7_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_7_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_7_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_7_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_7_SRC
- | GCLK_GENCTRL_ID(7));
-#endif
-#if defined(CONF_GCLK_GEN_8_GENEN) && CONF_GCLK_GEN_8_GENEN == 1
- hri_gclk_write_GENDIV_reg(GCLK, GCLK_GENDIV_DIV(CONF_GCLK_GEN_8_DIV) | GCLK_GENDIV_ID(8));
- hri_gclk_write_GENCTRL_reg(GCLK,
- (CONF_GCLK_GEN_8_RUNSTDBY << GCLK_GENCTRL_RUNSTDBY_Pos)
- | (CONF_GCLK_GEN_8_DIVSEL << GCLK_GENCTRL_DIVSEL_Pos)
- | (CONF_GCLK_GEN_8_OE << GCLK_GENCTRL_OE_Pos)
- | (CONF_GCLK_GEN_8_OOV << GCLK_GENCTRL_OOV_Pos)
- | (CONF_GCLK_GEN_8_IDC << GCLK_GENCTRL_IDC_Pos)
- | (CONF_GCLK_GEN_8_GENEN << GCLK_GENCTRL_GENEN_Pos)
- | CONF_GCLK_GEN_8_SRC
- | GCLK_GENCTRL_ID(8));
-#endif
-}
diff --git a/atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk_base.h b/atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk_base.h
deleted file mode 100644
index 6451647f5..000000000
--- a/atmel-samd/asf4/samd21/hpl/gclk/hpl_gclk_base.h
+++ /dev/null
@@ -1,91 +0,0 @@
-/**
- * \file
- *
- * \brief Generic Clock Controller.
- *
- * Copyright (C) 2014 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef _HPL_GCLK_H_INCLUDED
-#define _HPL_GCLK_H_INCLUDED
-
-#include <compiler.h>
-#ifdef _UNIT_TEST_
-#include <hri_gclk1_v210_mock.h>
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \addtogroup gclk_group GCLK Hardware Proxy Layer
- *
- * \section gclk_hpl_rev Revision History
- * - v0.0.0.1 Initial Commit
- *
- *@{
- */
-
-/**
- * \name HPL functions
- */
-//@{
-/**
- * \brief Enable clock on the given channel with the given clock source
- *
- * This function maps the given clock source to the given clock channel
- * and enables channel.
- *
- * \param[in] channel The channel to enable clock for
- * \param[in] source The clock source for the given channel
- */
-static inline void _gclk_enable_channel(const uint8_t channel, const uint8_t source)
-{
-
- hri_gclk_write_CLKCTRL_reg(GCLK,
- GCLK_CLKCTRL_ID(channel) | GCLK_CLKCTRL_GEN(source) | (1 << GCLK_CLKCTRL_CLKEN_Pos));
-}
-
-//@}
-/**@}*/
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _HPL_GCLK_H_INCLUDED */
diff --git a/atmel-samd/asf4/samd21/hpl/nvmctrl/hpl_nvmctrl.c b/atmel-samd/asf4/samd21/hpl/nvmctrl/hpl_nvmctrl.c
deleted file mode 100644
index 3e751e3d5..000000000
--- a/atmel-samd/asf4/samd21/hpl/nvmctrl/hpl_nvmctrl.c
+++ /dev/null
@@ -1,684 +0,0 @@
-
-/**
-* \file
-*
-* \brief Non-Volatile Memory Controller
-*
-* Copyright (C) 2015-2017 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 LIMIT ED TO, PROCUREMENT OF SUBSTITUTE GOODS
-* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-* POSSIBILITY OF SUCH DAMAGE.
-*
-* \asf_license_stop
-*
-*/
-
-#include <hpl_flash.h>
-#include <hpl_user_area.h>
-#include <string.h>
-#include <utils_assert.h>
-#include <utils.h>
-#include <hpl_nvmctrl_config.h>
-
-#define NVM_MEMORY ((volatile uint16_t *)FLASH_ADDR)
-
-/**
- * \brief NVM configuration type
- */
-struct nvm_configuration {
- hri_nvmctrl_ctrlb_reg_t ctrlb; /*!< Control B Register */
-};
-
-/**
- * \brief Array of NVM configurations
- */
-static struct nvm_configuration _nvm
- = {(CONF_NVM_CACHE << NVMCTRL_CTRLB_CACHEDIS_Pos) | (CONF_NVM_READ_MODE << NVMCTRL_CTRLB_READMODE_Pos)
- | (CONF_NVM_SLEEPPRM << NVMCTRL_CTRLB_SLEEPPRM_Pos)};
-
-/*!< Pointer to hpl device */
-static struct _flash_device *_nvm_dev = NULL;
-
-static void _flash_erase_row(void *const hw, const uint32_t dst_addr);
-static void _flash_program(void *const hw, const uint32_t dst_addr, const uint8_t *buffer, const uint16_t size);
-
-/**
- * \brief Initialize NVM
- */
-int32_t _flash_init(struct _flash_device *const device, void *const hw)
-{
- ASSERT(device && (hw == NVMCTRL));
- uint32_t ctrlb;
-
- device->hw = hw;
- ctrlb = _nvm.ctrlb & ~(NVMCTRL_CTRLB_RWS_Msk | NVMCTRL_CTRLB_MANW);
- ctrlb |= hri_nvmctrl_get_CTRLB_reg(device->hw, NVMCTRL_CTRLB_RWS_Msk | NVMCTRL_CTRLB_MANW);
- hri_nvmctrl_write_CTRLB_reg(device->hw, ctrlb);
-
- _nvm_dev = device;
- NVIC_DisableIRQ(NVMCTRL_IRQn);
- NVIC_ClearPendingIRQ(NVMCTRL_IRQn);
- NVIC_EnableIRQ(NVMCTRL_IRQn);
- return ERR_NONE;
-}
-
-/**
- * \brief De-initialize NVM
- */
-void _flash_deinit(struct _flash_device *const device)
-{
- device->hw = NULL;
- NVIC_DisableIRQ(NVMCTRL_IRQn);
-}
-
-/**
- * \brief Get the flash page size.
- */
-uint32_t _flash_get_page_size(struct _flash_device *const device)
-{
- (void)device;
- return (uint32_t)NVMCTRL_PAGE_SIZE;
-}
-
-/**
- * \brief Get the numbers of flash page.
- */
-uint32_t _flash_get_total_pages(struct _flash_device *const device)
-{
- (void)device;
- return (uint32_t)FLASH_NB_OF_PAGES;
-}
-
-/**
- * \brief Get the number of wait states for read and write operations.
- */
-uint8_t _flash_get_wait_state(struct _flash_device *const device)
-{
- return hri_nvmctrl_get_CTRLB_reg(device->hw, NVMCTRL_CTRLB_RWS_Msk);
-}
-
-/**
- * \brief Set the number of wait states for read and write operations.
- */
-void _flash_set_wait_state(struct _flash_device *const device, uint8_t state)
-{
- hri_nvmctrl_write_CTRLB_RWS_bf(device->hw, state);
-}
-
-/**
- * \brief Reads a number of bytes to a page in the internal Flash.
- */
-void _flash_read(struct _flash_device *const device, const uint32_t src_addr, uint8_t *buffer, uint32_t length)
-{
- uint32_t nvm_address = src_addr / 2;
- uint32_t i;
- uint16_t data;
-
- /* Check if the module is busy */
- while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
- /* Wait until this module isn't busy */
- }
-
- /* Clear flags */
- hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
-
- /* Check whether byte address is word-aligned*/
- if (src_addr % 2) {
- data = NVM_MEMORY[nvm_address++];
- buffer[0] = data >> 8;
- i = 1;
- } else {
- i = 0;
- }
-
- /* NVM _must_ be accessed as a series of 16-bit words, perform manual copy
- * to ensure alignment */
- while (i < length) {
- data = NVM_MEMORY[nvm_address++];
- buffer[i] = (data & 0xFF);
- if (i < (length - 1)) {
- buffer[i + 1] = (data >> 8);
- }
- i += 2;
- }
-}
-
-/**
- * \brief Writes a number of bytes to a page in the internal Flash.
- */
-void _flash_write(struct _flash_device *const device, const uint32_t dst_addr, const uint8_t *buffer, uint32_t length)
-{
- uint8_t tmp_buffer[NVMCTRL_ROW_PAGES][NVMCTRL_PAGE_SIZE];
- uint32_t row_start_addr, row_end_addr;
- uint32_t i, j, k;
- uint32_t wr_start_addr = dst_addr;
-
- do {
- row_start_addr = wr_start_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
- row_end_addr = row_start_addr + NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE - 1;
-
- /* store the erase data into temp buffer before write */
- for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
- _flash_read(device, row_start_addr + i * NVMCTRL_PAGE_SIZE, tmp_buffer[i], NVMCTRL_PAGE_SIZE);
- }
-
- /* temp buffer update */
- j = (wr_start_addr - row_start_addr) / NVMCTRL_PAGE_SIZE;
- k = wr_start_addr - row_start_addr - j * NVMCTRL_PAGE_SIZE;
- while ((wr_start_addr <= row_end_addr) && (length > 0)) {
- tmp_buffer[j][k] = *buffer;
- k = (k + 1) % NVMCTRL_PAGE_SIZE;
- if (0 == k) {
- j++;
- }
- wr_start_addr++;
- buffer++;
- length--;
- }
-
- /* erase row before write */
- _flash_erase_row(device->hw, row_start_addr);
-
- /* write buffer to flash */
- for (i = 0; i < NVMCTRL_ROW_PAGES; i++) {
- _flash_program(device->hw, row_start_addr + i * NVMCTRL_PAGE_SIZE, tmp_buffer[i], NVMCTRL_PAGE_SIZE);
- }
-
- } while (row_end_addr < (wr_start_addr + length - 1));
-}
-
-/**
- * \brief Appends a number of bytes in the internal Flash.
- */
-void _flash_append(struct _flash_device *const device, const uint32_t dst_addr, const uint8_t *buffer, uint32_t length)
-{
- uint32_t page_start_addr = dst_addr & ~(NVMCTRL_PAGE_SIZE - 1);
- uint32_t size;
- uint32_t offset = 0;
-
- if (dst_addr != page_start_addr) {
- /* Need to write some data to the end of a page */
- size = min(length, NVMCTRL_PAGE_SIZE - (dst_addr - page_start_addr));
- _flash_program(device->hw, dst_addr, buffer, size);
- page_start_addr += NVMCTRL_PAGE_SIZE;
- offset += size;
- }
-
- while (offset < length) {
- size = min(length - offset, NVMCTRL_PAGE_SIZE);
- _flash_program(device->hw, page_start_addr, buffer + offset, size);
- page_start_addr += NVMCTRL_PAGE_SIZE;
- offset += size;
- }
-}
-
-/**
- * \brief Execute erase in the internal flash
- */
-void _flash_erase(struct _flash_device *const device, uint32_t dst_addr, uint32_t page_nums)
-{
- uint8_t tmp_buffer[NVMCTRL_PAGE_SIZE];
- uint32_t row_start_addr;
- uint32_t i;
-
- row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
-
- memset(tmp_buffer, 0xFF, NVMCTRL_PAGE_SIZE);
-
- /* when address is not aligned with row start address */
- if (dst_addr != row_start_addr) {
- row_start_addr += NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE;
- for (i = 0; i < NVMCTRL_ROW_PAGES - 1; i++) {
- _flash_write(device, dst_addr, tmp_buffer, NVMCTRL_PAGE_SIZE);
- if (--page_nums == 0) {
- return;
- }
- dst_addr += NVMCTRL_PAGE_SIZE;
- if (dst_addr == row_start_addr) {
- break;
- }
- }
- }
-
- while (page_nums >= NVMCTRL_ROW_PAGES) {
- _flash_erase_row(device->hw, row_start_addr);
- row_start_addr += NVMCTRL_ROW_PAGES * NVMCTRL_PAGE_SIZE;
- page_nums -= NVMCTRL_ROW_PAGES;
- }
-
- if (page_nums != 0) {
- for (i = 0; i < page_nums; i++) {
- _flash_write(device, row_start_addr, tmp_buffer, NVMCTRL_PAGE_SIZE);
- row_start_addr += NVMCTRL_PAGE_SIZE;
- }
- }
-}
-
-/**
- * \brief Execute lock in the internal flash
- */
-int32_t _flash_lock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums)
-{
- uint32_t region_pages;
- uint32_t row_start_addr;
-
- region_pages = (uint32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
- row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
-
- if ((page_nums != region_pages) || (dst_addr != row_start_addr)) {
- return ERR_INVALID_ARG;
- }
-
- while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
- /* Wait until this module isn't busy */
- }
-
- /* Clear flags */
- hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
-
- hri_nvmctrl_write_ADDR_reg(device->hw, dst_addr / 2);
- hri_nvmctrl_write_CTRLA_reg(device->hw, NVMCTRL_CTRLA_CMD_LR | NVMCTRL_CTRLA_CMDEX_KEY);
-
- return (int32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
-}
-
-/**
- * \brief Execute unlock in the internal flash
- */
-int32_t _flash_unlock(struct _flash_device *const device, const uint32_t dst_addr, uint32_t page_nums)
-{
- uint32_t region_pages;
- uint32_t row_start_addr;
-
- region_pages = (uint32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
- row_start_addr = dst_addr & ~((NVMCTRL_PAGE_SIZE * NVMCTRL_ROW_PAGES) - 1);
-
- if ((page_nums != region_pages) || (dst_addr != row_start_addr)) {
- return ERR_INVALID_ARG;
- }
-
- while (!hri_nvmctrl_get_interrupt_READY_bit(device->hw)) {
- /* Wait until this module isn't busy */
- }
-
- /* Clear flags */
- hri_nvmctrl_clear_STATUS_reg(device->hw, NVMCTRL_STATUS_MASK);
-
- hri_nvmctrl_write_ADDR_reg(device->hw, dst_addr / 2);
- hri_nvmctrl_write_CTRLA_reg(device->hw, NVMCTRL_CTRLA_CMD_UR | NVMCTRL_CTRLA_CMDEX_KEY);
-
- return (int32_t)NVMCTRL_FLASH_SIZE / (16 * NVMCTRL_PAGE_SIZE);
-}
-
-/**
- * \brief check whether the region which is pointed by address
- */
-bool _flash_is_locked(struct _flash_device *const device, const uint32_t dst_addr)
-{
- uint16_t region_id;
-
- /* Get region for given page */
- region_id = dst_addr / (NVMCTRL_FLASH_SIZE / 16);
-
- return !(hri_nvmctrl_get_LOCK_reg(device->hw, 1 << region_id));
-}
-
-/**
- * \brief Enable/disable Flash interrupt
- */
-void _flash_set_irq_state(struct _flash_device *const device, const enum _flash_cb_type type, const bool state)
-{
- ASSERT(device);
-
- if (FLASH_DEVICE_CB_READY == type) {
- hri_nvmctrl_write_INTEN_READY_bit(device->hw, state);
- } else if (FLASH_DEVICE_CB_ERROR == type) {
- hri_nvmctrl_write_INTEN_ERROR_bit(device->hw, state);
- }
-}
-
-/**
- * \internal erase a row in flash
- * \param[in] hw The pointer to hardware instance
- * \param[in] dst_addr Destination page address to erase
- */
-static void _flash_erase_row(void *const hw, const uint32_t dst_addr)
-{
- while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
- /* Wait until this module isn't busy */
- }
-
- /* Clear flags */
- hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
-
- /* Set address and command */
- hri_nvmctrl_write_ADDR_reg(hw, dst_addr / 2);
- hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_ER | NVMCTRL_CTRLA_CMDEX_KEY);
-}
-
-/**
- * \internal write a page in flash
- * \param[in] hw The pointer to hardware instance
- * \param[in] dst_addr Destination page address to write
- * \param[in] buffer Pointer to buffer where the data to
- * write is stored
- * \param[in] size The size of data to write to a page
- */
-static void _flash_program(void *const hw, const uint32_t dst_addr, const uint8_t *buffer, const uint16_t size)
-{
- ASSERT(!(dst_addr % 2));
-
- uint32_t nvm_address = dst_addr / 2;
- uint16_t i, data;
-
- while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
- /* Wait until this module isn't busy */
- }
-
- hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY);
-
- while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
- /* Wait until this module isn't busy */
- }
-
- /* Clear flags */
- hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
-
- for (i = 0; i < size; i += 2) {
- data = buffer[i];
- if (i < NVMCTRL_PAGE_SIZE - 1) {
- data |= (buffer[i + 1] << 8);
- }
- NVM_MEMORY[nvm_address++] = data;
- }
-
- while (!hri_nvmctrl_get_interrupt_READY_bit(hw)) {
- /* Wait until this module isn't busy */
- }
-
- hri_nvmctrl_write_ADDR_reg(hw, dst_addr / 2);
- hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_WP | NVMCTRL_CTRLA_CMDEX_KEY);
-}
-
-/**
- * \internal NVM interrupt handler
- */
-void NVMCTRL_Handler(void)
-{
- void *const hw = _nvm_dev->hw;
-
- if (hri_nvmctrl_get_interrupt_READY_bit(hw)) {
- hri_nvmctrl_clear_interrupt_READY_bit(hw);
- if (NULL != _nvm_dev->flash_cb.ready_cb) {
- _nvm_dev->flash_cb.ready_cb(_nvm_dev);
- }
- } else if (hri_nvmctrl_get_interrupt_ERROR_bit(hw)) {
- hri_nvmctrl_clear_interrupt_ERROR_bit(hw);
- if (NULL != _nvm_dev->flash_cb.error_cb) {
- _nvm_dev->flash_cb.error_cb(_nvm_dev);
- }
- }
-}
-
-/*
-The NVM User Row contains calibration data that are automatically read at device
-power on.
-The NVM User Row can be read at address 0x804000.
-*/
-#ifndef _NVM_USER_ROW_BASE
-#define _NVM_USER_ROW_BASE 0x804000
-#endif
-#define _NVM_USER_ROW_N_BITS 64
-#define _NVM_USER_ROW_N_BYTES (_NVM_USER_ROW_N_BITS / 8)
-#define _NVM_USER_ROW_END (((uint8_t *)_NVM_USER_ROW_BASE) + _NVM_USER_ROW_N_BYTES - 1)
-#define _IS_NVM_USER_ROW(b) \
- (((uint8_t *)(b) >= (uint8_t *)(_NVM_USER_ROW_BASE)) && ((uint8_t *)(b) <= (uint8_t *)(_NVM_USER_ROW_END)))
-#define _IN_NVM_USER_ROW(b, o) (((uint8_t *)(b) + (o)) <= (uint8_t *)(_NVM_USER_ROW_END))
-
-/*
-The NVM Software Calibration Area can be read at address 0x806020.
-The NVM Software Calibration Area can not be written.
-*/
-#ifndef _NVM_SW_CALIB_AREA_BASE
-#define _NVM_SW_CALIB_AREA_BASE 0x806020
-#endif
-#define _NVM_SW_CALIB_AREA_N_BITS 128
-#define _NVM_SW_CALIB_AREA_N_BYTES (_NVM_SW_CALIB_AREA_N_BITS / 8)
-#define _NVM_SW_CALIB_AREA_END (((uint8_t *)_NVM_SW_CALIB_AREA_BASE) + _NVM_SW_CALIB_AREA_N_BYTES - 1)
-#define _IS_NVM_SW_CALIB_AREA(b) \
- (((uint8_t *)(b) >= (uint8_t *)_NVM_SW_CALIB_AREA_BASE) && ((uint8_t *)(b) <= (uint8_t *)_NVM_SW_CALIB_AREA_END))
-#define _IN_NVM_SW_CALIB_AREA(b, o) (((uint8_t *)(b) + (o)) <= (uint8_t *)(_NVM_SW_CALIB_AREA_END))
-
-/**
- * \internal Read left aligned data bits
- * \param[in] base Base address for the data
- * \param[in] bit_offset Offset for the bitfield start
- * \param[in] n_bits Number of bits in the bitfield
- */
-static inline uint32_t _user_area_read_l32_bits(const volatile uint32_t *base, const uint32_t bit_offset,
- const uint8_t n_bits)
-{
- return base[bit_offset >> 5] & ((1 << n_bits) - 1);
-}
-
-/**
- * \internal Read right aligned data bits
- * \param[in] base Base address for the data
- * \param[in] bit_offset Offset for the bitfield start
- * \param[in] n_bits Number of bits in the bitfield
- */
-static inline uint32_t _user_area_read_r32_bits(const volatile uint32_t *base, const uint32_t bit_offset,
- const uint8_t n_bits)
-{
- return (base[bit_offset >> 5] >> (bit_offset & 0x1F)) & ((1 << n_bits) - 1);
-}
-
-int32_t _user_area_read(const void *base, const uint32_t offset, uint8_t *buf, uint32_t size)
-{
- ASSERT(buf);
-
- /** Parameter check. */
- if (_IS_NVM_USER_ROW(base)) {
- if (!_IN_NVM_USER_ROW(base, offset)) {
- return ERR_BAD_ADDRESS;
- }
- /* Cut off if request too many bytes */
- if (!_IN_NVM_USER_ROW(base, offset + size - 1)) {
- return ERR_INVALID_ARG;
- }
- } else if (_IS_NVM_SW_CALIB_AREA(base)) {
- if (!_IN_NVM_SW_CALIB_AREA(base, offset)) {
- return ERR_BAD_ADDRESS;
- }
- /* Cut off if request too many bytes */
- if (!_IN_NVM_SW_CALIB_AREA(base, offset + size - 1)) {
- return ERR_INVALID_ARG;
- }
- } else {
- return ERR_UNSUPPORTED_OP;
- }
-
- /* Copy data */
- memcpy(buf, ((uint8_t *)base) + offset, size);
- return ERR_NONE;
-}
-
-uint32_t _user_area_read_bits(const void *base, const uint32_t bit_offset, const uint8_t n_bits)
-{
- volatile uint32_t *mem_base = (volatile uint32_t *)base;
- uint32_t l_off, l_bits;
- uint32_t r_off, r_bits;
-
- /** Parameter check. */
- if (_IS_NVM_USER_ROW(base)) {
- ASSERT(_IN_NVM_USER_ROW(base, bit_offset >> 3) && _IN_NVM_USER_ROW(base, (bit_offset + n_bits - 1) >> 3));
- } else if (_IS_NVM_SW_CALIB_AREA(base)) {
- ASSERT(_IN_NVM_SW_CALIB_AREA(base, bit_offset >> 3)
- && _IN_NVM_SW_CALIB_AREA(base, (bit_offset + n_bits - 1) >> 3));
- } else {
- ASSERT(false);
- }
-
- /* Since the bitfield can cross 32-bits boundaries,
- * left and right bits are read from 32-bit aligned address
- * and then combined together. */
- l_off = bit_offset & (~(32 - 1));
- r_off = l_off + 32;
- l_bits = 32 - (bit_offset & (32 - 1));
- if (n_bits > l_bits) {
- r_bits = n_bits - l_bits;
- } else {
- l_bits = n_bits;
- r_bits = 0;
- }
- return _user_area_read_r32_bits(mem_base, bit_offset, l_bits)
- + (_user_area_read_l32_bits(mem_base, r_off, r_bits) << l_bits);
-}
-
-/** \internal Write 64-bit user row
- * \param[in] _row Pointer to 64-bit user row data.
- */
-static int32_t _user_row_write_exec(const uint32_t *_row)
-{
- Nvmctrl *hw = NVMCTRL;
- uint32_t ctrlb = hri_nvmctrl_read_CTRLB_reg(NVMCTRL);
-
- /* Denie if Security Bit is set */
- if (hri_nvmctrl_get_STATUS_reg(hw, NVMCTRL_STATUS_SB)) {
- return ERR_DENIED;
- }
-
- /* Do Save */
-
- /* - Prepare. */
- while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
- /* Wait until this module isn't busy */
- }
- hri_nvmctrl_clear_STATUS_reg(hw, NVMCTRL_STATUS_MASK);
- hri_nvmctrl_set_CTRLB_MANW_bit(hw);
-
- /* - Erase AUX row. */
- hri_nvmctrl_write_ADDR_reg(hw, (hri_nvmctrl_addr_reg_t)_NVM_USER_ROW_BASE);
- hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_EAR | NVMCTRL_CTRLA_CMDEX_KEY);
- while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
- /* Wait until this module isn't busy */
- }
-
- /* - Page buffer clear & write. */
- hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_PBC | NVMCTRL_CTRLA_CMDEX_KEY);
- while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
- /* Wait until this module isn't busy */
- }
- *((uint32_t *)NVMCTRL_AUX0_ADDRESS) = _row[0];
- *(((uint32_t *)NVMCTRL_AUX0_ADDRESS) + 1) = _row[1];
-
- /* - Write AUX row. */
- hri_nvmctrl_write_ADDR_reg(hw, (hri_nvmctrl_addr_reg_t)_NVM_USER_ROW_BASE);
- hri_nvmctrl_write_CTRLA_reg(hw, NVMCTRL_CTRLA_CMD_WAP | NVMCTRL_CTRLA_CMDEX_KEY);
- while (!hri_nvmctrl_get_INTFLAG_reg(hw, NVMCTRL_INTFLAG_READY)) {
- /* Wait until this module isn't busy */
- }
-
- /* Restore CTRLB */
- hri_nvmctrl_write_CTRLB_reg(NVMCTRL, ctrlb);
-
- return ERR_NONE;
-}
-
-int32_t _user_area_write(void *base, const uint32_t offset, const uint8_t *buf, const uint32_t size)
-{
- uint32_t _row[2]; /* Copy of user row. */
-
- /** Parameter check. */
- if (_IS_NVM_USER_ROW(base)) {
- if (!_IN_NVM_USER_ROW(base, offset)) {
- return ERR_BAD_ADDRESS;
- } else if (!_IN_NVM_USER_ROW(base, offset + size - 1)) {
- return ERR_INVALID_ARG;
- }
- } else if (_IS_NVM_SW_CALIB_AREA(base)) {
- return ERR_DENIED;
- } else {
- return ERR_UNSUPPORTED_OP;
- }
-
- memcpy(_row, base, 8); /* Store previous data. */
- memcpy((uint8_t *)_row + offset, buf, size); /* Modify with buf data. */
-
- return _user_row_write_exec(_row);
-}
-
-int32_t _user_area_write_bits(void *base, const uint32_t bit_offset, const uint32_t bits, const uint8_t n_bits)
-{
- uint32_t _row[2]; /* Copy of user row. */
- uint32_t l_off, l_bits;
- uint32_t r_off, r_bits;
-
- /** Parameter check. */
- if (_IS_NVM_USER_ROW(base)) {
- if (!_IN_NVM_USER_ROW(base, bit_offset >> 3)) {
- return ERR_BAD_ADDRESS;
- } else if (!_IN_NVM_USER_ROW(base, (bit_offset + n_bits - 1) >> 3)) {
- return ERR_INVALID_ARG;
- }
- } else if (_IS_NVM_SW_CALIB_AREA(base)) {
- return ERR_DENIED;
- } else {
- return ERR_UNSUPPORTED_OP;
- }
-
- /* Since the bitfield can cross 32-bits boundaries,
- * left and right bits are splitted for 32-bit aligned address
- * and then saved. */
- l_off = bit_offset & (~(32 - 1));
- r_off = l_off + 32;
- l_bits = 32 - (bit_offset & (32 - 1));
- if (n_bits > l_bits) {
- r_bits = n_bits - l_bits;
- } else {
- l_bits = n_bits;
- r_bits = 0;
- }
-
- memcpy(_row, base, 8); /* Store previous data. */
- if (l_bits) {
- uint32_t l_mask = ((1 << l_bits) - 1) << (bit_offset & (32 - 1));
- _row[bit_offset >> 5] &= ~l_mask;
- _row[bit_offset >> 5] |= (bits << (bit_offset & (32 - 1))) & l_mask;
- }
- if (r_bits) {
- uint32_t r_mask = (1 << r_bits) - 1;
- _row[r_off >> 5] &= ~r_mask;
- _row[r_off >> 5] |= bits >> l_bits;
- }
- return _user_row_write_exec(_row);
-}
diff --git a/atmel-samd/asf4/samd21/hpl/pm/hpl_pm.c b/atmel-samd/asf4/samd21/hpl/pm/hpl_pm.c
deleted file mode 100644
index 2df1169d0..000000000
--- a/atmel-samd/asf4/samd21/hpl/pm/hpl_pm.c
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * \file
- *
- * \brief SAM Power manager
- *
- * Copyright (C) 2014-2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_pm_base.h>
-#include <hpl_pm_config.h>
-#include <hpl_reset.h>
-#include <hpl_sleep.h>
-#include <utils_assert.h>
-
-/**
- * \brief Retrieve the reset reason
- */
-enum reset_reason _get_reset_reason(void)
-{
- return (enum reset_reason)hri_pm_read_RCAUSE_reg(PM);
-}
-
-/**
- * \brief Set the sleep mode for the device
- */
-int32_t _set_sleep_mode(const uint8_t mode)
-{
- switch (mode) {
- case 0:
- case 1:
- case 2:
- SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
- PM->SLEEP.reg = mode;
- return ERR_NONE;
- case 3:
- SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
- return ERR_NONE;
- default:
- return ERR_INVALID_ARG;
- }
-}
-
-/**
- * \brief Power Manager Init
- */
-void _pm_init(void)
-{
- hri_pm_set_CPUSEL_CPUDIV_bf(PM, CONF_CPU_DIV);
- hri_pm_set_APBASEL_APBADIV_bf(PM, CONF_APBA_DIV);
- hri_pm_set_APBBSEL_APBBDIV_bf(PM, CONF_APBB_DIV);
- hri_pm_set_APBCSEL_APBCDIV_bf(PM, CONF_APBC_DIV);
-}
diff --git a/atmel-samd/asf4/samd21/hpl/pm/hpl_pm_base.h b/atmel-samd/asf4/samd21/hpl/pm/hpl_pm_base.h
deleted file mode 100644
index 3f308b426..000000000
--- a/atmel-samd/asf4/samd21/hpl/pm/hpl_pm_base.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/**
- * \file
- *
- * \brief SAM Power manager
- *
- * Copyright (C) 2014-2017 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 distributionn.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- */
-
-#ifndef _HPL_PM_BASE_H_INCLUDED
-#define _HPL_PM_BASE_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <utils_assert.h>
-
-/**
- * \addtogroup pm_group PM Low Level Driver Helpers
- *
- * \section pm_helpers_rev Revision History
- * - v0.0.0.1 Initial Commit
- *
- *@{
- */
-
-/**
- * \brief Power Manager buses
- */
-enum _pm_bus { PM_BUS_AHB, PM_BUS_APBA, PM_BUS_APBB, PM_BUS_APBC };
-
-/**
- * \name HPL functions
- */
-//@{
-/**
- * \brief Retrieve AHB index
- *
- * \param[in] module Module to get index for
- *
- * \return index of the given module if succeeds, ERR_INVALID_ARG otherwise
- */
-static inline int32_t _pm_get_ahb_index(const void *const module)
-{
- if ((uint32_t)module == (uint32_t)PM_BUS_APBA) {
- return 0;
- } else if ((uint32_t)module == (uint32_t)PM_BUS_APBB) {
- return 1;
- } else if ((uint32_t)module == (uint32_t)PM_BUS_APBC) {
- return 2;
- }
- if ((uint32_t)module == (uint32_t)DSU) {
- return 3;
- } else if ((uint32_t)module == (uint32_t)NVMCTRL) {
- return 4;
- } else if ((uint32_t)module == (uint32_t)DMAC) {
- return 5;
- }
-#ifdef USB
- else if ((uint32_t)module == (uint32_t)USB) {
- return 6;
- }
-#endif
-
- return ERR_INVALID_ARG;
-}
-
-/**
- * \brief Retrieve APBB index
- *
- * \param[in] module Module to get index for
- *
- * \return index of the given module if succeeds, ERR_INVALID_ARG otherwise
- */
-static inline int32_t _pm_get_apbb_index(const void *const module)
-{
- if ((uint32_t)module == (uint32_t)PAC1) {
- return 0;
- } else if ((uint32_t)module == (uint32_t)DSU) {
- return 1;
- } else if ((uint32_t)module == (uint32_t)NVMCTRL) {
- return 2;
- }
- if ((uint32_t)module == (uint32_t)PORT) {
- return 3;
- } else if ((uint32_t)module == (uint32_t)DMAC) {
- return 4;
- }
-#ifdef USB
- else if ((uint32_t)module == (uint32_t)USB) {
- return 5;
- }
-#endif
-
- return ERR_INVALID_ARG;
-}
-
-/**
- * \brief Enable clock on the given bus for the given hardware module
- *
- * This function enables clock on the given bus for the given hardware module.
- * For an overview of available buses and hardware modules see datasheet.
- *
- * \param[in] bus A bus to enable clock on
- * \param[in] module A hardware module to enable clock for
- */
-static inline void _pm_enable_bus_clock(const enum _pm_bus bus, const void *const module)
-{
- uint32_t peripheral = ((uint32_t)module & 0x0000ff00) >> 10;
-
- switch (bus) {
- case PM_BUS_AHB:
- if (_pm_get_ahb_index(module) >= 0) {
- peripheral = (uint32_t)_pm_get_ahb_index(module);
- PM->AHBMASK.reg |= 1 << peripheral;
- }
- break;
- case PM_BUS_APBA:
- PM->APBAMASK.reg |= 1 << peripheral;
- break;
- case PM_BUS_APBB:
- if (_pm_get_apbb_index(module) >= 0) {
- peripheral = (uint32_t)_pm_get_apbb_index(module);
- PM->APBBMASK.reg |= 1 << peripheral;
- }
- break;
- case PM_BUS_APBC:
- PM->APBCMASK.reg |= 1 << peripheral;
- break;
- default:
- ASSERT(false);
- break;
- }
-}
-
-/**
- * \brief Disable clock on the given bus for the given hardware module
- *
- * This function disables clock on the given bus for the given hardware module.
- * For an overview of available buses and hardware modules see datasheet.
- *
- * \param[in] bus A bus to disable clock on
- * \param[in] module A hardware module to disable clock for
- */
-static inline void _pm_disable_bus_clock(const enum _pm_bus bus, const void *const module)
-{
- uint32_t peripheral = ((uint32_t)module & 0x0000ff00) >> 10;
-
- switch (bus) {
- case PM_BUS_AHB:
- if (_pm_get_ahb_index(module) >= 0) {
- peripheral = (uint32_t)_pm_get_ahb_index(module);
- PM->AHBMASK.reg &= ~(1 << peripheral);
- }
- break;
- case PM_BUS_APBA:
- PM->APBAMASK.reg &= ~(1 << peripheral);
- break;
- case PM_BUS_APBB:
- if (_pm_get_apbb_index(module) >= 0) {
- peripheral = (uint32_t)_pm_get_apbb_index(module);
- PM->APBBMASK.reg &= ~(1 << peripheral);
- }
- break;
- case PM_BUS_APBC:
- PM->APBCMASK.reg &= ~(1 << peripheral);
- break;
- default:
- ASSERT(false);
- break;
- }
-}
-
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _HPL_PM_BASE_H_INCLUDED */
diff --git a/atmel-samd/asf4/samd21/hpl/port/hpl_gpio_base.h b/atmel-samd/asf4/samd21/hpl/port/hpl_gpio_base.h
deleted file mode 100644
index 6ff4dcaa9..000000000
--- a/atmel-samd/asf4/samd21/hpl/port/hpl_gpio_base.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/**
- * \file
- *
- * \brief SAM PORT.
- *
- * 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
- *
- */
-#include <compiler.h>
-#include <hpl_gpio.h>
-#include <utils_assert.h>
-
-/**
- * \brief Set direction on port with mask
- */
-static inline void _gpio_set_direction(const enum gpio_port port, const uint32_t mask,
- const enum gpio_direction direction)
-{
- switch (direction) {
- case GPIO_DIRECTION_OFF:
- hri_port_clear_DIR_reg(PORT_IOBUS, port, mask);
- hri_port_write_WRCONFIG_reg(PORT, port, PORT_WRCONFIG_WRPINCFG | (mask & 0xffff));
- hri_port_write_WRCONFIG_reg(
- PORT, port, PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | ((mask & 0xffff0000) >> 16));
- break;
-
- case GPIO_DIRECTION_IN:
- hri_port_clear_DIR_reg(PORT_IOBUS, port, mask);
- hri_port_write_WRCONFIG_reg(PORT, port, PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_INEN | (mask & 0xffff));
- hri_port_write_WRCONFIG_reg(PORT,
- port,
- PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | PORT_WRCONFIG_INEN
- | ((mask & 0xffff0000) >> 16));
- break;
-
- case GPIO_DIRECTION_OUT:
- hri_port_set_DIR_reg(PORT_IOBUS, port, mask);
- hri_port_write_WRCONFIG_reg(PORT, port, PORT_WRCONFIG_WRPINCFG | (mask & 0xffff));
- hri_port_write_WRCONFIG_reg(
- PORT, port, PORT_WRCONFIG_HWSEL | PORT_WRCONFIG_WRPINCFG | ((mask & 0xffff0000) >> 16));
- break;
-
- default:
- ASSERT(false);
- }
-}
-
-/**
- * \brief Set output level on port with mask
- */
-static inline void _gpio_set_level(const enum gpio_port port, const uint32_t mask, const bool level)
-{
- if (level) {
- hri_port_set_OUT_reg(PORT_IOBUS, port, mask);
- } else {
- hri_port_clear_OUT_reg(PORT_IOBUS, port, mask);
- }
-}
-
-/**
- * \brief Change output level to the opposite with mask
- */
-static inline void _gpio_toggle_level(const enum gpio_port port, const uint32_t mask)
-{
- hri_port_toggle_OUT_reg(PORT_IOBUS, port, mask);
-}
-
-/**
- * \brief Get input levels on all port pins
- */
-static inline uint32_t _gpio_get_level(const enum gpio_port port)
-{
- uint32_t tmp;
-
- CRITICAL_SECTION_ENTER();
-
- uint32_t dir_tmp = hri_port_read_DIR_reg(PORT_IOBUS, port);
-
- tmp = hri_port_read_IN_reg(PORT, port) & ~dir_tmp;
- tmp |= hri_port_read_OUT_reg(PORT_IOBUS, port) & dir_tmp;
-
- CRITICAL_SECTION_LEAVE();
-
- return tmp;
-}
-
-/**
- * \brief Set pin pull mode
- */
-static inline void _gpio_set_pin_pull_mode(const enum gpio_port port, const uint8_t pin,
- const enum gpio_pull_mode pull_mode)
-{
- switch (pull_mode) {
- case GPIO_PULL_OFF:
- hri_port_clear_PINCFG_PULLEN_bit(PORT, port, pin);
- break;
-
- case GPIO_PULL_UP:
- hri_port_clear_DIR_reg(PORT_IOBUS, port, 1U << pin);
- hri_port_set_PINCFG_PULLEN_bit(PORT, port, pin);
- hri_port_set_OUT_reg(PORT_IOBUS, port, 1U << pin);
- break;
-
- case GPIO_PULL_DOWN:
- hri_port_clear_DIR_reg(PORT_IOBUS, port, 1U << pin);
- hri_port_set_PINCFG_PULLEN_bit(PORT, port, pin);
- hri_port_clear_OUT_reg(PORT_IOBUS, port, 1U << pin);
- break;
-
- default:
- ASSERT(false);
- break;
- }
-}
-
-/**
- * \brief Set gpio pin function
- */
-static inline void _gpio_set_pin_function(const uint32_t gpio, const uint32_t function)
-{
- uint8_t port = GPIO_PORT(gpio);
- uint8_t pin = GPIO_PIN(gpio);
-
- if (function == GPIO_PIN_FUNCTION_OFF) {
- hri_port_write_PINCFG_PMUXEN_bit(PORT, port, pin, false);
-
- } else {
- hri_port_write_PINCFG_PMUXEN_bit(PORT, port, pin, true);
-
- if (pin & 1) {
- // Odd numbered pin
- hri_port_write_PMUX_PMUXO_bf(PORT, port, pin >> 1, function & 0xffff);
- } else {
- // Even numbered pin
- hri_port_write_PMUX_PMUXE_bf(PORT, port, pin >> 1, function & 0xffff);
- }
- }
-}
diff --git a/atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc.c b/atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc.c
deleted file mode 100644
index 80fca2b5b..000000000
--- a/atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc.c
+++ /dev/null
@@ -1,201 +0,0 @@
-/**
- * \file
- *
- * \brief RTC Driver (Calendar Mode)
- *
- * Copyright (C) 2014-2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include "hpl_calendar.h"
-#include "hpl_timer.h"
-#include <hpl_rtc_config.h>
-#include <utils_assert.h>
-
-/*!< Pointer to hpl device */
-
-static struct _timer_device *_rtc_dev = NULL;
-
-/**
- * \brief Initialize Timer
- */
-int32_t _timer_init(struct _timer_device *const dev, void *const hw)
-{
- ASSERT(dev);
-
- uint16_t register_value;
- dev->hw = hw;
-
- hri_rtcmode0_write_CTRL_reg(dev->hw, RTC_MODE0_CTRL_SWRST);
- hri_rtcmode0_wait_for_sync(dev->hw);
-
- /* Set mode 0 */
- register_value = RTC_MODE0_CTRL_MODE(0);
-
- /* Set prescaler */
- register_value |= RTC_MODE0_CTRL_PRESCALER(CONF_RTC_PRESCALER);
-
- /* clear counter on compare/timer match */
- register_value |= RTC_MODE0_CTRL_MATCHCLR;
-
- hri_rtcmode0_write_CTRL_reg(dev->hw, register_value);
-
- hri_rtcmode0_write_COMP_COMP_bf(dev->hw, 0, CONF_RTC_COMP_VAL);
- hri_rtcmode0_set_INTEN_CMP0_bit(dev->hw);
-
-/* set event control */
-#if CONF_RTC_EVENT_CONTROL_ENABLE == 1
- hri_rtcmode0_write_EVCTRL_reg(dev->hw,
- (CONF_RTC_PEREO0 << RTC_MODE0_EVCTRL_PEREO0_Pos)
- | (CONF_RTC_PEREO1 << RTC_MODE0_EVCTRL_PEREO1_Pos)
- | (CONF_RTC_PEREO2 << RTC_MODE0_EVCTRL_PEREO2_Pos)
- | (CONF_RTC_PEREO3 << RTC_MODE0_EVCTRL_PEREO3_Pos)
- | (CONF_RTC_PEREO4 << RTC_MODE0_EVCTRL_PEREO4_Pos)
- | (CONF_RTC_PEREO5 << RTC_MODE0_EVCTRL_PEREO5_Pos)
- | (CONF_RTC_PEREO6 << RTC_MODE0_EVCTRL_PEREO6_Pos)
- | (CONF_RTC_PEREO7 << RTC_MODE0_EVCTRL_PEREO7_Pos)
- | (CONF_RTC_COMPE0 << RTC_MODE0_EVCTRL_CMPEO_Pos)
- | (CONF_RTC_OVFEO << RTC_MODE0_EVCTRL_OVFEO_Pos));
-#endif
-
- _rtc_dev = dev;
-
- return ERR_NONE;
-}
-
-/**
- * \brief De-initialize Timer
- */
-void _timer_deinit(struct _timer_device *const dev)
-{
- ASSERT(dev && dev->hw);
-
- NVIC_DisableIRQ(RTC_IRQn);
-
- hri_rtcmode0_write_CTRL_reg(dev->hw, RTC_MODE0_CTRL_SWRST);
-}
-
-/**
- * \brief Start hardware timer
- */
-void _timer_start(struct _timer_device *const dev)
-{
- ASSERT(dev && dev->hw);
-
- NVIC_EnableIRQ(RTC_IRQn);
- hri_rtcmode0_write_COUNT_COUNT_bf(dev->hw, 0);
- hri_rtcmode0_wait_for_sync(dev->hw);
- hri_rtcmode0_set_CTRL_ENABLE_bit(dev->hw);
-}
-
-/**
- * \brief Stop hardware timer
- */
-void _timer_stop(struct _timer_device *const dev)
-{
- ASSERT(dev && dev->hw);
-
- hri_rtcmode0_clear_CTRL_ENABLE_bit(dev->hw);
-}
-
-/**
- * \brief Set timer period
- */
-void _timer_set_period(struct _timer_device *const dev, const uint32_t clock_cycles)
-{
- hri_rtcmode0_write_COMP_COMP_bf(dev->hw, 0, clock_cycles);
-}
-
-/**
- * \brief Retrieve timer period
- */
-uint32_t _timer_get_period(const struct _timer_device *const dev)
-{
- return hri_rtcmode0_read_COMP_COMP_bf(dev->hw, 0);
-}
-
-/**
- * \brief Check if timer is running
- */
-bool _timer_is_started(const struct _timer_device *const dev)
-{
- return hri_rtcmode0_get_CTRL_ENABLE_bit(dev->hw);
-}
-
-/**
- * \brief Set timer IRQ
- */
-void _timer_set_irq(struct _timer_device *const dev)
-{
- (void)dev;
-}
-
-/**
- * \brief RTC Timer interrupt handler
- *
- * \param[in] p The pointer to calendar device struct
- */
-static void _rtc_timer_interrupt_handler(struct _timer_device *dev)
-{
- /* Read and mask interrupt flag register */
- uint16_t flag = hri_rtcmode0_read_INTFLAG_reg(dev->hw);
-
- if (flag & RTC_MODE0_INTFLAG_CMP0) {
- if (dev->timer_cb.period_expired) {
- dev->timer_cb.period_expired(dev);
- }
-
- /* Clear interrupt flag */
- hri_rtcmode0_clear_interrupt_CMP0_bit(dev->hw);
- }
-}
-
-/**
- * \brief Retrieve timer helper functions
- */
-struct _timer_hpl_interface *_rtc_get_timer(void)
-{
- return NULL;
-}
-
-/**
- * \brief Rtc interrupt handler
- */
-void RTC_Handler(void)
-{
- _rtc_timer_interrupt_handler(_rtc_dev);
-}
diff --git a/atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc_base.h b/atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc_base.h
deleted file mode 100644
index bbcf242b9..000000000
--- a/atmel-samd/asf4/samd21/hpl/rtc/hpl_rtc_base.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * \file
- *
- * \brief RTC
- *
- * Copyright (C) 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 distributionn.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- */
-
-#ifndef _HPL_RTC2_V200_H_INCLUDED
-#define _HPL_RTC2_V200_H_INCLUDED
-
-#include <hpl_timer.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \brief Retrieve timer helper functions
- *
- * \return A pointer to set of timer helper functions
- */
-struct _timer_hpl_interface *_rtc_get_timer(void);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _HPL_RTC2_V200_H_INCLUDED */
diff --git a/atmel-samd/asf4/samd21/hpl/sercom/hpl_sercom.c b/atmel-samd/asf4/samd21/hpl/sercom/hpl_sercom.c
deleted file mode 100644
index e9898b1d9..000000000
--- a/atmel-samd/asf4/samd21/hpl/sercom/hpl_sercom.c
+++ /dev/null
@@ -1,2897 +0,0 @@
-
-/**
- * \file
- *
- * \brief SAM Serial Communication Interface
- *
- * Copyright (C) 2014-2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-#include <hpl_dma.h>
-#include <hpl_i2c_m_async.h>
-#include <hpl_i2c_m_sync.h>
-#include <hpl_i2c_s_async.h>
-#include <hpl_sercom_config.h>
-#include <hpl_spi_m_async.h>
-#include <hpl_spi_m_sync.h>
-#include <hpl_spi_s_async.h>
-#include <hpl_spi_s_sync.h>
-#include <hpl_usart_async.h>
-#include <hpl_usart_sync.h>
-#include <utils.h>
-#include <utils_assert.h>
-
-#ifndef CONF_SERCOM_0_USART_ENABLE
-#define CONF_SERCOM_0_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_1_USART_ENABLE
-#define CONF_SERCOM_1_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_2_USART_ENABLE
-#define CONF_SERCOM_2_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_3_USART_ENABLE
-#define CONF_SERCOM_3_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_4_USART_ENABLE
-#define CONF_SERCOM_4_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_5_USART_ENABLE
-#define CONF_SERCOM_5_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_6_USART_ENABLE
-#define CONF_SERCOM_6_USART_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_7_USART_ENABLE
-#define CONF_SERCOM_7_USART_ENABLE 0
-#endif
-
-/** Amount of SERCOM that is used as USART. */
-#define SERCOM_USART_AMOUNT \
- (CONF_SERCOM_0_USART_ENABLE + CONF_SERCOM_1_USART_ENABLE + CONF_SERCOM_2_USART_ENABLE + CONF_SERCOM_3_USART_ENABLE \
- + CONF_SERCOM_4_USART_ENABLE \
- + CONF_SERCOM_5_USART_ENABLE \
- + CONF_SERCOM_6_USART_ENABLE \
- + CONF_SERCOM_7_USART_ENABLE)
-
-/**
- * \brief Macro is used to fill usart configuration structure based on
- * its number
- *
- * \param[in] n The number of structures
- */
-#define SERCOM_CONFIGURATION(n) \
- { \
- n, SERCOM_USART_CTRLA_MODE(CONF_SERCOM_##n##_USART_MODE) \
- | (CONF_SERCOM_##n##_USART_RUNSTDBY << SERCOM_USART_CTRLA_RUNSTDBY_Pos) \
- | (CONF_SERCOM_##n##_USART_IBON << SERCOM_USART_CTRLA_IBON_Pos) \
- | SERCOM_USART_CTRLA_SAMPR(CONF_SERCOM_##n##_USART_SAMPR) \
- | SERCOM_USART_CTRLA_TXPO(CONF_SERCOM_##n##_USART_TXPO) \
- | SERCOM_USART_CTRLA_RXPO(CONF_SERCOM_##n##_USART_RXPO) \
- | SERCOM_USART_CTRLA_SAMPA(CONF_SERCOM_##n##_USART_SAMPA) \
- | SERCOM_USART_CTRLA_FORM(CONF_SERCOM_##n##_USART_FORM) \
- | (CONF_SERCOM_##n##_USART_CMODE << SERCOM_USART_CTRLA_CMODE_Pos) \
- | (CONF_SERCOM_##n##_USART_CPOL << SERCOM_USART_CTRLA_CPOL_Pos) \
- | (CONF_SERCOM_##n##_USART_DORD << SERCOM_USART_CTRLA_DORD_Pos), \
- SERCOM_USART_CTRLB_CHSIZE(CONF_SERCOM_##n##_USART_CHSIZE) \
- | (CONF_SERCOM_##n##_USART_SBMODE << SERCOM_USART_CTRLB_SBMODE_Pos) \
- | (CONF_SERCOM_##n##_USART_CLODEN << SERCOM_USART_CTRLB_COLDEN_Pos) \
- | (CONF_SERCOM_##n##_USART_SFDE << SERCOM_USART_CTRLB_SFDE_Pos) \
- | (CONF_SERCOM_##n##_USART_ENC << SERCOM_USART_CTRLB_ENC_Pos) \
- | (CONF_SERCOM_##n##_USART_PMODE << SERCOM_USART_CTRLB_PMODE_Pos) \
- | (CONF_SERCOM_##n##_USART_TXEN << SERCOM_USART_CTRLB_TXEN_Pos) \
- | (CONF_SERCOM_##n##_USART_RXEN << SERCOM_USART_CTRLB_RXEN_Pos), \
- (uint16_t)(CONF_SERCOM_##n##_USART_BAUD_RATE), CONF_SERCOM_##n##_USART_FRACTIONAL, \
- CONF_SERCOM_##n##_USART_RECEIVE_PULSE_LENGTH, CONF_SERCOM_##n##_USART_DEBUG_STOP_MODE, \
- }
-
-/**
- * \brief SERCOM USART configuration type
- */
-struct usart_configuration {
- uint8_t number;
- hri_sercomusart_ctrla_reg_t ctrl_a;
- hri_sercomusart_ctrlb_reg_t ctrl_b;
- hri_sercomusart_baud_reg_t baud;
- uint8_t fractional;
- hri_sercomusart_rxpl_reg_t rxpl;
- hri_sercomusart_dbgctrl_reg_t debug_ctrl;
-};
-
-#if SERCOM_USART_AMOUNT < 1
-/** Dummy array to pass compiling. */
-static struct usart_configuration _usarts[1] = {{0}};
-#else
-/**
- * \brief Array of SERCOM USART configurations
- */
-static struct usart_configuration _usarts[] = {
-#if CONF_SERCOM_0_USART_ENABLE == 1
- SERCOM_CONFIGURATION(0),
-#endif
-#if CONF_SERCOM_1_USART_ENABLE == 1
- SERCOM_CONFIGURATION(1),
-#endif
-#if CONF_SERCOM_2_USART_ENABLE == 1
- SERCOM_CONFIGURATION(2),
-#endif
-#if CONF_SERCOM_3_USART_ENABLE == 1
- SERCOM_CONFIGURATION(3),
-#endif
-#if CONF_SERCOM_4_USART_ENABLE == 1
- SERCOM_CONFIGURATION(4),
-#endif
-#if CONF_SERCOM_5_USART_ENABLE == 1
- SERCOM_CONFIGURATION(5),
-#endif
-#if CONF_SERCOM_6_USART_ENABLE == 1
- SERCOM_CONFIGURATION(6),
-#endif
-#if CONF_SERCOM_7_USART_ENABLE == 1
- SERCOM_CONFIGURATION(7),
-#endif
-};
-#endif
-
-static uint8_t _get_sercom_index(const void *const hw);
-static uint8_t _sercom_get_irq_num(const void *const hw);
-static void _sercom_init_irq_param(const void *const hw, void *dev);
-static uint8_t _sercom_get_hardware_index(const void *const hw);
-
-static int32_t _usart_init(void *const hw);
-static inline void _usart_deinit(void *const hw);
-static uint16_t _usart_calculate_baud_rate(const uint32_t baud, const uint32_t clock_rate, const uint8_t samples,
- const enum usart_baud_rate_mode mode, const uint8_t fraction);
-static void _usart_set_baud_rate(void *const hw, const uint32_t baud_rate);
-static void _usart_set_data_order(void *const hw, const enum usart_data_order order);
-static void _usart_set_mode(void *const hw, const enum usart_mode mode);
-static void _usart_set_parity(void *const hw, const enum usart_parity parity);
-static void _usart_set_stop_bits(void *const hw, const enum usart_stop_bits stop_bits);
-static void _usart_set_character_size(void *const hw, const enum usart_character_size size);
-
-/**
- * \brief Initialize synchronous SERCOM USART
- */
-int32_t _usart_sync_init(struct _usart_sync_device *const device, void *const hw)
-{
- ASSERT(device);
-
- device->hw = hw;
-
- return _usart_init(hw);
-}
-
-/**
- * \brief Initialize asynchronous SERCOM USART
- */
-int32_t _usart_async_init(struct _usart_async_device *const device, void *const hw)
-{
- int32_t init_status;
-
- ASSERT(device);
-
- init_status = _usart_init(hw);
- if (init_status) {
- return init_status;
- }
- device->hw = hw;
- _sercom_init_irq_param(hw, (void *)device);
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_EnableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
-
- return ERR_NONE;
-}
-
-/**
- * \brief De-initialize SERCOM USART
- */
-void _usart_sync_deinit(struct _usart_sync_device *const device)
-{
- _usart_deinit(device->hw);
-}
-
-/**
- * \brief De-initialize SERCOM USART
- */
-void _usart_async_deinit(struct _usart_async_device *const device)
-{
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(device->hw));
- _usart_deinit(device->hw);
-}
-
-/**
- * \brief Calculate baud rate register value
- */
-uint16_t _usart_sync_calculate_baud_rate(const uint32_t baud, const uint32_t clock_rate, const uint8_t samples,
- const enum usart_baud_rate_mode mode, const uint8_t fraction)
-{
- return _usart_calculate_baud_rate(baud, clock_rate, samples, mode, fraction);
-}
-
-/**
- * \brief Calculate baud rate register value
- */
-uint16_t _usart_async_calculate_baud_rate(const uint32_t baud, const uint32_t clock_rate, const uint8_t samples,
- const enum usart_baud_rate_mode mode, const uint8_t fraction)
-{
- return _usart_calculate_baud_rate(baud, clock_rate, samples, mode, fraction);
-}
-
-/**
- * \brief Enable SERCOM module
- */
-void _usart_sync_enable(struct _usart_sync_device *const device)
-{
- hri_sercomusart_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Enable SERCOM module
- */
-void _usart_async_enable(struct _usart_async_device *const device)
-{
- hri_sercomusart_set_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable SERCOM module
- */
-void _usart_sync_disable(struct _usart_sync_device *const device)
-{
- hri_sercomusart_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Disable SERCOM module
- */
-void _usart_async_disable(struct _usart_async_device *const device)
-{
- hri_sercomusart_clear_CTRLA_ENABLE_bit(device->hw);
-}
-
-/**
- * \brief Set baud rate
- */
-void _usart_sync_set_baud_rate(struct _usart_sync_device *const device, const uint32_t baud_rate)
-{
- _usart_set_baud_rate(device->hw, baud_rate);
-}
-
-/**
- * \brief Set baud rate
- */
-void _usart_async_set_baud_rate(struct _usart_async_device *const device, const uint32_t baud_rate)
-{
- _usart_set_baud_rate(device->hw, baud_rate);
-}
-
-/**
- * \brief Set data order
- */
-void _usart_sync_set_data_order(struct _usart_sync_device *const device, const enum usart_data_order order)
-{
- _usart_set_data_order(device->hw, order);
-}
-
-/**
- * \brief Set data order
- */
-void _usart_async_set_data_order(struct _usart_async_device *const device, const enum usart_data_order order)
-{
- _usart_set_data_order(device->hw, order);
-}
-
-/**
- * \brief Set mode
- */
-void _usart_sync_set_mode(struct _usart_sync_device *const device, const enum usart_mode mode)
-{
- _usart_set_mode(device->hw, mode);
-}
-
-/**
- * \brief Set mode
- */
-void _usart_async_set_mode(struct _usart_async_device *const device, const enum usart_mode mode)
-{
- _usart_set_mode(device->hw, mode);
-}
-
-/**
- * \brief Set parity
- */
-void _usart_sync_set_parity(struct _usart_sync_device *const device, const enum usart_parity parity)
-{
- _usart_set_parity(device->hw, parity);
-}
-
-/**
- * \brief Set parity
- */
-void _usart_async_set_parity(struct _usart_async_device *const device, const enum usart_parity parity)
-{
- _usart_set_parity(device->hw, parity);
-}
-
-/**
- * \brief Set stop bits mode
- */
-void _usart_sync_set_stop_bits(struct _usart_sync_device *const device, const enum usart_stop_bits stop_bits)
-{
- _usart_set_stop_bits(device->hw, stop_bits);
-}
-
-/**
- * \brief Set stop bits mode
- */
-void _usart_async_set_stop_bits(struct _usart_async_device *const device, const enum usart_stop_bits stop_bits)
-{
- _usart_set_stop_bits(device->hw, stop_bits);
-}
-
-/**
- * \brief Set character size
- */
-void _usart_sync_set_character_size(struct _usart_sync_device *const device, const enum usart_character_size size)
-{
- _usart_set_character_size(device->hw, size);
-}
-
-/**
- * \brief Set character size
- */
-void _usart_async_set_character_size(struct _usart_async_device *const device, const enum usart_character_size size)
-{
- _usart_set_character_size(device->hw, size);
-}
-
-/**
- * \brief Retrieve SERCOM usart status
- */
-uint32_t _usart_sync_get_status(const struct _usart_sync_device *const device)
-{
- return hri_sercomusart_read_STATUS_reg(device->hw);
-}
-
-/**
- * \brief Retrieve SERCOM usart status
- */
-uint32_t _usart_async_get_status(const struct _usart_async_device *const device)
-{
- return hri_sercomusart_read_STATUS_reg(device->hw);
-}
-
-/**
- * \brief Write a byte to the given SERCOM USART instance
- */
-void _usart_sync_write_byte(struct _usart_sync_device *const device, uint8_t data)
-{
- hri_sercomusart_write_DATA_reg(device->hw, data);
-}
-
-/**
- * \brief Write a byte to the given SERCOM USART instance
- */
-void _usart_async_write_byte(struct _usart_async_device *const device, uint8_t data)
-{
- hri_sercomusart_write_DATA_reg(device->hw, data);
-}
-
-/**
- * \brief Read a byte from the given SERCOM USART instance
- */
-uint8_t _usart_sync_read_byte(const struct _usart_sync_device *const device)
-{
- return hri_sercomusart_read_DATA_reg(device->hw);
-}
-
-/**
- * \brief Check if USART is ready to send next byte
- */
-bool _usart_sync_is_byte_sent(const struct _usart_sync_device *const device)
-{
- return hri_sercomusart_get_interrupt_DRE_bit(device->hw);
-}
-
-/**
- * \brief Check if USART is ready to send next byte
- */
-bool _usart_async_is_byte_sent(const struct _usart_async_device *const device)
-{
- return hri_sercomusart_get_interrupt_DRE_bit(device->hw);
-}
-
-/**
- * \brief Check if there is data received by USART
- */
-bool _usart_sync_is_byte_received(const struct _usart_sync_device *const device)
-{
- return hri_sercomusart_get_interrupt_RXC_bit(device->hw);
-}
-
-/**
- * \brief Set the state of flow control pins
- */
-void _usart_sync_set_flow_control_state(struct _usart_sync_device *const device,
- const union usart_flow_control_state state)
-{
- (void)device;
- (void)state;
-}
-
-/**
- * \brief Set the state of flow control pins
- */
-void _usart_async_set_flow_control_state(struct _usart_async_device *const device,
- const union usart_flow_control_state state)
-{
- (void)device;
- (void)state;
-}
-
-/**
- * \brief Retrieve the state of flow control pins
- */
-union usart_flow_control_state _usart_sync_get_flow_control_state(const struct _usart_sync_device *const device)
-{
- (void)device;
- union usart_flow_control_state state;
-
- state.value = 0;
- state.bit.unavailable = 1;
- return state;
-}
-
-/**
- * \brief Retrieve the state of flow control pins
- */
-union usart_flow_control_state _usart_async_get_flow_control_state(const struct _usart_async_device *const device)
-{
- (void)device;
- union usart_flow_control_state state;
-
- state.value = 0;
- state.bit.unavailable = 1;
- return state;
-}
-
-/**
- * \brief Enable data register empty interrupt
- */
-void _usart_async_enable_byte_sent_irq(struct _usart_async_device *const device)
-{
- hri_sercomusart_set_INTEN_DRE_bit(device->hw);
-}
-
-/**
- * \brief Enable transmission complete interrupt
- */
-void _usart_async_enable_tx_done_irq(struct _usart_async_device *const device)
-{
- hri_sercomusart_set_INTEN_TXC_bit(device->hw);
-}
-
-/**
- * \brief Retrieve ordinal number of the given sercom hardware instance
- */
-static uint8_t _sercom_get_hardware_index(const void *const hw)
-{
-#ifdef _UNIT_TEST_
- return ((uint32_t)hw - (uint32_t)SERCOM0) / sizeof(Sercom);
-#endif
-
-#if defined __SAML21E18B__ || defined __ATSAML21E18B__ || defined __SAML21G18B__ || defined __ATSAML21G18B__ \
- || defined __SAML21J18B__ || defined __ATSAML21J18B__ || defined __ATSAMR30G18A__ || defined __ATSAMR30E18A__
- if ((uint32_t)SERCOM5 == (uint32_t)hw) {
- return 5;
- }
-#endif
-
- return ((uint32_t)hw - (uint32_t)SERCOM0) >> 10;
-}
-
-/**
- * \brief Retrieve ordinal number of the given SERCOM USART hardware instance
- */
-uint8_t _usart_sync_get_hardware_index(const struct _usart_sync_device *const device)
-{
- return _sercom_get_hardware_index(device->hw);
-}
-
-/**
- * \brief Retrieve ordinal number of the given SERCOM USART hardware instance
- */
-uint8_t _usart_async_get_hardware_index(const struct _usart_async_device *const device)
-{
- return _sercom_get_hardware_index(device->hw);
-}
-
-/**
- * \brief Enable/disable USART interrupt
- */
-void _usart_async_set_irq_state(struct _usart_async_device *const device, const enum _usart_async_callback_type type,
- const bool state)
-{
- ASSERT(device);
-
- if (USART_ASYNC_BYTE_SENT == type || USART_ASYNC_TX_DONE == type) {
- hri_sercomusart_write_INTEN_DRE_bit(device->hw, state);
- hri_sercomusart_write_INTEN_TXC_bit(device->hw, state);
- } else if (USART_ASYNC_RX_DONE == type) {
- hri_sercomusart_write_INTEN_RXC_bit(device->hw, state);
- } else if (USART_ASYNC_ERROR == type) {
- hri_sercomusart_write_INTEN_ERROR_bit(device->hw, state);
- }
-}
-
-/**
- * \internal Retrieve ordinal number of the given sercom hardware instance
- *
- * \param[in] hw The pointer to hardware instance
-
- * \return The ordinal number of the given sercom hardware instance
- */
-static uint8_t _get_sercom_index(const void *const hw)
-{
- uint8_t sercom_offset = _sercom_get_hardware_index(hw);
- uint8_t i;
-
- for (i = 0; i < ARRAY_SIZE(_usarts); i++) {
- if (_usarts[i].number == sercom_offset) {
- return i;
- }
- }
-
- ASSERT(false);
- return 0;
-}
-
-/**
- * \brief Init irq param with the given sercom hardware instance
- */
-static void _sercom_init_irq_param(const void *const hw, void *dev)
-{
-}
-
-/**
- * \internal Initialize SERCOM USART
- *
- * \param[in] hw The pointer to hardware instance
- *
- * \return The status of initialization
- */
-static int32_t _usart_init(void *const hw)
-{
- uint8_t i = _get_sercom_index(hw);
-
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_SWRST);
- if (hri_sercomusart_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_sercomusart_set_CTRLA_SWRST_bit(hw);
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_SWRST);
-
- hri_sercomusart_write_CTRLA_reg(hw, _usarts[i].ctrl_a);
- hri_sercomusart_write_CTRLB_reg(hw, _usarts[i].ctrl_b);
- if ((_usarts[i].ctrl_a & SERCOM_USART_CTRLA_SAMPR(0x1)) || (_usarts[i].ctrl_a & SERCOM_USART_CTRLA_SAMPR(0x3))) {
- ((Sercom *)hw)->USART.BAUD.FRAC.BAUD = _usarts[i].baud;
- ((Sercom *)hw)->USART.BAUD.FRAC.FP = _usarts[i].fractional;
- } else {
- hri_sercomusart_write_BAUD_reg(hw, _usarts[i].baud);
- }
-
- hri_sercomusart_write_RXPL_reg(hw, _usarts[i].rxpl);
- hri_sercomusart_write_DBGCTRL_reg(hw, _usarts[i].debug_ctrl);
-
- return ERR_NONE;
-}
-
-/**
- * \internal De-initialize SERCOM USART
- *
- * \param[in] hw The pointer to hardware instance
- */
-static inline void _usart_deinit(void *const hw)
-{
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
- hri_sercomusart_set_CTRLA_SWRST_bit(hw);
-}
-
-/**
- * \internal Calculate baud rate register value
- *
- * \param[in] baud Required baud rate
- * \param[in] clock_rate SERCOM clock frequency
- * \param[in] samples The number of samples
- * \param[in] mode USART mode
- * \param[in] fraction A fraction value
- *
- * \return Calculated baud rate register value
- */
-static uint16_t _usart_calculate_baud_rate(const uint32_t baud, const uint32_t clock_rate, const uint8_t samples,
- const enum usart_baud_rate_mode mode, const uint8_t fraction)
-{
- if (USART_BAUDRATE_ASYNCH_ARITHMETIC == mode) {
- return 65536 - ((uint64_t)65536 * samples * baud) / clock_rate;
- }
-
- if (USART_BAUDRATE_ASYNCH_FRACTIONAL == mode) {
- return clock_rate / baud / samples + SERCOM_USART_BAUD_FRACFP_FP(fraction);
- }
-
- if (USART_BAUDRATE_SYNCH == mode) {
- return clock_rate / baud / 2 - 1;
- }
-
- return 0;
-}
-
-/**
- * \internal Set baud rate
- *
- * \param[in] device The pointer to USART device instance
- * \param[in] baud_rate A baud rate to set
- */
-static void _usart_set_baud_rate(void *const hw, const uint32_t baud_rate)
-{
- bool enabled = hri_sercomusart_get_CTRLA_ENABLE_bit(hw);
-
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_ENABLE);
- hri_sercomusart_write_BAUD_reg(hw, baud_rate);
- CRITICAL_SECTION_LEAVE()
-
- hri_sercomusart_write_CTRLA_ENABLE_bit(hw, enabled);
-}
-
-/**
- * \internal Set data order
- *
- * \param[in] device The pointer to USART device instance
- * \param[in] order A data order to set
- */
-static void _usart_set_data_order(void *const hw, const enum usart_data_order order)
-{
- bool enabled = hri_sercomusart_get_CTRLA_ENABLE_bit(hw);
-
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_ENABLE);
- hri_sercomusart_write_CTRLA_DORD_bit(hw, order);
- CRITICAL_SECTION_LEAVE()
-
- hri_sercomusart_write_CTRLA_ENABLE_bit(hw, enabled);
-}
-
-/**
- * \internal Set mode
- *
- * \param[in] device The pointer to USART device instance
- * \param[in] mode A mode to set
- */
-static void _usart_set_mode(void *const hw, const enum usart_mode mode)
-{
- bool enabled = hri_sercomusart_get_CTRLA_ENABLE_bit(hw);
-
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_ENABLE);
- hri_sercomusart_write_CTRLA_CMODE_bit(hw, mode);
- CRITICAL_SECTION_LEAVE()
-
- hri_sercomusart_write_CTRLA_ENABLE_bit(hw, enabled);
-}
-
-/**
- * \internal Set parity
- *
- * \param[in] device The pointer to USART device instance
- * \param[in] parity A parity to set
- */
-static void _usart_set_parity(void *const hw, const enum usart_parity parity)
-{
- bool enabled = hri_sercomusart_get_CTRLA_ENABLE_bit(hw);
-
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_ENABLE);
-
- if (USART_PARITY_NONE != parity) {
- hri_sercomusart_set_CTRLA_FORM_bf(hw, 1);
- } else {
- hri_sercomusart_clear_CTRLA_FORM_bf(hw, 1);
- }
-
- hri_sercomusart_write_CTRLB_PMODE_bit(hw, parity);
- CRITICAL_SECTION_LEAVE()
-
- hri_sercomusart_write_CTRLA_ENABLE_bit(hw, enabled);
-}
-
-/**
- * \internal Set stop bits mode
- *
- * \param[in] device The pointer to USART device instance
- * \param[in] stop_bits A stop bits mode to set
- */
-static void _usart_set_stop_bits(void *const hw, const enum usart_stop_bits stop_bits)
-{
- bool enabled = hri_sercomusart_get_CTRLA_ENABLE_bit(hw);
-
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_ENABLE);
- hri_sercomusart_write_CTRLB_SBMODE_bit(hw, stop_bits);
- CRITICAL_SECTION_LEAVE()
-
- hri_sercomusart_write_CTRLA_ENABLE_bit(hw, enabled);
-}
-
-/**
- * \internal Set character size
- *
- * \param[in] device The pointer to USART device instance
- * \param[in] size A character size to set
- */
-static void _usart_set_character_size(void *const hw, const enum usart_character_size size)
-{
- bool enabled = hri_sercomusart_get_CTRLA_ENABLE_bit(hw);
-
- hri_sercomusart_clear_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomusart_wait_for_sync(hw, SERCOM_USART_SYNCBUSY_ENABLE);
- hri_sercomusart_write_CTRLB_CHSIZE_bf(hw, size);
- CRITICAL_SECTION_LEAVE()
-
- if (enabled) {
- hri_sercomusart_set_CTRLA_ENABLE_bit(hw);
- }
-}
-
-/* Sercom I2C implementation */
-
-#ifndef CONF_SERCOM_0_I2CM_ENABLE
-#define CONF_SERCOM_0_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_1_I2CM_ENABLE
-#define CONF_SERCOM_1_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_2_I2CM_ENABLE
-#define CONF_SERCOM_2_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_3_I2CM_ENABLE
-#define CONF_SERCOM_3_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_4_I2CM_ENABLE
-#define CONF_SERCOM_4_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_5_I2CM_ENABLE
-#define CONF_SERCOM_5_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_6_I2CM_ENABLE
-#define CONF_SERCOM_6_I2CM_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_7_I2CM_ENABLE
-#define CONF_SERCOM_7_I2CM_ENABLE 0
-#endif
-
-/** Amount of SERCOM that is used as I2C Master. */
-#define SERCOM_I2CM_AMOUNT \
- (CONF_SERCOM_0_I2CM_ENABLE + CONF_SERCOM_1_I2CM_ENABLE + CONF_SERCOM_2_I2CM_ENABLE + CONF_SERCOM_3_I2CM_ENABLE \
- + CONF_SERCOM_4_I2CM_ENABLE \
- + CONF_SERCOM_5_I2CM_ENABLE \
- + CONF_SERCOM_6_I2CM_ENABLE \
- + CONF_SERCOM_7_I2CM_ENABLE)
-
-/**
- * \brief Macro is used to fill i2cm configuration structure based on
- * its number
- *
- * \param[in] n The number of structures
- */
-#define I2CM_CONFIGURATION(n) \
- { \
- (n), (SERCOM_I2CM_CTRLA_MODE_I2C_MASTER) | (CONF_SERCOM_##n##_I2CM_RUNSTDBY << SERCOM_I2CM_CTRLA_RUNSTDBY_Pos) \
- | (CONF_SERCOM_##n##_I2CM_SPEED << SERCOM_I2CM_CTRLA_SPEED_Pos) \
- | (CONF_SERCOM_##n##_I2CM_MEXTTOEN << SERCOM_I2CM_CTRLA_MEXTTOEN_Pos) \
- | (CONF_SERCOM_##n##_I2CM_SEXTTOEN << SERCOM_I2CM_CTRLA_SEXTTOEN_Pos) \
- | (CONF_SERCOM_##n##_I2CM_INACTOUT << SERCOM_I2CM_CTRLA_INACTOUT_Pos) \
- | (CONF_SERCOM_##n##_I2CM_LOWTOUT << SERCOM_I2CM_CTRLA_LOWTOUTEN_Pos) \
- | (CONF_SERCOM_##n##_I2CM_SDAHOLD << SERCOM_I2CM_CTRLA_SDAHOLD_Pos), \
- SERCOM_I2CM_CTRLB_SMEN, (uint32_t)(CONF_SERCOM_##n##_I2CM_BAUD_RATE), \
- CONF_SERCOM_##n##_I2CM_DEBUG_STOP_MODE, CONF_SERCOM_##n##_I2CM_TRISE, CONF_GCLK_SERCOM##n##_CORE_FREQUENCY \
- }
-
-#define ERROR_FLAG (1 << 7)
-#define SB_FLAG (1 << 1)
-#define MB_FLAG (1 << 0)
-
-#define CMD_STOP 0x3
-#define I2C_IDLE 0x1
-#define I2C_SM 0x0
-#define I2C_FM 0x1
-#define I2C_HS 0x2
-#define TEN_ADDR_FRAME 0x78
-#define TEN_ADDR_MASK 0x3ff
-#define SEVEN_ADDR_MASK 0x7f
-
-/**
- * \brief SERCOM I2CM configuration type
- */
-struct i2cm_configuration {
- uint8_t number;
- hri_sercomi2cm_ctrla_reg_t ctrl_a;
- hri_sercomi2cm_ctrlb_reg_t ctrl_b;
- hri_sercomi2cm_baud_reg_t baud;
- hri_sercomi2cm_dbgctrl_reg_t dbgctrl;
- uint16_t trise;
- uint32_t clk; /* SERCOM peripheral clock frequency */
-};
-
-static inline void _i2c_m_enable_implementation(void *hw);
-static int32_t _i2c_m_sync_init_impl(struct _i2c_m_service *const service, void *const hw);
-
-#if SERCOM_I2CM_AMOUNT < 1
-/** Dummy array to pass compiling. */
-static struct i2cm_configuration _i2cms[1] = {{0}};
-#else
-/**
- * \brief Array of SERCOM I2CM configurations
- */
-static struct i2cm_configuration _i2cms[] = {
-#if CONF_SERCOM_0_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(0),
-#endif
-#if CONF_SERCOM_1_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(1),
-#endif
-#if CONF_SERCOM_2_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(2),
-#endif
-#if CONF_SERCOM_3_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(3),
-#endif
-#if CONF_SERCOM_4_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(4),
-#endif
-#if CONF_SERCOM_5_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(5),
-#endif
-#if CONF_SERCOM_6_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(6),
-#endif
-#if CONF_SERCOM_7_I2CM_ENABLE == 1
- I2CM_CONFIGURATION(7),
-#endif
-};
-#endif
-
-/**
- * \internal Retrieve ordinal number of the given sercom hardware instance
- *
- * \param[in] hw The pointer to hardware instance
-
- * \return The ordinal number of the given sercom hardware instance
- */
-static int8_t _get_i2cm_index(const void *const hw)
-{
- uint8_t sercom_offset = _sercom_get_hardware_index(hw);
- uint8_t i;
-
- for (i = 0; i < ARRAY_SIZE(_i2cms); i++) {
- if (_i2cms[i].number == sercom_offset) {
- return i;
- }
- }
-
- ASSERT(false);
- return -1;
-}
-
-static inline void _sercom_i2c_send_stop(void *const hw)
-{
- hri_sercomi2cm_set_CTRLB_CMD_bf(hw, CMD_STOP);
-}
-
-/**
- * \brief SERCOM I2CM analyze hardware status and transfer next byte
- */
-static inline int32_t _sercom_i2c_sync_analyse_flags(void *const hw, uint32_t flags, struct _i2c_m_msg *const msg)
-{
- int sclsm = hri_sercomi2cm_get_CTRLA_SCLSM_bit(hw);
- uint16_t status = hri_sercomi2cm_read_STATUS_reg(hw);
-
- if (flags & MB_FLAG) {
- /* tx error */
- if (status & SERCOM_I2CM_STATUS_ARBLOST) {
- hri_sercomi2cm_clear_interrupt_MB_bit(hw);
- msg->flags |= I2C_M_FAIL;
- msg->flags &= ~I2C_M_BUSY;
-
- if (status & SERCOM_I2CM_STATUS_BUSERR) {
- return I2C_ERR_BUS;
- }
-
- return I2C_ERR_BAD_ADDRESS;
- } else {
- if (status & SERCOM_I2CM_STATUS_RXNACK) {
-
- /* Slave rejects to receive more data */
- if (msg->len > 0) {
- msg->flags |= I2C_M_FAIL;
- }
-
- if (msg->flags & I2C_M_STOP) {
- _sercom_i2c_send_stop(hw);
- }
-
- msg->flags &= ~I2C_M_BUSY;
-
- return I2C_NACK;
- }
-
- if (msg->flags & I2C_M_TEN) {
- hri_sercomi2cm_write_ADDR_reg(hw,
- ((((msg->addr & TEN_ADDR_MASK) >> 8) | TEN_ADDR_FRAME) << 1) | I2C_M_RD
- | (hri_sercomi2cm_read_ADDR_reg(hw) & SERCOM_I2CM_ADDR_HS));
- msg->flags &= ~I2C_M_TEN;
-
- return I2C_OK;
- }
-
- if (msg->len == 0) {
- if (msg->flags & I2C_M_STOP) {
- _sercom_i2c_send_stop(hw);
- }
-
- msg->flags &= ~I2C_M_BUSY;
- } else {
- hri_sercomi2cm_write_DATA_reg(hw, *msg->buffer);
- msg->buffer++;
- msg->len--;
- }
-
- return I2C_OK;
- }
- } else if (flags & SB_FLAG) {
- if ((msg->len) && !(status & SERCOM_I2CM_STATUS_RXNACK)) {
- msg->len--;
-
- /* last byte, send nack */
- if ((msg->len == 0 && !sclsm) || (msg->len == 1 && sclsm)) {
- hri_sercomi2cm_set_CTRLB_ACKACT_bit(hw);
- }
-
- if (msg->len == 0) {
- if (msg->flags & I2C_M_STOP) {
- _sercom_i2c_send_stop(hw);
- }
-
- msg->flags &= ~I2C_M_BUSY;
- }
-
- /* Accessing DATA.DATA auto-triggers I2C bus operations.
- * The operation performed depends on the state of
- * CTRLB.ACKACT, CTRLB.SMEN
- **/
- *msg->buffer++ = hri_sercomi2cm_read_DATA_reg(hw);
- } else {
- hri_sercomi2cm_clear_interrupt_SB_bit(hw);
- return I2C_NACK;
- }
-
- hri_sercomi2cm_clear_interrupt_SB_bit(hw);
- }
-
- return I2C_OK;
-}
-
-/**
- * \brief Enable the i2c master module
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_async_enable(struct _i2c_m_async_device *const i2c_dev)
-{
- ASSERT(i2c_dev);
-
- _i2c_m_enable_implementation(i2c_dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Disable the i2c master module
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_async_disable(struct _i2c_m_async_device *const i2c_dev)
-{
- void *hw = i2c_dev->hw;
-
- ASSERT(i2c_dev);
- ASSERT(i2c_dev->hw);
-
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- hri_sercomi2cm_clear_CTRLA_ENABLE_bit(hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Set baudrate of master
- *
- * \param[in] i2c_dev The pointer to i2c device
- * \param[in] clkrate The clock rate of i2c master, in KHz
- * \param[in] baudrate The baud rate desired for i2c master, in KHz
- */
-int32_t _i2c_m_async_set_baudrate(struct _i2c_m_async_device *const i2c_dev, uint32_t clkrate, uint32_t baudrate)
-{
- uint32_t tmp;
- void * hw = i2c_dev->hw;
-
- if (hri_sercomi2cm_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
-
- tmp = _get_i2cm_index(hw);
- clkrate = _i2cms[tmp].clk / 1000;
-
- if (i2c_dev->service.mode == I2C_STANDARD_MODE) {
- tmp = (uint32_t)((clkrate - 10 * baudrate - baudrate * clkrate * (i2c_dev->service.trise * 0.000000001))
- / (2 * baudrate));
- hri_sercomi2cm_write_BAUD_BAUD_bf(hw, tmp);
- } else if (i2c_dev->service.mode == I2C_FASTMODE) {
- tmp = (uint32_t)((clkrate - 10 * baudrate - baudrate * clkrate * (i2c_dev->service.trise * 0.000000001))
- / (2 * baudrate));
- hri_sercomi2cm_write_BAUD_BAUD_bf(hw, tmp);
- } else if (i2c_dev->service.mode == I2C_HIGHSPEED_MODE) {
- tmp = (clkrate - 2 * baudrate) / (2 * baudrate);
- hri_sercomi2cm_write_BAUD_HSBAUD_bf(hw, tmp);
- } else {
- /* error baudrate */
- return ERR_INVALID_ARG;
- }
-
- return ERR_NONE;
-}
-
-/**
- * \brief Retrieve IRQ number for the given hardware instance
- */
-static uint8_t _sercom_get_irq_num(const void *const hw)
-{
- return SERCOM0_IRQn + _sercom_get_hardware_index(hw);
-}
-
-/**
- * \brief Initialize sercom i2c module to use in async mode
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_async_init(struct _i2c_m_async_device *const i2c_dev, void *const hw)
-{
- int32_t init_status;
-
- ASSERT(i2c_dev);
-
- i2c_dev->hw = hw;
-
- init_status = _i2c_m_sync_init_impl(&i2c_dev->service, hw);
- if (init_status) {
- return init_status;
- }
-
- _sercom_init_irq_param(hw, (void *)i2c_dev);
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_EnableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
-
- return ERR_NONE;
-}
-
-/**
- * \brief Deinitialize sercom i2c module
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_async_deinit(struct _i2c_m_async_device *const i2c_dev)
-{
- ASSERT(i2c_dev);
-
- hri_sercomi2cm_clear_CTRLA_ENABLE_bit(i2c_dev->hw);
- hri_sercomi2cm_set_CTRLA_SWRST_bit(i2c_dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Transfer the slave address to bus, which will start the transfer
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-static int32_t _sercom_i2c_send_address(struct _i2c_m_async_device *const i2c_dev)
-{
- void * hw = i2c_dev->hw;
- struct _i2c_m_msg *msg = &i2c_dev->service.msg;
- int sclsm = hri_sercomi2cm_get_CTRLA_SCLSM_bit(hw);
-
- ASSERT(i2c_dev);
-
- if (msg->len == 1 && sclsm) {
- hri_sercomi2cm_set_CTRLB_ACKACT_bit(hw);
- } else {
- hri_sercomi2cm_clear_CTRLB_ACKACT_bit(hw);
- }
-
- /* ten bit address */
- if (msg->addr & I2C_M_TEN) {
- if (msg->flags & I2C_M_RD) {
- msg->flags |= I2C_M_TEN;
- }
-
- hri_sercomi2cm_write_ADDR_reg(hw,
- ((msg->addr & TEN_ADDR_MASK) << 1) | SERCOM_I2CM_ADDR_TENBITEN
- | (hri_sercomi2cm_read_ADDR_reg(hw) & SERCOM_I2CM_ADDR_HS));
- } else {
- hri_sercomi2cm_write_ADDR_reg(hw,
- ((msg->addr & SEVEN_ADDR_MASK) << 1) | (msg->flags & I2C_M_RD ? I2C_M_RD : 0x0)
- | (hri_sercomi2cm_read_ADDR_reg(hw) & SERCOM_I2CM_ADDR_HS));
- }
-
- return ERR_NONE;
-}
-
-/**
- * \brief Transfer data specified by msg
- *
- * \param[in] i2c_dev The pointer to i2c device
- * \param[in] msg The pointer to i2c message
- *
- * \return Transfer status.
- * \retval 0 Transfer success
- * \retval <0 Transfer fail, return the error code
- */
-int32_t _i2c_m_async_transfer(struct _i2c_m_async_device *i2c_dev, struct _i2c_m_msg *msg)
-{
- int ret;
-
- ASSERT(i2c_dev);
- ASSERT(i2c_dev->hw);
- ASSERT(msg);
-
- if (msg->len == 0) {
- return ERR_NONE;
- }
-
- if (i2c_dev->service.msg.flags & I2C_M_BUSY) {
- return ERR_BUSY;
- }
-
- msg->flags |= I2C_M_BUSY;
- i2c_dev->service.msg = *msg;
-
- ret = _sercom_i2c_send_address(i2c_dev);
-
- if (ret) {
- i2c_dev->service.msg.flags &= ~I2C_M_BUSY;
-
- return ret;
- }
-
- return ERR_NONE;
-}
-
-/**
- * \brief Set callback to be called in interrupt handler
- *
- * \param[in] i2c_dev The pointer to master i2c device
- * \param[in] type The callback type
- * \param[in] func The callback function pointer
- */
-int32_t _i2c_m_async_register_callback(struct _i2c_m_async_device *const i2c_dev, enum _i2c_m_async_callback_type type,
- FUNC_PTR func)
-{
- switch (type) {
- case I2C_M_ASYNC_DEVICE_ERROR:
- i2c_dev->cb.error = (_i2c_error_cb_t)func;
- break;
- case I2C_M_ASYNC_DEVICE_TX_COMPLETE:
- i2c_dev->cb.tx_complete = (_i2c_complete_cb_t)func;
- break;
- case I2C_M_ASYNC_DEVICE_RX_COMPLETE:
- i2c_dev->cb.rx_complete = (_i2c_complete_cb_t)func;
- break;
- default:
- /* error */
- break;
- }
-
- return ERR_NONE;
-}
-
-/**
- * \brief Set stop condition on I2C
- *
- * \param i2c_dev Pointer to master i2c device
- *
- * \return Operation status
- * \retval I2C_OK Operation was successfull
- */
-int32_t _i2c_m_async_send_stop(struct _i2c_m_async_device *const i2c_dev)
-{
- void *hw = i2c_dev->hw;
-
- _sercom_i2c_send_stop(hw);
-
- return I2C_OK;
-}
-
-/**
- * \brief Get number of bytes left in transfer buffer
- *
- * \param i2c_dev Pointer to i2c master device
- *
- * \return Bytes left in buffer
- * \retval =>0 Bytes left in buffer
- */
-int32_t _i2c_m_async_get_bytes_left(struct _i2c_m_async_device *const i2c_dev)
-{
- if (i2c_dev->service.msg.flags & I2C_M_BUSY) {
- return i2c_dev->service.msg.len;
- }
-
- return 0;
-}
-
-/**
- * \brief Initialize sercom i2c module to use in sync mode
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_sync_init(struct _i2c_m_sync_device *const i2c_dev, void *const hw)
-{
- ASSERT(i2c_dev);
-
- i2c_dev->hw = hw;
-
- return _i2c_m_sync_init_impl(&i2c_dev->service, hw);
-}
-
-/**
- * \brief Deinitialize sercom i2c module
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_sync_deinit(struct _i2c_m_sync_device *const i2c_dev)
-{
- ASSERT(i2c_dev);
-
- hri_sercomi2cm_clear_CTRLA_ENABLE_bit(i2c_dev->hw);
- hri_sercomi2cm_set_CTRLA_SWRST_bit(i2c_dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable the i2c master module
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_sync_enable(struct _i2c_m_sync_device *const i2c_dev)
-{
- ASSERT(i2c_dev);
-
- _i2c_m_enable_implementation(i2c_dev->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Disable the i2c master module
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-int32_t _i2c_m_sync_disable(struct _i2c_m_sync_device *const i2c_dev)
-{
- void *hw = i2c_dev->hw;
-
- ASSERT(i2c_dev);
- ASSERT(i2c_dev->hw);
-
- hri_sercomi2cm_clear_CTRLA_ENABLE_bit(hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Set baudrate of master
- *
- * \param[in] i2c_dev The pointer to i2c device
- * \param[in] clkrate The clock rate of i2c master, in KHz
- * \param[in] baudrate The baud rate desired for i2c master, in KHz
- */
-int32_t _i2c_m_sync_set_baudrate(struct _i2c_m_sync_device *const i2c_dev, uint32_t clkrate, uint32_t baudrate)
-{
- uint32_t tmp;
- void * hw = i2c_dev->hw;
-
- if (hri_sercomi2cm_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
-
- tmp = _get_i2cm_index(hw);
- clkrate = _i2cms[tmp].clk / 1000;
-
- if (i2c_dev->service.mode == I2C_STANDARD_MODE) {
- tmp = (uint32_t)((clkrate - 10 * baudrate - baudrate * clkrate * (i2c_dev->service.trise * 0.000000001))
- / (2 * baudrate));
- hri_sercomi2cm_write_BAUD_BAUD_bf(hw, tmp);
- } else if (i2c_dev->service.mode == I2C_FASTMODE) {
- tmp = (uint32_t)((clkrate - 10 * baudrate - baudrate * clkrate * (i2c_dev->service.trise * 0.000000001))
- / (2 * baudrate));
- hri_sercomi2cm_write_BAUD_BAUD_bf(hw, tmp);
- } else if (i2c_dev->service.mode == I2C_HIGHSPEED_MODE) {
- tmp = (clkrate - 2 * baudrate) / (2 * baudrate);
- hri_sercomi2cm_write_BAUD_HSBAUD_bf(hw, tmp);
- } else {
- /* error baudrate */
- return ERR_INVALID_ARG;
- }
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable/disable I2C master interrupt
- */
-void _i2c_m_async_set_irq_state(struct _i2c_m_async_device *const device, const enum _i2c_m_async_callback_type type,
- const bool state)
-{
- if (I2C_M_ASYNC_DEVICE_TX_COMPLETE == type || I2C_M_ASYNC_DEVICE_RX_COMPLETE == type) {
- hri_sercomi2cm_write_INTEN_SB_bit(device->hw, state);
- hri_sercomi2cm_write_INTEN_MB_bit(device->hw, state);
- } else if (I2C_M_ASYNC_DEVICE_ERROR == type) {
- hri_sercomi2cm_write_INTEN_ERROR_bit(device->hw, state);
- }
-}
-
-/**
- * \brief Wait for bus response
- *
- * \param[in] i2c_dev The pointer to i2c device
- * \param[in] flags Store the hardware response
- *
- * \return Bus response status.
- * \retval 0 Bus response status OK
- * \retval <0 Bus response fail
- */
-inline static int32_t _sercom_i2c_sync_wait_bus(struct _i2c_m_sync_device *const i2c_dev, uint32_t *flags)
-{
- uint32_t timeout = 65535;
- void * hw = i2c_dev->hw;
-
- do {
- *flags = hri_sercomi2cm_read_INTFLAG_reg(hw);
-
- if (timeout-- == 0) {
- return I2C_ERR_BUS;
- }
- } while (!(*flags & MB_FLAG) && !(*flags & SB_FLAG));
-
- return I2C_OK;
-}
-
-/**
- * \brief Send the slave address to bus, which will start the transfer
- *
- * \param[in] i2c_dev The pointer to i2c device
- */
-static int32_t _sercom_i2c_sync_send_address(struct _i2c_m_sync_device *const i2c_dev)
-{
- void * hw = i2c_dev->hw;
- struct _i2c_m_msg *msg = &i2c_dev->service.msg;
- int sclsm = hri_sercomi2cm_get_CTRLA_SCLSM_bit(hw);
- uint32_t flags;
-
- ASSERT(i2c_dev);
-
- if (msg->len == 1 && sclsm) {
- hri_sercomi2cm_set_CTRLB_ACKACT_bit(hw);
- } else {
- hri_sercomi2cm_clear_CTRLB_ACKACT_bit(hw);
- }
-
- /* ten bit address */
- if (msg->addr & I2C_M_TEN) {
- if (msg->flags & I2C_M_RD) {
- msg->flags |= I2C_M_TEN;
- }
-
- hri_sercomi2cm_write_ADDR_reg(hw,
- ((msg->addr & TEN_ADDR_MASK) << 1) | SERCOM_I2CM_ADDR_TENBITEN
- | (hri_sercomi2cm_read_ADDR_reg(hw) & SERCOM_I2CM_ADDR_HS));
- } else {
- hri_sercomi2cm_write_ADDR_reg(hw,
- ((msg->addr & SEVEN_ADDR_MASK) << 1) | (msg->flags & I2C_M_RD ? I2C_M_RD : 0x0)
- | (hri_sercomi2cm_read_ADDR_reg(hw) & SERCOM_I2CM_ADDR_HS));
- }
-
- _sercom_i2c_sync_wait_bus(i2c_dev, &flags);
- return _sercom_i2c_sync_analyse_flags(hw, flags, msg);
-}
-
-/**
- * \brief Transfer data specified by msg
- *
- * \param[in] i2c_dev The pointer to i2c device
- * \param[in] msg The pointer to i2c message
- *
- * \return Transfer status.
- * \retval 0 Transfer success
- * \retval <0 Transfer fail or partial fail, return the error code
- */
-int32_t _i2c_m_sync_transfer(struct _i2c_m_sync_device *const i2c_dev, struct _i2c_m_msg *msg)
-{
- uint32_t flags;
- int ret;
- void * hw = i2c_dev->hw;
-
- ASSERT(i2c_dev);
- ASSERT(i2c_dev->hw);
- ASSERT(msg);
-
- if (i2c_dev->service.msg.flags & I2C_M_BUSY) {
- return I2C_ERR_BUSY;
- }
-
- msg->flags |= I2C_M_BUSY;
- i2c_dev->service.msg = *msg;
-
- ret = _sercom_i2c_sync_send_address(i2c_dev);
-
- if (ret) {
- i2c_dev->service.msg.flags &= ~I2C_M_BUSY;
-
- return ret;
- }
-
- while (i2c_dev->service.msg.flags & I2C_M_BUSY) {
- ret = _sercom_i2c_sync_wait_bus(i2c_dev, &flags);
-
- if (ret) {
- if (msg->flags & I2C_M_STOP) {
- _sercom_i2c_send_stop(hw);
- }
-
- i2c_dev->service.msg.flags &= ~I2C_M_BUSY;
-
- return ret;
- }
-
- ret = _sercom_i2c_sync_analyse_flags(hw, flags, &i2c_dev->service.msg);
- }
-
- return ret;
-}
-
-int32_t _i2c_m_sync_send_stop(struct _i2c_m_sync_device *const i2c_dev)
-{
- void *hw = i2c_dev->hw;
-
- _sercom_i2c_send_stop(hw);
-
- return I2C_OK;
-}
-
-static inline void _i2c_m_enable_implementation(void *const hw)
-{
- int timeout = 65535;
-
- ASSERT(hw);
-
- /* Enable interrupts */
- hri_sercomi2cm_set_CTRLA_ENABLE_bit(hw);
-
- while (hri_sercomi2cm_read_STATUS_BUSSTATE_bf(hw) != I2C_IDLE) {
- timeout--;
-
- if (timeout <= 0) {
- hri_sercomi2cm_clear_STATUS_reg(hw, SERCOM_I2CM_STATUS_BUSSTATE(I2C_IDLE));
- }
- }
-}
-
-static int32_t _i2c_m_sync_init_impl(struct _i2c_m_service *const service, void *const hw)
-{
- uint8_t i = _get_i2cm_index(hw);
-
- hri_sercomi2cm_wait_for_sync(hw, SERCOM_I2CM_SYNCBUSY_SWRST);
- /* Check if module is enabled. */
- if (hri_sercomi2cm_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_sercomi2cm_set_CTRLA_SWRST_bit(hw);
- hri_sercomi2cm_wait_for_sync(hw, SERCOM_I2CM_SYNCBUSY_SWRST);
-
- hri_sercomi2cm_write_CTRLA_reg(hw, _i2cms[i].ctrl_a);
- hri_sercomi2cm_write_CTRLB_reg(hw, _i2cms[i].ctrl_b);
- hri_sercomi2cm_write_BAUD_reg(hw, _i2cms[i].baud);
-
- service->mode = (_i2cms[i].ctrl_a & SERCOM_I2CM_CTRLA_SPEED_Msk) >> SERCOM_I2CM_CTRLA_SPEED_Pos;
- hri_sercomi2cm_write_ADDR_HS_bit(hw, service->mode < I2C_HS ? 0 : 1);
-
- service->trise = _i2cms[i].trise;
-
- return ERR_NONE;
-}
-
-/* SERCOM I2C slave */
-
-#ifndef CONF_SERCOM_0_I2CS_ENABLE
-#define CONF_SERCOM_0_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_1_I2CS_ENABLE
-#define CONF_SERCOM_1_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_2_I2CS_ENABLE
-#define CONF_SERCOM_2_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_3_I2CS_ENABLE
-#define CONF_SERCOM_3_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_4_I2CS_ENABLE
-#define CONF_SERCOM_4_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_5_I2CS_ENABLE
-#define CONF_SERCOM_5_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_6_I2CS_ENABLE
-#define CONF_SERCOM_6_I2CS_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_7_I2CS_ENABLE
-#define CONF_SERCOM_7_I2CS_ENABLE 0
-#endif
-
-/** Amount of SERCOM that is used as I2C Slave. */
-#define SERCOM_I2CS_AMOUNT \
- (CONF_SERCOM_0_I2CS_ENABLE + CONF_SERCOM_1_I2CS_ENABLE + CONF_SERCOM_2_I2CS_ENABLE + CONF_SERCOM_3_I2CS_ENABLE \
- + CONF_SERCOM_4_I2CS_ENABLE \
- + CONF_SERCOM_5_I2CS_ENABLE \
- + CONF_SERCOM_6_I2CS_ENABLE \
- + CONF_SERCOM_7_I2CS_ENABLE)
-
-/**
- * \brief Macro is used to fill I2C slave configuration structure based on
- * its number
- *
- * \param[in] n The number of structures
- */
-#define I2CS_CONFIGURATION(n) \
- { \
- n, SERCOM_I2CM_CTRLA_MODE_I2C_SLAVE | (CONF_SERCOM_##n##_I2CS_RUNSTDBY << SERCOM_I2CS_CTRLA_RUNSTDBY_Pos) \
- | SERCOM_I2CS_CTRLA_SDAHOLD(CONF_SERCOM_##n##_I2CS_SDAHOLD) \
- | (CONF_SERCOM_##n##_I2CS_SEXTTOEN << SERCOM_I2CS_CTRLA_SEXTTOEN_Pos) \
- | (CONF_SERCOM_##n##_I2CS_SPEED << SERCOM_I2CS_CTRLA_SPEED_Pos) \
- | (CONF_SERCOM_##n##_I2CS_SCLSM << SERCOM_I2CS_CTRLA_SCLSM_Pos) \
- | (CONF_SERCOM_##n##_I2CS_LOWTOUT << SERCOM_I2CS_CTRLA_LOWTOUTEN_Pos), \
- SERCOM_I2CS_CTRLB_SMEN | SERCOM_I2CS_CTRLB_AACKEN | SERCOM_I2CS_CTRLB_AMODE(CONF_SERCOM_##n##_I2CS_AMODE), \
- (CONF_SERCOM_##n##_I2CS_GENCEN << SERCOM_I2CS_ADDR_GENCEN_Pos) \
- | SERCOM_I2CS_ADDR_ADDR(CONF_SERCOM_##n##_I2CS_ADDRESS) \
- | (CONF_SERCOM_##n##_I2CS_TENBITEN << SERCOM_I2CS_ADDR_TENBITEN_Pos) \
- | SERCOM_I2CS_ADDR_ADDRMASK(CONF_SERCOM_##n##_I2CS_ADDRESS_MASK) \
- }
-
-/**
- * \brief Macro to check 10-bit addressing
- */
-#define I2CS_7BIT_ADDRESSING_MASK 0x7F
-
-static int32_t _i2c_s_init(void *const hw);
-static int8_t _get_i2c_s_index(const void *const hw);
-static inline void _i2c_s_deinit(void *const hw);
-static int32_t _i2c_s_set_address(void *const hw, const uint16_t address);
-
-/**
- * \brief SERCOM I2C slave configuration type
- */
-struct i2cs_configuration {
- uint8_t number;
- hri_sercomi2cs_ctrla_reg_t ctrl_a;
- hri_sercomi2cs_ctrlb_reg_t ctrl_b;
- hri_sercomi2cs_addr_reg_t address;
-};
-
-#if SERCOM_I2CS_AMOUNT < 1
-/** Dummy array for compiling. */
-static struct i2cs_configuration _i2css[1] = {{0}};
-#else
-/**
- * \brief Array of SERCOM I2C slave configurations
- */
-static struct i2cs_configuration _i2css[] = {
-#if CONF_SERCOM_0_I2CS_ENABLE == 1
- I2CS_CONFIGURATION(0),
-#endif
-#if CONF_SERCOM_1_I2CS_ENABLE == 1
- I2CS_CONFIGURATION(1),
-#endif
-#if CONF_SERCOM_2_I2CS_ENABLE == 1
- I2CS_CONFIGURATION(2),
-#endif
-#if CONF_SERCOM_3_I2CS_ENABLE == 1
- I2CS_CONFIGURATION(3),
-#endif
-#if CONF_SERCOM_4_I2CS_ENABLE == 1
- I2CS_CONFIGURATION(4),
-#endif
-#if CONF_SERCOM_5_I2CS_ENABLE == 1
- I2CS_CONFIGURATION(5),
-#endif
-};
-#endif
-
-/**
- * \brief Initialize synchronous I2C slave
- */
-int32_t _i2c_s_sync_init(struct _i2c_s_sync_device *const device, void *const hw)
-{
- int32_t status;
-
- ASSERT(device);
-
- status = _i2c_s_init(hw);
- if (status) {
- return status;
- }
- device->hw = hw;
-
- return ERR_NONE;
-}
-
-/**
- * \brief Initialize asynchronous I2C slave
- */
-int32_t _i2c_s_async_init(struct _i2c_s_async_device *const device, void *const hw)
-{
- int32_t init_status;
-
- ASSERT(device);
-
- init_status = _i2c_s_init(hw);
- if (init_status) {
- return init_status;
- }
-
- device->hw = hw;
- _sercom_init_irq_param(hw, (void *)device);
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_EnableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
-
- return ERR_NONE;
-}
-
-/**
- * \brief Deinitialize synchronous I2C
- */
-int32_t _i2c_s_sync_deinit(struct _i2c_s_sync_device *const device)
-{
- _i2c_s_deinit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Deinitialize asynchronous I2C
- */
-int32_t _i2c_s_async_deinit(struct _i2c_s_async_device *const device)
-{
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(device->hw));
- _i2c_s_deinit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable I2C module
- */
-int32_t _i2c_s_sync_enable(struct _i2c_s_sync_device *const device)
-{
- hri_sercomi2cs_set_CTRLA_ENABLE_bit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable I2C module
- */
-int32_t _i2c_s_async_enable(struct _i2c_s_async_device *const device)
-{
- hri_sercomi2cs_set_CTRLA_ENABLE_bit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Disable I2C module
- */
-int32_t _i2c_s_sync_disable(struct _i2c_s_sync_device *const device)
-{
- hri_sercomi2cs_clear_CTRLA_ENABLE_bit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Disable I2C module
- */
-int32_t _i2c_s_async_disable(struct _i2c_s_async_device *const device)
-{
- hri_sercomi2cs_clear_CTRLA_ENABLE_bit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Check if 10-bit addressing mode is on
- */
-int32_t _i2c_s_sync_is_10bit_addressing_on(const struct _i2c_s_sync_device *const device)
-{
- return hri_sercomi2cs_get_ADDR_TENBITEN_bit(device->hw);
-}
-
-/**
- * \brief Check if 10-bit addressing mode is on
- */
-int32_t _i2c_s_async_is_10bit_addressing_on(const struct _i2c_s_async_device *const device)
-{
- return hri_sercomi2cs_get_ADDR_TENBITEN_bit(device->hw);
-}
-
-/**
- * \brief Set I2C slave address
- */
-int32_t _i2c_s_sync_set_address(struct _i2c_s_sync_device *const device, const uint16_t address)
-{
- return _i2c_s_set_address(device->hw, address);
-}
-
-/**
- * \brief Set I2C slave address
- */
-int32_t _i2c_s_async_set_address(struct _i2c_s_async_device *const device, const uint16_t address)
-{
- return _i2c_s_set_address(device->hw, address);
-}
-
-/**
- * \brief Write a byte to the given I2C instance
- */
-void _i2c_s_sync_write_byte(struct _i2c_s_sync_device *const device, const uint8_t data)
-{
- hri_sercomi2cs_write_DATA_reg(device->hw, data);
-}
-
-/**
- * \brief Write a byte to the given I2C instance
- */
-void _i2c_s_async_write_byte(struct _i2c_s_async_device *const device, const uint8_t data)
-{
- hri_sercomi2cs_write_DATA_reg(device->hw, data);
-}
-
-/**
- * \brief Read a byte from the given I2C instance
- */
-uint8_t _i2c_s_sync_read_byte(const struct _i2c_s_sync_device *const device)
-{
- return hri_sercomi2cs_read_DATA_reg(device->hw);
-}
-
-/**
- * \brief Check if I2C is ready to send next byt
- */
-bool _i2c_s_sync_is_byte_sent(const struct _i2c_s_sync_device *const device)
-{
- return hri_sercomi2cs_get_interrupt_DRDY_bit(device->hw);
-}
-
-/**
- * \brief Check if there is data received by I2C
- */
-bool _i2c_s_sync_is_byte_received(const struct _i2c_s_sync_device *const device)
-{
- return hri_sercomi2cs_get_interrupt_DRDY_bit(device->hw);
-}
-
-/**
- * \brief Retrieve I2C slave status
- */
-i2c_s_status_t _i2c_s_sync_get_status(const struct _i2c_s_sync_device *const device)
-{
- return hri_sercomi2cs_read_STATUS_reg(device->hw);
-}
-
-/**
- * \brief Retrieve I2C slave status
- */
-i2c_s_status_t _i2c_s_async_get_status(const struct _i2c_s_async_device *const device)
-{
- return hri_sercomi2cs_read_STATUS_reg(device->hw);
-}
-
-/**
- * \brief Abort data transmission
- */
-int32_t _i2c_s_async_abort_transmission(const struct _i2c_s_async_device *const device)
-{
- hri_sercomi2cs_clear_INTEN_DRDY_bit(device->hw);
-
- return ERR_NONE;
-}
-
-/**
- * \brief Enable/disable I2C slave interrupt
- */
-int32_t _i2c_s_async_set_irq_state(struct _i2c_s_async_device *const device, const enum _i2c_s_async_callback_type type,
- const bool state)
-{
- ASSERT(device);
-
- if (I2C_S_DEVICE_TX == type || I2C_S_DEVICE_RX_COMPLETE == type) {
- hri_sercomi2cs_write_INTEN_DRDY_bit(device->hw, state);
- } else if (I2C_S_DEVICE_ERROR == type) {
- hri_sercomi2cs_write_INTEN_ERROR_bit(device->hw, state);
- }
-
- return ERR_NONE;
-}
-
-/**
- * \internal Initalize i2c slave hardware
- *
- * \param[in] p The pointer to hardware instance
- *
- *\ return status of initialization
- */
-static int32_t _i2c_s_init(void *const hw)
-{
- int8_t i = _get_i2c_s_index(hw);
- if (i == -1) {
- return ERR_INVALID_ARG;
- }
-
- hri_sercomi2cs_wait_for_sync(hw, SERCOM_I2CS_CTRLA_SWRST);
- if (hri_sercomi2cs_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_sercomi2cs_set_CTRLA_SWRST_bit(hw);
- hri_sercomi2cs_wait_for_sync(hw, SERCOM_I2CS_CTRLA_SWRST);
-
- hri_sercomi2cs_write_CTRLA_reg(hw, _i2css[i].ctrl_a);
- hri_sercomi2cs_write_CTRLB_reg(hw, _i2css[i].ctrl_b);
- hri_sercomi2cs_write_ADDR_reg(hw, _i2css[i].address);
-
- return ERR_NONE;
-}
-
-/**
- * \internal Retrieve ordinal number of the given sercom hardware instance
- *
- * \param[in] hw The pointer to hardware instance
- *
- * \return The ordinal number of the given sercom hardware instance
- */
-static int8_t _get_i2c_s_index(const void *const hw)
-{
- uint8_t sercom_offset = _sercom_get_hardware_index(hw);
- uint8_t i;
-
- for (i = 0; i < ARRAY_SIZE(_i2css); i++) {
- if (_i2css[i].number == sercom_offset) {
- return i;
- }
- }
-
- ASSERT(false);
- return -1;
-}
-
-/**
- * \internal De-initialize i2c slave
- *
- * \param[in] hw The pointer to hardware instance
- */
-static inline void _i2c_s_deinit(void *const hw)
-{
- hri_sercomi2cs_clear_CTRLA_ENABLE_bit(hw);
- hri_sercomi2cs_set_CTRLA_SWRST_bit(hw);
-}
-
-/**
- * \internal De-initialize i2c slave
- *
- * \param[in] hw The pointer to hardware instance
- * \param[in] address Address to set
- */
-static int32_t _i2c_s_set_address(void *const hw, const uint16_t address)
-{
- bool enabled;
-
- enabled = hri_sercomi2cs_get_CTRLA_ENABLE_bit(hw);
-
- CRITICAL_SECTION_ENTER()
- hri_sercomi2cs_clear_CTRLA_ENABLE_bit(hw);
- hri_sercomi2cs_write_ADDR_ADDR_bf(hw, address);
- CRITICAL_SECTION_LEAVE()
-
- if (enabled) {
- hri_sercomi2cs_set_CTRLA_ENABLE_bit(hw);
- }
-
- return ERR_NONE;
-}
-
-/* Sercom SPI implementation */
-
-#ifndef SERCOM_USART_CTRLA_MODE_SPI_SLAVE
-#define SERCOM_USART_CTRLA_MODE_SPI_SLAVE (2 << 2)
-#endif
-
-#define SPI_DEV_IRQ_MODE 0x8000
-
-#define _SPI_CS_PORT_EXTRACT(cs) (((cs) >> 0) & 0xFF)
-#define _SPI_CS_PIN_EXTRACT(cs) (((cs) >> 8) & 0xFF)
-
-COMPILER_PACK_SET(1)
-/** Initialization configuration of registers. */
-struct sercomspi_regs_cfg {
- uint32_t ctrla;
- uint32_t ctrlb;
- uint32_t addr;
- uint8_t baud;
- uint8_t dbgctrl;
- uint16_t dummy_byte;
- uint8_t n;
-};
-COMPILER_PACK_RESET()
-
-/** Build configuration from header macros. */
-#define SERCOMSPI_REGS(n) \
- { \
- ((CONF_SERCOM_##n##_SPI_DORD) | (CONF_SERCOM_##n##_SPI_CPOL << SERCOM_SPI_CTRLA_CPOL_Pos) \
- | (CONF_SERCOM_##n##_SPI_CPHA << SERCOM_SPI_CTRLA_CPHA_Pos) \
- | (CONF_SERCOM_##n##_SPI_AMODE_EN ? SERCOM_SPI_CTRLA_FORM(2) : SERCOM_SPI_CTRLA_FORM(0)) \
- | SERCOM_SPI_CTRLA_DOPO(CONF_SERCOM_##n##_SPI_TXPO) \
- | SERCOM_SPI_CTRLA_DIPO(CONF_SERCOM_##n##_SPI_RXPO) \
- | (CONF_SERCOM_##n##_SPI_IBON << SERCOM_SPI_CTRLA_IBON_Pos) \
- | (CONF_SERCOM_##n##_SPI_RUNSTDBY << SERCOM_SPI_CTRLA_RUNSTDBY_Pos) \
- | SERCOM_SPI_CTRLA_MODE(CONF_SERCOM_##n##_SPI_MODE)), /* ctrla */ \
- ((CONF_SERCOM_##n##_SPI_RXEN << SERCOM_SPI_CTRLB_RXEN_Pos) \
- | (CONF_SERCOM_##n##_SPI_MSSEN << SERCOM_SPI_CTRLB_MSSEN_Pos) \
- | (CONF_SERCOM_##n##_SPI_SSDE << SERCOM_SPI_CTRLB_SSDE_Pos) \
- | (CONF_SERCOM_##n##_SPI_PLOADEN << SERCOM_SPI_CTRLB_PLOADEN_Pos) \
- | SERCOM_SPI_CTRLB_AMODE(CONF_SERCOM_##n##_SPI_AMODE) \
- | SERCOM_SPI_CTRLB_CHSIZE(CONF_SERCOM_##n##_SPI_CHSIZE)), /* ctrlb */ \
- (SERCOM_SPI_ADDR_ADDR(CONF_SERCOM_##n##_SPI_ADDR) \
- | SERCOM_SPI_ADDR_ADDRMASK(CONF_SERCOM_##n##_SPI_ADDRMASK)), /* addr */ \
- ((uint8_t)CONF_SERCOM_##n##_SPI_BAUD_RATE), /* baud */ \
- (CONF_SERCOM_##n##_SPI_DBGSTOP << SERCOM_SPI_DBGCTRL_DBGSTOP_Pos), /* dbgctrl */ \
- CONF_SERCOM_##n##_SPI_DUMMYBYTE, /* Dummy byte for SPI master mode */ \
- n /* sercom number */ \
- }
-
-#ifndef CONF_SERCOM_0_SPI_ENABLE
-#define CONF_SERCOM_0_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_1_SPI_ENABLE
-#define CONF_SERCOM_1_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_2_SPI_ENABLE
-#define CONF_SERCOM_2_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_3_SPI_ENABLE
-#define CONF_SERCOM_3_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_4_SPI_ENABLE
-#define CONF_SERCOM_4_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_5_SPI_ENABLE
-#define CONF_SERCOM_5_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_6_SPI_ENABLE
-#define CONF_SERCOM_6_SPI_ENABLE 0
-#endif
-#ifndef CONF_SERCOM_7_SPI_ENABLE
-#define CONF_SERCOM_7_SPI_ENABLE 0
-#endif
-
-/** Amount of SERCOM that is used as SPI */
-#define SERCOM_SPI_AMOUNT \
- (CONF_SERCOM_0_SPI_ENABLE + CONF_SERCOM_1_SPI_ENABLE + CONF_SERCOM_2_SPI_ENABLE + CONF_SERCOM_3_SPI_ENABLE \
- + CONF_SERCOM_4_SPI_ENABLE \
- + CONF_SERCOM_5_SPI_ENABLE \
- + CONF_SERCOM_6_SPI_ENABLE \
- + CONF_SERCOM_7_SPI_ENABLE)
-
-#if SERCOM_SPI_AMOUNT < 1
-/** Dummy array for compiling. */
-static const struct sercomspi_regs_cfg sercomspi_regs[1] = {{0}};
-#else
-/** The SERCOM SPI configurations of SERCOM that is used as SPI. */
-static const struct sercomspi_regs_cfg sercomspi_regs[] = {
-#if CONF_SERCOM_0_SPI_ENABLE
- SERCOMSPI_REGS(0),
-#endif
-#if CONF_SERCOM_1_SPI_ENABLE
- SERCOMSPI_REGS(1),
-#endif
-#if CONF_SERCOM_2_SPI_ENABLE
- SERCOMSPI_REGS(2),
-#endif
-#if CONF_SERCOM_3_SPI_ENABLE
- SERCOMSPI_REGS(3),
-#endif
-#if CONF_SERCOM_4_SPI_ENABLE
- SERCOMSPI_REGS(4),
-#endif
-#if CONF_SERCOM_5_SPI_ENABLE
- SERCOMSPI_REGS(5),
-#endif
-#if CONF_SERCOM_6_SPI_ENABLE
- SERCOMSPI_REGS(6),
-#endif
-#if CONF_SERCOM_7_SPI_ENABLE
- SERCOMSPI_REGS(7),
-#endif
-};
-#endif
-
-/** \internal De-initialize SERCOM SPI
- *
- * \param[in] hw Pointer to the hardware register base.
- *
- * \return De-initialization status
- */
-static int32_t _spi_deinit(void *const hw)
-{
- hri_sercomspi_clear_CTRLA_ENABLE_bit(hw);
- hri_sercomspi_set_CTRLA_SWRST_bit(hw);
-
- return ERR_NONE;
-}
-
-/** \internal Enable SERCOM SPI
- *
- * \param[in] hw Pointer to the hardware register base.
- *
- * \return Enabling status
- */
-static int32_t _spi_sync_enable(void *const hw)
-{
- if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST)) {
- return ERR_BUSY;
- }
-
- hri_sercomspi_set_CTRLA_ENABLE_bit(hw);
-
- return ERR_NONE;
-}
-
-/** \internal Enable SERCOM SPI
- *
- * \param[in] hw Pointer to the hardware register base.
- *
- * \return Enabling status
- */
-static int32_t _spi_async_enable(void *const hw)
-{
- _spi_sync_enable(hw);
- NVIC_EnableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_EnableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
-
- return ERR_NONE;
-}
-
-/** \internal Disable SERCOM SPI
- *
- * \param[in] hw Pointer to the hardware register base.
- *
- * \return Disabling status
- */
-static int32_t _spi_sync_disable(void *const hw)
-{
- if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST)) {
- return ERR_BUSY;
- }
- hri_sercomspi_clear_CTRLA_ENABLE_bit(hw);
-
- return ERR_NONE;
-}
-
-/** \internal Disable SERCOM SPI
- *
- * \param[in] hw Pointer to the hardware register base.
- *
- * \return Disabling status
- */
-static int32_t _spi_async_disable(void *const hw)
-{
- _spi_sync_disable(hw);
- hri_sercomspi_clear_INTEN_reg(
- hw, SERCOM_SPI_INTFLAG_ERROR | SERCOM_SPI_INTFLAG_RXC | SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE);
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
-
- return ERR_NONE;
-}
-
-/** \internal Set SERCOM SPI mode
- *
- * \param[in] hw Pointer to the hardware register base.
- * \param[in] mode The mode to set
- *
- * \return Setting mode status
- */
-static int32_t _spi_set_mode(void *const hw, const enum spi_transfer_mode mode)
-{
- uint32_t ctrla;
-
- if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_ENABLE)) {
- return ERR_BUSY;
- }
-
- ctrla = hri_sercomspi_read_CTRLA_reg(hw);
- ctrla &= ~(SERCOM_SPI_CTRLA_CPOL | SERCOM_SPI_CTRLA_CPHA);
- ctrla |= (mode & 0x3u) << SERCOM_SPI_CTRLA_CPHA_Pos;
- hri_sercomspi_write_CTRLA_reg(hw, ctrla);
-
- return ERR_NONE;
-}
-
-/** \internal Set SERCOM SPI baudrate
- *
- * \param[in] hw Pointer to the hardware register base.
- * \param[in] baud_val The baudrate to set
- *
- * \return Setting baudrate status
- */
-static int32_t _spi_set_baudrate(void *const hw, const uint32_t baud_val)
-{
- if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST)) {
- return ERR_BUSY;
- }
-
- hri_sercomspi_write_BAUD_reg(hw, baud_val);
-
- return ERR_NONE;
-}
-
-/** \internal Set SERCOM SPI char size
- *
- * \param[in] hw Pointer to the hardware register base.
- * \param[in] baud_val The baudrate to set
- * \param[out] size Stored char size
- *
- * \return Setting char size status
- */
-static int32_t _spi_set_char_size(void *const hw, const enum spi_char_size char_size, uint8_t *const size)
-{
- /* Only 8-bit or 9-bit accepted */
- if (!(char_size == SPI_CHAR_SIZE_8 || char_size == SPI_CHAR_SIZE_9)) {
- return ERR_INVALID_ARG;
- }
-
- if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_CTRLB)) {
- return ERR_BUSY;
- }
-
- hri_sercomspi_write_CTRLB_CHSIZE_bf(hw, char_size);
- *size = (char_size == SPI_CHAR_SIZE_8) ? 1 : 2;
-
- return ERR_NONE;
-}
-
-/** \internal Set SERCOM SPI data order
- *
- * \param[in] hw Pointer to the hardware register base.
- * \param[in] baud_val The baudrate to set
- *
- * \return Setting data order status
- */
-static int32_t _spi_set_data_order(void *const hw, const enum spi_data_order dord)
-{
- uint32_t ctrla;
-
- if (hri_sercomspi_is_syncing(hw, SERCOM_SPI_SYNCBUSY_SWRST)) {
- return ERR_BUSY;
- }
-
- ctrla = hri_sercomspi_read_CTRLA_reg(hw);
-
- if (dord == SPI_DATA_ORDER_LSB_1ST) {
- ctrla |= SERCOM_SPI_CTRLA_DORD;
- } else {
- ctrla &= ~SERCOM_SPI_CTRLA_DORD;
- }
- hri_sercomspi_write_CTRLA_reg(hw, ctrla);
-
- return ERR_NONE;
-}
-
-/** \brief Load SERCOM registers to init for SPI master mode
- * The settings will be applied with default master mode, unsupported things
- * are ignored.
- * \param[in, out] hw Pointer to the hardware register base.
- * \param[in] regs Pointer to register configuration values.
- */
-static inline void _spi_load_regs_master(void *const hw, const struct sercomspi_regs_cfg *regs)
-{
- ASSERT(hw && regs);
- hri_sercomspi_write_CTRLA_reg(
- hw, regs->ctrla & ~(SERCOM_SPI_CTRLA_IBON | SERCOM_SPI_CTRLA_ENABLE | SERCOM_SPI_CTRLA_SWRST));
- hri_sercomspi_write_CTRLB_reg(
- hw,
- (regs->ctrlb
- & ~(SERCOM_SPI_CTRLB_MSSEN | SERCOM_SPI_CTRLB_AMODE_Msk | SERCOM_SPI_CTRLB_SSDE | SERCOM_SPI_CTRLB_PLOADEN))
- | (SERCOM_SPI_CTRLB_RXEN));
- hri_sercomspi_write_BAUD_reg(hw, regs->baud);
- hri_sercomspi_write_DBGCTRL_reg(hw, regs->dbgctrl);
-}
-
-/** \brief Load SERCOM registers to init for SPI slave mode
- * The settings will be applied with default slave mode, unsupported things
- * are ignored.
- * \param[in, out] hw Pointer to the hardware register base.
- * \param[in] regs Pointer to register configuration values.
- */
-static inline void _spi_load_regs_slave(void *const hw, const struct sercomspi_regs_cfg *regs)
-{
- ASSERT(hw && regs);
- hri_sercomspi_write_CTRLA_reg(
- hw, regs->ctrla & ~(SERCOM_SPI_CTRLA_IBON | SERCOM_SPI_CTRLA_ENABLE | SERCOM_SPI_CTRLA_SWRST));
- hri_sercomspi_write_CTRLB_reg(hw,
- (regs->ctrlb & ~(SERCOM_SPI_CTRLB_MSSEN))
- | (SERCOM_SPI_CTRLB_RXEN | SERCOM_SPI_CTRLB_SSDE | SERCOM_SPI_CTRLB_PLOADEN));
- hri_sercomspi_write_ADDR_reg(hw, regs->addr);
- hri_sercomspi_write_DBGCTRL_reg(hw, regs->dbgctrl);
- while (hri_sercomspi_is_syncing(hw, 0xFFFFFFFF))
- ;
-}
-
-/** \brief Return the pointer to register settings of specific SERCOM
- * \param[in] hw_addr The hardware register base address.
- * \return Pointer to register settings of specific SERCOM.
- */
-static inline const struct sercomspi_regs_cfg *_spi_get_regs(const uint32_t hw_addr)
-{
- uint8_t n = _sercom_get_hardware_index((const void *)hw_addr);
- uint8_t i;
-
- for (i = 0; i < sizeof(sercomspi_regs) / sizeof(struct sercomspi_regs_cfg); i++) {
- if (sercomspi_regs[i].n == n) {
- return &sercomspi_regs[i];
- }
- }
-
- return NULL;
-}
-
-int32_t _spi_m_sync_init(struct _spi_m_sync_dev *dev, void *const hw)
-{
- const struct sercomspi_regs_cfg *regs = _spi_get_regs((uint32_t)hw);
-
- ASSERT(dev && hw);
-
- if (regs == NULL) {
- return ERR_INVALID_ARG;
- }
-
- hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_SWRST);
- if (hri_sercomspi_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_sercomspi_set_CTRLA_SWRST_bit(hw);
- hri_sercomspi_wait_for_sync(hw, SERCOM_SPI_SYNCBUSY_SWRST);
- dev->prvt = hw;
-
- if ((regs->ctrla & SERCOM_SPI_CTRLA_MODE_Msk) == SERCOM_USART_CTRLA_MODE_SPI_SLAVE) {
- _spi_load_regs_slave(hw, regs);
- } else {
- _spi_load_regs_master(hw, regs);
- }
-
- /* Load character size from default hardware configuration */
- dev->char_size = ((regs->ctrlb & SERCOM_SPI_CTRLB_CHSIZE_Msk) == 0) ? 1 : 2;
-
- dev->dummy_byte = regs->dummy_byte;
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_sync_init(struct _spi_s_sync_dev *dev, void *const hw)
-{
- return _spi_m_sync_init(dev, hw);
-}
-
-int32_t _spi_m_async_init(struct _spi_async_dev *dev, void *const hw)
-{
- struct _spi_async_dev *spid = dev;
- /* Do hardware initialize. */
- int32_t rc = _spi_m_sync_init((struct _spi_m_sync_dev *)dev, hw);
-
- if (rc < 0) {
- return rc;
- }
-
- _sercom_init_irq_param(hw, (void *)dev);
- /* Initialize callbacks: must use them */
- spid->callbacks.complete = NULL;
- spid->callbacks.rx = NULL;
- spid->callbacks.tx = NULL;
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(hw));
- NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(hw));
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_async_init(struct _spi_s_async_dev *dev, void *const hw)
-{
- return _spi_m_async_init(dev, hw);
-}
-
-int32_t _spi_m_async_deinit(struct _spi_async_dev *dev)
-{
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(dev->prvt));
- NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(dev->prvt));
-
- return _spi_deinit(dev->prvt);
-}
-
-int32_t _spi_s_async_deinit(struct _spi_s_async_dev *dev)
-{
- NVIC_DisableIRQ((IRQn_Type)_sercom_get_irq_num(dev->prvt));
- NVIC_ClearPendingIRQ((IRQn_Type)_sercom_get_irq_num(dev->prvt));
-
- return _spi_deinit(dev->prvt);
-}
-
-int32_t _spi_m_sync_deinit(struct _spi_m_sync_dev *dev)
-{
- return _spi_deinit(dev->prvt);
-}
-
-int32_t _spi_s_sync_deinit(struct _spi_s_sync_dev *dev)
-{
- return _spi_deinit(dev->prvt);
-}
-
-int32_t _spi_m_sync_enable(struct _spi_m_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_sync_enable(dev->prvt);
-}
-
-int32_t _spi_s_sync_enable(struct _spi_s_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_sync_enable(dev->prvt);
-}
-
-int32_t _spi_m_async_enable(struct _spi_async_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_async_enable(dev->prvt);
-}
-
-int32_t _spi_s_async_enable(struct _spi_s_async_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_async_enable(dev->prvt);
-}
-
-int32_t _spi_m_sync_disable(struct _spi_m_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_sync_disable(dev->prvt);
-}
-
-int32_t _spi_s_sync_disable(struct _spi_s_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_sync_disable(dev->prvt);
-}
-
-int32_t _spi_m_async_disable(struct _spi_async_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_async_disable(dev->prvt);
-}
-
-int32_t _spi_s_async_disable(struct _spi_s_async_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_async_disable(dev->prvt);
-}
-
-int32_t _spi_m_sync_set_mode(struct _spi_m_sync_dev *dev, const enum spi_transfer_mode mode)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_mode(dev->prvt, mode);
-}
-
-int32_t _spi_m_async_set_mode(struct _spi_async_dev *dev, const enum spi_transfer_mode mode)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_mode(dev->prvt, mode);
-}
-
-int32_t _spi_s_async_set_mode(struct _spi_s_async_dev *dev, const enum spi_transfer_mode mode)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_mode(dev->prvt, mode);
-}
-
-int32_t _spi_s_sync_set_mode(struct _spi_s_sync_dev *dev, const enum spi_transfer_mode mode)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_mode(dev->prvt, mode);
-}
-
-int32_t _spi_calc_baud_val(struct spi_dev *dev, const uint32_t clk, const uint32_t baud)
-{
- int32_t rc;
- ASSERT(dev);
-
- /* Not accept 0es */
- if (clk == 0 || baud == 0) {
- return ERR_INVALID_ARG;
- }
-
- /* Check baudrate range of current assigned clock */
- if (!(baud <= (clk >> 1) && baud >= (clk >> 8))) {
- return ERR_INVALID_ARG;
- }
-
- rc = ((clk >> 1) / baud) - 1;
- return rc;
-}
-
-int32_t _spi_m_sync_set_baudrate(struct _spi_m_sync_dev *dev, const uint32_t baud_val)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_baudrate(dev->prvt, baud_val);
-}
-
-int32_t _spi_m_async_set_baudrate(struct _spi_async_dev *dev, const uint32_t baud_val)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_baudrate(dev->prvt, baud_val);
-}
-
-int32_t _spi_m_sync_set_char_size(struct _spi_m_sync_dev *dev, const enum spi_char_size char_size)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_char_size(dev->prvt, char_size, &dev->char_size);
-}
-
-int32_t _spi_m_async_set_char_size(struct _spi_async_dev *dev, const enum spi_char_size char_size)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_char_size(dev->prvt, char_size, &dev->char_size);
-}
-
-int32_t _spi_s_async_set_char_size(struct _spi_s_async_dev *dev, const enum spi_char_size char_size)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_char_size(dev->prvt, char_size, &dev->char_size);
-}
-
-int32_t _spi_s_sync_set_char_size(struct _spi_s_sync_dev *dev, const enum spi_char_size char_size)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_char_size(dev->prvt, char_size, &dev->char_size);
-}
-
-int32_t _spi_m_sync_set_data_order(struct _spi_m_sync_dev *dev, const enum spi_data_order dord)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_data_order(dev->prvt, dord);
-}
-
-int32_t _spi_m_async_set_data_order(struct _spi_async_dev *dev, const enum spi_data_order dord)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_data_order(dev->prvt, dord);
-}
-
-int32_t _spi_s_async_set_data_order(struct _spi_s_async_dev *dev, const enum spi_data_order dord)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_data_order(dev->prvt, dord);
-}
-
-int32_t _spi_s_sync_set_data_order(struct _spi_s_sync_dev *dev, const enum spi_data_order dord)
-{
- ASSERT(dev && dev->prvt);
-
- return _spi_set_data_order(dev->prvt, dord);
-}
-
-/** Wait until SPI bus idle. */
-static inline void _spi_wait_bus_idle(void *const hw)
-{
- while (!(hri_sercomspi_get_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE))) {
- ;
- }
- hri_sercomspi_clear_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_TXC | SERCOM_SPI_INTFLAG_DRE);
-}
-
-/** Holds run time information for message sync transaction. */
-struct _spi_trans_ctrl {
- /** Pointer to transmitting data buffer. */
- uint8_t *txbuf;
- /** Pointer to receiving data buffer. */
- uint8_t *rxbuf;
- /** Count number of data transmitted. */
- uint32_t txcnt;
- /** Count number of data received. */
- uint32_t rxcnt;
- /** Data character size. */
- uint8_t char_size;
-};
-
-/** Check interrupt flag of RXC and update transaction runtime information. */
-static inline bool _spi_rx_check_and_receive(void *const hw, const uint32_t iflag, struct _spi_trans_ctrl *ctrl)
-{
- uint32_t data;
-
- if (!(iflag & SERCOM_SPI_INTFLAG_RXC)) {
- return false;
- }
-
- data = hri_sercomspi_read_DATA_reg(hw);
-
- if (ctrl->rxbuf) {
- *ctrl->rxbuf++ = (uint8_t)data;
-
- if (ctrl->char_size > 1) {
- *ctrl->rxbuf++ = (uint8_t)(data >> 8);
- }
- }
-
- ctrl->rxcnt++;
-
- return true;
-}
-
-/** Check interrupt flag of DRE and update transaction runtime information. */
-static inline void _spi_tx_check_and_send(void *const hw, const uint32_t iflag, struct _spi_trans_ctrl *ctrl,
- uint16_t dummy)
-{
- uint32_t data;
-
- if (!(SERCOM_SPI_INTFLAG_DRE & iflag)) {
- return;
- }
-
- if (ctrl->txbuf) {
- data = *ctrl->txbuf++;
-
- if (ctrl->char_size > 1) {
- data |= (*ctrl->txbuf) << 8;
- ctrl->txbuf++;
- }
- } else {
- data = dummy;
- }
-
- ctrl->txcnt++;
- hri_sercomspi_write_DATA_reg(hw, data);
-}
-
-/** Check interrupt flag of ERROR and update transaction runtime information. */
-static inline int32_t _spi_err_check(const uint32_t iflag, void *const hw)
-{
- if (SERCOM_SPI_INTFLAG_ERROR & iflag) {
- hri_sercomspi_clear_STATUS_reg(hw, ~0);
- hri_sercomspi_clear_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_ERROR);
- return ERR_OVERFLOW;
- }
-
- return ERR_NONE;
-}
-
-int32_t _spi_m_sync_trans(struct _spi_m_sync_dev *dev, const struct spi_msg *msg)
-{
- void * hw = dev->prvt;
- int32_t rc = 0;
- struct _spi_trans_ctrl ctrl = {msg->txbuf, msg->rxbuf, 0, 0, dev->char_size};
-
- ASSERT(dev && hw);
-
- /* If settings are not applied (pending), we can not go on */
- if (hri_sercomspi_is_syncing(
- hw, (SERCOM_SPI_SYNCBUSY_SWRST | SERCOM_SPI_SYNCBUSY_ENABLE | SERCOM_SPI_SYNCBUSY_CTRLB))) {
- return ERR_BUSY;
- }
-
- /* SPI must be enabled to start synchronous transfer */
- if (!hri_sercomspi_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_NOT_INITIALIZED;
- }
-
- for (;;) {
- uint32_t iflag = hri_sercomspi_read_INTFLAG_reg(hw);
-
- if (!_spi_rx_check_and_receive(hw, iflag, &ctrl)) {
- /* In master mode, do not start next byte before previous byte received
- * to make better output waveform */
- if (ctrl.rxcnt >= ctrl.txcnt) {
- _spi_tx_check_and_send(hw, iflag, &ctrl, dev->dummy_byte);
- }
- }
-
- rc = _spi_err_check(iflag, hw);
-
- if (rc < 0) {
- break;
- }
- if (ctrl.txcnt >= msg->size && ctrl.rxcnt >= msg->size) {
- rc = ctrl.txcnt;
- break;
- }
- }
- /* Wait until SPI bus idle */
- _spi_wait_bus_idle(hw);
-
- return rc;
-}
-
-int32_t _spi_m_async_enable_tx(struct _spi_async_dev *dev, bool state)
-{
- void *hw = dev->prvt;
-
- ASSERT(dev && hw);
-
- if (state) {
- hri_sercomspi_set_INTEN_DRE_bit(hw);
- } else {
- hri_sercomspi_clear_INTEN_DRE_bit(hw);
- }
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_async_enable_tx(struct _spi_s_async_dev *dev, bool state)
-{
- return _spi_m_async_enable_tx(dev, state);
-}
-
-int32_t _spi_m_async_enable_rx(struct _spi_async_dev *dev, bool state)
-{
- void *hw = dev->prvt;
-
- ASSERT(dev);
- ASSERT(hw);
-
- if (state) {
- hri_sercomspi_set_INTEN_RXC_bit(hw);
- } else {
- hri_sercomspi_clear_INTEN_RXC_bit(hw);
- }
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_async_enable_rx(struct _spi_s_async_dev *dev, bool state)
-{
- return _spi_m_async_enable_rx(dev, state);
-}
-
-int32_t _spi_m_async_enable_ss_detect(struct _spi_async_dev *dev, bool state)
-{
- ASSERT(dev && dev->prvt);
-
- if (state) {
- hri_sercomspi_set_INTEN_TXC_bit(dev->prvt);
- } else {
- hri_sercomspi_clear_INTEN_TXC_bit(dev->prvt);
- }
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_async_enable_ss_detect(struct _spi_s_async_dev *dev, bool state)
-{
- return _spi_m_async_enable_ss_detect(dev, state);
-}
-
-int32_t _spi_m_async_write_one(struct _spi_async_dev *dev, uint16_t data)
-{
- ASSERT(dev && dev->prvt);
-
- hri_sercomspi_write_DATA_reg(dev->prvt, data);
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_async_write_one(struct _spi_s_async_dev *dev, uint16_t data)
-{
- ASSERT(dev && dev->prvt);
-
- hri_sercomspi_write_DATA_reg(dev->prvt, data);
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_sync_write_one(struct _spi_s_sync_dev *dev, uint16_t data)
-{
- ASSERT(dev && dev->prvt);
-
- hri_sercomspi_write_DATA_reg(dev->prvt, data);
-
- return ERR_NONE;
-}
-
-uint16_t _spi_m_async_read_one(struct _spi_async_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return hri_sercomspi_read_DATA_reg(dev->prvt);
-}
-
-uint16_t _spi_s_async_read_one(struct _spi_s_async_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return hri_sercomspi_read_DATA_reg(dev->prvt);
-}
-
-uint16_t _spi_s_sync_read_one(struct _spi_s_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return hri_sercomspi_read_DATA_reg(dev->prvt);
-}
-
-int32_t _spi_m_async_register_callback(struct _spi_async_dev *dev, const enum _spi_async_dev_cb_type cb_type,
- const FUNC_PTR func)
-{
- typedef void (*func_t)(void);
- struct _spi_async_dev *spid = dev;
-
- ASSERT(dev && (cb_type < SPI_DEV_CB_N));
-
- func_t *p_ls = (func_t *)&spid->callbacks;
- p_ls[cb_type] = (func_t)func;
-
- return ERR_NONE;
-}
-
-int32_t _spi_s_async_register_callback(struct _spi_s_async_dev *dev, const enum _spi_s_async_dev_cb_type cb_type,
- const FUNC_PTR func)
-{
- return _spi_m_async_register_callback(dev, cb_type, func);
-}
-
-bool _spi_s_sync_is_tx_ready(struct _spi_s_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return hri_sercomi2cm_get_INTFLAG_reg(dev->prvt, SERCOM_SPI_INTFLAG_DRE);
-}
-
-bool _spi_s_sync_is_rx_ready(struct _spi_s_sync_dev *dev)
-{
- ASSERT(dev && dev->prvt);
-
- return hri_sercomi2cm_get_INTFLAG_reg(dev->prvt, SERCOM_SPI_INTFLAG_RXC);
-}
-
-bool _spi_s_sync_is_ss_deactivated(struct _spi_s_sync_dev *dev)
-{
- void *hw = dev->prvt;
-
- ASSERT(dev && hw);
-
- if (hri_sercomi2cm_get_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_TXC)) {
- hri_sercomspi_clear_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_TXC);
- return true;
- }
- return false;
-}
-
-bool _spi_s_sync_is_error(struct _spi_s_sync_dev *dev)
-{
- void *hw = dev->prvt;
-
- ASSERT(dev && hw);
-
- if (hri_sercomi2cm_get_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_ERROR)) {
- hri_sercomspi_clear_STATUS_reg(hw, SERCOM_SPI_STATUS_BUFOVF);
- hri_sercomspi_clear_INTFLAG_reg(hw, SERCOM_SPI_INTFLAG_ERROR);
- return true;
- }
- return false;
-}
-
-/**
- * \brief Enable/disable SPI master interrupt
- *
- * param[in] device The pointer to SPI master device instance
- * param[in] type The type of interrupt to disable/enable if applicable
- * param[in] state Enable or disable
- */
-void _spi_m_async_set_irq_state(struct _spi_async_dev *const device, const enum _spi_async_dev_cb_type type,
- const bool state)
-{
- ASSERT(device);
-
- if (SPI_DEV_CB_COMPLETE == type) {
- hri_sercomspi_write_INTEN_ERROR_bit(device->prvt, state);
- }
-}
diff --git a/atmel-samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c b/atmel-samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c
deleted file mode 100644
index fb0156082..000000000
--- a/atmel-samd/asf4/samd21/hpl/sysctrl/hpl_sysctrl.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/**
- * \file
- *
- * \brief SAM System Controller.
- *
- * Copyright (C) 2015 - 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
- *
- */
-
-#include <hpl_init.h>
-#include <hpl_sysctrl_config.h>
-#include <utils_assert.h>
-
-/**
- * \brief Initializes clock generators
- *
- * All GCLK generators are running when this function returns.
- */
-void _sysctrl_init_sources(void)
-{
- void * hw = (void *)SYSCTRL;
- uint16_t calib;
-
-#if CONF_XOSC32K_CONFIG == 1
- hri_sysctrl_write_XOSC32K_reg(hw,
- (CONF_XOSC32K_WRTLOCK << SYSCTRL_XOSC32K_WRTLOCK_Pos)
- | SYSCTRL_XOSC32K_STARTUP(CONF_XOSC32K_STARTUP)
- | (CONF_XOSC32K_RUNSTDBY << SYSCTRL_XOSC32K_RUNSTDBY_Pos)
- | (CONF_XOSC32K_AAMPEN << SYSCTRL_XOSC32K_AAMPEN_Pos)
- | (CONF_XOSC32K_EN1K << SYSCTRL_XOSC32K_EN1K_Pos)
- | (CONF_XOSC32K_EN32K << SYSCTRL_XOSC32K_EN32K_Pos)
- | (CONF_XOSC32K_XTALEN << SYSCTRL_XOSC32K_XTALEN_Pos)
- | (CONF_XOSC32K_ENABLE << SYSCTRL_XOSC32K_ENABLE_Pos));
-#endif
-
-#if CONF_XOSC_CONFIG == 1
- hri_sysctrl_write_XOSC_reg(hw,
- SYSCTRL_XOSC_STARTUP(CONF_XOSC_STARTUP) | (CONF_XOSC_AMPGC << SYSCTRL_XOSC_AMPGC_Pos)
- | SYSCTRL_XOSC_GAIN(CONF_XOSC_GAIN)
- | (CONF_XOSC_RUNSTDBY << SYSCTRL_XOSC_RUNSTDBY_Pos)
- | (CONF_XOSC_XTALEN << SYSCTRL_XOSC_XTALEN_Pos)
- | (CONF_XOSC_ENABLE << SYSCTRL_XOSC_ENABLE_Pos));
-#endif
-
-#if CONF_OSC8M_CONFIG == 1
- calib = hri_sysctrl_read_OSC8M_CALIB_bf(hw);
-
- hri_sysctrl_write_OSC8M_reg(hw,
- SYSCTRL_OSC8M_FRANGE(hri_sysctrl_read_OSC8M_FRANGE_bf(hw)) |
-#if CONF_OSC8M_OVERWRITE_CALIBRATION == 1
- SYSCTRL_OSC8M_CALIB(CONF_OSC8M_CALIB) |
-#else
- SYSCTRL_OSC8M_CALIB(calib) |
-#endif
- SYSCTRL_OSC8M_PRESC(CONF_OSC8M_PRESC)
- | (CONF_OSC8M_RUNSTDBY << SYSCTRL_OSC8M_RUNSTDBY_Pos)
- | (CONF_OSC8M_ENABLE << SYSCTRL_OSC8M_ENABLE_Pos));
-#endif
-
-#if CONF_OSC32K_CONFIG == 1
- /* OSC32K calibration value at bit 44:38 of memory 0x00806020 */
- calib = (*((uint32_t *)0x00806024) & 0x0001FC0) >> 6;
-
- hri_sysctrl_write_OSC32K_reg(hw,
-#if CONF_OSC32K_OVERWRITE_CALIBRATION == 1
- SYSCTRL_OSC32K_CALIB(CONF_OSC32K_CALIB) |
-#else
- SYSCTRL_OSC32K_CALIB(calib) |
-#endif
- (CONF_OSC32K_WRTLOCK << SYSCTRL_OSC32K_WRTLOCK_Pos)
- | SYSCTRL_OSC32K_STARTUP(CONF_OSC32K_STARTUP)
- | (CONF_OSC32K_RUNSTDBY << SYSCTRL_OSC32K_RUNSTDBY_Pos)
- | (CONF_OSC32K_EN1K << SYSCTRL_OSC32K_EN1K_Pos)
- | (CONF_OSC32K_EN32K << SYSCTRL_OSC32K_EN32K_Pos)
- | (1 << SYSCTRL_OSC32K_ENABLE_Pos));
-#else
- /* Enable OSC32K anyway since GCLK configuration may need it to sync */
- hri_sysctrl_set_OSC32K_ENABLE_bit(hw);
-#endif
-
-#if CONF_OSCULP32K_CONFIG == 1
- hri_sysctrl_write_OSCULP32K_reg(hw,
-#if CONF_OSC32K_OVERWRITE_CALIBRATION == 1
- SYSCTRL_OSCULP32K_CALIB(CONF_OSCULP32K_CALIB) |
-#else
- SYSCTRL_OSCULP32K_CALIB(calib) |
-#endif
- (CONF_OSC32K_WRTLOCK << SYSCTRL_OSCULP32K_WRTLOCK_Pos));
-#endif
-
-#if CONF_XOSC32K_CONFIG == 1
-#if CONF_XOSC32K_ENABLE == 1
- while (!hri_sysctrl_get_PCLKSR_XOSC32KRDY_bit(hw))
- ;
-#endif
-#if CONF_XOSC32K_ONDEMAND == 1
- hri_sysctrl_set_XOSC32K_ONDEMAND_bit(hw);
-#endif
-#endif
-
-#if CONF_XOSC_CONFIG == 1
-#if CONF_XOSC_ENABLE == 1
- while (!hri_sysctrl_get_PCLKSR_XOSCRDY_bit(hw))
- ;
-#endif
-#if CONF_XOSC_ONDEMAND == 1
- hri_sysctrl_set_XOSC_ONDEMAND_bit(hw);
-#endif
-#endif
-
-#if CONF_OSC32K_CONFIG == 1
-#if CONF_OSC32K_ENABLE == 1
- while (!hri_sysctrl_get_PCLKSR_OSC32KRDY_bit(hw))
- ;
-#endif
-#if CONF_OSC32K_ONDEMAND == 1
- hri_sysctrl_set_OSC32K_ONDEMAND_bit(hw);
-#endif
-#endif
-
-#if CONF_OSC8M_CONFIG == 1
-#if CONF_OSC8M_ENABLE == 1
- while (!hri_sysctrl_get_PCLKSR_OSC8MRDY_bit(hw))
- ;
-#endif
-#if CONF_OSC8M_ONDEMAND == 1
- hri_sysctrl_set_OSC8M_ONDEMAND_bit(hw);
-#endif
-#endif
-
- (void)calib, (void)hw;
-}
-
-void _sysctrl_init_referenced_generators(void)
-{
- void *hw = (void *)SYSCTRL;
-
-#if CONF_DFLL_CONFIG == 1
-
-#if CONF_DFLL_USBCRM != 1 && CONF_DFLL_MODE != CONF_DFLL_OPEN_LOOP_MODE
- hri_gclk_write_CLKCTRL_reg(GCLK,
- GCLK_CLKCTRL_ID(0) | GCLK_CLKCTRL_GEN(CONF_DFLL_GCLK) | (1 << GCLK_CLKCTRL_CLKEN_Pos));
-#endif
-
- hri_sysctrl_write_DFLLCTRL_reg(hw, SYSCTRL_DFLLCTRL_ENABLE);
- while (!hri_sysctrl_get_PCLKSR_DFLLRDY_bit(hw))
- ;
-
- hri_sysctrl_write_DFLLMUL_reg(hw,
- SYSCTRL_DFLLMUL_CSTEP(CONF_DFLL_CSTEP) | SYSCTRL_DFLLMUL_FSTEP(CONF_DFLL_FSTEP)
- | SYSCTRL_DFLLMUL_MUL(CONF_DFLL_MUL));
- hri_sysctrl_write_DFLLVAL_reg(hw, CONF_DFLLVAL);
-
- hri_sysctrl_dfllctrl_reg_t tmp =
-
- (CONF_DFLL_WAITLOCK << SYSCTRL_DFLLCTRL_WAITLOCK_Pos) | (CONF_DFLL_BPLCKC << SYSCTRL_DFLLCTRL_BPLCKC_Pos)
- | (CONF_DFLL_QLDIS << SYSCTRL_DFLLCTRL_QLDIS_Pos) | (CONF_DFLL_CCDIS << SYSCTRL_DFLLCTRL_CCDIS_Pos)
- | (CONF_DFLL_RUNSTDBY << SYSCTRL_DFLLCTRL_RUNSTDBY_Pos) | (CONF_DFLL_USBCRM << SYSCTRL_DFLLCTRL_USBCRM_Pos)
- | (CONF_DFLL_LLAW << SYSCTRL_DFLLCTRL_LLAW_Pos) | (CONF_DFLL_STABLE << SYSCTRL_DFLLCTRL_STABLE_Pos)
- | (CONF_DFLL_MODE << SYSCTRL_DFLLCTRL_MODE_Pos) | (CONF_DFLL_ENABLE << SYSCTRL_DFLLCTRL_ENABLE_Pos);
-
- hri_sysctrl_write_DFLLCTRL_reg(hw, tmp);
-#endif
-
-#if CONF_DPLL_CONFIG == 1
-#if CONF_DPLL_REFCLK == SYSCTRL_DPLLCTRLB_REFCLK_GCLK_Val
- hri_gclk_write_CLKCTRL_reg(GCLK,
- GCLK_CLKCTRL_ID(1) | GCLK_CLKCTRL_GEN(CONF_DPLL_GCLK) | (1 << GCLK_CLKCTRL_CLKEN_Pos));
-#endif
-
- hri_sysctrl_write_DPLLCTRLA_reg(hw,
- (CONF_DPLL_RUNSTDBY << SYSCTRL_DPLLCTRLA_RUNSTDBY_Pos)
- | (CONF_DPLL_ENABLE << SYSCTRL_DPLLCTRLA_ENABLE_Pos));
- hri_sysctrl_write_DPLLRATIO_reg(
- hw, SYSCTRL_DPLLRATIO_LDRFRAC(CONF_DPLL_LDRFRAC) | SYSCTRL_DPLLRATIO_LDR(CONF_DPLL_LDR));
- hri_sysctrl_write_DPLLCTRLB_reg(hw,
- SYSCTRL_DPLLCTRLB_DIV(CONF_DPLL_DIV)
- | (CONF_DPLL_LBYPASS << SYSCTRL_DPLLCTRLB_LBYPASS_Pos)
- | SYSCTRL_DPLLCTRLB_LTIME(CONF_DPLL_LTIME)
- | SYSCTRL_DPLLCTRLB_REFCLK(CONF_DPLL_REFCLK)
- | (CONF_DPLL_WUF << SYSCTRL_DPLLCTRLB_WUF_Pos)
- | (CONF_DPLL_LPEN << SYSCTRL_DPLLCTRLB_LPEN_Pos)
- | SYSCTRL_DPLLCTRLB_FILTER(CONF_DPLL_FILTER));
-#endif
-
-#if CONF_DFLL_CONFIG == 1
-#if CONF_DFLL_ENABLE == 1
- if (hri_sysctrl_get_DFLLCTRL_MODE_bit(hw)) {
-
-#if CONF_DFLL_USBCRM == 0
- hri_sysctrl_pclksr_reg_t status_mask
- = SYSCTRL_PCLKSR_DFLLRDY | SYSCTRL_PCLKSR_DFLLLCKF | SYSCTRL_PCLKSR_DFLLLCKC;
-#else
- hri_sysctrl_pclksr_reg_t status_mask = SYSCTRL_PCLKSR_DFLLRDY;
-#endif
-
- while (hri_sysctrl_get_PCLKSR_reg(hw, status_mask) != status_mask)
- ;
- } else {
- while (!hri_sysctrl_get_PCLKSR_DFLLRDY_bit(hw))
- ;
- }
-#endif
-#if CONF_DFLL_ONDEMAND == 1
- hri_sysctrl_set_DFLLCTRL_ONDEMAND_bit(hw);
-#endif
-#endif
-
-#if CONF_DPLL_CONFIG == 1
-#if CONF_DPLL_ENABLE == 1
- while (!(hri_sysctrl_get_DPLLSTATUS_ENABLE_bit(hw) || hri_sysctrl_get_DPLLSTATUS_LOCK_bit(hw)
- || hri_sysctrl_get_DPLLSTATUS_CLKRDY_bit(hw)))
- ;
-#endif
-#if CONF_DPLL_ONDEMAND == 1
- hri_sysctrl_set_DPLLCTRLA_ONDEMAND_bit(hw);
-#endif
-#endif
-
-#if CONF_DFLL_CONFIG == 1
- while (hri_gclk_get_STATUS_SYNCBUSY_bit(GCLK))
- ;
-#endif
-
-#if CONF_OSC32K_CONFIG == 0 || CONF_OSC32K_ENABLE == 0
- /* Disable after all possible configurations needs sync written. */
- hri_sysctrl_clear_OSC32K_ENABLE_bit(hw);
-#endif
-
- (void)hw;
-}
diff --git a/atmel-samd/asf4/samd21/hpl/systick/hpl_systick.c b/atmel-samd/asf4/samd21/hpl/systick/hpl_systick.c
deleted file mode 100644
index 783f306e0..000000000
--- a/atmel-samd/asf4/samd21/hpl/systick/hpl_systick.c
+++ /dev/null
@@ -1,113 +0,0 @@
-
-/**
- * \file
- *
- * \brief SysTick related functionality implementation.
- *
- * Copyright (C) 2014 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_time_measure.h>
-#include <hpl_systick_config.h>
-
-/**
- * \brief Initialize system time module
- */
-void _system_time_init(void *const hw)
-{
- (void)hw;
- SysTick->LOAD = (0xFFFFFF << SysTick_LOAD_RELOAD_Pos);
- SysTick->CTRL = (1 << SysTick_CTRL_ENABLE_Pos) | (CONF_SYSTICK_TICKINT << SysTick_CTRL_TICKINT_Pos)
- | (1 << SysTick_CTRL_CLKSOURCE_Pos);
-}
-/**
- * \brief Initialize delay functionality
- */
-void _delay_init(void *const hw)
-{
- _system_time_init(hw);
-}
-
-/**
- * \brief De-initialize system time module
- */
-void _system_time_deinit(void *const hw)
-{
- (void)hw;
- SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;
-}
-
-/**
- * \brief Get system time
- */
-system_time_t _system_time_get(const void *const hw)
-{
- (void)hw;
- return (system_time_t)SysTick->VAL;
-}
-
-/**
- * \brief Get maximum possible system time
- */
-system_time_t _system_time_get_max_time_value(const void *const hw)
-{
- (void)hw;
- return 0xFFFFFF;
-}
-/**
- * \brief Delay loop to delay n number of cycles
- */
-void _delay_cycles(void *const hw, uint32_t cycles)
-{
- (void)hw;
- uint8_t n = cycles >> 24;
- uint32_t buf = cycles;
-
- while (n--) {
- SysTick->LOAD = 0xFFFFFF;
- SysTick->VAL = 0xFFFFFF;
- while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
- ;
- buf -= 0xFFFFFF;
- }
-
- SysTick->LOAD = buf;
- SysTick->VAL = buf;
- while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk))
- ;
-}
diff --git a/atmel-samd/asf4/samd21/hpl/tc/hpl_tc.c b/atmel-samd/asf4/samd21/hpl/tc/hpl_tc.c
deleted file mode 100644
index 9344729da..000000000
--- a/atmel-samd/asf4/samd21/hpl/tc/hpl_tc.c
+++ /dev/null
@@ -1,369 +0,0 @@
-/**
- * \file
- *
- * \brief SAM TC
- *
- * Copyright (C) 2015 - 2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <hpl_pwm.h>
-#include <hpl_tc_config.h>
-#include <hpl_timer.h>
-#include <utils.h>
-#include <utils_assert.h>
-#include <hpl_tc_base.h>
-
-#ifndef CONF_TC3_ENABLE
-#define CONF_TC3_ENABLE 0
-#endif
-#ifndef CONF_TC4_ENABLE
-#define CONF_TC4_ENABLE 0
-#endif
-#ifndef CONF_TC5_ENABLE
-#define CONF_TC5_ENABLE 0
-#endif
-#ifndef CONF_TC6_ENABLE
-#define CONF_TC6_ENABLE 0
-#endif
-#ifndef CONF_TC7_ENABLE
-#define CONF_TC7_ENABLE 0
-#endif
-
-/**
- * \brief TC IRQ base index
- */
-#define TC_IRQ_BASE_INDEX ((uint8_t)TC3_IRQn)
-
-/**
- * \brief TC base address
- */
-#define TC_HW_BASE_ADDR ((uint32_t)TC3)
-
-/**
- * \brief TC number offset
- */
-#define TC_NUMBER_OFFSET 3
-
-/**
- * \brief Macro is used to fill usart configuration structure based on its
- * number
- *
- * \param[in] n The number of structures
- */
-#define TC_CONFIGURATION(n) \
- { \
- (n), TC_CTRLA_MODE(CONF_TC##n##_MODE) | TC_CTRLA_WAVEGEN(TC_CTRLA_WAVEGEN_MPWM_Val) \
- | TC_CTRLA_PRESCALER(CONF_TC##n##_PRESCALER) | (CONF_TC##n##_RUNSTDBY << TC_CTRLA_RUNSTDBY_Pos) \
- | TC_CTRLA_PRESCSYNC(CONF_TC##n##_PRESCSYNC), \
- (CONF_TC##n##_DBGRUN << TC_DBGCTRL_DBGRUN_Pos), \
- (CONF_TC##n##_OVFEO << TC_EVCTRL_OVFEO_Pos) | (CONF_TC##n##_TCEI << TC_EVCTRL_TCEI_Pos) \
- | (CONF_TC##n##_TCINV << TC_EVCTRL_TCINV_Pos) | (CONF_TC##n##_EVACT << TC_EVCTRL_EVACT_Pos) \
- | (CONF_TC##n##_MCEO0 << TC_EVCTRL_MCEO0_Pos) | (CONF_TC##n##_MCEO1 << TC_EVCTRL_MCEO1_Pos), \
- CONF_TC##n##_PER, CONF_TC##n##_CC0, CONF_TC##n##_CC1 \
- }
-/**
- * \brief TC configuration type
- */
-struct tc_configuration {
- uint8_t number;
- hri_tc_ctrla_reg_t ctrl_a;
- hri_tc_dbgctrl_reg_t dbg_ctrl;
- hri_tc_evctrl_reg_t event_ctrl;
- hri_tc_per_reg_t per;
- hri_tc_cc32_reg_t cc0;
- hri_tc_cc32_reg_t cc1;
-};
-
-/**
- * \brief Array of TC configurations
- */
-static struct tc_configuration _tcs[] = {
-#if CONF_TC3_ENABLE == 1
- TC_CONFIGURATION(3),
-#endif
-#if CONF_TC4_ENABLE == 1
- TC_CONFIGURATION(4),
-#endif
-#if CONF_TC5_ENABLE == 1
- TC_CONFIGURATION(5),
-#endif
-#if CONF_TC6_ENABLE == 1
- TC_CONFIGURATION(6),
-#endif
-#if CONF_TC7_ENABLE == 1
- TC_CONFIGURATION(7),
-#endif
-};
-
-static struct _pwm_device *_tc3_dev = NULL;
-
-static int8_t get_tc_index(const void *const hw);
-static uint8_t tc_get_hardware_index(const void *const hw);
-static void _tc_init_irq_param(const void *const hw, void *dev);
-static inline uint8_t _get_hardware_offset(const void *const hw);
-/**
- * \brief Initialize TC for PWM mode
- */
-int32_t _pwm_init(struct _pwm_device *const device, void *const hw)
-{
- int8_t i = get_tc_index(hw);
- device->hw = hw;
-
- hri_tc_wait_for_sync(hw);
- if (hri_tc_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_tc_set_CTRLA_SWRST_bit(hw);
- hri_tc_wait_for_sync(hw);
-
- hri_tc_write_CTRLA_reg(hw, _tcs[i].ctrl_a);
- hri_tc_write_DBGCTRL_reg(hw, _tcs[i].dbg_ctrl);
- hri_tc_write_EVCTRL_reg(hw, _tcs[i].event_ctrl);
-
- if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT32) {
- hri_tccount32_write_CC_reg(hw, 0, _tcs[i].cc0);
- hri_tccount32_write_CC_reg(hw, 1, _tcs[i].cc1);
- } else if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT16) {
- hri_tccount16_write_CC_reg(hw, 0, (hri_tc_count16_reg_t)_tcs[i].cc0);
- hri_tccount16_write_CC_reg(hw, 1, (hri_tc_count16_reg_t)_tcs[i].cc1);
- } else {
- /* 8-bit resolution is not accepted by duty cycle control */
- return ERR_INVALID_DATA;
- }
-
- _tc_init_irq_param(hw, (void *)device);
- NVIC_DisableIRQ((IRQn_Type)((uint8_t)TC_IRQ_BASE_INDEX + tc_get_hardware_index(hw)));
- NVIC_ClearPendingIRQ((IRQn_Type)((uint8_t)TC_IRQ_BASE_INDEX + tc_get_hardware_index(hw)));
- NVIC_EnableIRQ((IRQn_Type)((uint8_t)TC_IRQ_BASE_INDEX + tc_get_hardware_index(hw)));
-
- return ERR_NONE;
-}
-/**
- * \brief De-initialize TC for PWM mode
- */
-void _pwm_deinit(struct _pwm_device *const device)
-{
- void *const hw = device->hw;
-
- NVIC_DisableIRQ((IRQn_Type)(TC_IRQ_BASE_INDEX + tc_get_hardware_index(hw)));
-
- hri_tc_clear_CTRLA_ENABLE_bit(hw);
- hri_tc_set_CTRLA_SWRST_bit(hw);
-}
-/**
- * \brief Start PWM
- */
-void _pwm_enable(struct _pwm_device *const device)
-{
- hri_tc_set_CTRLA_ENABLE_bit(device->hw);
-}
-/**
- * \brief Stop PWM
- */
-void _pwm_disable(struct _pwm_device *const device)
-{
- hri_tc_clear_CTRLA_ENABLE_bit(device->hw);
-}
-/**
- * \brief Set PWM parameter
- */
-void _pwm_set_param(struct _pwm_device *const device, const pwm_period_t period, const pwm_period_t duty_cycle)
-{
- int8_t i = get_tc_index(device->hw);
- void *const hw = device->hw;
- _tcs[i].cc0 = period;
- _tcs[i].cc1 = duty_cycle;
- if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT32) {
- hri_tccount32_write_CC_reg(hw, 0, _tcs[i].cc0);
- hri_tccount32_write_CC_reg(hw, 1, _tcs[i].cc1);
- } else {
- hri_tccount16_write_CC_reg(hw, 0, _tcs[i].cc0);
- hri_tccount16_write_CC_reg(hw, 1, _tcs[i].cc1);
- }
-}
-/**
- * \brief Get pwm waveform period value
- */
-pwm_period_t _pwm_get_period(const struct _pwm_device *const device)
-{
- void *const hw = device->hw;
- int8_t i = get_tc_index(hw);
-
- if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT32) {
- return (pwm_period_t)(hri_tccount32_read_CC_reg(hw, 0));
- } else {
- return (pwm_period_t)(hri_tccount16_read_CC_reg(hw, 0));
- }
-}
-/**
- * \brief Get pwm waveform duty cycle
- */
-uint32_t _pwm_get_duty(const struct _pwm_device *const device)
-{
- void *const hw = device->hw;
- int8_t i = get_tc_index(hw);
- uint32_t per;
- uint32_t duty_cycle;
-
- if ((_tcs[i].ctrl_a & TC_CTRLA_MODE_Msk) == TC_CTRLA_MODE_COUNT32) {
- per = hri_tccount32_read_CC_reg(hw, 0);
- duty_cycle = hri_tccount32_read_CC_reg(hw, 1);
- } else {
- per = hri_tccount16_read_CC_reg(hw, 0);
- duty_cycle = hri_tccount16_read_CC_reg(hw, 1);
- }
-
- return ((duty_cycle * 1000) / per);
-}
-/**
- * \brief Check if PWM is running
- */
-bool _pwm_is_enabled(const struct _pwm_device *const device)
-{
- return hri_tc_get_CTRLA_ENABLE_bit(device->hw);
-}
-/**
- * \brief Enable/disable PWM interrupt
- */
-void _pwm_set_irq_state(struct _pwm_device *const device, const enum _pwm_callback_type type, const bool disable)
-{
- ASSERT(device);
-
- if (PWM_DEVICE_PERIOD_CB == type) {
- hri_tc_write_INTEN_OVF_bit(device->hw, disable);
- } else if (PWM_DEVICE_ERROR_CB == type) {
- hri_tc_write_INTEN_ERR_bit(device->hw, disable);
- }
-}
-
-/**
- * \brief Retrieve timer helper functions
- */
-struct _timer_hpl_interface *_tc_get_timer(void)
-{
- return NULL;
-}
-
-/**
- * \brief Retrieve pwm helper functions
- */
-struct _pwm_hpl_interface *_tc_get_pwm(void)
-{
- return NULL;
-}
-/**
- * \internal TC interrupt handler for PWM
- *
- * \param[in] instance TC instance number
- */
-static void tc_pwm_interrupt_handler(struct _pwm_device *device)
-{
- void *const hw = device->hw;
-
- if (hri_tc_get_interrupt_OVF_bit(hw)) {
- hri_tc_clear_interrupt_OVF_bit(hw);
- if (NULL != device->callback.pwm_period_cb) {
- device->callback.pwm_period_cb(device);
- }
- }
- if (hri_tc_get_INTEN_ERR_bit(hw)) {
- hri_tc_clear_interrupt_ERR_bit(hw);
- if (NULL != device->callback.pwm_error_cb) {
- device->callback.pwm_error_cb(device);
- }
- }
-}
-
-/**
-* \brief TC interrupt handler
-*/
-void TC3_Handler(void)
-{
- tc_pwm_interrupt_handler(_tc3_dev);
-}
-
-/**
- * \internal Retrieve TC hardware index
- *
- * \param[in] hw The pointer to hardware instance
- */
-static uint8_t tc_get_hardware_index(const void *const hw)
-{
-#ifndef _UNIT_TEST_
- return ((uint32_t)hw - TC_HW_BASE_ADDR) >> 10;
-#else
- return ((uint32_t)hw - TC_HW_BASE_ADDR) / sizeof(Tc);
-#endif
-}
-
-/**
- * \internal Retrieve TC index
- *
- * \param[in] hw The pointer to hardware instance
- *
- * \return The index of TC configuration
- */
-static int8_t get_tc_index(const void *const hw)
-{
- uint8_t tc_offset = tc_get_hardware_index(hw) + TC_NUMBER_OFFSET;
- uint8_t i;
-
- for (i = 0; i < ARRAY_SIZE(_tcs); i++) {
- if (_tcs[i].number == tc_offset) {
- return i;
- }
- }
-
- ASSERT(false);
- return -1;
-}
-
-/**
- * \brief Init irq param with the given tc hardware instance
- */
-static void _tc_init_irq_param(const void *const hw, void *dev)
-{
- if (hw == TC3) {
- _tc3_dev = (struct _pwm_device *)dev;
- }
-}
-
-static inline uint8_t _get_hardware_offset(const void *const hw)
-{
- return (((uint32_t)hw - TC_HW_BASE_ADDR) >> 10) + TC_NUMBER_OFFSET;
-}
diff --git a/atmel-samd/asf4/samd21/hpl/tc/hpl_tc_base.h b/atmel-samd/asf4/samd21/hpl/tc/hpl_tc_base.h
deleted file mode 100644
index 9d7f2c72a..000000000
--- a/atmel-samd/asf4/samd21/hpl/tc/hpl_tc_base.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/**
- * \file
- *
- * \brief SAM Timer/Counter
- *
- * 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 distributionn.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- */
-
-#ifndef _HPL_TC_BASE_H_INCLUDED
-#define _HPL_TC_BASE_H_INCLUDED
-
-#include <hpl_timer.h>
-#include <hpl_pwm.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * \addtogroup tc_group TC Hardware Proxy Layer
- *
- * \section tc_hpl_rev Revision History
- * - v0.0.0.1 Initial Commit
- *
- *@{
- */
-
-/**
- * \name HPL functions
- */
-//@{
-
-/**
- * \brief Retrieve timer helper functions
- *
- * \return A pointer to set of timer helper functions
- */
-struct _timer_hpl_interface *_tc_get_timer(void);
-
-/**
- * \brief Retrieve pwm helper functions
- *
- * \return A pointer to set of pwm helper functions
- */
-struct _pwm_hpl_interface *_tc_get_pwm(void);
-
-//@}
-/**@}*/
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* _HPL_TC_BASE_H_INCLUDED */
diff --git a/atmel-samd/asf4/samd21/hpl/usb/hpl_usb.c b/atmel-samd/asf4/samd21/hpl/usb/hpl_usb.c
deleted file mode 100644
index d134967d3..000000000
--- a/atmel-samd/asf4/samd21/hpl/usb/hpl_usb.c
+++ /dev/null
@@ -1,2051 +0,0 @@
-/**
- * \file
- *
- * \brief SAM USB HPL
- *
- * Copyright (C) 2015-2017 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#include <compiler.h>
-#include <hal_atomic.h>
-#include <hpl_usb.h>
-#include <hpl_usb_device.h>
-
-#include <hpl_usb_config.h>
-#include <string.h>
-#include <utils_assert.h>
-
-/**
- * \brief Dummy callback function
- * \return Always false.
- */
-static bool _dummy_func_no_return(uint32_t unused0, uint32_t unused1)
-{
- (void)unused0;
- (void)unused1;
- return false;
-}
-
-/**
- * \brief Load USB calibration value from NVM
- */
-static void _usb_load_calib(void)
-{
-#define NVM_USB_PAD_TRANSN_POS 45
-#define NVM_USB_PAD_TRANSN_SIZE 5
-#define NVM_USB_PAD_TRANSP_POS 50
-#define NVM_USB_PAD_TRANSP_SIZE 5
-#define NVM_USB_PAD_TRIM_POS 55
-#define NVM_USB_PAD_TRIM_SIZE 3
- Usb * hw = USB;
- uint32_t pad_transn
- = (*((uint32_t *)(NVMCTRL_OTP4) + (NVM_USB_PAD_TRANSN_POS / 32)) >> (NVM_USB_PAD_TRANSN_POS % 32))
- & ((1 << NVM_USB_PAD_TRANSN_SIZE) - 1);
- uint32_t pad_transp
- = (*((uint32_t *)(NVMCTRL_OTP4) + (NVM_USB_PAD_TRANSP_POS / 32)) >> (NVM_USB_PAD_TRANSP_POS % 32))
- & ((1 << NVM_USB_PAD_TRANSP_SIZE) - 1);
- uint32_t pad_trim = (*((uint32_t *)(NVMCTRL_OTP4) + (NVM_USB_PAD_TRIM_POS / 32)) >> (NVM_USB_PAD_TRIM_POS % 32))
- & ((1 << NVM_USB_PAD_TRIM_SIZE) - 1);
- if (pad_transn == 0x1F) {
- pad_transn = 5;
- }
- if (pad_transp == 0x1F) {
- pad_transp = 29;
- }
- if (pad_trim == 0x7) {
- pad_trim = 5;
- }
-
- hw->DEVICE.PADCAL.reg = USB_PADCAL_TRANSN(pad_transn) | USB_PADCAL_TRANSP(pad_transp) | USB_PADCAL_TRIM(pad_trim);
-
- hw->DEVICE.QOSCTRL.bit.CQOS = 3;
- hw->DEVICE.QOSCTRL.bit.DQOS = 3;
-}
-
-/** \name USB clock source management */
-/*@{*/
-
-/** USB clock is generated by DFLL. */
-#define USB_CLK_SRC_DFLL 0
-
-/** USB clock is generated by DPLL. */
-#define USB_CLK_SRC_DPLL 1
-
-/** Uses DFLL as USB clock source. */
-#define CONF_USB_D_CLK_SRC USB_CLK_SRC_DFLL
-
-/** Retry for USB remote wakeup sending. */
-#define CONF_USB_RMT_WKUP_RETRY 5
-
-/**
- * \brief Wait DPLL clock to be ready
- */
-static inline void _usb_d_dev_wait_dpll_rdy(void)
-{
-#define DPLL_READY_FLAG (SYSCTRL_DPLLSTATUS_ENABLE | SYSCTRL_DPLLSTATUS_CLKRDY | SYSCTRL_DPLLSTATUS_LOCK)
- while (hri_sysctrl_get_DPLLSTATUS_reg(SYSCTRL, DPLL_READY_FLAG) != DPLL_READY_FLAG)
- ;
-}
-
-/**
- * \brief Wait DFLL clock to be ready
- */
-static inline void _usb_d_dev_wait_dfll_rdy(void)
-{
-#define DFLL_READY_FLAG (SYSCTRL_PCLKSR_DFLLRDY | SYSCTRL_PCLKSR_DFLLLCKF | SYSCTRL_PCLKSR_DFLLLCKC)
- /* In USB recovery mode the status is not checked */
- if (!(SYSCTRL->DFLLCTRL.reg & SYSCTRL_DFLLCTRL_USBCRM)) {
- while (hri_sysctrl_get_PCLKSR_reg(SYSCTRL, DFLL_READY_FLAG) != DFLL_READY_FLAG)
- ;
- } else {
- while (hri_sysctrl_get_PCLKSR_reg(SYSCTRL, SYSCTRL_PCLKSR_DFLLRDY) != SYSCTRL_PCLKSR_DFLLRDY)
- ;
- }
-}
-
-/**
- * \brief Wait USB source clock to be ready
- * \param[in] clk_src Clock source, could be \ref USB_CLK_SRC_DFLL or
- * \ref USB_CLK_SRC_DPLL.
- */
-static inline void _usb_d_dev_wait_clk_rdy(const uint8_t clk_src)
-{
- if (clk_src == USB_CLK_SRC_DFLL) {
- _usb_d_dev_wait_dfll_rdy();
- } else if (clk_src == USB_CLK_SRC_DPLL) {
- _usb_d_dev_wait_dpll_rdy();
- }
-}
-
-/*@}*/
-
-/** \name USB general settings */
-/*@{*/
-
-/** Increase the value to be aligned. */
-#define _usb_align_up(val) (((val)&0x3) ? (((val) + 4 - ((val)&0x3))) : (val))
-
-/** Check if the buffer is in RAM (can DMA), or cache needed
- * \param[in] a Buffer start address.
- * \param[in] s Buffer size, in number of bytes.
- * \return \c true If the buffer is in RAM.
- */
-#define _IN_RAM(a, s) ((0x20000000 <= (uint32_t)(a)) && (((uint32_t)(a) + (s)) < 0x20008000))
-
-/** Check if the address should be placed in RAM. */
-#define _usb_is_addr4dma(addr, size) _IN_RAM((addr), (size))
-
-/** Check if the address is 32-bit aligned. */
-#define _usb_is_aligned(val) (((uint32_t)(val)&0x3) == 0)
-/*@}*/
-
-/* Cache static configurations.
- * By default, all OUT endpoint have 64 bytes cache. */
-#ifndef CONF_USB_EP0_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP0_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP0_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP0_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP1_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP1_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP1_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP1_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP2_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP2_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP2_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP2_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP3_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP3_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP3_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP3_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP4_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP4_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP4_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP4_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP5_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP5_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP5_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP5_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP6_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP6_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP6_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP6_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP7_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP7_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP7_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP7_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP8_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP8_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP8_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP8_I_CACHE 0
-#endif
-
-#ifndef CONF_USB_EP9_CACHE
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#define CONF_USB_EP9_CACHE 64
-#endif
-
-#ifndef CONF_USB_EP9_I_CACHE
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define CONF_USB_EP9_I_CACHE 0
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP0_CACHE
-static uint32_t _usb_ep0_cache[_usb_align_up(CONF_USB_EP0_CACHE) / 4];
-#else
-#define _usb_ep0_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#define _usb_ep0_i_cache NULL
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP1_CACHE && CONF_USB_D_MAX_EP_N >= 1
-uint32_t _usb_ep1_cache[_usb_align_up(CONF_USB_EP1_CACHE) / 4];
-#else
-#define _usb_ep1_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP1_I_CACHE && CONF_USB_D_MAX_EP_N >= 1
-static uint32_t _usb_ep1_i_cache[_usb_align_up(CONF_USB_EP1_I_CACHE) / 4];
-#else
-#define _usb_ep1_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP2_CACHE && CONF_USB_D_MAX_EP_N >= 2
-static uint32_t _usb_ep2_cache[_usb_align_up(CONF_USB_EP2_CACHE) / 4];
-#else
-#define _usb_ep2_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP2_I_CACHE && CONF_USB_D_MAX_EP_N >= 2
-static uint32_t _usb_ep2_i_cache[_usb_align_up(CONF_USB_EP2_I_CACHE) / 4];
-#else
-#define _usb_ep2_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP3_CACHE && CONF_USB_D_MAX_EP_N >= 3
-static uint32_t _usb_ep3_cache[_usb_align_up(CONF_USB_EP3_CACHE) / 4];
-#else
-#define _usb_ep3_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP3_I_CACHE && CONF_USB_D_MAX_EP_N >= 3
-static uint32_t _usb_ep3_i_cache[_usb_align_up(CONF_USB_EP3_I_CACHE) / 4];
-#else
-#define _usb_ep3_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP4_CACHE && CONF_USB_D_MAX_EP_N >= 4
-static uint32_t _usb_ep4_cache[_usb_align_up(CONF_USB_EP4_CACHE) / 4];
-#else
-#define _usb_ep4_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP4_I_CACHE && CONF_USB_D_MAX_EP_N >= 4
-static uint32_t _usb_ep4_i_cache[_usb_align_up(CONF_USB_EP4_I_CACHE) / 4];
-#else
-#define _usb_ep4_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP5_CACHE && CONF_USB_D_MAX_EP_N >= 5
-static uint32_t _usb_ep5_cache[_usb_align_up(CONF_USB_EP5_CACHE) / 4];
-#else
-#define _usb_ep5_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP5_I_CACHE && CONF_USB_D_MAX_EP_N >= 5
-static uint32_t _usb_ep5_i_cache[_usb_align_up(CONF_USB_EP5_I_CACHE) / 4];
-#else
-#define _usb_ep5_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP6_CACHE && CONF_USB_D_MAX_EP_N >= 6
-static uint32_t _usb_ep6_cache[_usb_align_up(CONF_USB_EP6_CACHE) / 4];
-#else
-#define _usb_ep6_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP6_I_CACHE && CONF_USB_D_MAX_EP_N >= 6
-static uint32_t _usb_ep6_i_cache[_usb_align_up(CONF_USB_EP6_I_CACHE) / 4];
-#else
-#define _usb_ep6_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP7_CACHE && CONF_USB_D_MAX_EP_N >= 7
-static uint32_t _usb_ep7_cache[_usb_align_up(CONF_USB_EP7_CACHE) / 4];
-#else
-#define _usb_ep7_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP7_I_CACHE && CONF_USB_D_MAX_EP_N >= 7
-static uint32_t _usb_ep7_i_cache[_usb_align_up(CONF_USB_EP7_I_CACHE) / 4];
-#else
-#define _usb_ep7_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP8_CACHE && CONF_USB_D_MAX_EP_N >= 8
-static uint32_t _usb_ep8_cache[_usb_align_up(CONF_USB_EP8_CACHE) / 4];
-#else
-#define _usb_ep8_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP8_I_CACHE && CONF_USB_D_MAX_EP_N >= 8
-static uint32_t _usb_ep8_i_cache[_usb_align_up(CONF_USB_EP8_I_CACHE) / 4];
-#else
-#define _usb_ep8_i_cache NULL
-#endif
-
-/** Endpoint cache buffer for OUT transactions (none-control) or SETUP/IN/OUT
- * transactions (control). */
-#if CONF_USB_EP9_CACHE && CONF_USB_D_MAX_EP_N >= 9
-static uint32_t _usb_ep9_cache[_usb_align_up(CONF_USB_EP9_CACHE) / 4];
-#else
-#define _usb_ep9_cache NULL
-#endif
-
-/** Endpoint cache buffer for IN transactions (none-control). */
-#if CONF_USB_EP9_I_CACHE && CONF_USB_D_MAX_EP_N >= 9
-static uint32_t _usb_ep9_i_cache[_usb_align_up(CONF_USB_EP9_I_CACHE) / 4];
-#else
-#define _usb_ep9_i_cache NULL
-#endif
-
-/** Access endpoint cache buffer for OUT transactions (none-control) or
- * SETUP/IN/OUT transactions (control). */
-#define _USB_EP_CACHE(n) ((void *)_usb_ep##n##_cache)
-
-/** Access endpoint cache buffer for IN transactions (none-control). */
-#define _USB_EP_I_CACHE(n) ((void *)_usb_ep##n##_i_cache)
-
-/** The configuration settings for one of the endpoint hardware. */
-struct _usb_ep_cfg_item {
- /* Endpoint cache buffer for OUT transactions (none-control) or
- * SETUP/IN/OUT transactions (control). */
- void *cache;
- /* endpoint cache buffer for IN transactions (none-control). */
- void *i_cache;
- /* Cache buffer size for OUT transactions (none-control) or
- * SETUP/IN/OUT transactions (control). */
- uint16_t size;
- /* Cache buffer size for IN transactions (none-control). */
- uint16_t i_size;
-};
-
-/** Build the endpoint configuration settings for one endpoint. */
-#define _USB_EP_CFG_ITEM(n) \
- { \
- _USB_EP_CACHE(n), _USB_EP_I_CACHE(n), CONF_USB_EP##n##_CACHE, CONF_USB_EP##n##_I_CACHE, \
- }
-
-/** The configuration settings for all endpoint. */
-static const struct _usb_ep_cfg_item _usb_ep_cfgs[] = {_USB_EP_CFG_ITEM(0)
-#if CONF_USB_D_MAX_EP_N >= 1
- ,
- _USB_EP_CFG_ITEM(1)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 2
- ,
- _USB_EP_CFG_ITEM(2)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 3
- ,
- _USB_EP_CFG_ITEM(3)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 4
- ,
- _USB_EP_CFG_ITEM(4)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 5
- ,
- _USB_EP_CFG_ITEM(5)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 6
- ,
- _USB_EP_CFG_ITEM(6)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 7
- ,
- _USB_EP_CFG_ITEM(7)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 8
- ,
- _USB_EP_CFG_ITEM(8)
-#endif
-#if CONF_USB_D_MAX_EP_N >= 9
- ,
- _USB_EP_CFG_ITEM(9)
-#endif
-};
-
-/** \name HW specific settings and implements */
-/*@{*/
-
-/** Number of endpoints supported. */
-#define USB_D_N_EP (1 + CONF_USB_D_NUM_EP_SP * 2)
-
-/** HPL USB device endpoint struct. */
-struct _usb_d_dev_ep {
- /** Pointer to transaction buffer. */
- uint8_t *trans_buf;
- /** Transaction size. */
- uint32_t trans_size;
- /** Transaction transferred count. */
- uint32_t trans_count;
-
- /** Pointer to cache buffer, must be aligned. */
- uint8_t *cache;
-
- /** Endpoint size. */
- uint16_t size;
- /** Endpoint address. */
- uint8_t ep;
- /** Feature flags. */
- union {
- /** Interpreted by bit fields. */
- struct {
- /** EPCFG.ETYPE. */
- uint8_t eptype : 3;
- /** Stall status. */
- uint8_t is_stalled : 1;
- /** Transaction auto ZLP. */
- uint8_t need_zlp : 1;
- /** Transaction with cache */
- uint8_t use_cache : 1;
- /** Endpoint is busy. */
- uint8_t is_busy : 1;
- /** Transaction direction. */
- uint8_t dir : 1;
- } bits;
- uint8_t u8;
- } flags;
-};
-
-/** Check if the endpoint is used. */
-#define _usb_d_dev_ep_is_used(ept) ((ept)->ep != 0xFF)
-
-/** Check if the endpoint is busy doing transactions. */
-#define _usb_d_dev_ep_is_busy(ept) ((ept)->flags.bits.is_busy)
-
-/** Check if the endpoint is control endpoint. */
-#define _usb_d_dev_ep_is_ctrl(ept) ((ept)->flags.bits.eptype == USB_D_EPTYPE_CTRL)
-
-/** Check if the endpoint transactions are IN. */
-#define _usb_d_dev_ep_is_in(ept) ((ept)->flags.bits.dir)
-
-/** Interrupt flags for SETUP transaction. */
-#define USB_D_SETUP_INT_FLAGS (USB_DEVICE_EPINTFLAG_RXSTP)
-
-/** Interrupt flags for BANK1 transactions. */
-#define USB_D_BANK1_INT_FLAGS (USB_DEVICE_EPINTFLAG_TRCPT1 | USB_DEVICE_EPINTFLAG_TRFAIL1 | USB_DEVICE_EPINTFLAG_STALL1)
-
-/** Interrupt flags for BANK0 transactions. */
-#define USB_D_BANK0_INT_FLAGS (USB_DEVICE_EPINTFLAG_TRCPT0 | USB_DEVICE_EPINTFLAG_TRFAIL0 | USB_DEVICE_EPINTFLAG_STALL0)
-
-/** Interrupt flags for SETUP/IN/OUT transactions. */
-#define USB_D_ALL_INT_FLAGS (0x7F)
-
-/** Interrupt flags for WAKEUP event. */
-#define USB_D_WAKEUP_INT_FLAGS (USB_DEVICE_INTFLAG_UPRSM | USB_DEVICE_INTFLAG_EORSM | USB_DEVICE_INTFLAG_WAKEUP)
-
-/** Interrupt flags for SUSPEND event. */
-#define USB_D_SUSPEND_INT_FLAGS (USB_DEVICE_INTFLAG_LPMSUSP | USB_DEVICE_INTFLAG_SUSPEND)
-
-/** Max data bytes for a single DMA transfer. */
-#define USB_D_DEV_TRANS_MAX 8192 /* 14-bits, uses 13-bits. */
-
-/** Endpoint type setting to disable. */
-#define USB_D_EPTYPE_DISABLE 0
-
-/** Endpoint type setting to work as control endpoint. */
-#define USB_D_EPTYPE_CTRL 1
-
-/** Endpoint type setting to work as isochronous endpoint. */
-#define USB_D_EPTYPE_ISOCH 2
-
-/** Endpoint type setting to work as interrupt endpoint. */
-#define USB_D_EPTYPE_INT 3
-
-/** Endpoint type setting to work as bulk endpoint. */
-#define USB_D_EPTYPE_BULK 4
-
-/** Endpoint type setting for dual bank endpoint. */
-#define USB_D_EPTYPE_DUAL 5
-
-/** EPCFG register value for control endpoints. */
-#define USB_D_EPCFG_CTRL 0x11
-
-/** HPL USB device struct. */
-struct _usb_d_dev {
- /** Callbacks of USB device. */
- struct _usb_d_dev_callbacks callbacks;
- /** Endpoint transaction callbacks. */
- struct _usb_d_dev_ep_callbacks ep_callbacks;
- /** Endpoints (ep0 + others). */
- struct _usb_d_dev_ep ep[USB_D_N_EP];
-};
-
-/** Private data for SAM0 USB peripheral.
- */
-typedef struct _usb_d_dev_prvt {
- /** USB device descriptor table for peripheral to work. */
- UsbDeviceDescriptor desc_table[CONF_USB_D_MAX_EP_N + 1];
-} usb_d_dev_prvt_t;
-
-/*@}*/
-
-/** USB device driver instance. */
-static struct _usb_d_dev dev_inst;
-
-/** USB device driver private data instance. */
-static struct _usb_d_dev_prvt prvt_inst;
-
-static void _usb_d_dev_reset_epts(void);
-
-static void _usb_d_dev_trans_done(struct _usb_d_dev_ep *ept, const int32_t status);
-static void _usb_d_dev_trans_stop(struct _usb_d_dev_ep *ept, bool dir, const int32_t code);
-
-static void _usb_d_dev_in_next(struct _usb_d_dev_ep *ept, bool isr);
-static void _usb_d_dev_out_next(struct _usb_d_dev_ep *ept, bool isr);
-
-static inline void _usb_d_dev_trans_setup(struct _usb_d_dev_ep *ept);
-
-/** \brief ACK the endpoint interrupt
- * \param[in] epn Endpoint number.
- * \param[in] flags Interrupt flags.
- */
-static inline void _usbd_ep_int_ack(uint8_t epn, uint32_t flags)
-{
- hri_usbendpoint_clear_EPINTFLAG_reg(USB, epn, flags);
-}
-
-/** \brief Enable the endpoint interrupt
- * \param[in] epn Endpoint number.
- * \param[in] flags Interrupt flags.
- */
-static inline void _usbd_ep_int_en(uint8_t epn, uint32_t flags)
-{
- hri_usbendpoint_set_EPINTEN_reg(USB, epn, flags);
-}
-
-/** \brief Disable the endpoint interrupt
- * \param[in] epn Endpoint number.
- * \param[in] flags Interrupt flags.
- */
-static inline void _usbd_ep_int_dis(uint8_t epn, uint32_t flags)
-{
- hri_usbendpoint_clear_EPINTEN_reg(USB, epn, flags);
-}
-
-/** \brief Check if endpoint is control endpoint
- * \param[in] epn Endpoint number.
- */
-static inline bool _usbd_ep_is_ctrl(uint8_t epn)
-{
- return (hri_usbendpoint_read_EPCFG_reg(USB, epn) == USB_D_EPCFG_CTRL);
-}
-
-/** \brief Set endpoint stall
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] st Stall status.
- */
-static inline void _usbd_ep_set_stall(uint8_t epn, uint8_t bank_n, bool st)
-{
- if (st) {
- hri_usbendpoint_set_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_STALLRQ0 << bank_n));
- } else {
- hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_STALLRQ0 << bank_n));
- }
-}
-
-/** \brief Check if the endpoint is stalled
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \return \c true if it's stalled.
- */
-static inline bool _usbd_ep_is_stalled(uint8_t epn, uint8_t bank_n)
-{
- Usb *hw = USB;
- return (hri_usbendpoint_read_EPSTATUS_reg(hw, epn) & (USB_DEVICE_EPSTATUS_STALLRQ0 << bank_n));
-}
-
-/** \brief Check if stall has been sent from the endpoint
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \return \c true if it's sent.
- */
-static inline bool _usbd_ep_is_stall_sent(uint8_t epn, uint8_t bank_n)
-{
- Usb *hw = USB;
- return (hri_usbendpoint_read_EPINTFLAG_reg(hw, epn) & (USB_DEVICE_EPINTFLAG_STALL0 << bank_n));
-}
-
-/** \brief ACK endpoint STALL interrupt
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- */
-static inline void _usbd_ep_ack_stall(uint8_t epn, uint8_t bank_n)
-{
- _usbd_ep_int_ack(epn, (USB_DEVICE_EPINTFLAG_STALL0 << bank_n));
-}
-
-/** \brief Enable/disable endpoint STALL interrupt
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] en \c true to enable, \c false to disable.
- */
-static inline void _usbd_ep_int_stall_en(uint8_t epn, uint8_t bank_n, const bool en)
-{
- if (en) {
- _usbd_ep_int_en(epn, USB_DEVICE_EPINTFLAG_STALL0 << bank_n);
- } else {
- _usbd_ep_int_dis(epn, USB_DEVICE_EPINTFLAG_STALL0 << bank_n);
- }
-}
-
-/** \brief Stop SETUP transactions
- * \param[in] epn Endpoint number.
- */
-static inline void _usbd_ep_stop_setup(uint8_t epn)
-{
- hri_usbendpoint_clear_EPINTEN_RXSTP_bit(USB, epn);
-}
-
-/** \brief Check if SETUP packet is ready in cache
- * \param[in] epn Endpoint number.
- */
-static inline bool _usbd_ep_is_setup(uint8_t epn)
-{
- return hri_usbendpoint_get_EPINTFLAG_reg(USB, epn, USB_DEVICE_EPINTFLAG_RXSTP);
-}
-
-/** \brief ACK endpoint SETUP interrupt
- * \param[in] epn Endpoint number.
- */
-static inline void _usbd_ep_ack_setup(uint8_t epn)
-{
- _usbd_ep_int_ack(epn, USB_DEVICE_EPINTFLAG_RXSTP);
-}
-
-/** \brief Set endpoint toggle value
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] tgl Toggle value.
- */
-static inline void _usbd_ep_set_toggle(uint8_t epn, uint8_t bank_n, uint8_t tgl)
-{
- if (tgl) {
- hri_usbendpoint_set_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_DTGLOUT << bank_n));
- } else {
- hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, (USB_DEVICE_EPSTATUS_DTGLOUT << bank_n));
- }
-}
-
-/** \brief ACK IN/OUT complete interrupt
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- */
-static inline void _usbd_ep_ack_io_cpt(uint8_t epn, uint8_t bank_n)
-{
- _usbd_ep_int_ack(epn, USB_DEVICE_EPINTFLAG_TRCPT0 << bank_n);
-}
-
-/** \brief Set DMA buffer used for bank data
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] addr DMA buffer address to set.
- */
-static inline void _usbd_ep_set_buf(uint8_t epn, uint8_t bank_n, uint32_t addr)
-{
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
- bank->ADDR.reg = addr;
-}
-
-/** \brief Set bank count for IN transactions
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] count Data count for IN.
- */
-static inline void _usbd_ep_set_in_count(uint8_t epn, uint8_t bank_n, uint16_t count)
-{
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
- bank->PCKSIZE.bit.MULTI_PACKET_SIZE = count;
-}
-
-/** \brief Set bank size for IN transactions
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] size Data size for IN.
- */
-static inline void _usbd_ep_set_in_size(uint8_t epn, uint8_t bank_n, uint16_t size)
-{
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
- bank->PCKSIZE.bit.BYTE_COUNT = size;
-}
-
-/** \brief Set bank count for OUT transaction
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] count Data count for OUT.
- */
-static inline void _usbd_ep_set_out_count(uint8_t epn, uint8_t bank_n, uint16_t count)
-{
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
- bank->PCKSIZE.bit.BYTE_COUNT = count;
-}
-
-/** \brief Set bank size for OUT transactions
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] size Data size for OUT.
- */
-static inline void _usbd_ep_set_out_size(uint8_t epn, uint8_t bank_n, uint16_t size)
-{
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
- bank->PCKSIZE.bit.MULTI_PACKET_SIZE = size;
-}
-
-/** Set bank size and count for IN transactions
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] size Data size.
- * \param[in] count Initial data count.
- */
-static inline void _usbd_ep_set_in_trans(uint8_t epn, uint8_t bank_n, uint32_t size, uint32_t count)
-{
- _usbd_ep_set_in_size(epn, bank_n, size);
- _usbd_ep_set_in_count(epn, bank_n, count);
-}
-
-/** \brief Set bank size and count for OUT transaction
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] size Data size.
- * \param[in] count Initial data count.
- */
-static inline void _usbd_ep_set_out_trans(uint8_t epn, uint8_t bank_n, uint32_t size, uint32_t count)
-{
- _usbd_ep_set_out_size(epn, bank_n, size);
- _usbd_ep_set_out_count(epn, bank_n, count);
-}
-
-/** \brief Clear bank status
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- */
-static inline void _usbd_ep_clear_bank_status(uint8_t epn, uint8_t bank_n)
-{
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[bank_n];
- bank->STATUS_BK.reg = 0;
-}
-
-/** Set IN ready for IN transactions
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] rdy Set to \c true to indicate IN packet ready to TX.
- */
-static inline void _usbd_ep_set_in_rdy(uint8_t epn, uint8_t bank_n, const bool rdy)
-{
- if (rdy) {
- hri_usbendpoint_set_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
- } else {
- hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
- }
-}
-
-/** \brief Set bank ready for OUT transactions
- * \param[in] epn Endpoint number.
- * \param[in] bank_n Endpoint bank number.
- * \param[in] rdy Set to \c true to indicate OUT bank ready to RX.
- */
-static inline void _usbd_ep_set_out_rdy(uint8_t epn, uint8_t bank_n, const bool rdy)
-{
- if (rdy) {
- hri_usbendpoint_clear_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
- } else {
- hri_usbendpoint_set_EPSTATUS_reg(USB, epn, USB_DEVICE_EPSTATUS_BK0RDY << bank_n);
- }
-}
-
-/**
- * \brief Convert USB endpoint size to HW PCKSIZE.SIZE
- * \param[in] n Number of bytes of endpoint size.
- */
-static inline uint8_t _usbd_ep_pcksize_size(uint16_t n)
-{
- return (
- (n > 512)
- ? 7
- : ((n > 256) ? 6 : ((n > 128) ? 5 : ((n > 64) ? 4 : ((n > 32) ? 3 : ((n > 16) ? 2 : ((n > 8) ? 1 : 0)))))));
-}
-
-/**
- * \brief Obtain endpoint descriptor pointer
- * \param[in] epn Endpoint number.
- * \param[in] dir Endpoint direction.
- */
-static inline struct _usb_d_dev_ep *_usb_d_dev_ept(uint8_t epn, bool dir)
-{
- uint8_t ep_index = (epn == 0) ? 0 : (dir ? (epn + CONF_USB_D_MAX_EP_N) : epn);
- return &dev_inst.ep[ep_index];
-}
-
-/**
- * \brief Handles USB SOF interrupt
- */
-static inline void _usb_d_dev_sof(void)
-{
- /* ACK SOF interrupt. */
- hri_usbdevice_clear_INTFLAG_reg(USB, USB_DEVICE_INTFLAG_SOF);
- dev_inst.callbacks.sof();
-}
-
-/**
- * \brief Handles USB LPM Suspend interrupt
- */
-static inline void _usb_d_dev_lpmsusp(void)
-{
- uint8_t i;
- uint32_t lpm_variable = 0;
-
- /* ACK LPMSUSP interrupt. */
- hri_usbdevice_clear_INTFLAG_reg(USB, USB_D_SUSPEND_INT_FLAGS);
- /* Change interrupt masks */
- hri_usbdevice_clear_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
- hri_usbdevice_set_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
-
- /* Find LPM data */
- for (i = 0; i < CONF_USB_D_MAX_EP_N; i++) {
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[i].DeviceDescBank[0];
- if (bank->EXTREG.bit.SUBPID == 0x3) {
- /* Save LPM variable */
- lpm_variable = bank->EXTREG.bit.VARIABLE;
- /* Clear */
- bank->EXTREG.reg = 0;
- break;
- }
- }
- dev_inst.callbacks.event(USB_EV_LPM_SUSPEND, lpm_variable);
-}
-
-/**
- * \brief Handles USB RAM Error interrupt
- */
-static inline void _usb_d_dev_ramerr(void)
-{
- hri_usbdevice_clear_INTFLAG_reg(USB, USB_DEVICE_INTFLAG_RAMACER);
- dev_inst.callbacks.event(USB_EV_ERROR, 0);
-}
-
-/**
- * \brief Handles USB resume/wakeup interrupts
- */
-static inline void _usb_d_dev_wakeup(void)
-{
- hri_usbdevice_clear_INTFLAG_reg(USB, USB_D_WAKEUP_INT_FLAGS);
- hri_usbdevice_clear_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
- hri_usbdevice_set_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
-
- _usb_d_dev_wait_clk_rdy(CONF_USB_D_CLK_SRC);
- dev_inst.callbacks.event(USB_EV_WAKEUP, 0);
-}
-
-/**
- * \brief Handles USB signal reset interrupt
- */
-static inline void _usb_d_dev_reset(void)
-{
- /* EP0 will not be reseted by USB RESET, disable manually. */
- hri_usbendpoint_write_EPCFG_reg(USB, 0, 0);
-
- hri_usbdevice_clear_INTFLAG_reg(USB, USB_DEVICE_INTFLAG_EORST);
- hri_usbdevice_clear_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
- hri_usbdevice_set_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
-
- _usb_d_dev_reset_epts();
- dev_inst.callbacks.event(USB_EV_RESET, 0);
-}
-
-static inline void _usb_d_dev_suspend(void)
-{
- hri_usbdevice_clear_INTFLAG_reg(USB, USB_D_SUSPEND_INT_FLAGS);
- hri_usbdevice_clear_INTEN_reg(USB, USB_D_SUSPEND_INT_FLAGS);
- hri_usbdevice_set_INTEN_reg(USB, USB_D_WAKEUP_INT_FLAGS);
-
- dev_inst.callbacks.event(USB_EV_SUSPEND, 0);
-}
-
-/**
- * \brief Handles USB non-endpoint interrupt
- */
-static inline bool _usb_d_dev_handle_nep(void)
-{
- bool rc = true;
- uint16_t flags = hri_usbdevice_read_INTFLAG_reg(USB);
- flags &= hri_usbdevice_read_INTEN_reg(USB);
-
- if (flags & USB_DEVICE_INTFLAG_SOF) {
- _usb_d_dev_sof();
- return true;
- }
- if (flags & USB_DEVICE_INTFLAG_LPMSUSP) {
- _usb_d_dev_lpmsusp();
- } else if (flags & USB_DEVICE_INTFLAG_RAMACER) {
- _usb_d_dev_ramerr();
- } else if (flags & USB_D_WAKEUP_INT_FLAGS) {
- _usb_d_dev_wakeup();
- } else if (flags & USB_DEVICE_INTFLAG_EORST) {
- _usb_d_dev_reset();
- } else if (flags & USB_DEVICE_INTFLAG_SUSPEND) {
- _usb_d_dev_suspend();
- } else {
- rc = false;
- }
- return rc;
-}
-
-/**
- * \brief Prepare next IN transactions
- * \param[in] ept Pointer to endpoint information.
- * \param[in] isr Invoked from ISR.
- */
-static void _usb_d_dev_in_next(struct _usb_d_dev_ep *ept, bool isr)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ept->ep);
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[0];
- uint16_t trans_count = isr ? bank[1].PCKSIZE.bit.BYTE_COUNT : 0;
- uint16_t trans_next;
- uint16_t last_pkt = trans_count & ((ept->size == 1023) ? ept->size : (ept->size - 1));
- uint8_t inten = 0;
- bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
-
- if (isr) {
- _usbd_ep_ack_io_cpt(epn, 1);
- }
-
- ept->trans_count += trans_count;
- /* Send more data. */
- if (ept->trans_count < ept->trans_size) {
- trans_next = ept->trans_size - ept->trans_count;
- if (ept->flags.bits.use_cache) {
- if (trans_next > ept->size) {
- trans_next = ept->size;
- }
- memcpy(ept->cache, &ept->trans_buf[ept->trans_count], trans_next);
- _usbd_ep_set_buf(epn, 1, (uint32_t)ept->cache);
- } else {
- if (trans_next > USB_D_DEV_TRANS_MAX) {
- trans_next = USB_D_DEV_TRANS_MAX;
- }
- _usbd_ep_set_buf(epn, 1, (uint32_t)&ept->trans_buf[ept->trans_count]);
- }
- _usbd_ep_set_in_trans(epn, 1, trans_next, 0);
- goto _in_tx_exec;
- } else if (ept->flags.bits.need_zlp) {
- ept->flags.bits.need_zlp = 0;
- _usbd_ep_set_in_trans(epn, 1, 0, 0);
- goto _in_tx_exec;
- }
- /* Complete. */
- if (is_ctrl) {
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK1_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRCPT0);
- } else {
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK1_INT_FLAGS);
- }
-
- /* No ping-pong, so ask more data without background transfer. */
- if (last_pkt == ept->size) {
- ept->flags.bits.is_busy = 0;
- if (dev_inst.ep_callbacks.more(ept->ep, ept->trans_count)) {
- /* More data added. */
- return;
- }
- ept->flags.bits.is_busy = 1;
- }
- /* Finish normally. */
- _usb_d_dev_trans_done(ept, USB_TRANS_DONE);
- return;
-
-_in_tx_exec:
- if (!isr) {
- if (is_ctrl) {
- /* Control endpoint: SETUP or OUT will abort IN transaction.
- * SETUP: terminate the IN without any notification. Trigger
- * SETUP callback.
- * OUT NAK: terminate IN.
- */
- inten = USB_D_BANK1_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL0;
- } else {
- /* Initialize normal IN transaction. */
- inten = USB_D_BANK1_INT_FLAGS;
- }
- hri_usbendpoint_set_EPINTEN_reg(hw, epn, inten);
- }
- _usbd_ep_set_in_rdy(epn, 1, true);
-}
-
-/**
- * \brief Prepare next OUT transactions
- * \param[in] ept Pointer to endpoint information.
- * \param[in] isr Invoked from ISR.
- */
-static void _usb_d_dev_out_next(struct _usb_d_dev_ep *ept, bool isr)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ept->ep);
- UsbDeviceDescBank *bank = &prvt_inst.desc_table[epn].DeviceDescBank[0];
- uint16_t trans_size = isr ? bank->PCKSIZE.bit.MULTI_PACKET_SIZE : 0;
- uint16_t last_trans = isr ? bank->PCKSIZE.bit.BYTE_COUNT : 0;
- uint16_t size_mask = (ept->size == 1023) ? 1023 : (ept->size - 1);
- uint16_t last_pkt = last_trans & size_mask;
- uint16_t trans_next;
- uint8_t inten;
- bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
-
- if (isr) {
- _usbd_ep_ack_io_cpt(epn, 0);
- }
-
- /* If cache is used, copy data to buffer. */
- if (ept->flags.bits.use_cache && ept->trans_size) {
- uint16_t buf_remain = ept->trans_size - ept->trans_count;
- memcpy(&ept->trans_buf[ept->trans_count], ept->cache, (buf_remain > last_pkt) ? last_pkt : buf_remain);
- }
-
- /* Force wait ZLP */
- if (ept->trans_size == 0 && ept->flags.bits.need_zlp) {
- ept->flags.bits.need_zlp = 0;
- ept->flags.bits.use_cache = 1;
- _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
- _usbd_ep_set_out_trans(epn, 0, ept->size, 0);
- goto _out_rx_exec;
- } else if (isr && last_pkt < ept->size) {
- /* Short packet. */
- ept->flags.bits.need_zlp = 0;
- ept->trans_count += last_trans;
- } else {
- /* Full packets. */
- ept->trans_count += trans_size;
-
- /* Wait more data */
- if (ept->trans_count < ept->trans_size) {
- /* Continue OUT */
- trans_next = ept->trans_size - ept->trans_count;
- if (ept->flags.bits.use_cache) {
- /* Expect single packet each time. */
- if (trans_next > ept->size) {
- trans_next = ept->size;
- }
- _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
- } else {
- /* Multiple packets each time. */
- if (trans_next > ept->size) {
- if (trans_next > USB_D_DEV_TRANS_MAX) {
- trans_next = USB_D_DEV_TRANS_MAX;
- } else {
- /* Must expect multiple of ep size. */
- trans_next -= trans_next & size_mask;
- }
- } else if (trans_next < ept->size) {
- /* Last un-aligned packet should be cached. */
- ept->flags.bits.use_cache = 1;
- }
- _usbd_ep_set_buf(epn, 0, (uint32_t)&ept->trans_buf[ept->trans_count]);
- }
- _usbd_ep_set_out_trans(epn, 0, trans_next, 0);
- goto _out_rx_exec;
- }
- }
- /* Finish normally. */
- if (is_ctrl) {
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK0_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL1);
- } else {
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_BANK0_INT_FLAGS);
- }
- /* Use ep0 out cache for next setup packets */
- if (0 == epn) {
- _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
- }
- _usb_d_dev_trans_done(ept, USB_TRANS_DONE);
- return;
-
-_out_rx_exec:
- if (!isr) {
- if (is_ctrl) {
- /* Initialize control OUT transaction. */
-
- /* Control transfer: SETUP or IN request will abort the
- * OUT transactions.
- * SETUP: terminate OUT without any notification.
- * Trigger SETUP notification.
- * IN NAK: finish OUT normally. Notify data done.
- */
- _usbd_ep_clear_bank_status(epn, 1);
- /* Detect OUT, SETUP, NAK IN */
- inten = USB_D_BANK0_INT_FLAGS | USB_DEVICE_EPINTFLAG_TRFAIL1;
- } else {
- /* Initialize normal OUT transaction. */
- inten = USB_D_BANK0_INT_FLAGS;
- }
- hri_usbendpoint_set_EPINTEN_reg(hw, epn, inten);
- }
- _usbd_ep_set_out_rdy(epn, 0, true);
-}
-
-/**
- * \brief Handles setup received interrupt
- * \param[in] ept Pointer to endpoint information.
- */
-static void _usb_d_dev_handle_setup(struct _usb_d_dev_ep *ept)
-{
- uint8_t epn = USB_EP_GET_N(ept->ep);
- bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
-
- if (!is_ctrl) {
- /* Should never be here! */
- _usbd_ep_ack_setup(epn);
- _usbd_ep_stop_setup(epn);
- return;
- }
- /* Control transfer:
- * SETUP transaction will terminate IN/OUT transaction,
- * and start new transaction with received SETUP packet.
- */
- if (_usb_d_dev_ep_is_busy(ept)) {
- ept->flags.bits.is_busy = 0;
-
- /* Stop transfer on either direction. */
- _usbd_ep_set_in_rdy(epn, 1, false);
- _usbd_ep_set_out_rdy(epn, 0, false);
- }
- ept->flags.bits.is_stalled = 0;
-
- /* Clear status and notify SETUP */
- _usbd_ep_clear_bank_status(epn, 0);
- _usbd_ep_clear_bank_status(epn, 1);
- _usbd_ep_int_ack(epn, USB_D_BANK0_INT_FLAGS | USB_D_BANK1_INT_FLAGS);
- _usbd_ep_int_dis(epn, USB_D_BANK0_INT_FLAGS | USB_D_BANK1_INT_FLAGS);
- /* Invoke callback. */
- dev_inst.ep_callbacks.setup(ept->ep);
-}
-
-/**
- * \brief Handles stall sent interrupt
- * \param[in] ept Pointer to endpoint information.
- * \param[in] bank_n Bank number.
- */
-static void _usb_d_dev_handle_stall(struct _usb_d_dev_ep *ept, const uint8_t bank_n)
-{
- uint8_t epn = USB_EP_GET_N(ept->ep);
- /* Clear interrupt enable. Leave status there for status check. */
- _usbd_ep_int_stall_en(epn, bank_n, false);
- dev_inst.ep_callbacks.done(ept->ep, USB_TRANS_STALL, ept->trans_count);
-}
-
-/**
- * \brief Handles transaction fail interrupt
- * \param[in] ept Pointer to endpoint information.
- * \param[in] bank_n Bank number.
- */
-static void _usb_d_dev_handle_trfail(struct _usb_d_dev_ep *ept, const uint8_t bank_n)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ept->ep);
- const uint8_t fail[2] = {USB_DEVICE_EPINTFLAG_TRFAIL0, USB_DEVICE_EPINTFLAG_TRFAIL1};
- UsbDeviceDescBank *bank = prvt_inst.desc_table[epn].DeviceDescBank;
- uint8_t eptype
- = bank_n ? hri_usbendpoint_read_EPCFG_EPTYPE1_bf(hw, epn) : hri_usbendpoint_read_EPCFG_EPTYPE0_bf(hw, epn);
- bool is_ctrl = _usb_d_dev_ep_is_ctrl(ept);
- USB_DEVICE_STATUS_BK_Type st;
- st.reg = bank[bank_n].STATUS_BK.reg;
-
- if ((eptype == USB_D_EPTYPE_ISOCH) && st.bit.CRCERR) {
- bank[bank_n].STATUS_BK.bit.CRCERR = 0;
- hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
- _usb_d_dev_trans_stop(ept, bank_n, USB_TRANS_ERROR);
- } else if (st.bit.ERRORFLOW) {
- bank[bank_n].STATUS_BK.bit.ERRORFLOW = 0;
- hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
- /* Abort control transfer. */
- if (is_ctrl && _usb_d_dev_ep_is_busy(ept)) {
- if (bank_n != _usb_d_dev_ep_is_in(ept)) {
- _usb_d_dev_trans_stop(ept, _usb_d_dev_ep_is_in(ept), USB_TRANS_DONE);
- }
- }
- } else {
- _usbd_ep_clear_bank_status(epn, bank_n);
- hri_usbendpoint_clear_EPINTFLAG_reg(hw, epn, fail[bank_n]);
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, fail[bank_n]);
- }
-}
-
-/**
- * \brief Analyze flags for setup transaction
- * \param[in] ept Pointer to endpoint information.
- * \param[in] flags Endpoint interrupt flags.
- */
-static inline void _usb_d_dev_trans_setup_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
-{
- /*
- * SETPU is automatically ACKed by hardware
- * OUT & IN should be set to NAK when checking SETUP
- * No need to check OUT & IN status.
- */
- if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
- _usb_d_dev_handle_setup(ept);
- } else if (flags & USB_DEVICE_EPINTFLAG_STALL1) {
- _usb_d_dev_handle_stall(ept, 1);
- } else if (flags & USB_DEVICE_EPINTFLAG_STALL0) {
- _usb_d_dev_handle_stall(ept, 0);
- }
-}
-
-/**
- * \brief Analyze flags for IN transactions
- * \param[in] ept Pointer to endpoint information.
- * \param[in] flags Endpoint interrupt flags.
- */
-static inline void _usb_d_dev_trans_in_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
-{
- /*
- * Check IN flags
- * If control endpoint, SETUP & OUT is checked to see if abort
- */
- if (flags & USB_DEVICE_EPINTFLAG_STALL1) {
- _usb_d_dev_handle_stall(ept, 1);
- } else if (flags & USB_DEVICE_EPINTFLAG_TRFAIL1) {
- _usb_d_dev_handle_trfail(ept, 1);
- } else if (flags & USB_DEVICE_EPINTFLAG_TRCPT1) {
- _usb_d_dev_in_next(ept, true);
- } else if (_usb_d_dev_ep_is_ctrl(ept)) {
- /* Check OUT NAK
- * Check SETUP
- */
- if (flags & USB_DEVICE_EPINTFLAG_TRFAIL0) {
- _usb_d_dev_handle_trfail(ept, 0);
- } else if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
- _usb_d_dev_handle_setup(ept);
- }
- }
-}
-
-/**
- * \brief Analyze flags for OUT transactions
- * \param[in] ept Pointer to endpoint information.
- * \param[in] flags Endpoint interrupt flags.
- */
-static inline void _usb_d_dev_trans_out_isr(struct _usb_d_dev_ep *ept, const uint8_t flags)
-{
- /*
- * Check OUT flags.
- * If control endpoint, SETUP & IN NAK is checked to see if abort
- */
- if (flags & USB_DEVICE_EPINTFLAG_STALL0) {
- _usb_d_dev_handle_stall(ept, 0);
- } else if (flags & USB_DEVICE_EPINTFLAG_TRFAIL0) {
- _usb_d_dev_handle_trfail(ept, 0);
- } else if (flags & USB_DEVICE_EPINTFLAG_TRCPT0) {
- _usb_d_dev_out_next(ept, true);
- } else if (_usb_d_dev_ep_is_ctrl(ept)) {
- /* Check IN NAK
- * Check SETUP
- */
- if (flags & USB_DEVICE_EPINTFLAG_TRFAIL1) {
- _usb_d_dev_handle_trfail(ept, 1);
- } else if (flags & USB_DEVICE_EPINTFLAG_RXSTP) {
- _usb_d_dev_handle_setup(ept);
- }
- }
-}
-
-/**
- * \brief Handles the endpoint interrupts.
- * \param[in] epint Endpoint interrupt summary (by bits).
- * \param[in] ept Pointer to endpoint information.
- */
-static inline void _usb_d_dev_handle_eps(uint32_t epint, struct _usb_d_dev_ep *ept)
-{
- Usb *hw = USB;
-
- uint8_t flags, mask;
- uint8_t epn = USB_EP_GET_N(ept->ep);
-
- if (!(epint & (1u << epn))) {
- return;
- }
- flags = hw->DEVICE.DeviceEndpoint[epn].EPINTFLAG.reg;
- mask = hw->DEVICE.DeviceEndpoint[epn].EPINTENSET.reg;
- flags &= mask;
- if (flags) {
- if ((ept->flags.bits.eptype == 0x1) && !_usb_d_dev_ep_is_busy(ept)) {
- _usb_d_dev_trans_setup_isr(ept, flags);
- } else if (_usb_d_dev_ep_is_in(ept)) {
- _usb_d_dev_trans_in_isr(ept, flags);
- } else {
- _usb_d_dev_trans_out_isr(ept, flags);
- }
- }
-}
-
-/**
- * \brief USB device interrupt handler
- * \param[in] unused The parameter is not used
- */
-static void _usb_d_dev_handler(void)
-{
- Usb * hw = USB;
- uint8_t i;
-
- uint16_t epint = hw->DEVICE.EPINTSMRY.reg;
- if (0 == epint) {
- if (_usb_d_dev_handle_nep()) {
- return;
- }
- }
- /* Handle endpoints */
- for (i = 0; i < USB_D_N_EP; i++) {
- struct _usb_d_dev_ep *ept = &dev_inst.ep[i];
- if (ept->ep == 0xFF) {
- continue;
- }
- _usb_d_dev_handle_eps(epint, ept);
- }
-}
-
-/**
- * \brief Reset all endpoint software instances
- */
-static void _usb_d_dev_reset_epts(void)
-{
- uint8_t i;
- for (i = 0; i < USB_D_N_EP; i++) {
- _usb_d_dev_trans_done(&dev_inst.ep[i], USB_TRANS_RESET);
- dev_inst.ep[i].ep = 0xFF;
- dev_inst.ep[i].flags.u8 = 0;
- }
- memset(prvt_inst.desc_table, 0, sizeof(UsbDeviceDescriptor) * (CONF_USB_D_MAX_EP_N + 1));
-}
-
-int32_t _usb_d_dev_init(void)
-{
- Usb * hw = USB;
- uint8_t speed = CONF_USB_D_SPEED;
- const uint8_t spdconf[4] = {
- USB_DEVICE_CTRLB_SPDCONF(1), /* LS */
- USB_DEVICE_CTRLB_SPDCONF(0), /* FS */
- 0,
- 0 /* Reserved */
- };
-
- hri_usbdevice_wait_for_sync(hw, USB_SYNCBUSY_SWRST);
- if (hri_usbdevice_get_CTRLA_ENABLE_bit(hw)) {
- return ERR_DENIED;
- }
- hri_usbdevice_set_CTRLA_SWRST_bit(hw);
- hri_usbdevice_wait_for_sync(hw, USB_SYNCBUSY_SWRST);
-
- dev_inst.callbacks.sof = (_usb_d_dev_sof_cb_t)_dummy_func_no_return;
- dev_inst.callbacks.event = (_usb_d_dev_event_cb_t)_dummy_func_no_return;
-
- dev_inst.ep_callbacks.setup = (_usb_d_dev_ep_cb_setup_t)_dummy_func_no_return;
- dev_inst.ep_callbacks.more = (_usb_d_dev_ep_cb_more_t)_dummy_func_no_return;
- dev_inst.ep_callbacks.done = (_usb_d_dev_ep_cb_done_t)_dummy_func_no_return;
-
- _usb_d_dev_reset_epts();
-
- _usb_load_calib();
-
- hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_RUNSTDBY);
- hri_usbdevice_write_DESCADD_reg(hw, (uint32_t)prvt_inst.desc_table);
- hri_usbdevice_write_CTRLB_reg(hw, spdconf[speed] | USB_DEVICE_CTRLB_DETACH);
-
- return ERR_NONE;
-}
-
-void _usb_d_dev_deinit(void)
-{
- Usb *hw = USB;
-
- while (_usb_d_dev_disable() < 0)
- ;
-
- hri_usbdevice_write_CTRLA_reg(hw, USB_CTRLA_SWRST);
-
- NVIC_DisableIRQ(USB_IRQn);
- NVIC_ClearPendingIRQ(USB_IRQn);
-}
-
-int32_t _usb_d_dev_enable(void)
-{
- Usb * hw = USB;
- uint8_t ctrla;
-
- if (hri_usbdevice_get_SYNCBUSY_reg(hw, (USB_SYNCBUSY_ENABLE | USB_SYNCBUSY_SWRST))) {
- return -USB_ERR_DENIED;
- }
- ctrla = hri_usbdevice_read_CTRLA_reg(hw);
- if ((ctrla & USB_CTRLA_ENABLE) == 0) {
- hri_usbdevice_write_CTRLA_reg(hw, ctrla | USB_CTRLA_ENABLE);
- }
-
- NVIC_EnableIRQ(USB_IRQn);
-
- hri_usbdevice_set_INTEN_reg(hw,
- USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST | USB_DEVICE_INTENSET_RAMACER
- | USB_D_SUSPEND_INT_FLAGS);
-
- return ERR_NONE;
-}
-
-int32_t _usb_d_dev_disable(void)
-{
- Usb * hw = USB;
- uint8_t ctrla;
-
- if (hri_usbdevice_get_SYNCBUSY_reg(hw, (USB_SYNCBUSY_ENABLE | USB_SYNCBUSY_SWRST))) {
- return -USB_ERR_DENIED;
- }
-
- ctrla = hri_usbdevice_read_CTRLA_reg(hw);
- if (ctrla & USB_CTRLA_ENABLE) {
- hri_usbdevice_write_CTRLA_reg(hw, ctrla & ~USB_CTRLA_ENABLE);
- }
- NVIC_DisableIRQ(USB_IRQn);
-
- hri_usbdevice_clear_INTEN_reg(hw,
- USB_DEVICE_INTENSET_SOF | USB_DEVICE_INTENSET_EORST | USB_DEVICE_INTENSET_RAMACER
- | USB_D_SUSPEND_INT_FLAGS
- | USB_D_WAKEUP_INT_FLAGS);
-
- return ERR_NONE;
-}
-
-void _usb_d_dev_attach(void)
-{
- hri_usbdevice_clear_CTRLB_DETACH_bit(USB);
-}
-
-void _usb_d_dev_detach(void)
-{
- hri_usbdevice_set_CTRLB_DETACH_bit(USB);
-}
-
-#ifndef USB_FSMSTATUS_FSMSTATE_ON
-#define USB_FSMSTATUS_FSMSTATE_ON USB_FSMSTATUS_FSMSTATE(2ul)
-#endif
-void _usb_d_dev_send_remotewakeup(void)
-{
- uint32_t retry = CONF_USB_RMT_WKUP_RETRY;
- _usb_d_dev_wait_clk_rdy(CONF_USB_D_CLK_SRC);
- while ((USB_FSMSTATUS_FSMSTATE_ON != hri_usbdevice_read_FSMSTATUS_FSMSTATE_bf(USB)) && (retry--)) {
- USB->DEVICE.CTRLB.bit.UPRSM = 1;
- }
-}
-
-enum usb_speed _usb_d_dev_get_speed(void)
-{
- uint8_t sp = (enum usb_speed)hri_usbdevice_read_STATUS_SPEED_bf(USB);
- const enum usb_speed speed[2] = {USB_SPEED_FS, USB_SPEED_LS};
-
- return speed[sp];
-}
-
-void _usb_d_dev_set_address(uint8_t addr)
-{
- hri_usbdevice_write_DADD_reg(USB, USB_DEVICE_DADD_ADDEN | USB_DEVICE_DADD_DADD(addr));
-}
-
-uint8_t _usb_d_dev_get_address(void)
-{
- uint8_t addr = hri_usbdevice_read_DADD_DADD_bf(USB);
- return addr;
-}
-
-uint16_t _usb_d_dev_get_frame_n(void)
-{
- uint16_t fn = hri_usbdevice_read_FNUM_FNUM_bf(USB);
- return fn;
-}
-
-uint8_t _usb_d_dev_get_uframe_n(void)
-{
- uint8_t ufn = hri_usbdevice_read_FNUM_MFNUM_bf(USB);
- return ufn;
-}
-
-/**
- * \brief Start a setup transaction
- * \param[in] ept Endpoint information.
- */
-static inline void _usb_d_dev_trans_setup(struct _usb_d_dev_ep *ept)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ept->ep);
-
- _usbd_ep_set_buf(epn, 0, (uint32_t)ept->cache);
- _usbd_ep_set_out_trans(epn, 0, ept->size, 0);
-
- hri_usbendpoint_clear_EPSTATUS_reg(hw, epn, USB_DEVICE_EPSTATUS_STALLRQ(0x3) | USB_DEVICE_EPSTATUS_BK1RDY);
- _usbd_ep_set_out_rdy(epn, 0, false);
-
- hri_usbendpoint_set_EPINTEN_reg(hw, epn, USB_D_SETUP_INT_FLAGS);
-}
-
-int32_t _usb_d_dev_ep0_init(const uint8_t max_pkt_siz)
-{
- return _usb_d_dev_ep_init(0, USB_EP_XTYPE_CTRL, max_pkt_siz);
-}
-
-int32_t _usb_d_dev_ep_init(const uint8_t ep, const uint8_t attr, const uint16_t max_pkt_siz)
-{
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
-
- uint8_t ep_type = attr & USB_EP_XTYPE_MASK;
- const struct _usb_ep_cfg_item *pcfg = &_usb_ep_cfgs[epn];
-
- if (epn > CONF_USB_D_MAX_EP_N) {
- return -USB_ERR_PARAM;
- }
- if (ept->ep != 0xFF) {
- return -USB_ERR_REDO;
- }
- if (ep_type == USB_EP_XTYPE_CTRL) {
- struct _usb_d_dev_ep *ept_in = _usb_d_dev_ept(epn, !dir);
- if (ept_in->ep != 0xFF) {
- return -USB_ERR_REDO;
- }
- if (pcfg->cache == NULL) {
- return -USB_ERR_FUNC;
- }
- }
- if ((dir ? pcfg->i_cache : pcfg->cache) && ((dir ? pcfg->i_size : pcfg->size) < max_pkt_siz)) {
- return -USB_ERR_FUNC;
- }
-
- /* Initialize EP n settings */
- ept->cache = (uint8_t *)(dir ? pcfg->i_cache : pcfg->cache);
- ept->size = max_pkt_siz;
- ept->flags.u8 = (ep_type + 1);
- ept->ep = ep;
-
- return USB_OK;
-}
-
-void _usb_d_dev_ep_deinit(uint8_t ep)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
-
- if (epn > CONF_USB_D_MAX_EP_N || !_usb_d_dev_ep_is_used(ept)) {
- return;
- }
-
- /* Finish pending transactions. */
- _usb_d_dev_trans_stop(ept, dir, USB_TRANS_RESET);
-
- /* Disable the endpoint. */
- if (_usb_d_dev_ep_is_ctrl(ept)) {
- hw->DEVICE.DeviceEndpoint[ep].EPCFG.reg = 0;
- } else if (USB_EP_GET_DIR(ep)) {
- hw->DEVICE.DeviceEndpoint[USB_EP_GET_N(ep)].EPCFG.reg &= ~USB_DEVICE_EPCFG_EPTYPE1_Msk;
- } else {
- hw->DEVICE.DeviceEndpoint[ep].EPCFG.reg &= ~USB_DEVICE_EPCFG_EPTYPE0_Msk;
- }
- ept->flags.u8 = 0;
- ept->ep = 0xFF;
-}
-
-int32_t _usb_d_dev_ep_enable(const uint8_t ep)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
- uint8_t epcfg = hri_usbendpoint_read_EPCFG_reg(hw, epn);
- UsbDeviceDescBank * bank;
-
- if (epn > CONF_USB_D_MAX_EP_N || !_usb_d_dev_ep_is_used(ept)) {
- return -USB_ERR_PARAM;
- }
-
- bank = prvt_inst.desc_table[epn].DeviceDescBank;
- if (ept->flags.bits.eptype == USB_D_EPTYPE_CTRL) {
- if (epcfg & (USB_DEVICE_EPCFG_EPTYPE1_Msk | USB_DEVICE_EPCFG_EPTYPE0_Msk)) {
- return -USB_ERR_REDO;
- }
- hri_usbendpoint_write_EPCFG_reg(hw, epn, USB_D_EPCFG_CTRL);
- bank[0].PCKSIZE.reg = USB_DEVICE_PCKSIZE_MULTI_PACKET_SIZE(ept->size)
- | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
- bank[1].PCKSIZE.reg
- = USB_DEVICE_PCKSIZE_BYTE_COUNT(ept->size) | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
- /* By default, control endpoint accept SETUP and NAK all other token. */
- _usbd_ep_set_out_rdy(epn, 0, false);
- _usbd_ep_set_in_rdy(epn, 1, false);
-
- _usbd_ep_clear_bank_status(epn, 0);
- _usbd_ep_clear_bank_status(epn, 1);
-
- /* Enable SETUP reception for control endpoint. */
- _usb_d_dev_trans_setup(ept);
-
- } else if (dir) {
- if (epcfg & USB_DEVICE_EPCFG_EPTYPE1_Msk) {
- return -USB_ERR_REDO;
- }
- epcfg |= USB_DEVICE_EPCFG_EPTYPE1(ept->flags.bits.eptype);
- hri_usbendpoint_write_EPCFG_reg(hw, epn, epcfg);
-
- bank[1].PCKSIZE.reg
- = USB_DEVICE_PCKSIZE_BYTE_COUNT(ept->size) | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
-
- /* By default, IN endpoint will NAK all token. */
- _usbd_ep_set_in_rdy(epn, 1, false);
- _usbd_ep_clear_bank_status(epn, 1);
-
- } else {
-
- if (epcfg & USB_DEVICE_EPCFG_EPTYPE0_Msk) {
- return -USB_ERR_REDO;
- }
- epcfg |= USB_DEVICE_EPCFG_EPTYPE0(ept->flags.bits.eptype);
- hri_usbendpoint_write_EPCFG_reg(hw, epn, epcfg);
-
- bank[0].PCKSIZE.reg = USB_DEVICE_PCKSIZE_MULTI_PACKET_SIZE(ept->size)
- | USB_DEVICE_PCKSIZE_SIZE(_usbd_ep_pcksize_size(ept->size));
-
- /* By default, OUT endpoint will NAK all token. */
- _usbd_ep_set_out_rdy(epn, 0, false);
- _usbd_ep_clear_bank_status(epn, 0);
- }
-
- return USB_OK;
-}
-
-void _usb_d_dev_ep_disable(const uint8_t ep)
-{
- Usb * hw = USB;
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
-
- _usb_d_dev_trans_stop(ept, dir, USB_TRANS_RESET);
- if (_usb_d_dev_ep_is_ctrl(ept)) {
- hri_usbendpoint_clear_EPINTEN_reg(hw, epn, USB_D_ALL_INT_FLAGS);
- }
-}
-
-/**
- * \brief Get endpoint stall status
- * \param[in] ept Pointer to endpoint information.
- * \param[in] dir Endpoint direction.
- * \return Stall status.
- * \retval \c true Endpoint is stalled.
- * \retval \c false Endpoint is not stalled.
- */
-static inline int32_t _usb_d_dev_ep_stall_get(struct _usb_d_dev_ep *ept, bool dir)
-{
- uint8_t epn = USB_EP_GET_N(ept->ep);
- return _usbd_ep_is_stalled(epn, dir);
-}
-
-/**
- * \brief Set endpoint stall
- * \param[in, out] ept Pointer to endpoint information.
- * \param[in] dir Endpoint direction.
- * \return Always 0, success.
- */
-static inline int32_t _usb_d_dev_ep_stall_set(struct _usb_d_dev_ep *ept, bool dir)
-{
- uint8_t epn = USB_EP_GET_N(ept->ep);
- _usbd_ep_set_stall(epn, dir, true);
- _usbd_ep_int_en(epn, USB_DEVICE_EPINTFLAG_STALL0 << dir);
- ept->flags.bits.is_stalled = 1;
- /* In stall interrupt abort the transfer. */
- return ERR_NONE;
-}
-
-/**
- * \brief Clear endpoint stall
- * \param[in, out] ept Pointer to endpoint information.
- * \param[in] dir Endpoint direction.
- * \return Always 0, success.
- */
-static inline int32_t _usb_d_dev_ep_stall_clr(struct _usb_d_dev_ep *ept, bool dir)
-{
- uint8_t epn = USB_EP_GET_N(ept->ep);
- bool is_stalled = _usbd_ep_is_stalled(epn, dir);
- if (!is_stalled) {
- return ERR_NONE;
- }
- _usbd_ep_set_stall(epn, dir, false);
- _usbd_ep_int_dis(epn, USB_DEVICE_EPINTFLAG_STALL0 << dir);
- if (_usbd_ep_is_stall_sent(epn, dir)) {
- _usbd_ep_ack_stall(epn, dir);
- _usbd_ep_set_toggle(epn, dir, 0);
- }
- if (_usb_d_dev_ep_is_ctrl(ept)) {
- if ((hri_usbendpoint_read_EPSTATUS_reg(USB, epn) & USB_DEVICE_EPSTATUS_STALLRQ_Msk) == 0) {
- ept->flags.bits.is_stalled = 0;
- }
- } else {
- ept->flags.bits.is_stalled = 0;
- }
- return ERR_NONE;
-}
-
-int32_t _usb_d_dev_ep_stall(const uint8_t ep, const enum usb_ep_stall_ctrl ctrl)
-{
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
- int32_t rc;
-
- if (epn > CONF_USB_D_MAX_EP_N) {
- return -USB_ERR_PARAM;
- }
-
- if (USB_EP_STALL_SET == ctrl) {
- rc = _usb_d_dev_ep_stall_set(ept, dir);
- } else if (USB_EP_STALL_CLR == ctrl) {
- rc = _usb_d_dev_ep_stall_clr(ept, dir);
- } else {
- rc = _usb_d_dev_ep_stall_get(ept, dir);
- }
- return rc;
-}
-
-/**
- * \brief Finish the transaction and invoke callback
- * \param[in, out] ept Pointer to endpoint information.
- * \param[in] code Information code passed.
- */
-static void _usb_d_dev_trans_done(struct _usb_d_dev_ep *ept, const int32_t code)
-{
- if (!(_usb_d_dev_ep_is_used(ept) && _usb_d_dev_ep_is_busy(ept))) {
- return;
- }
- ept->flags.bits.is_busy = 0;
- dev_inst.ep_callbacks.done(ept->ep, code, ept->trans_count);
-}
-
-/**
- * \brief Terminate the transaction with specific status code
- * \param[in, out] ept Pointer to endpoint information.
- * \param[in] dir Endpoint direction.
- * \param[in] code Information code passed.
- */
-static void _usb_d_dev_trans_stop(struct _usb_d_dev_ep *ept, bool dir, const int32_t code)
-{
- uint8_t epn = USB_EP_GET_N(ept->ep);
- ;
- const uint8_t intflags[2] = {USB_D_BANK0_INT_FLAGS, USB_D_BANK1_INT_FLAGS};
- if (!(_usb_d_dev_ep_is_used(ept) && _usb_d_dev_ep_is_busy(ept))) {
- return;
- }
- /* Stop transfer */
- if (dir) {
- /* NAK IN */
- _usbd_ep_set_in_rdy(epn, 1, false);
- } else {
- /* NAK OUT */
- _usbd_ep_set_out_rdy(epn, 0, false);
- }
- _usbd_ep_int_ack(epn, intflags[dir]);
- _usbd_ep_int_dis(epn, intflags[dir]);
- _usb_d_dev_trans_done(ept, code);
-}
-
-int32_t _usb_d_dev_ep_read_req(const uint8_t ep, uint8_t *req_buf)
-{
- uint8_t epn = USB_EP_GET_N(ep);
- UsbDeviceDescBank *bank = prvt_inst.desc_table[epn].DeviceDescBank;
- uint32_t addr = bank[0].ADDR.reg;
- uint16_t bytes = bank[0].PCKSIZE.bit.BYTE_COUNT;
-
- if (epn > CONF_USB_D_MAX_EP_N || !req_buf) {
- return -USB_ERR_PARAM;
- }
- if (!_usbd_ep_is_ctrl(epn)) {
- return -USB_ERR_FUNC;
- }
- if (!_usbd_ep_is_setup(epn)) {
- return ERR_NONE;
- }
- memcpy(req_buf, (void *)addr, 8);
- _usbd_ep_ack_setup(epn);
-
- return bytes;
-}
-
-int32_t _usb_d_dev_ep_trans(const struct usb_d_transfer *trans)
-{
- uint8_t epn = USB_EP_GET_N(trans->ep);
- bool dir = USB_EP_GET_DIR(trans->ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
-
- uint16_t size_mask = (ept->size == 1023) ? 1023 : (ept->size - 1);
- bool size_n_aligned = (trans->size & size_mask);
-
- bool use_cache = false;
-
- volatile hal_atomic_t flags;
-
- if (epn > CONF_USB_D_MAX_EP_N) {
- return -USB_ERR_PARAM;
- }
-
- /* Cases that needs cache:
- * 1. Buffer not in RAM (cache all).
- * 2. IN/OUT with unaligned buffer (cache all).
- * 3. OUT with unaligned packet size (cache last packet).
- * 4. OUT size < 8 (sub-case for 3).
- */
- if (!_usb_is_addr4dma(trans->buf, trans->size) || (!_usb_is_aligned(trans->buf))
- || (!dir && (trans->size < ept->size))) {
- if (!ept->cache) {
- return -USB_ERR_FUNC;
- }
- /* Use cache all the time. */
- use_cache = true;
- }
- if (!dir && size_n_aligned) {
- if (!ept->cache) {
- return -USB_ERR_PARAM;
- }
- /* Set 'use_cache' on last packet. */
- }
-
- /* Check halt */
- if (ept->flags.bits.is_stalled) {
- return USB_HALTED;
- }
-
- /* Try to start transactions. */
-
- atomic_enter_critical(&flags);
- if (_usb_d_dev_ep_is_busy(ept)) {
- atomic_leave_critical(&flags);
- return USB_BUSY;
- }
- ept->flags.bits.is_busy = 1;
- atomic_leave_critical(&flags);
-
- /* Copy transaction information. */
- ept->trans_buf = trans->buf;
- ept->trans_size = trans->size;
- ept->trans_count = 0;
-
- ept->flags.bits.dir = dir;
- ept->flags.bits.use_cache = use_cache;
- ept->flags.bits.need_zlp = (trans->zlp && (!size_n_aligned));
-
- if (dir) {
- _usb_d_dev_in_next(ept, false);
- } else {
- _usb_d_dev_out_next(ept, false);
- }
-
- return ERR_NONE;
-}
-
-void _usb_d_dev_ep_abort(const uint8_t ep)
-{
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
- if (epn > CONF_USB_D_MAX_EP_N) {
- return;
- }
- _usb_d_dev_trans_stop(ept, dir, USB_TRANS_ABORT);
-}
-
-int32_t _usb_d_dev_ep_get_status(const uint8_t ep, struct usb_d_trans_status *stat)
-{
- uint8_t epn = USB_EP_GET_N(ep);
- bool dir = USB_EP_GET_DIR(ep);
- struct _usb_d_dev_ep *ept = _usb_d_dev_ept(epn, dir);
- bool busy, stall;
-
- if (epn > CONF_USB_D_MAX_EP_N) {
- return USB_ERR_PARAM;
- }
- busy = ept->flags.bits.is_busy;
- stall = ept->flags.bits.is_stalled;
- if (stat) {
- stat->stall = stall;
- stat->busy = busy;
- stat->setup = USB->DEVICE.DeviceEndpoint[epn].EPINTFLAG.bit.RXSTP;
- stat->dir = ept->flags.bits.dir;
- stat->size = ept->trans_size;
- stat->count = ept->trans_count;
- stat->ep = ep;
- stat->xtype = ept->flags.bits.eptype - 1;
- }
- if (stall) {
- return USB_HALTED;
- }
- if (busy) {
- return USB_BUSY;
- }
- return USB_OK;
-}
-
-void _usb_d_dev_register_callback(const enum usb_d_cb_type type, const FUNC_PTR func)
-{
- FUNC_PTR f = (func == NULL) ? (FUNC_PTR)_dummy_func_no_return : (FUNC_PTR)func;
- if (type == USB_D_CB_EVENT) {
- dev_inst.callbacks.event = (_usb_d_dev_event_cb_t)f;
- } else if (type == USB_D_CB_SOF) {
- dev_inst.callbacks.sof = (_usb_d_dev_sof_cb_t)f;
- }
-}
-
-void _usb_d_dev_register_ep_callback(const enum usb_d_dev_ep_cb_type type, const FUNC_PTR func)
-{
- FUNC_PTR f = (func == NULL) ? (FUNC_PTR)_dummy_func_no_return : (FUNC_PTR)func;
- if (type == USB_D_DEV_EP_CB_SETUP) {
- dev_inst.ep_callbacks.setup = (_usb_d_dev_ep_cb_setup_t)f;
- } else if (type == USB_D_DEV_EP_CB_MORE) {
- dev_inst.ep_callbacks.more = (_usb_d_dev_ep_cb_more_t)f;
- } else if (type == USB_D_DEV_EP_CB_DONE) {
- dev_inst.ep_callbacks.done = (_usb_d_dev_ep_cb_done_t)f;
- }
-}
-
-/**
-* \brief USB interrupt handler
-*/
-void USB_Handler(void)
-{
-
- _usb_d_dev_handler();
-}