You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
249 lines
6.2 KiB
249 lines
6.2 KiB
4 years ago
|
|
||
|
/**
|
||
|
* \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);
|
||
|
}
|
||
|
}
|