http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.c ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.c deleted file mode 100755 index 52424d7..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.c +++ /dev/null @@ -1,232 +0,0 @@ -/** - * \file - * - * \brief SAM External Interrupt Driver - * - * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ -#include "extint.h" -#include "extint_callback.h" - -/** - * \internal - * Internal driver device instance struct, declared in the main module driver. - */ -extern struct _extint_module _extint_dev; - -/** - * \internal - * This is the number of the channel whose callback is currently running. - */ -uint8_t _current_channel; - -/** - * \brief Registers an asynchronous callback function with the driver. - * - * Registers an asynchronous callback with the EXTINT driver, fired when a - * channel detects the configured channel detection criteria - * (e.g. edge or level). Callbacks are fired once for each detected channel. - * - * \note NMI channel callbacks cannot be registered via this function; the - * device's NMI interrupt should be hooked directly in the user - * application and the NMI flags manually cleared via - * \ref extint_nmi_clear_detected(). - * - * \param[in] callback Pointer to the callback function to register - * \param[in] channel Logical channel to register callback for - * \param[in] type Type of callback function to register - * - * \return Status of the registration operation. - * \retval STATUS_OK The callback was registered successfully - * \retval STATUS_ERR_INVALID_ARG If an invalid callback type was supplied - * \retval STATUS_ERR_ALREADY_INITIALIZED Callback function has been - * registered, need unregister first - */ -enum status_code extint_register_callback( - const extint_callback_t callback, - const uint8_t channel, - const enum extint_callback_type type) -{ - /* Sanity check arguments */ - Assert(callback); - - if (type != EXTINT_CALLBACK_TYPE_DETECT) { - Assert(false); - return STATUS_ERR_INVALID_ARG; - } - - if (_extint_dev.callbacks[channel] == NULL) { - _extint_dev.callbacks[channel] = callback; - return STATUS_OK; - } else if (_extint_dev.callbacks[channel] == callback) { - return STATUS_OK; - } - - return STATUS_ERR_ALREADY_INITIALIZED; -} - -/** - * \brief Unregisters an asynchronous callback function with the driver. - * - * Unregisters an asynchronous callback with the EXTINT driver, removing it - * from the internal callback registration table. - * - * \param[in] callback Pointer to the callback function to unregister - * \param[in] channel Logical channel to unregister callback for - * \param[in] type Type of callback function to unregister - * - * \return Status of the de-registration operation. - * \retval STATUS_OK The callback was unregistered successfully - * \retval STATUS_ERR_INVALID_ARG If an invalid callback type was supplied - * \retval STATUS_ERR_BAD_ADDRESS No matching entry was found in the - * registration table - */ -enum status_code extint_unregister_callback( - const extint_callback_t callback, - const uint8_t channel, - const enum extint_callback_type type) -{ - /* Sanity check arguments */ - Assert(callback); - - if (type != EXTINT_CALLBACK_TYPE_DETECT) { - Assert(false); - return STATUS_ERR_INVALID_ARG; - } - - if (_extint_dev.callbacks[channel] == callback) { - _extint_dev.callbacks[channel] = NULL; - return STATUS_OK; - } - - return STATUS_ERR_BAD_ADDRESS; -} - -/** - * \brief Enables asynchronous callback generation for a given channel and type. - * - * Enables asynchronous callbacks for a given logical external interrupt channel - * and type. This must be called before an external interrupt channel will - * generate callback events. - * - * \param[in] channel Logical channel to enable callback generation for - * \param[in] type Type of callback function callbacks to enable - * - * \return Status of the callback enable operation. - * \retval STATUS_OK The callback was enabled successfully - * \retval STATUS_ERR_INVALID_ARG If an invalid callback type was supplied - */ -enum status_code extint_chan_enable_callback( - const uint8_t channel, - const enum extint_callback_type type) -{ - if (type == EXTINT_CALLBACK_TYPE_DETECT) { - Eic *const eic = _extint_get_eic_from_channel(channel); - - eic->INTENSET.reg = (1UL << channel); - } - else { - Assert(false); - return STATUS_ERR_INVALID_ARG; - } - - return STATUS_OK; -} - -/** - * \brief Disables asynchronous callback generation for a given channel and type. - * - * Disables asynchronous callbacks for a given logical external interrupt - * channel and type. - * - * \param[in] channel Logical channel to disable callback generation for - * \param[in] type Type of callback function callbacks to disable - * - * \return Status of the callback disable operation. - * \retval STATUS_OK The callback was disabled successfully - * \retval STATUS_ERR_INVALID_ARG If an invalid callback type was supplied - */ -enum status_code extint_chan_disable_callback( - const uint8_t channel, - const enum extint_callback_type type) -{ - if (type == EXTINT_CALLBACK_TYPE_DETECT) { - Eic *const eic = _extint_get_eic_from_channel(channel); - - eic->INTENCLR.reg = (1UL << channel); - } - else { - Assert(false); - return STATUS_ERR_INVALID_ARG; - } - - return STATUS_OK; -} - -/** - * \brief Find what channel caused the callback. - * - * Can be used in an EXTINT callback function to find what channel caused - * the callback in case the same callback is used by multiple channels. - * - * \return Channel number. - */ -uint8_t extint_get_current_channel(void) -{ - return _current_channel; -} - -/** Handler for the EXTINT hardware module interrupt. */ -void EIC_Handler(void) -{ - /* Find any triggered channels, run associated callback handlers */ - for (_current_channel = 0; _current_channel < EIC_NUMBER_OF_INTERRUPTS ; _current_channel++) { - if (extint_chan_is_detected(_current_channel)) { - /* Clear flag */ - extint_chan_clear_detected(_current_channel); - /* Find any associated callback entries in the callback table */ - if (_extint_dev.callbacks[_current_channel] != NULL) { - /* Run the registered callback */ - _extint_dev.callbacks[_current_channel](); - } - } - } -}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.h ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.h b/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.h deleted file mode 100755 index 35cf230..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_callback.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * \file - * - * \brief SAM External Interrupt Driver - * - * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ -#ifndef EXTINT_CALLBACK_H_INCLUDED -#define EXTINT_CALLBACK_H_INCLUDED - -#include <compiler.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \addtogroup asfdoc_sam0_extint_group - * - * @{ - */ - -/** \name Callback Configuration and Initialization - * @{ - */ - -/** Enum for the possible callback types for the EXTINT module. */ -enum extint_callback_type -{ - /** Callback type for when an external interrupt detects the configured - * channel criteria (i.e. edge or level detection) - */ - EXTINT_CALLBACK_TYPE_DETECT, -}; - -enum status_code extint_register_callback( - const extint_callback_t callback, - const uint8_t channel, - const enum extint_callback_type type); - -enum status_code extint_unregister_callback( - const extint_callback_t callback, - const uint8_t channel, - const enum extint_callback_type type); - -uint8_t extint_get_current_channel(void); - -/** @} */ - -/** \name Callback Enabling and Disabling (Channel) - * @{ - */ - -enum status_code extint_chan_enable_callback( - const uint8_t channel, - const enum extint_callback_type type); - -enum status_code extint_chan_disable_callback( - const uint8_t channel, - const enum extint_callback_type type); - -/** @} */ - -/** @} */ - -#ifdef __cplusplus -} -#endif - -#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_sam_d_r/extint.c ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_sam_d_r/extint.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_sam_d_r/extint.c deleted file mode 100755 index a9697d0..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/extint_sam_d_r/extint.c +++ /dev/null @@ -1,425 +0,0 @@ -/** - * \file - * - * \brief SAM External Interrupt Driver - * - * Copyright (C) 2012-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ -#include <system.h> -#include <system_interrupt.h> -#include <extint.h> -#include <conf_extint.h> - -#if !defined(EXTINT_CLOCK_SOURCE) || defined(__DOXYGEN__) -# warning EXTINT_CLOCK_SOURCE is not defined, assuming GCLK_GENERATOR_0. - -/** Configuration option, setting the EIC clock source which can be used for - * EIC edge detection or filtering. This option may be overridden in the module - * configuration header file \c conf_extint.h. - */ -# define EXTINT_CLOCK_SOURCE GCLK_GENERATOR_0 -#endif - -/** - * \internal - * Internal driver device instance struct. - */ -struct _extint_module _extint_dev; - -/** - * \brief Determin if the general clock is required - * - * \param[in] filter_input_signal Filter the raw input signal to prevent noise - * \param[in] detection_criteria Edge detection mode to use (\ref extint_detect) - */ -#define _extint_is_gclk_required(filter_input_signal, detection_criteria) \ - ((filter_input_signal) ? true : (\ - (EXTINT_DETECT_RISING == (detection_criteria)) ? true : (\ - (EXTINT_DETECT_FALLING == (detection_criteria)) ? true : (\ - (EXTINT_DETECT_BOTH == (detection_criteria)) ? true : false)))) - -static void _extint_enable(void); -static void _extint_disable(void); - -/** - * \brief Determines if the hardware module(s) are currently synchronizing to the bus. - * - * Checks to see if the underlying hardware peripheral module(s) are currently - * synchronizing across multiple clock domains to the hardware bus, This - * function can be used to delay further operations on a module until such time - * that it is ready, to prevent blocking delays for synchronization in the - * user application. - * - * \return Synchronization status of the underlying hardware module(s). - * - * \retval true If the module synchronization is ongoing - * \retval false If the module has completed synchronization - */ -static inline bool extint_is_syncing(void) -{ - Eic *const eics[EIC_INST_NUM] = EIC_INSTS; - - for (uint32_t i = 0; i < EIC_INST_NUM; i++) { - if (eics[i]->STATUS.reg & EIC_STATUS_SYNCBUSY) { - return true; - } - } - return false; -} -/** - * \internal - * \brief Initializes and enables the External Interrupt driver. - * - * Enable the clocks used by External Interrupt driver. - * - * Resets the External Interrupt driver, resetting all hardware - * module registers to their power-on defaults, then enable it for further use. - * - * Reset the callback list if callback mode is used. - * - * This function must be called before attempting to use any NMI or standard - * external interrupt channel functions. - * - * \note When SYSTEM module is used, this function will be invoked by - * \ref system_init() automatically if the module is included. - */ -void _system_extint_init(void); -void _system_extint_init(void) -{ - Eic *const eics[EIC_INST_NUM] = EIC_INSTS; - - /* Turn on the digital interface clock */ - system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_EIC); - - /* Configure the generic clock for the module and enable it */ - struct system_gclk_chan_config gclk_chan_conf; - system_gclk_chan_get_config_defaults(&gclk_chan_conf); - gclk_chan_conf.source_generator = EXTINT_CLOCK_SOURCE; - system_gclk_chan_set_config(EIC_GCLK_ID, &gclk_chan_conf); - - /* Enable the clock anyway, since when needed it will be requested - * by External Interrupt driver */ - system_gclk_chan_enable(EIC_GCLK_ID); - - /* Reset all EIC hardware modules. */ - for (uint32_t i = 0; i < EIC_INST_NUM; i++) { - eics[i]->CTRL.reg |= EIC_CTRL_SWRST; - } - - while (extint_is_syncing()) { - /* Wait for all hardware modules to complete synchronization */ - } - - /* Reset the software module */ -#if EXTINT_CALLBACK_MODE == true - /* Clear callback registration table */ - for (uint8_t j = 0; j < EIC_NUMBER_OF_INTERRUPTS; j++) { - _extint_dev.callbacks[j] = NULL; - } - system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_EIC); -#endif - - /* Enables the driver for further use */ - _extint_enable(); -} - -/** - * \internal - * \brief Enables the External Interrupt driver. - * - * Enables EIC modules. - * Registered callback list will not be affected if callback mode is used. - */ -void _extint_enable(void) -{ - Eic *const eics[EIC_INST_NUM] = EIC_INSTS; - - /* Enable all EIC hardware modules. */ - for (uint32_t i = 0; i < EIC_INST_NUM; i++) { - eics[i]->CTRL.reg |= EIC_CTRL_ENABLE; - } - - while (extint_is_syncing()) { - /* Wait for all hardware modules to complete synchronization */ - } -} - -/** - * \internal - * \brief Disables the External Interrupt driver. - * - * Disables EIC modules that were previously started via a call to - * \ref _extint_enable(). - * Registered callback list will not be affected if callback mode is used. - */ -void _extint_disable(void) -{ - Eic *const eics[EIC_INST_NUM] = EIC_INSTS; - - /* Disable all EIC hardware modules. */ - for (uint32_t i = 0; i < EIC_INST_NUM; i++) { - eics[i]->CTRL.reg &= ~EIC_CTRL_ENABLE; - } - - while (extint_is_syncing()) { - /* Wait for all hardware modules to complete synchronization */ - } -} - -/** - * \brief Initializes an External Interrupt channel configuration structure to defaults. - * - * Initializes a given External Interrupt channel configuration structure to a - * set of known default values. This function should be called on all new - * instances of these configuration structures before being modified by the - * user application. - * - * The default configuration is as follows: - * \li Wake the device if an edge detection occurs whilst in sleep - * \li Input filtering disabled - * \li Internal pull-up enabled - * \li Detect falling edges of a signal - * - * \param[out] config Configuration structure to initialize to default values - */ -void extint_chan_get_config_defaults( - struct extint_chan_conf *const config) -{ - /* Sanity check arguments */ - Assert(config); - - /* Default configuration values */ - config->gpio_pin = 0; - config->gpio_pin_mux = 0; - config->gpio_pin_pull = EXTINT_PULL_UP; - config->wake_if_sleeping = true; - config->filter_input_signal = false; - config->detection_criteria = EXTINT_DETECT_FALLING; -} - -/** - * \brief Writes an External Interrupt channel configuration to the hardware module. - * - * Writes out a given configuration of an External Interrupt channel - * configuration to the hardware module. If the channel is already configured, - * the new configuration will replace the existing one. - * - * \param[in] channel External Interrupt channel to configure - * \param[in] config Configuration settings for the channel - - */ -void extint_chan_set_config( - const uint8_t channel, - const struct extint_chan_conf *const config) -{ - /* Sanity check arguments */ - Assert(config); - /* Sanity check clock requirements */ - Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && - _extint_is_gclk_required(config->filter_input_signal, - config->detection_criteria))); - - struct system_pinmux_config pinmux_config; - system_pinmux_get_config_defaults(&pinmux_config); - - pinmux_config.mux_position = config->gpio_pin_mux; - pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; - pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull; - system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config); - - /* Get a pointer to the module hardware instance */ - Eic *const EIC_module = _extint_get_eic_from_channel(channel); - - uint32_t config_pos = (4 * (channel % 8)); - uint32_t new_config; - - /* Determine the channel's new edge detection configuration */ - new_config = (config->detection_criteria << EIC_CONFIG_SENSE0_Pos); - - /* Enable the hardware signal filter if requested in the config */ - if (config->filter_input_signal) { - new_config |= EIC_CONFIG_FILTEN0; - } - - /* Clear the existing and set the new channel configuration */ - EIC_module->CONFIG[channel / 8].reg - = (EIC_module->CONFIG[channel / 8].reg & - ~((EIC_CONFIG_SENSE0_Msk | EIC_CONFIG_FILTEN0) << config_pos)) | - (new_config << config_pos); - - /* Set the channel's new wake up mode setting */ - if (config->wake_if_sleeping) { - EIC_module->WAKEUP.reg |= (1UL << channel); - } else { - EIC_module->WAKEUP.reg &= ~(1UL << channel); - } -} - -/** - * \brief Writes an External Interrupt NMI channel configuration to the hardware module. - * - * Writes out a given configuration of an External Interrupt NMI channel - * configuration to the hardware module. If the channel is already configured, - * the new configuration will replace the existing one. - * - * \param[in] nmi_channel External Interrupt NMI channel to configure - * \param[in] config Configuration settings for the channel - * - * \returns Status code indicating the success or failure of the request. - * \retval STATUS_OK Configuration succeeded - * \retval STATUS_ERR_PIN_MUX_INVALID An invalid pinmux value was supplied - * \retval STATUS_ERR_BAD_FORMAT An invalid detection mode was requested - */ -enum status_code extint_nmi_set_config( - const uint8_t nmi_channel, - const struct extint_nmi_conf *const config) -{ - /* Sanity check arguments */ - Assert(config); - /* Sanity check clock requirements */ - Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && - _extint_is_gclk_required(config->filter_input_signal, - config->detection_criteria))); - - struct system_pinmux_config pinmux_config; - system_pinmux_get_config_defaults(&pinmux_config); - - pinmux_config.mux_position = config->gpio_pin_mux; - pinmux_config.direction = SYSTEM_PINMUX_PIN_DIR_INPUT; - pinmux_config.input_pull = SYSTEM_PINMUX_PIN_PULL_UP; - pinmux_config.input_pull = (enum system_pinmux_pin_pull)config->gpio_pin_pull; - system_pinmux_pin_set_config(config->gpio_pin, &pinmux_config); - - /* Get a pointer to the module hardware instance */ - Eic *const EIC_module = _extint_get_eic_from_channel(nmi_channel); - - uint32_t new_config; - - /* Determine the NMI's new edge detection configuration */ - new_config = (config->detection_criteria << EIC_NMICTRL_NMISENSE_Pos); - - /* Enable the hardware signal filter if requested in the config */ - if (config->filter_input_signal) { - new_config |= EIC_NMICTRL_NMIFILTEN; - } - - /* Disable EIC and general clock to configure NMI */ - _extint_disable(); - system_gclk_chan_disable(EIC_GCLK_ID); - - EIC_module->NMICTRL.reg = new_config; - - /* Enable the general clock and EIC after configure NMI */ - system_gclk_chan_enable(EIC_GCLK_ID); - _extint_enable(); - - return STATUS_OK; -} - -/** - * \brief Enables an External Interrupt event output. - * - * Enables one or more output events from the External Interrupt module. See - * \ref extint_events "here" for a list of events this module supports. - * - * \note Events cannot be altered while the module is enabled. - * - * \param[in] events Struct containing flags of events to enable - */ -void extint_enable_events( - struct extint_events *const events) -{ - /* Sanity check arguments */ - Assert(events); - - /* Array of available EICs. */ - Eic *const eics[EIC_INST_NUM] = EIC_INSTS; - - /* Update the event control register for each physical EIC instance */ - for (uint32_t i = 0; i < EIC_INST_NUM; i++) { - uint32_t event_mask = 0; - - /* Create an enable mask for the current EIC module */ - for (uint32_t j = 0; j < 32; j++) { - if (events->generate_event_on_detect[(32 * i) + j]) { - event_mask |= (1UL << j); - } - } - - /* Enable the masked events */ - eics[i]->EVCTRL.reg |= event_mask; - } -} - -/** - * \brief Disables an External Interrupt event output. - * - * Disables one or more output events from the External Interrupt module. See - * \ref extint_events "here" for a list of events this module supports. - * - * \note Events cannot be altered while the module is enabled. - * - * \param[in] events Struct containing flags of events to disable - */ -void extint_disable_events( - struct extint_events *const events) -{ - /* Sanity check arguments */ - Assert(events); - - /* Array of available EICs. */ - Eic *const eics[EIC_INST_NUM] = EIC_INSTS; - - /* Update the event control register for each physical EIC instance */ - for (uint32_t i = 0; i < EIC_INST_NUM; i++) { - uint32_t event_mask = 0; - - /* Create a disable mask for the current EIC module */ - for (uint32_t j = 0; j < 32; j++) { - if (events->generate_event_on_detect[(32 * i) + j]) { - event_mask |= (1UL << j); - } - } - - /* Disable the masked events */ - eics[i]->EVCTRL.reg &= ~event_mask; - } -} http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/module_config/conf_extint.h ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/module_config/conf_extint.h b/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/module_config/conf_extint.h deleted file mode 100755 index fd8611e..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/extint/module_config/conf_extint.h +++ /dev/null @@ -1,65 +0,0 @@ -/** - * \file - * - * \brief SAM External Interrupt Driver Configuration Header - * - * Copyright (C) 2013-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ -#ifndef CONF_EXTINT_H_INCLUDED -#define CONF_EXTINT_H_INCLUDED - -/** - * Define which clock type is used to clock EIC peripheral: - * - EXTINT_CLK_GCLK - * - EXTINT_CLK_ULP32K - * - * EXTINT_CLK_ULP32K is available for SAM L21/C21. - */ -#define EXTINT_CLOCK_SELECTION EXTINT_CLK_GCLK - -/** - * Define which GCLK source is used when selecting EXTINT_CLK_GCLK type. - */ -#if (EXTINT_CLOCK_SELECTION == EXTINT_CLK_GCLK) -# define EXTINT_CLOCK_SOURCE GCLK_GENERATOR_0 -#endif - -#endif http://git-wip-us.apache.org/repos/asf/incubator-mynewt-larva/blob/a280628a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.c ---------------------------------------------------------------------- diff --git a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.c b/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.c deleted file mode 100755 index 1f571f9..0000000 --- a/hw/mcu/atmel/samd21xx/src/sam0/drivers/i2s/i2s.c +++ /dev/null @@ -1,750 +0,0 @@ -/** - * \file - * - * \brief SAM I2S - Inter-IC Sound Controller - * - * Copyright (C) 2014-2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * 4. This software may only be redistributed and used in connection with an - * Atmel microcontroller product. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ -/* - * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> - */ - -#include "i2s.h" - -/** - * \brief Initializes a hardware I2S module instance - * - * Enables the clock and initialize the I2S module. - * - * \param[in,out] module_inst Pointer to the software module instance struct - * \param[in] hw Pointer to the TCC hardware module - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The module was initialized successfully - * \retval STATUS_BUSY Hardware module was busy when the - * initialization procedure was attempted - * \retval STATUS_ERR_DENIED Hardware module was already enabled - */ -enum status_code i2s_init( - struct i2s_module *const module_inst, - I2s *hw) -{ - Assert(module_inst); - Assert(hw); - - /* Enable the user interface clock in the PM */ - system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_I2S); - - /* Status check */ - uint32_t ctrla; - ctrla = module_inst->hw->CTRLA.reg; - if (ctrla & I2S_CTRLA_ENABLE) { - if (ctrla & (I2S_CTRLA_SEREN1 | - I2S_CTRLA_SEREN0 | I2S_CTRLA_CKEN1 | I2S_CTRLA_CKEN0)) { - return STATUS_BUSY; - } else { - return STATUS_ERR_DENIED; - } - } - - /* Initialize module */ - module_inst->hw = hw; - - /* Initialize serializers */ -#if I2S_CALLBACK_MODE == true - int i, j; - for (i = 0; i < 2; i ++) { - for (j = 0; j < I2S_SERIALIZER_CALLBACK_N; j ++) { - module_inst->serializer[i].callback[j] = NULL; - } - module_inst->serializer[i].registered_callback_mask = 0; - module_inst->serializer[i].enabled_callback_mask = 0; - - module_inst->serializer[i].job_buffer = NULL; - module_inst->serializer[i].job_status = STATUS_OK; - module_inst->serializer[i].requested_words = 0; - module_inst->serializer[i].transferred_words = 0; - - module_inst->serializer[i].mode = I2S_SERIALIZER_RECEIVE; - module_inst->serializer[i].data_size = I2S_DATA_SIZE_32BIT; - } - - _i2s_instances[0] = module_inst; - - system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_I2S); -#endif - - return STATUS_OK; -} - - -/** - * \brief Configure specified I2S clock unit - * - * Enables the clock and initialize the clock unit, based on the given - * configurations. - * - * \param[in,out] module_inst Pointer to the software module instance struct - * \param[in] clock_unit I2S clock unit to initialize and configure - * \param[in] config Pointer to the I2S clock unit configuration - * options struct - * - * \return Status of the configuration procedure. - * - * \retval STATUS_OK The module was initialized successfully - * \retval STATUS_BUSY Hardware module was busy when the - * configuration procedure was attempted - * \retval STATUS_ERR_DENIED Hardware module was already enabled - * \retval STATUS_ERR_INVALID_ARG Invalid divider value or - * MCK direction setting conflict - */ -enum status_code i2s_clock_unit_set_config( - struct i2s_module *const module_inst, - const enum i2s_clock_unit clock_unit, - const struct i2s_clock_unit_config *config) -{ - Assert(module_inst); - Assert(module_inst->hw); - Assert(clock_unit < I2S_CLOCK_UNIT_N); - Assert(config); - - /* Status check */ - uint32_t ctrla, syncbusy; - syncbusy = module_inst->hw->SYNCBUSY.reg; - ctrla = module_inst->hw->CTRLA.reg; - - /* Busy ? */ - if (syncbusy & (I2S_SYNCBUSY_CKEN0 << clock_unit)) { - return STATUS_BUSY; - } - /* Already enabled ? */ - if (ctrla & (I2S_CTRLA_CKEN0 << clock_unit)) { - return STATUS_ERR_DENIED; - } - /* Parameter check */ - if (config->clock.mck_src && config->clock.mck_out_enable) { - return STATUS_ERR_INVALID_ARG; - } - - /* Initialize Clock Unit */ - uint32_t clkctrl = - (config->clock.mck_out_invert ? I2S_CLKCTRL_MCKOUTINV : 0) | - (config->clock.sck_out_invert ? I2S_CLKCTRL_SCKOUTINV : 0) | - (config->frame.frame_sync.invert_out ? I2S_CLKCTRL_FSOUTINV : 0) | - (config->clock.mck_out_enable ? I2S_CLKCTRL_MCKEN : 0) | - (config->clock.mck_src ? I2S_CLKCTRL_MCKSEL : 0) | - (config->clock.sck_src ? I2S_CLKCTRL_SCKSEL : 0) | - (config->frame.frame_sync.invert_use ? I2S_CLKCTRL_FSINV : 0) | - (config->frame.frame_sync.source ? I2S_CLKCTRL_FSSEL : 0) | - (config->frame.data_delay ? I2S_CLKCTRL_BITDELAY : 0); - - uint8_t div_val = config->clock.mck_out_div; - if ((div_val > 0x21) || (div_val == 0)) { - return STATUS_ERR_INVALID_ARG; - } else { - div_val --; - } - clkctrl |= I2S_CLKCTRL_MCKOUTDIV(div_val); - - div_val = config->clock.sck_div; - if ((div_val > 0x21) || (div_val == 0)) { - return STATUS_ERR_INVALID_ARG; - } else { - div_val --; - } - clkctrl |= I2S_CLKCTRL_MCKDIV(div_val); - - uint8_t number_slots = config->frame.number_slots; - if (number_slots > 8) { - return STATUS_ERR_INVALID_ARG; - } else if (number_slots > 0) { - number_slots --; - } - clkctrl |= - I2S_CLKCTRL_NBSLOTS(number_slots) | - I2S_CLKCTRL_FSWIDTH(config->frame.frame_sync.width) | - I2S_CLKCTRL_SLOTSIZE(config->frame.slot_size); - - /* Write clock unit configurations */ - module_inst->hw->CLKCTRL[clock_unit].reg = clkctrl; - - /* Select general clock source */ - const uint8_t i2s_gclk_ids[2] = {I2S_GCLK_ID_0, I2S_GCLK_ID_1}; - struct system_gclk_chan_config gclk_chan_config; - system_gclk_chan_get_config_defaults(&gclk_chan_config); - gclk_chan_config.source_generator = config->clock.gclk_src; - system_gclk_chan_set_config(i2s_gclk_ids[clock_unit], &gclk_chan_config); - system_gclk_chan_enable(i2s_gclk_ids[clock_unit]); - - /* Initialize pins */ - struct system_pinmux_config pin_config; - system_pinmux_get_config_defaults(&pin_config); - if (config->mck_pin.enable) { - pin_config.mux_position = config->mck_pin.mux; - system_pinmux_pin_set_config(config->mck_pin.gpio, &pin_config); - } - if (config->sck_pin.enable) { - pin_config.mux_position = config->sck_pin.mux; - system_pinmux_pin_set_config(config->sck_pin.gpio, &pin_config); - } - if (config->fs_pin.enable) { - pin_config.mux_position = config->fs_pin.mux; - system_pinmux_pin_set_config(config->fs_pin.gpio, &pin_config); - } - - return STATUS_OK; -} - - -/** - * \brief Configure specified I2S serializer - * - * Enables the clock and initialize the serializer, based on the given - * configurations. - * - * \param[in,out] module_inst Pointer to the software module instance struct - * \param[in] serializer I2S serializer to initialize and configure - * \param[in] config Pointer to the I2S serializer configuration - * options struct - * - * \return Status of the configuration procedure. - * - * \retval STATUS_OK The module was initialized successfully - * \retval STATUS_BUSY Hardware module was busy when the - * configuration procedure was attempted - * \retval STATUS_ERR_DENIED Hardware module was already enabled - */ -enum status_code i2s_serializer_set_config( - struct i2s_module *const module_inst, - const enum i2s_serializer serializer, - const struct i2s_serializer_config *config) -{ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - Assert(config); - - /* Status check */ - uint32_t ctrla, syncbusy; - syncbusy = module_inst->hw->SYNCBUSY.reg; - ctrla = module_inst->hw->CTRLA.reg; - - /* Busy ? */ - if (syncbusy & ((I2S_SYNCBUSY_SEREN0 | I2S_SYNCBUSY_DATA0) << serializer)) { - return STATUS_BUSY; - } - /* Already enabled ? */ - if (ctrla & (I2S_CTRLA_CKEN0 << serializer)) { - return STATUS_ERR_DENIED; - } - - /* Initialize Serializer */ - uint32_t serctrl = - (config->loop_back ? I2S_SERCTRL_RXLOOP : 0) | - (config->dma_usage ? I2S_SERCTRL_DMA : 0) | - (config->mono_mode ? I2S_SERCTRL_MONO : 0) | - (config->disable_data_slot[7] ? I2S_SERCTRL_SLOTDIS7 : 0) | - (config->disable_data_slot[6] ? I2S_SERCTRL_SLOTDIS6 : 0) | - (config->disable_data_slot[5] ? I2S_SERCTRL_SLOTDIS5 : 0) | - (config->disable_data_slot[4] ? I2S_SERCTRL_SLOTDIS4 : 0) | - (config->disable_data_slot[3] ? I2S_SERCTRL_SLOTDIS3 : 0) | - (config->disable_data_slot[2] ? I2S_SERCTRL_SLOTDIS2 : 0) | - (config->disable_data_slot[1] ? I2S_SERCTRL_SLOTDIS1 : 0) | - (config->disable_data_slot[0] ? I2S_SERCTRL_SLOTDIS0 : 0) | - (config->transfer_lsb_first ? I2S_SERCTRL_BITREV : 0) | - (config->data_adjust_left_in_word ? I2S_SERCTRL_WORDADJ : 0) | - (config->data_adjust_left_in_slot ? I2S_SERCTRL_SLOTADJ : 0) | - (config->data_padding ? I2S_SERCTRL_TXSAME : 0); - - if (config->clock_unit < I2S_CLOCK_UNIT_N) { - serctrl |= (config->clock_unit ? I2S_SERCTRL_CLKSEL : 0); - } else { - return STATUS_ERR_INVALID_ARG; - } - - serctrl |= - I2S_SERCTRL_SERMODE(config->mode) | - I2S_SERCTRL_TXDEFAULT(config->line_default_state) | - I2S_SERCTRL_DATASIZE(config->data_size) | - I2S_SERCTRL_EXTEND(config->bit_padding); - - /* Write Serializer configuration */ - module_inst->hw->SERCTRL[serializer].reg = serctrl; - - /* Initialize pins */ - struct system_pinmux_config pin_config; - system_pinmux_get_config_defaults(&pin_config); - if (config->data_pin.enable) { - pin_config.mux_position = config->data_pin.mux; - system_pinmux_pin_set_config(config->data_pin.gpio, &pin_config); - } - - /* Save configure */ - module_inst->serializer[serializer].mode = config->mode; - module_inst->serializer[serializer].data_size = config->data_size; - - return STATUS_OK; -} - - - -/** - * \brief Retrieves the current module status. - * - * Retrieves the status of the module, giving overall state information. - * - * \param[in] module_inst Pointer to the I2S software instance struct - * - * \return Bitmask of \c I2S_STATUS_* flags. - * - * \retval I2S_STATUS_SYNC_BUSY Module is busy synchronization - * \retval I2S_STATUS_TRANSMIT_UNDERRUN(x) Serializer x (0~1) is underrun - * \retval I2S_STATUS_TRANSMIT_READY(x) Serializer x (0~1) is ready to - * transmit new data word - * \retval I2S_STATUS_RECEIVE_OVERRUN(x) Serializer x (0~1) is overrun - * \retval I2S_STATUS_RECEIVE_READY(x) Serializer x (0~1) has data ready to - * read - */ -uint32_t i2s_get_status( - const struct i2s_module *const module_inst) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - uint32_t intflag = module_inst->hw->INTFLAG.reg; - uint32_t status; - if (module_inst->hw->SYNCBUSY.reg) { - status = I2S_STATUS_SYNC_BUSY; - } else { - status = 0; - } - if (intflag & I2S_INTFLAG_TXUR0) { - status |= I2S_STATUS_TRANSMIT_UNDERRUN(0); - } - if (intflag & I2S_INTFLAG_TXUR1) { - status |= I2S_STATUS_TRANSMIT_UNDERRUN(1); - } - if ((intflag & I2S_INTFLAG_TXRDY0) && - !module_inst->hw->SYNCBUSY.bit.DATA0) { - status |= I2S_STATUS_TRANSMIT_READY(0); - } - if ((intflag & I2S_INTFLAG_TXRDY1) && - !module_inst->hw->SYNCBUSY.bit.DATA1) { - status |= I2S_STATUS_TRANSMIT_READY(1); - } - if (intflag & I2S_INTFLAG_RXOR0) { - status |= I2S_STATUS_RECEIVE_OVERRUN(0); - } - if (intflag & I2S_INTFLAG_RXOR1) { - status |= I2S_STATUS_RECEIVE_OVERRUN(1); - } - if (intflag & I2S_INTFLAG_RXRDY0) { - status |= I2S_STATUS_RECEIVE_READY(0); - } - if (intflag & I2S_INTFLAG_RXRDY1) { - status |= I2S_STATUS_RECEIVE_READY(1); - } - return status; -} - -/** - * \brief Clears a module status flags. - * - * Clears the given status flags of the module. - * - * \param[in] module_inst Pointer to the I2S software instance struct - * \param[in] status Bitmask of \c I2S_STATUS_* flags to clear - */ -void i2s_clear_status( - const struct i2s_module *const module_inst, - uint32_t status) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - uint32_t intflag = 0; - - if (status & I2S_STATUS_TRANSMIT_UNDERRUN(0)) { - intflag = I2S_INTFLAG_TXUR0; - } - if (status & I2S_STATUS_TRANSMIT_UNDERRUN(1)) { - intflag = I2S_INTFLAG_TXUR1; - } - if (status & I2S_STATUS_TRANSMIT_READY(0)) { - intflag = I2S_INTFLAG_TXRDY0; - } - if (status & I2S_STATUS_TRANSMIT_READY(1)) { - intflag = I2S_INTFLAG_TXRDY1; - } - if (status & I2S_STATUS_RECEIVE_OVERRUN(0)) { - intflag = I2S_INTFLAG_RXOR0; - } - if (status & I2S_STATUS_RECEIVE_OVERRUN(1)) { - intflag = I2S_INTFLAG_RXOR1; - } - if (status & I2S_STATUS_RECEIVE_READY(0)) { - intflag = I2S_INTFLAG_RXRDY0; - } - if (status & I2S_STATUS_RECEIVE_READY(1)) { - intflag = I2S_INTFLAG_RXRDY1; - } - module_inst->hw->INTFLAG.reg = intflag; -} - -/** - * \brief Enable interrupts on status set - * - * Enable the given status interrupt request from the I2S module. - * - * \param[in] module_inst Pointer to the I2S software instance struct - * \param[in] status Status interrupts to enable - * - * \return Status of enable procedure. - * - * \retval STATUS_OK Interrupt is enabled successfully - * \retval STATUS_ERR_INVALID_ARG Status with no interrupt is passed - */ -enum status_code i2s_enable_status_interrupt( - struct i2s_module *const module_inst, - uint32_t status) -{ - /* Sanity check arguments */ - Assert(module_inst); - - /* No sync busy interrupt */ - if (status & I2S_STATUS_SYNC_BUSY) { - return STATUS_ERR_INVALID_ARG; - } - Assert(module_inst->hw); - - uint32_t intflag = 0; - if (status & I2S_STATUS_TRANSMIT_UNDERRUN(0)) { - intflag = I2S_INTFLAG_TXUR0; - } - if (status & I2S_STATUS_TRANSMIT_UNDERRUN(1)) { - intflag = I2S_INTFLAG_TXUR1; - } - if (status & I2S_STATUS_TRANSMIT_READY(0)) { - intflag = I2S_INTFLAG_TXRDY0; - } - if (status & I2S_STATUS_TRANSMIT_READY(1)) { - intflag = I2S_INTFLAG_TXRDY1; - } - if (status & I2S_STATUS_RECEIVE_OVERRUN(0)) { - intflag = I2S_INTFLAG_RXOR0; - } - if (status & I2S_STATUS_RECEIVE_OVERRUN(1)) { - intflag = I2S_INTFLAG_RXOR1; - } - if (status & I2S_STATUS_RECEIVE_READY(0)) { - intflag = I2S_INTFLAG_RXRDY0; - } - if (status & I2S_STATUS_RECEIVE_READY(1)) { - intflag = I2S_INTFLAG_RXRDY1; - } - module_inst->hw->INTENSET.reg = intflag; - return STATUS_OK; -} - -/** - * \brief Disable interrupts on status set - * - * Disable the given status interrupt request from the I2S module. - * - * \param[in] module_inst Pointer to the I2S software instance struct - * \param[in] status Status interrupts to disable - */ -void i2s_disable_status_interrupt( - struct i2s_module *const module_inst, - uint32_t status) -{ - /* Sanity check arguments */ - Assert(module_inst); - Assert(module_inst->hw); - - uint32_t intflag = 0; - if (status & I2S_STATUS_TRANSMIT_UNDERRUN(0)) { - intflag = I2S_INTFLAG_TXUR0; - } - if (status & I2S_STATUS_TRANSMIT_UNDERRUN(1)) { - intflag = I2S_INTFLAG_TXUR1; - } - if (status & I2S_STATUS_TRANSMIT_READY(0)) { - intflag = I2S_INTFLAG_TXRDY0; - } - if (status & I2S_STATUS_TRANSMIT_READY(1)) { - intflag = I2S_INTFLAG_TXRDY1; - } - if (status & I2S_STATUS_RECEIVE_OVERRUN(0)) { - intflag = I2S_INTFLAG_RXOR0; - } - if (status & I2S_STATUS_RECEIVE_OVERRUN(1)) { - intflag = I2S_INTFLAG_RXOR1; - } - if (status & I2S_STATUS_RECEIVE_READY(0)) { - intflag = I2S_INTFLAG_RXRDY0; - } - if (status & I2S_STATUS_RECEIVE_READY(1)) { - intflag = I2S_INTFLAG_RXRDY1; - } - module_inst->hw->INTENCLR.reg = intflag; -} - - -/** - * \brief Write buffer to the specified Serializer of I2S module - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The serializer to write to - * \param[in] buffer The data buffer to write - * \param[in] size Number of data words to write - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The data was sent successfully - * \retval STATUS_ERR_DENIED The module or serializer is disabled - * \retval STATUS_ERR_INVALID_ARG An invalid buffer pointer was supplied - */ -enum status_code i2s_serializer_write_buffer_wait( - const struct i2s_module *const module_inst, - enum i2s_serializer serializer, - void *buffer, uint32_t size) -{ - Assert(module_inst); - Assert(module_inst->hw); - Assert(serializer < I2S_SERIALIZER_N); - Assert(buffer); - - if (size == 0) { - return STATUS_OK; - } - - uint8_t data_size = 1; /* number of bytes */ - struct i2s_serializer_module *data_module = (struct i2s_serializer_module *) - &module_inst->serializer[serializer]; - - /* Check buffer */ - switch(data_module->data_size) { - case I2S_DATA_SIZE_32BIT: - case I2S_DATA_SIZE_24BIT: - case I2S_DATA_SIZE_20BIT: - case I2S_DATA_SIZE_18BIT: - if ((uint32_t)buffer & 0x3) { - return STATUS_ERR_INVALID_ARG; - } - data_size = 4; - break; - case I2S_DATA_SIZE_16BIT: - case I2S_DATA_SIZE_16BIT_COMPACT: - if ((uint32_t)buffer & 0x1) { - return STATUS_ERR_INVALID_ARG; - } - data_size = 2; - break; - default: - break; - } - - /* Check status */ - if (!(module_inst->hw->CTRLA.reg & - (I2S_CTRLA_ENABLE | (I2S_CTRLA_SEREN0 << serializer)))) { - return STATUS_ERR_DENIED; - } - - /* Write */ - uint32_t i; - uint32_t sync_bit = I2S_SYNCBUSY_DATA0 << serializer; - uint32_t ready_bit = I2S_INTFLAG_TXRDY0 << serializer; - if (4 == data_size) { - uint32_t *p32 = (uint32_t*)buffer; - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Tx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - module_inst->hw->DATA[serializer].reg = p32[i]; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } else if (2 == data_size) { - uint16_t *p16 = (uint16_t*)buffer; - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Tx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - module_inst->hw->DATA[serializer].reg = p16[i]; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } else { - uint8_t *p8 = (uint8_t*)buffer; - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Tx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - module_inst->hw->DATA[serializer].reg = p8[i]; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } - - return STATUS_OK; -} - -/** - * \brief Read from the specified Serializer of I2S module to a buffer - * - * \param[in] module_inst Pointer to the software module instance struct - * \param[in] serializer The serializer to write to - * \param[in] buffer The buffer to fill read data (NULL to discard) - * \param[in] size Number of data words to read - * - * \return Status of the initialization procedure. - * - * \retval STATUS_OK The data was sent successfully - * \retval STATUS_ERR_DENIED The module or serializer is disabled - * \retval STATUS_ERR_INVALID_ARG An invalid buffer pointer was supplied - */ -enum status_code i2s_serializer_read_buffer_wait( - const struct i2s_module *const module_inst, - enum i2s_serializer serializer, - void *buffer, uint32_t size) -{ - Assert(module_inst); - Assert(module_inst->hw); - - if (size == 0) { - return STATUS_OK; - } - - uint8_t data_size = 1; /* number of bytes */ - struct i2s_serializer_module *data_module = (struct i2s_serializer_module *) - &module_inst->serializer[serializer]; - - /* Check buffer */ - switch(data_module->data_size) { - case I2S_DATA_SIZE_32BIT: - case I2S_DATA_SIZE_24BIT: - case I2S_DATA_SIZE_20BIT: - case I2S_DATA_SIZE_18BIT: - if ((uint32_t)buffer & 0x3) { - return STATUS_ERR_INVALID_ARG; - } - data_size = 4; - break; - case I2S_DATA_SIZE_16BIT: - case I2S_DATA_SIZE_16BIT_COMPACT: - if ((uint32_t)buffer & 0x1) { - return STATUS_ERR_INVALID_ARG; - } - data_size = 2; - break; - default: - break; - } - - /* Check status */ - if (!(module_inst->hw->CTRLA.reg & - (I2S_CTRLA_ENABLE | (I2S_CTRLA_SEREN0 << serializer)))) { - return STATUS_ERR_DENIED; - } - - /* Read */ - uint32_t i; - uint32_t sync_bit = I2S_SYNCBUSY_DATA0 << serializer; - uint32_t ready_bit = I2S_INTFLAG_RXRDY0 << serializer; - if (buffer == NULL) { - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Rx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - module_inst->hw->DATA[serializer].reg; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } - else if (4 == data_size) { - uint32_t *p32 = (uint32_t*)buffer; - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Rx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - p32[i] = module_inst->hw->DATA[serializer].reg; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } else if (2 == data_size) { - uint16_t *p16 = (uint16_t*)buffer; - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Rx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - p16[i] = module_inst->hw->DATA[serializer].reg; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } else { - uint8_t *p8 = (uint8_t*)buffer; - for (i = 0; i < size; i ++) { - while(!(module_inst->hw->INTFLAG.reg & ready_bit)) { - /* Wait Tx ready */ - } - while(module_inst->hw->SYNCBUSY.reg & sync_bit) { - /* Wait Sync */ - } - p8[i] = module_inst->hw->DATA[serializer].reg; - module_inst->hw->INTFLAG.reg = ready_bit; - } - } - - return STATUS_OK; -}