atmel-samd: Add direct write access to the DAC output.
This commit is contained in:
parent
259ae8a39d
commit
16fc045509
@ -48,6 +48,8 @@ INC += $(addprefix -Iasf/sam0/,\
|
||||
drivers/port \
|
||||
drivers/system \
|
||||
drivers/adc/adc_sam_d_r \
|
||||
drivers/dac \
|
||||
drivers/dac/dac_sam_d_c \
|
||||
drivers/system/clock \
|
||||
drivers/system/clock/clock_samd21_r21_da \
|
||||
drivers/system/interrupt \
|
||||
@ -93,12 +95,13 @@ endif
|
||||
|
||||
|
||||
SRC_ASF = $(addprefix asf/sam0/,\
|
||||
drivers/adc/adc_sam_d_r/adc.c \
|
||||
drivers/dac/dac_sam_d_c/dac.c \
|
||||
drivers/port/port.c \
|
||||
drivers/sercom/sercom.c \
|
||||
drivers/sercom/sercom_interrupt.c \
|
||||
drivers/sercom/usart/usart.c \
|
||||
drivers/sercom/usart/usart_interrupt.c \
|
||||
drivers/adc/adc_sam_d_r/adc.c \
|
||||
drivers/system/clock/clock_samd21_r21_da/clock.c \
|
||||
drivers/system/clock/clock_samd21_r21_da/gclk.c \
|
||||
drivers/system/interrupt/system_interrupt.c \
|
||||
@ -114,6 +117,7 @@ SRC_C = \
|
||||
main.c \
|
||||
modmachine.c \
|
||||
modutime.c \
|
||||
mpdac.c \
|
||||
mphalport.c \
|
||||
pin.c \
|
||||
pin_named_pins.c \
|
||||
|
207
atmel-samd/asf/sam0/drivers/dac/dac.h
Normal file
207
atmel-samd/asf/sam0/drivers/dac/dac.h
Normal file
@ -0,0 +1,207 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Peripheral Digital-to-Analog Converter 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 DAC_H_INCLUDED
|
||||
#define DAC_H_INCLUDED
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <compiler.h>
|
||||
#include <clock.h>
|
||||
#include <gclk.h>
|
||||
|
||||
/**
|
||||
* \addtogroup asfdoc_sam0_dac_group
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Define DAC features set according to different device families.
|
||||
* @{
|
||||
*/
|
||||
#if (SAMD21 || SAMD10 || SAMD11 || SAMDA1)
|
||||
# define FEATURE_DAC_DATABUF_WRITE_PROTECTION
|
||||
#endif
|
||||
/**@}*/
|
||||
|
||||
#ifndef DAC_TIMEOUT
|
||||
# define DAC_TIMEOUT 0xFFFF
|
||||
#endif
|
||||
|
||||
#if DAC_CALLBACK_MODE == true
|
||||
# include <system_interrupt.h>
|
||||
|
||||
/** Forward definition of the device instance. */
|
||||
struct dac_module;
|
||||
|
||||
#if !defined(__DOXYGEN__)
|
||||
extern struct dac_module *_dac_instances[DAC_INST_NUM];
|
||||
#endif
|
||||
|
||||
/** Type definition for a DAC module callback function. */
|
||||
typedef void (*dac_callback_t)(uint8_t channel);
|
||||
|
||||
/** Enum for the possible callback types for the DAC module. */
|
||||
enum dac_callback {
|
||||
/** Callback type for when a DAC channel data empty condition occurs
|
||||
* (requires event triggered mode) */
|
||||
DAC_CALLBACK_DATA_EMPTY,
|
||||
|
||||
/** Callback type for when a DAC channel data underrun condition occurs
|
||||
* (requires event triggered mode) */
|
||||
DAC_CALLBACK_DATA_UNDERRUN,
|
||||
|
||||
/** Callback type for when a DAC channel write buffer job complete (requires
|
||||
* event triggered mode) */
|
||||
DAC_CALLBACK_TRANSFER_COMPLETE,
|
||||
#if !defined(__DOXYGEN__)
|
||||
DAC_CALLBACK_N,
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#include <dac_feature.h>
|
||||
|
||||
/**
|
||||
* \name Configuration and Initialization
|
||||
* @{
|
||||
*/
|
||||
|
||||
bool dac_is_syncing(
|
||||
struct dac_module *const dev_inst);
|
||||
|
||||
void dac_get_config_defaults(
|
||||
struct dac_config *const config);
|
||||
|
||||
enum status_code dac_init(
|
||||
struct dac_module *const dev_inst,
|
||||
Dac *const module,
|
||||
struct dac_config *const config);
|
||||
|
||||
void dac_reset(
|
||||
struct dac_module *const dev_inst);
|
||||
|
||||
void dac_enable(
|
||||
struct dac_module *const dev_inst);
|
||||
|
||||
void dac_disable(
|
||||
struct dac_module *const dev_inst);
|
||||
|
||||
void dac_enable_events(
|
||||
struct dac_module *const module_inst,
|
||||
struct dac_events *const events);
|
||||
|
||||
void dac_disable_events(
|
||||
struct dac_module *const module_inst,
|
||||
struct dac_events *const events);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \name Configuration and Initialization (Channel)
|
||||
* @{
|
||||
*/
|
||||
|
||||
void dac_chan_get_config_defaults(
|
||||
struct dac_chan_config *const config);
|
||||
|
||||
void dac_chan_set_config(
|
||||
struct dac_module *const dev_inst,
|
||||
const enum dac_channel channel,
|
||||
struct dac_chan_config *const config);
|
||||
|
||||
void dac_chan_enable(
|
||||
struct dac_module *const dev_inst,
|
||||
enum dac_channel channel);
|
||||
|
||||
void dac_chan_disable(
|
||||
struct dac_module *const dev_inst,
|
||||
enum dac_channel channel);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \name Channel Data Management
|
||||
* @{
|
||||
*/
|
||||
|
||||
enum status_code dac_chan_write(
|
||||
struct dac_module *const dev_inst,
|
||||
enum dac_channel channel,
|
||||
const uint16_t data);
|
||||
|
||||
enum status_code dac_chan_write_buffer_wait(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel,
|
||||
uint16_t *buffer,
|
||||
uint32_t length);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \name Status Management
|
||||
* @{
|
||||
*/
|
||||
uint32_t dac_get_status(
|
||||
struct dac_module *const module_inst);
|
||||
void dac_clear_status(
|
||||
struct dac_module *const module_inst,
|
||||
uint32_t status_flags);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
|
||||
|
||||
#endif /* DAC_H_INCLUDED */
|
119
atmel-samd/asf/sam0/drivers/dac/dac_callback.h
Normal file
119
atmel-samd/asf/sam0/drivers/dac/dac_callback.h
Normal file
@ -0,0 +1,119 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Digital-to-Analog Interrupt Driver
|
||||
*
|
||||
* 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 DAC_CALLBACK_H_INCLUDED
|
||||
#define DAC_CALLBACK_H_INCLUDED
|
||||
|
||||
#include <compiler.h>
|
||||
#include "dac.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \addtogroup asfdoc_sam0_dac_group
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \name Callback Configuration and Initialization
|
||||
* @{
|
||||
*/
|
||||
enum status_code dac_chan_write_buffer_job(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
uint16_t *buffer,
|
||||
uint32_t buffer_size);
|
||||
|
||||
enum status_code dac_chan_write_job(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
uint16_t data);
|
||||
|
||||
enum status_code dac_register_callback(
|
||||
struct dac_module *const module,
|
||||
const enum dac_channel channel,
|
||||
const dac_callback_t callback,
|
||||
const enum dac_callback type);
|
||||
|
||||
enum status_code dac_unregister_callback(
|
||||
struct dac_module *const module,
|
||||
const enum dac_channel channel,
|
||||
const enum dac_callback type);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** \name Callback Enabling and Disabling (Channel)
|
||||
* @{
|
||||
*/
|
||||
|
||||
enum status_code dac_chan_enable_callback(
|
||||
struct dac_module *const module,
|
||||
const enum dac_channel channel,
|
||||
const enum dac_callback type);
|
||||
|
||||
enum status_code dac_chan_disable_callback(
|
||||
struct dac_module *const module,
|
||||
const enum dac_channel channel,
|
||||
const enum dac_callback type);
|
||||
|
||||
enum status_code dac_chan_get_job_status(
|
||||
struct dac_module *module_inst,
|
||||
const enum dac_channel channel);
|
||||
|
||||
void dac_chan_abort_job(
|
||||
struct dac_module *module_inst,
|
||||
const enum dac_channel channel);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
779
atmel-samd/asf/sam0/drivers/dac/dac_sam_d_c/dac.c
Normal file
779
atmel-samd/asf/sam0/drivers/dac/dac_sam_d_c/dac.c
Normal file
@ -0,0 +1,779 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Peripheral Digital-to-Analog Converter Driver
|
||||
*
|
||||
* Copyright (C) 2012-2016 Atmel Corporation. All rights reserved.
|
||||
*
|
||||
* \asf_license_start
|
||||
*
|
||||
* \page License
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* 3. The name of Atmel may not be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* 4. This software may only be redistributed and used in connection with an
|
||||
* Atmel microcontroller product.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
|
||||
* EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* \asf_license_stop
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
|
||||
*/
|
||||
#include "dac.h"
|
||||
#include <system.h>
|
||||
#include <pinmux.h>
|
||||
|
||||
/**
|
||||
* \internal Writes a DAC configuration to the hardware module.
|
||||
*
|
||||
* Writes out a given configuration to the hardware module.
|
||||
*
|
||||
* \param[out] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] config Pointer to the configuration struct
|
||||
*
|
||||
*/
|
||||
static void _dac_set_config(
|
||||
struct dac_module *const module_inst,
|
||||
struct dac_config *const config)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(config);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Set selected DAC output to be enabled when enabling the module */
|
||||
module_inst->output = config->output;
|
||||
module_inst->start_on_event = false;
|
||||
|
||||
uint32_t new_ctrla = 0;
|
||||
uint32_t new_ctrlb = 0;
|
||||
|
||||
/* Enable DAC in standby sleep mode if configured */
|
||||
if (config->run_in_standby) {
|
||||
new_ctrla |= DAC_CTRLA_RUNSTDBY;
|
||||
}
|
||||
|
||||
/* Set reference voltage */
|
||||
new_ctrlb |= config->reference;
|
||||
|
||||
/* Left adjust data if configured */
|
||||
if (config->left_adjust) {
|
||||
new_ctrlb |= DAC_CTRLB_LEFTADJ;
|
||||
}
|
||||
|
||||
#ifdef FEATURE_DAC_DATABUF_WRITE_PROTECTION
|
||||
/* Bypass DATABUF write protection if configured */
|
||||
if (config->databuf_protection_bypass) {
|
||||
new_ctrlb |= DAC_CTRLB_BDWP;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Voltage pump disable if configured */
|
||||
if (config->voltage_pump_disable) {
|
||||
new_ctrlb |= DAC_CTRLB_VPD;
|
||||
}
|
||||
|
||||
/* Apply the new configuration to the hardware module */
|
||||
dac_module->CTRLA.reg = new_ctrla;
|
||||
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
/* Wait until the synchronization is complete */
|
||||
}
|
||||
|
||||
dac_module->CTRLB.reg = new_ctrlb;
|
||||
}
|
||||
|
||||
/**
|
||||
* \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.
|
||||
*
|
||||
* \param[in] dev_inst Pointer to the DAC software instance struct
|
||||
*
|
||||
* \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
|
||||
*/
|
||||
bool dac_is_syncing(
|
||||
struct dac_module *const dev_inst)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(dev_inst);
|
||||
|
||||
Dac *const dac_module = dev_inst->hw;
|
||||
|
||||
#if (SAMC21)
|
||||
if (dac_module->SYNCBUSY.reg) {
|
||||
#else
|
||||
if (dac_module->STATUS.reg & DAC_STATUS_SYNCBUSY) {
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initializes a DAC configuration structure to defaults.
|
||||
*
|
||||
* Initializes a given DAC configuration structure to a set of
|
||||
* known default values. This function should be called on any new
|
||||
* instance of the configuration structures before being modified by the
|
||||
* user application.
|
||||
*
|
||||
* The default configuration is as follows:
|
||||
* \li 1V from internal bandgap reference
|
||||
* \li Drive the DAC output to the VOUT pin
|
||||
* \li Right adjust data
|
||||
* \li GCLK generator 0 (GCLK main) clock source
|
||||
* \li The output buffer is disabled when the chip enters STANDBY sleep
|
||||
* mode
|
||||
*
|
||||
* \param[out] config Configuration structure to initialize to default values
|
||||
*/
|
||||
void dac_get_config_defaults(
|
||||
struct dac_config *const config)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(config);
|
||||
|
||||
/* Default configuration values */
|
||||
config->reference = DAC_REFERENCE_INT1V;
|
||||
config->output = DAC_OUTPUT_EXTERNAL;
|
||||
config->left_adjust = false;
|
||||
#ifdef FEATURE_DAC_DATABUF_WRITE_PROTECTION
|
||||
config->databuf_protection_bypass = false;
|
||||
#endif
|
||||
config->voltage_pump_disable = false;
|
||||
config->clock_source = GCLK_GENERATOR_0;
|
||||
config->run_in_standby = false;
|
||||
#if (SAMC21)
|
||||
config->dither_mode = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initialize the DAC device struct.
|
||||
*
|
||||
* Use this function to initialize the Digital to Analog Converter. Resets the
|
||||
* underlying hardware module and configures it.
|
||||
*
|
||||
* \note The DAC channel must be configured separately.
|
||||
*
|
||||
* \param[out] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] module Pointer to the DAC module instance
|
||||
* \param[in] config Pointer to the config struct, created by the user
|
||||
* application
|
||||
*
|
||||
* \return Status of initialization.
|
||||
* \retval STATUS_OK Module initiated correctly
|
||||
* \retval STATUS_ERR_DENIED If module is enabled
|
||||
* \retval STATUS_BUSY If module is busy resetting
|
||||
*/
|
||||
enum status_code dac_init(
|
||||
struct dac_module *const module_inst,
|
||||
Dac *const module,
|
||||
struct dac_config *const config)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module);
|
||||
Assert(config);
|
||||
|
||||
/* Initialize device instance */
|
||||
module_inst->hw = module;
|
||||
|
||||
/* Turn on the digital interface clock */
|
||||
#if (SAMC21)
|
||||
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, MCLK_APBCMASK_DAC);
|
||||
#else
|
||||
system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_DAC);
|
||||
#endif
|
||||
|
||||
/* Check if module is enabled. */
|
||||
if (module->CTRLA.reg & DAC_CTRLA_ENABLE) {
|
||||
return STATUS_ERR_DENIED;
|
||||
}
|
||||
|
||||
/* Check if reset is in progress. */
|
||||
if (module->CTRLA.reg & DAC_CTRLA_SWRST) {
|
||||
return STATUS_BUSY;
|
||||
}
|
||||
|
||||
/* Configure GCLK channel and enable clock */
|
||||
struct system_gclk_chan_config gclk_chan_conf;
|
||||
system_gclk_chan_get_config_defaults(&gclk_chan_conf);
|
||||
gclk_chan_conf.source_generator = config->clock_source;
|
||||
system_gclk_chan_set_config(DAC_GCLK_ID, &gclk_chan_conf);
|
||||
system_gclk_chan_enable(DAC_GCLK_ID);
|
||||
|
||||
/* MUX the DAC VOUT pin */
|
||||
struct system_pinmux_config pin_conf;
|
||||
system_pinmux_get_config_defaults(&pin_conf);
|
||||
|
||||
/* Set up the DAC VOUT pin */
|
||||
pin_conf.mux_position = MUX_PA02B_DAC_VOUT;
|
||||
pin_conf.direction = SYSTEM_PINMUX_PIN_DIR_INPUT;
|
||||
pin_conf.input_pull = SYSTEM_PINMUX_PIN_PULL_NONE;
|
||||
system_pinmux_pin_set_config(PIN_PA02B_DAC_VOUT, &pin_conf);
|
||||
|
||||
/* Write configuration to module */
|
||||
_dac_set_config(module_inst, config);
|
||||
|
||||
/* Store reference selection for later use */
|
||||
module_inst->reference = config->reference;
|
||||
|
||||
#if DAC_CALLBACK_MODE == true
|
||||
for (uint8_t i = 0; i < DAC_CALLBACK_N; i++) {
|
||||
module_inst->callback[i] = NULL;
|
||||
};
|
||||
|
||||
_dac_instances[0] = module_inst;
|
||||
#endif
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Resets the DAC module.
|
||||
*
|
||||
* This function will reset the DAC module to its power on default values and
|
||||
* disable it.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
*/
|
||||
void dac_reset(
|
||||
struct dac_module *const module_inst)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
/* Wait until the synchronization is complete */
|
||||
}
|
||||
|
||||
/* Software reset the module */
|
||||
dac_module->CTRLA.reg |= DAC_CTRLA_SWRST;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable the DAC module.
|
||||
*
|
||||
* Enables the DAC interface and the selected output. If any internal reference
|
||||
* is selected it will be enabled.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
*
|
||||
*/
|
||||
void dac_enable(
|
||||
struct dac_module *const module_inst)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Enable selected output */
|
||||
dac_module->CTRLB.reg |= module_inst->output;
|
||||
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
/* Wait until the synchronization is complete */
|
||||
}
|
||||
|
||||
/* Enable the module */
|
||||
dac_module->CTRLA.reg |= DAC_CTRLA_ENABLE;
|
||||
|
||||
/* Enable internal bandgap reference if selected in the configuration */
|
||||
if (module_inst->reference == DAC_REFERENCE_INT1V) {
|
||||
#if (SAMC21)
|
||||
system_voltage_reference_enable(SYSTEM_VOLTAGE_REFERENCE_OUTPUT);
|
||||
}
|
||||
|
||||
if(dac_module->CTRLA.reg & DAC_CTRLA_ENABLE) {
|
||||
while(! (dac_module->STATUS.reg & DAC_STATUS_READY)) {
|
||||
};
|
||||
}
|
||||
#else
|
||||
system_voltage_reference_enable(SYSTEM_VOLTAGE_REFERENCE_BANDGAP);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable the DAC module.
|
||||
*
|
||||
* Disables the DAC interface and the output buffer.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
*
|
||||
*/
|
||||
void dac_disable(
|
||||
struct dac_module *const module_inst)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Wait until the synchronization is complete */
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
};
|
||||
|
||||
/* Disbale interrupt */
|
||||
dac_module->INTENCLR.reg = DAC_INTENCLR_MASK;
|
||||
/* Clear interrupt flag */
|
||||
dac_module->INTFLAG.reg = DAC_INTFLAG_MASK;
|
||||
|
||||
/* Disable DAC */
|
||||
dac_module->CTRLA.reg &= ~DAC_CTRLA_ENABLE;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enables a DAC event input or output.
|
||||
*
|
||||
* Enables one or more input or output events to or from the DAC module. See
|
||||
* \ref dac_events "dac_events" for a list of events this module supports.
|
||||
*
|
||||
* \note Events cannot be altered while the module is enabled.
|
||||
*
|
||||
* \param[in] module_inst Software instance for the DAC peripheral
|
||||
* \param[in] events Struct containing flags of events to enable
|
||||
*/
|
||||
void dac_enable_events(
|
||||
struct dac_module *const module_inst,
|
||||
struct dac_events *const events)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
Assert(events);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
uint32_t event_mask = 0;
|
||||
|
||||
#if(SAMC21)
|
||||
/* Configure Enable Inversion of input event */
|
||||
if (events->generate_event_on_chan_falling_edge) {
|
||||
event_mask |= DAC_EVCTRL_INVEI;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Configure Buffer Empty event */
|
||||
if (events->generate_event_on_buffer_empty) {
|
||||
event_mask |= DAC_EVCTRL_EMPTYEO;
|
||||
}
|
||||
|
||||
/* Configure Conversion Start event */
|
||||
if (events->on_event_start_conversion) {
|
||||
event_mask |= DAC_EVCTRL_STARTEI;
|
||||
module_inst->start_on_event = true;
|
||||
}
|
||||
|
||||
dac_module->EVCTRL.reg |= event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disables a DAC event input or output.
|
||||
*
|
||||
* Disables one or more input or output events to or from the DAC module. See
|
||||
* \ref dac_events "dac_events" for a list of events this module supports.
|
||||
*
|
||||
* \note Events cannot be altered while the module is enabled.
|
||||
*
|
||||
* \param[in] module_inst Software instance for the DAC peripheral
|
||||
* \param[in] events Struct containing flags of events to disable
|
||||
*/
|
||||
void dac_disable_events(
|
||||
struct dac_module *const module_inst,
|
||||
struct dac_events *const events)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
Assert(events);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
uint32_t event_mask = 0;
|
||||
|
||||
/* Configure Buffer Empty event */
|
||||
if (events->generate_event_on_buffer_empty) {
|
||||
event_mask |= DAC_EVCTRL_EMPTYEO;
|
||||
}
|
||||
|
||||
/* Configure Conversion Start event */
|
||||
if (events->on_event_start_conversion) {
|
||||
event_mask |= DAC_EVCTRL_STARTEI;
|
||||
module_inst->start_on_event = false;
|
||||
}
|
||||
|
||||
dac_module->EVCTRL.reg &= ~event_mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Initializes a DAC channel configuration structure to defaults.
|
||||
*
|
||||
* Initializes a given DAC channel configuration structure to a set of
|
||||
* known default values. This function should be called on any new
|
||||
* instance of the configuration structures before being modified by the
|
||||
* user application.
|
||||
*
|
||||
* The default configuration is as follows:
|
||||
* \li Start Conversion Event Input enabled
|
||||
* \li Start Data Buffer Empty Event Output disabled
|
||||
*
|
||||
* \param[out] config Configuration structure to initialize to default values
|
||||
*/
|
||||
void dac_chan_get_config_defaults(
|
||||
struct dac_chan_config *const config)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(config);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Writes a DAC channel configuration to the hardware module.
|
||||
*
|
||||
* Writes a given channel configuration to the hardware module.
|
||||
*
|
||||
* \note The DAC device instance structure must be initialized before calling
|
||||
* this function.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel Channel to configure
|
||||
* \param[in] config Pointer to the configuration struct
|
||||
*
|
||||
*/
|
||||
void dac_chan_set_config(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
struct dac_chan_config *const config)
|
||||
{
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable a DAC channel.
|
||||
*
|
||||
* Enables the selected DAC channel.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel Channel to enable
|
||||
*
|
||||
*/
|
||||
void dac_chan_enable(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel)
|
||||
{
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable a DAC channel.
|
||||
*
|
||||
* Disables the selected DAC channel.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel Channel to disable
|
||||
*
|
||||
*/
|
||||
void dac_chan_disable(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel)
|
||||
{
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enable the output buffer.
|
||||
*
|
||||
* Enables the output buffer and drives the DAC output to the VOUT pin.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel DAC channel to alter
|
||||
*/
|
||||
void dac_chan_enable_output_buffer(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Enable output buffer */
|
||||
dac_module->CTRLB.reg |= DAC_OUTPUT_EXTERNAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disable the output buffer.
|
||||
*
|
||||
* Disables the output buffer.
|
||||
*
|
||||
* \note The output buffer(s) should be disabled when a channel's output is not
|
||||
* currently needed, as it will draw current even if the system is in
|
||||
* sleep mode.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel DAC channel to alter
|
||||
*/
|
||||
void dac_chan_disable_output_buffer(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel)
|
||||
{
|
||||
/* Sanity check arguments*/
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Disable output buffer */
|
||||
dac_module->CTRLB.reg &= ~DAC_OUTPUT_EXTERNAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write to the DAC.
|
||||
*
|
||||
* This function writes to the DATA or DATABUF register.
|
||||
* If the conversion is not event-triggered, the data will be written to
|
||||
* the DATA register and the conversion will start.
|
||||
* If the conversion is event-triggered, the data will be written to DATABUF
|
||||
* and transferred to the DATA register and converted when a Start Conversion
|
||||
* Event is issued.
|
||||
* Conversion data must be right or left adjusted according to configuration
|
||||
* settings.
|
||||
* \note To be event triggered, the enable_start_on_event must be
|
||||
* enabled in the configuration.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software device struct
|
||||
* \param[in] channel DAC channel to write to
|
||||
* \param[in] data Conversion data
|
||||
*
|
||||
* \return Status of the operation.
|
||||
* \retval STATUS_OK If the data was written
|
||||
*/
|
||||
enum status_code dac_chan_write(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel,
|
||||
const uint16_t data)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Wait until the synchronization is complete */
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
};
|
||||
|
||||
if (module_inst->start_on_event) {
|
||||
/* Write the new value to the buffered DAC data register */
|
||||
dac_module->DATABUF.reg = data;
|
||||
} else {
|
||||
/* Write the new value to the DAC data register */
|
||||
dac_module->DATA.reg = data;
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Write to the DAC.
|
||||
*
|
||||
* This function converts a specific number of digital data.
|
||||
* The conversion should be event-triggered, the data will be written to DATABUF
|
||||
* and transferred to the DATA register and converted when a Start Conversion
|
||||
* Event is issued.
|
||||
* Conversion data must be right or left adjusted according to configuration
|
||||
* settings.
|
||||
* \note To be event triggered, the enable_start_on_event must be
|
||||
* enabled in the configuration.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software device struct
|
||||
* \param[in] channel DAC channel to write to
|
||||
* \param[in] buffer Pointer to the digital data write buffer to be converted
|
||||
* \param[in] length Length of the write buffer
|
||||
*
|
||||
* \return Status of the operation.
|
||||
* \retval STATUS_OK If the data was written or no data conversion required
|
||||
* \retval STATUS_ERR_UNSUPPORTED_DEV The DAC is not configured as using event trigger
|
||||
* \retval STATUS_BUSY The DAC is busy to convert
|
||||
*/
|
||||
enum status_code dac_chan_write_buffer_wait(
|
||||
struct dac_module *const module_inst,
|
||||
enum dac_channel channel,
|
||||
uint16_t *buffer,
|
||||
uint32_t length)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
/* No channel support yet */
|
||||
UNUSED(channel);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* Wait until the synchronization is complete */
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
};
|
||||
|
||||
/* Zero length request */
|
||||
if (length == 0) {
|
||||
/* No data to be converted */
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
#if DAC_CALLBACK_MODE == true
|
||||
/* Check if busy */
|
||||
if (module_inst->job_status == STATUS_BUSY) {
|
||||
return STATUS_BUSY;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Only support event triggered conversion */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
/* Blocks while buffer is being transferred */
|
||||
while (length--) {
|
||||
/* Convert one data */
|
||||
dac_chan_write(module_inst, channel, buffer[length]);
|
||||
|
||||
/* Wait until Transmit is complete or timeout */
|
||||
for (uint32_t i = 0; i <= DAC_TIMEOUT; i++) {
|
||||
if (dac_module->INTFLAG.reg & DAC_INTFLAG_EMPTY) {
|
||||
break;
|
||||
} else if (i == DAC_TIMEOUT) {
|
||||
return STATUS_ERR_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Retrieves the current module status
|
||||
*
|
||||
* Checks the status of the module and returns it as a bitmask of status
|
||||
* flags.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software device struct
|
||||
*
|
||||
* \return Bitmask of status flags.
|
||||
*
|
||||
* \retval DAC_STATUS_CHANNEL_0_EMPTY Data has been transferred from DATABUF
|
||||
* to DATA by a start conversion event
|
||||
* and DATABUF is ready for new data
|
||||
* \retval DAC_STATUS_CHANNEL_0_UNDERRUN A start conversion event has occurred
|
||||
* when DATABUF is empty
|
||||
*
|
||||
*/
|
||||
uint32_t dac_get_status(
|
||||
struct dac_module *const module_inst)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
uint8_t intflags = dac_module->INTFLAG.reg;
|
||||
uint32_t status_flags = 0;
|
||||
|
||||
if (intflags & DAC_INTFLAG_EMPTY) {
|
||||
status_flags |= DAC_STATUS_CHANNEL_0_EMPTY;
|
||||
}
|
||||
|
||||
if (intflags & DAC_INTFLAG_UNDERRUN) {
|
||||
status_flags |= DAC_STATUS_CHANNEL_0_UNDERRUN;
|
||||
}
|
||||
|
||||
return status_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Clears a module status flag
|
||||
*
|
||||
* Clears the given status flag of the module.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software device struct
|
||||
* \param[in] status_flags Bit mask of status flags to clear
|
||||
*
|
||||
*/
|
||||
void dac_clear_status(
|
||||
struct dac_module *const module_inst,
|
||||
uint32_t status_flags)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
uint32_t intflags = 0;
|
||||
|
||||
if (status_flags & DAC_STATUS_CHANNEL_0_EMPTY) {
|
||||
intflags |= DAC_INTFLAG_EMPTY;
|
||||
}
|
||||
|
||||
if (status_flags & DAC_STATUS_CHANNEL_0_UNDERRUN) {
|
||||
intflags |= DAC_INTFLAG_UNDERRUN;
|
||||
}
|
||||
|
||||
dac_module->INTFLAG.reg = intflags;
|
||||
}
|
435
atmel-samd/asf/sam0/drivers/dac/dac_sam_d_c/dac_callback.c
Normal file
435
atmel-samd/asf/sam0/drivers/dac/dac_sam_d_c/dac_callback.c
Normal file
@ -0,0 +1,435 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Digital-to-Analog Interrupt Driver
|
||||
*
|
||||
* 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>
|
||||
*/
|
||||
#include "dac.h"
|
||||
#include "dac_callback.h"
|
||||
|
||||
struct dac_module *_dac_instances[DAC_INST_NUM];
|
||||
|
||||
/**
|
||||
* \brief Convert a specific number digital data to analog through DAC.
|
||||
*
|
||||
* This function will perform a conversion of specific number of digital data.
|
||||
* The conversion should be event-triggered, the data will be written to DATABUF
|
||||
* and transferred to the DATA register and converted when a Start Conversion
|
||||
* Event is issued.
|
||||
* Conversion data must be right or left adjusted according to configuration
|
||||
* settings.
|
||||
* \note To be event triggered, the enable_start_on_event must be
|
||||
* enabled in the configuration.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software device struct
|
||||
* \param[in] channel DAC channel to write to
|
||||
* \param[in] buffer Pointer to the digital data write buffer to be converted
|
||||
* \param[in] length Size of the write buffer
|
||||
*
|
||||
* \return Status of the operation.
|
||||
* \retval STATUS_OK If the data was written
|
||||
* \retval STATUS_ERR_UNSUPPORTED_DEV If a callback that requires event driven
|
||||
* mode was specified with a DAC instance
|
||||
* configured in non-event mode
|
||||
* \retval STATUS_BUSY The DAC is busy to accept new job
|
||||
*/
|
||||
enum status_code dac_chan_write_buffer_job(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
uint16_t *buffer,
|
||||
uint32_t length)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
Assert(buffer);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
Dac *const dac_module = module_inst->hw;
|
||||
|
||||
/* DAC interrupts require it to be driven by events to work, fail if in
|
||||
* unbuffered (polled) mode */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
if(module_inst->remaining_conversions != 0 ||
|
||||
module_inst->job_status == STATUS_BUSY){
|
||||
return STATUS_BUSY;
|
||||
}
|
||||
|
||||
/* Wait until the synchronization is complete */
|
||||
while (dac_is_syncing(module_inst)) {
|
||||
};
|
||||
|
||||
module_inst->job_status = STATUS_BUSY;
|
||||
|
||||
module_inst->remaining_conversions = length;
|
||||
module_inst->job_buffer = buffer;
|
||||
module_inst->transferred_conversions = 0;
|
||||
|
||||
/* Enable interrupt */
|
||||
system_interrupt_enable(SYSTEM_INTERRUPT_MODULE_DAC);
|
||||
dac_module->INTFLAG.reg = DAC_INTFLAG_UNDERRUN | DAC_INTFLAG_EMPTY;
|
||||
dac_module->INTENSET.reg = DAC_INTENSET_UNDERRUN | DAC_INTENSET_EMPTY;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Convert one digital data job.
|
||||
*
|
||||
* This function will perform a conversion of specfic number of digital data.
|
||||
* The conversion is event-triggered, the data will be written to DATABUF
|
||||
* and transferred to the DATA register and converted when a Start Conversion
|
||||
* Event is issued.
|
||||
* Conversion data must be right or left adjusted according to configuration
|
||||
* settings.
|
||||
* \note To be event triggered, the enable_start_on_event must be
|
||||
* enabled in the configuration.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software device struct
|
||||
* \param[in] channel DAC channel to write to
|
||||
* \param[in] data Digital data to be converted
|
||||
*
|
||||
* \return Status of the operation.
|
||||
* \retval STATUS_OK If the data was written
|
||||
* \retval STATUS_ERR_UNSUPPORTED_DEV If a callback that requires event driven
|
||||
* mode was specified with a DAC instance
|
||||
* configured in non-event mode
|
||||
* \retval STATUS_BUSY The DAC is busy to accept new job
|
||||
*/
|
||||
enum status_code dac_chan_write_job(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
uint16_t data)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(module_inst->hw);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
/* DAC interrupts require it to be driven by events to work, fail if in
|
||||
* unbuffered (polled) mode */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
if(module_inst->remaining_conversions != 0 ||
|
||||
module_inst->job_status == STATUS_BUSY){
|
||||
return STATUS_BUSY;
|
||||
}
|
||||
|
||||
dac_chan_write_buffer_job(module_inst, channel, &data, 1);
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Registers an asynchronous callback function with the driver.
|
||||
*
|
||||
* Registers an asynchronous callback with the DAC driver, fired when a callback
|
||||
* condition occurs.
|
||||
*
|
||||
* \param[in,out] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] callback Pointer to the callback function to register
|
||||
* \param[in] channel Logical channel to register callback function
|
||||
* \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_UNSUPPORTED_DEV If a callback that requires event driven
|
||||
* mode was specified with a DAC instance
|
||||
* configured in non-event mode
|
||||
*/
|
||||
enum status_code dac_register_callback(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
const dac_callback_t callback,
|
||||
const enum dac_callback type)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
Assert(callback);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
/* DAC interrupts require it to be driven by events to work, fail if in
|
||||
* unbuffered (polled) mode */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
if ((uint8_t)type < DAC_CALLBACK_N) {
|
||||
module_inst->callback[(uint8_t)type] = callback;
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
return STATUS_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Unregisters an asynchronous callback function with the driver.
|
||||
*
|
||||
* Unregisters an asynchronous callback with the DAC driver, removing it
|
||||
* from the internal callback registration table.
|
||||
*
|
||||
* \param[in,out] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel Logical channel to unregister callback function
|
||||
* \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_UNSUPPORTED_DEV If a callback that requires event driven
|
||||
* mode was specified with a DAC instance
|
||||
* configured in non-event mode
|
||||
*/
|
||||
enum status_code dac_unregister_callback(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
const enum dac_callback type)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
/* DAC interrupts require it to be driven by events to work, fail if in
|
||||
* unbuffered (polled) mode */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
if ((uint8_t)type < DAC_CALLBACK_N) {
|
||||
module_inst->callback[(uint8_t)type] = NULL;
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
return STATUS_ERR_INVALID_ARG;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Enables asynchronous callback generation for a given channel and type.
|
||||
*
|
||||
* Enables asynchronous callbacks for a given logical DAC channel and type. This
|
||||
* must be called before a DAC channel will generate callback events.
|
||||
*
|
||||
* \param[in,out] dac_module Pointer to the DAC software instance struct
|
||||
* \param[in] channel Logical channel to enable callback function
|
||||
* \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_UNSUPPORTED_DEV If a callback that requires event driven
|
||||
* mode was specified with a DAC instance
|
||||
* configured in non-event mode
|
||||
*/
|
||||
enum status_code dac_chan_enable_callback(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
const enum dac_callback type)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
/* DAC interrupts require it to be driven by events to work, fail if in
|
||||
* unbuffered (polled) mode */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
module_inst->callback_enable[type] = true;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Disables asynchronous callback generation for a given channel and type.
|
||||
*
|
||||
* Disables asynchronous callbacks for a given logical DAC channel and type.
|
||||
*
|
||||
* \param[in,out] dac_module Pointer to the DAC software instance struct
|
||||
* \param[in] channel Logical channel to disable callback function
|
||||
* \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_UNSUPPORTED_DEV If a callback that requires event driven
|
||||
* mode was specified with a DAC instance
|
||||
* configured in non-event mode
|
||||
*/
|
||||
enum status_code dac_chan_disable_callback(
|
||||
struct dac_module *const module_inst,
|
||||
const enum dac_channel channel,
|
||||
const enum dac_callback type)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
/* DAC interrupts require it to be driven by events to work, fail if in
|
||||
* unbuffered (polled) mode */
|
||||
if (module_inst->start_on_event == false) {
|
||||
return STATUS_ERR_UNSUPPORTED_DEV;
|
||||
}
|
||||
|
||||
module_inst->callback_enable[type] = false;
|
||||
|
||||
return STATUS_OK;
|
||||
}
|
||||
|
||||
/** \internal
|
||||
* Internal handler for DAC module interrupts.
|
||||
*
|
||||
* \param[in] instance DAC instance number
|
||||
*/
|
||||
static void _dac_interrupt_handler(const uint8_t instance)
|
||||
{
|
||||
struct dac_module *module = _dac_instances[instance];
|
||||
Dac *const dac_hw = module->hw;
|
||||
|
||||
if (dac_hw->INTFLAG.reg & DAC_INTFLAG_UNDERRUN) {
|
||||
dac_hw->INTFLAG.reg = DAC_INTFLAG_UNDERRUN;
|
||||
|
||||
if ((module->callback) &&
|
||||
(module->callback_enable[DAC_CALLBACK_DATA_UNDERRUN])){
|
||||
module->callback[DAC_CALLBACK_DATA_UNDERRUN](0);
|
||||
}
|
||||
}
|
||||
|
||||
if (dac_hw->INTFLAG.reg & DAC_INTFLAG_EMPTY) {
|
||||
dac_hw->INTFLAG.reg = DAC_INTFLAG_EMPTY;
|
||||
|
||||
/* If in a write buffer job */
|
||||
if (module->remaining_conversions) {
|
||||
|
||||
/* Fill the data buffer with next data in write buffer */
|
||||
dac_hw->DATABUF.reg =
|
||||
module->job_buffer[module->transferred_conversions++];
|
||||
|
||||
/* Write buffer size decrement */
|
||||
module->remaining_conversions --;
|
||||
|
||||
/* If in a write buffer job and all the data are converted */
|
||||
if (module->remaining_conversions == 0) {
|
||||
module->job_status = STATUS_OK;
|
||||
|
||||
/* Disable interrupt */
|
||||
dac_hw->INTENCLR.reg = DAC_INTENCLR_EMPTY;
|
||||
dac_hw->INTFLAG.reg = DAC_INTFLAG_EMPTY;
|
||||
system_interrupt_disable(SYSTEM_INTERRUPT_MODULE_DAC);
|
||||
|
||||
if ((module->callback) &&
|
||||
(module->callback_enable[DAC_CALLBACK_TRANSFER_COMPLETE])) {
|
||||
module->callback[DAC_CALLBACK_TRANSFER_COMPLETE](0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((module->callback) &&
|
||||
(module->callback_enable[DAC_CALLBACK_DATA_EMPTY])) {
|
||||
module->callback[DAC_CALLBACK_DATA_EMPTY](0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Handler for the DAC hardware module interrupt. */
|
||||
void DAC_Handler(void)
|
||||
{
|
||||
_dac_interrupt_handler(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Gets the status of a job
|
||||
*
|
||||
* Gets the status of an ongoing or the last job.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel Logical channel to enable callback function
|
||||
*
|
||||
* \return Status of the job.
|
||||
*/
|
||||
enum status_code dac_chan_get_job_status(
|
||||
struct dac_module *module_inst,
|
||||
const enum dac_channel channel)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
return module_inst->job_status;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Aborts an ongoing job
|
||||
*
|
||||
* Aborts an ongoing job.
|
||||
*
|
||||
* \param[in] module_inst Pointer to the DAC software instance struct
|
||||
* \param[in] channel Logical channel to enable callback function
|
||||
*/
|
||||
void dac_chan_abort_job(
|
||||
struct dac_module *module_inst,
|
||||
const enum dac_channel channel)
|
||||
{
|
||||
/* Sanity check arguments */
|
||||
Assert(module_inst);
|
||||
|
||||
UNUSED(channel);
|
||||
|
||||
/* Disable interrupt */
|
||||
module_inst->hw->INTFLAG.reg = DAC_INTFLAG_UNDERRUN | DAC_INTFLAG_EMPTY;
|
||||
module_inst->hw->INTENCLR.reg = DAC_INTENCLR_UNDERRUN | DAC_INTENCLR_EMPTY;
|
||||
|
||||
/* Mark job as aborted */
|
||||
module_inst->job_status = STATUS_ABORTED;
|
||||
module_inst->remaining_conversions = 0;
|
||||
|
||||
}
|
634
atmel-samd/asf/sam0/drivers/dac/dac_sam_d_c/dac_feature.h
Normal file
634
atmel-samd/asf/sam0/drivers/dac/dac_sam_d_c/dac_feature.h
Normal file
@ -0,0 +1,634 @@
|
||||
/**
|
||||
* \file
|
||||
*
|
||||
* \brief SAM Peripheral Digital-to-Analog Converter 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 DAC_FEATURE_H_INCLUDED
|
||||
#define DAC_FEATURE_H_INCLUDED
|
||||
|
||||
/**
|
||||
* \defgroup asfdoc_sam0_dac_group SAM Digital-to-Analog (DAC) Driver
|
||||
*
|
||||
* This driver for Atmel® | SMART ARM®-based microcontrollers provides an interface for the conversion of
|
||||
* digital values to analog voltage. The following driver API modes are covered
|
||||
* by this manual:
|
||||
*
|
||||
* - Polled APIs
|
||||
* \if DAC_CALLBACK_MODE
|
||||
* - Callback APIs
|
||||
* \endif
|
||||
*
|
||||
* The following peripheral is used by this module:
|
||||
* - DAC (Digital-to-Analog Converter)
|
||||
*
|
||||
* The following devices can use this module:
|
||||
* - Atmel | SMART SAM D20/D21
|
||||
* - Atmel | SMART SAM D10/D11
|
||||
* - Atmel | SMART SAM DA1
|
||||
* - Atmel | SMART SAM C21
|
||||
*
|
||||
* The outline of this documentation is as follows:
|
||||
* - \ref asfdoc_sam0_dac_prerequisites
|
||||
* - \ref asfdoc_sam0_dac_module_overview
|
||||
* - \ref asfdoc_sam0_dac_special_considerations
|
||||
* - \ref asfdoc_sam0_dac_extra_info
|
||||
* - \ref asfdoc_sam0_dac_examples
|
||||
* - \ref asfdoc_sam0_dac_api_overview
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_prerequisites Prerequisites
|
||||
*
|
||||
* There are no prerequisites for this module.
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_module_overview Module Overview
|
||||
*
|
||||
* The Digital-to-Analog converter converts a digital value to analog voltage.
|
||||
* The SAM DAC module has one channel with 10-bit resolution,
|
||||
* and is capable of converting up to 350k samples per second (ksps).
|
||||
*
|
||||
* A common use of DAC is to generate audio signals by connecting the DAC
|
||||
* output to a speaker, or to generate a reference voltage; either for an
|
||||
* external circuit or an internal peripheral such as the Analog Comparator.
|
||||
*
|
||||
* After being set up, the DAC will convert new digital values written to the
|
||||
* conversion data register (DATA) to an analog value either on the VOUT pin of
|
||||
* the device, or internally for use as an input to the AC, ADC, and other analog
|
||||
* modules.
|
||||
*
|
||||
* Writing the DATA register will start a new conversion. It is also possible
|
||||
* to trigger the conversion from the event system.
|
||||
*
|
||||
* A simplified block diagram of the DAC can be seen in
|
||||
* \ref asfdoc_sam0_dac_module_block_diagram "the figure below".
|
||||
*
|
||||
* \anchor asfdoc_sam0_dac_module_block_diagram
|
||||
* \image html dac_block_diagram.svg "DAC Block Diagram"
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_conversion_range Conversion Range
|
||||
* The conversion range is between GND and the selected voltage reference.
|
||||
* Available voltage references are:
|
||||
* \li AVCC voltage reference
|
||||
* \li Internal 1V reference (INT1V)
|
||||
* \li External voltage reference (AREF)
|
||||
*
|
||||
* \note Internal references will be enabled by the driver, but not disabled.
|
||||
* Any reference not used by the application should be disabled by the application.
|
||||
*
|
||||
* The output voltage from a DAC channel is given as:
|
||||
* \f[
|
||||
* V_{OUT} = \frac{DATA}{0x3FF} \times VREF
|
||||
* \f]
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_conversion Conversion
|
||||
* The digital value written to the conversion data register (DATA) will be
|
||||
* converted to an analog value.
|
||||
* Writing the DATA register will start a new conversion.
|
||||
* It is also possible to write the conversion data to the DATABUF register,
|
||||
* the writing of the DATA register can then be triggered from the event
|
||||
* system, which will load the value from DATABUF to DATA.
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_analog_output Analog Output
|
||||
* The analog output value can be output to either the VOUT pin or internally,
|
||||
* but not both at the same time.
|
||||
*
|
||||
* \subsubsection asfdoc_sam0_dac_analog_output_external External Output
|
||||
* The output buffer must be enabled in order to drive the DAC output to the
|
||||
* VOUT pin. Due to the output buffer, the DAC has high drive strength, and is
|
||||
* capable of driving both resistive and capacitive loads, as well as loads
|
||||
* which combine both.
|
||||
*
|
||||
* \subsubsection asfdoc_sam0_dac_analog_output_internal Internal Output
|
||||
* The analog value can be internally available for use as input to the
|
||||
* AC or ADC modules.
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_events Events
|
||||
* Events generation and event actions are configurable in the DAC.
|
||||
* The DAC has one event line input and one event output: <i>Start Conversion</i>
|
||||
* and <i>Data Buffer Empty</i>.
|
||||
*
|
||||
* If the Start Conversion input event is enabled in the module configuration,
|
||||
* an incoming event will load data from the data buffer to the data register
|
||||
* and start a new conversion. This method synchronizes conversions with
|
||||
* external events (such as those from a timer module) and ensures regular and
|
||||
* fixed conversion intervals.
|
||||
*
|
||||
* If the Data Buffer Empty output event is enabled in the module configuration,
|
||||
* events will be generated when the DAC data buffer register becomes empty and
|
||||
* new data can be loaded to the buffer.
|
||||
*
|
||||
* \note The connection of events between modules requires the use of the event
|
||||
* driver to route output event of one module to the input event of another.
|
||||
* For more information on event routing, refer to the documentation
|
||||
* \ref asfdoc_sam0_events_group "SAM Event System (EVENTS) Driver".
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_data_adjust Left and Right Adjusted Values
|
||||
* The 10-bit input value to the DAC is contained in a 16-bit register. This
|
||||
* can be configured to be either left or right adjusted. In
|
||||
* \ref asfdoc_sam0_dac_module_adj_modes "the figure below" both options are
|
||||
* shown, and the position of the most (MSB) and the least (LSB) significant bits
|
||||
* are indicated. The unused bits should always be written to zero.
|
||||
*
|
||||
* \anchor asfdoc_sam0_dac_module_adj_modes
|
||||
* \dot
|
||||
* digraph {
|
||||
* subgraph cluster_right {
|
||||
* msbl [label="MSB", shape=none, group="msbl"];
|
||||
* lsbl [label="LSB", shape=none];
|
||||
* node [shape=none];
|
||||
* color="white";
|
||||
* reg_left [label=<
|
||||
* <table cellspacing="0" cellpadding="2" width="100%">
|
||||
* <tr>
|
||||
* <td port="msb">15</td>
|
||||
* <td>14</td>
|
||||
* <td>13</td>
|
||||
* <td>12</td>
|
||||
* <td>11</td>
|
||||
* <td>10</td>
|
||||
* <td>9</td>
|
||||
* <td>8</td>
|
||||
* <td>7</td>
|
||||
* <td port="lsb">6</td>
|
||||
* <td>5</td>
|
||||
* <td>4</td>
|
||||
* <td>3</td>
|
||||
* <td>2</td>
|
||||
* <td>1</td>
|
||||
* <td>0</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td COLSPAN="10"> DATA[9:0] </td>
|
||||
* <td BGCOLOR="lightgray"> </td>
|
||||
* <td BGCOLOR="lightgray"> </td>
|
||||
* <td BGCOLOR="lightgray"> </td>
|
||||
* <td BGCOLOR="lightgray"> </td>
|
||||
* <td BGCOLOR="lightgray"> </td>
|
||||
* <td BGCOLOR="lightgray"> </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* >];
|
||||
* msbl -> reg_left:msb:n;
|
||||
* lsbl -> reg_left:lsb;
|
||||
* label ="Left adjusted.\n";
|
||||
* }
|
||||
* subgraph cluster_left {
|
||||
* rankdir=TB;
|
||||
* msb [label="MSB", shape=none];
|
||||
* lsb [label="LSB", shape=none];
|
||||
* color="white";
|
||||
* node [shape=none];
|
||||
* reg_right [label=<
|
||||
* <table cellspacing="0" cellpadding="2">
|
||||
* <tr>
|
||||
* <td>15</td>
|
||||
* <td>14</td>
|
||||
* <td>13</td>
|
||||
* <td>12</td>
|
||||
* <td>11</td>
|
||||
* <td>10</td>
|
||||
* <td port="msb">9</td>
|
||||
* <td>8</td>
|
||||
* <td>7</td>
|
||||
* <td>6</td>
|
||||
* <td>5</td>
|
||||
* <td>4</td>
|
||||
* <td>3</td>
|
||||
* <td>2</td>
|
||||
* <td>1</td>
|
||||
* <td port="lsb">0</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td BGCOLOR="lightgray"></td>
|
||||
* <td BGCOLOR="lightgray"></td>
|
||||
* <td BGCOLOR="lightgray"></td>
|
||||
* <td BGCOLOR="lightgray"></td>
|
||||
* <td BGCOLOR="lightgray"></td>
|
||||
* <td BGCOLOR="lightgray"></td>
|
||||
* <td COLSPAN="10"> DATA[9:0] </td>
|
||||
* </tr>
|
||||
* </table>
|
||||
* >];
|
||||
* msb -> reg_right:msb;
|
||||
* lsb -> reg_right:lsb:n;
|
||||
* label = "Right adjusted.\n";
|
||||
* graph [shape=none];
|
||||
* }
|
||||
* }
|
||||
* \enddot
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_clk_sources Clock Sources
|
||||
* The clock for the DAC interface (CLK_DAC) is generated by the Power Manager.
|
||||
* This clock is turned on by default, and can be enabled and disabled in the
|
||||
* Power Manager.
|
||||
*
|
||||
* Additionally, an asynchronous clock source (GCLK_DAC) is required.
|
||||
* These clocks are normally disabled by default. The selected clock source
|
||||
* must be enabled in the Power Manager before it can be used by the DAC.
|
||||
* The DAC core operates asynchronously from the user interface and
|
||||
* peripheral bus. As a consequence, the DAC needs two clock cycles of both
|
||||
* CLK_DAC and GCLK_DAC to synchronize the values written to some of the
|
||||
* control and data registers.
|
||||
* The oscillator source for the GCLK_DAC clock is selected in the System
|
||||
* Control Interface (SCIF).
|
||||
*
|
||||
* \section asfdoc_sam0_dac_special_considerations Special Considerations
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_special_considerations_output_buffer Output Driver
|
||||
* The DAC can only do conversions in Active or Idle modes. However, if the
|
||||
* output buffer is enabled it will draw current even if the system is in
|
||||
* sleep mode. Therefore, always make sure that the output buffer is not
|
||||
* enabled when it is not needed, to ensure minimum power consumption.
|
||||
*
|
||||
* \subsection asfdoc_sam0_dac_special_considerations_conversion_time Conversion Time
|
||||
* DAC conversion time is approximately 2.85µs. The user must ensure that new
|
||||
* data is not written to the DAC before the last conversion is complete.
|
||||
* Conversions should be triggered by a periodic event from a Timer/Counter or
|
||||
* another peripheral.
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_extra_info Extra Information
|
||||
*
|
||||
* For extra information, see \ref asfdoc_sam0_dac_extra. This includes:
|
||||
* - \ref asfdoc_sam0_dac_extra_acronyms
|
||||
* - \ref asfdoc_sam0_dac_extra_dependencies
|
||||
* - \ref asfdoc_sam0_dac_extra_errata
|
||||
* - \ref asfdoc_sam0_dac_extra_history
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_examples Examples
|
||||
*
|
||||
* For a list of examples related to this driver, see
|
||||
* \ref asfdoc_sam0_dac_exqsg.
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_api_overview API Overview
|
||||
* @{
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <compiler.h>
|
||||
#include <clock.h>
|
||||
#include <gclk.h>
|
||||
|
||||
|
||||
/**
|
||||
* \name DAC Status Flags
|
||||
*
|
||||
* DAC status flags, returned by \ref dac_get_status() and cleared by
|
||||
* \ref dac_clear_status().
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Data Buffer Empty Channel 0 - Set when data is transferred from DATABUF
|
||||
* to DATA by a start conversion event and DATABUF is ready for new data.
|
||||
*/
|
||||
#define DAC_STATUS_CHANNEL_0_EMPTY (1UL << 0)
|
||||
|
||||
/** Under-run Channel 0 - Set when a start conversion event occurs when
|
||||
* DATABUF is empty.
|
||||
*/
|
||||
#define DAC_STATUS_CHANNEL_0_UNDERRUN (1UL << 1)
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \brief DAC reference voltage enum.
|
||||
*
|
||||
* Enum for the possible reference voltages for the DAC.
|
||||
*/
|
||||
enum dac_reference {
|
||||
/** 1V from the internal band-gap reference*/
|
||||
DAC_REFERENCE_INT1V = DAC_CTRLB_REFSEL(0),
|
||||
/** Analog V<SUB>CC</SUB> as reference */
|
||||
DAC_REFERENCE_AVCC = DAC_CTRLB_REFSEL(1),
|
||||
/** External reference on AREF */
|
||||
DAC_REFERENCE_AREF = DAC_CTRLB_REFSEL(2),
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DAC output selection enum.
|
||||
*
|
||||
* Enum for the DAC output selection.
|
||||
*/
|
||||
enum dac_output {
|
||||
/** DAC output to VOUT pin */
|
||||
DAC_OUTPUT_EXTERNAL = DAC_CTRLB_EOEN,
|
||||
/** DAC output as internal reference */
|
||||
DAC_OUTPUT_INTERNAL = DAC_CTRLB_IOEN,
|
||||
/** No output */
|
||||
DAC_OUTPUT_NONE = 0,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DAC channel selection enum.
|
||||
*
|
||||
* Enum for the DAC channel selection.
|
||||
*/
|
||||
enum dac_channel {
|
||||
/** DAC output channel 0 */
|
||||
DAC_CHANNEL_0,
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DAC software device instance structure.
|
||||
*
|
||||
* DAC software instance structure, used to retain software state information
|
||||
* of an associated hardware module instance.
|
||||
*
|
||||
* \note The fields of this structure should not be altered by the user
|
||||
* application; they are reserved for module-internal use only.
|
||||
*/
|
||||
struct dac_module {
|
||||
#if !defined(__DOXYGEN__)
|
||||
/** DAC hardware module */
|
||||
Dac *hw;
|
||||
/** DAC output selection */
|
||||
enum dac_output output;
|
||||
/** Reference selection */
|
||||
enum dac_reference reference;
|
||||
/** DAC event selection */
|
||||
bool start_on_event;
|
||||
# if DAC_CALLBACK_MODE == true
|
||||
/** Pointer to buffer used for ADC results */
|
||||
volatile uint16_t *job_buffer;
|
||||
/** Remaining number of conversions in current job */
|
||||
volatile uint16_t remaining_conversions;
|
||||
/** Transferred number of conversions in current job */
|
||||
volatile uint16_t transferred_conversions;
|
||||
/** DAC callback enable */
|
||||
bool callback_enable[DAC_CALLBACK_N];
|
||||
/** DAC registered callback functions */
|
||||
dac_callback_t callback[DAC_CALLBACK_N];
|
||||
/** Holds the status of the ongoing or last conversion job */
|
||||
volatile enum status_code job_status;
|
||||
# endif
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DAC configuration structure.
|
||||
*
|
||||
* Configuration structure for a DAC instance. This structure should be
|
||||
* initialized by the \ref dac_get_config_defaults()
|
||||
* function before being modified by the user application.
|
||||
*/
|
||||
struct dac_config {
|
||||
/** Reference voltage */
|
||||
enum dac_reference reference;
|
||||
/** Select DAC output */
|
||||
enum dac_output output;
|
||||
/** Left adjusted data */
|
||||
bool left_adjust;
|
||||
/** GCLK generator used to clock the peripheral */
|
||||
enum gclk_generator clock_source;
|
||||
#ifdef FEATURE_DAC_DATABUF_WRITE_PROTECTION
|
||||
/** Bypass DATABUF write protection */
|
||||
bool databuf_protection_bypass;
|
||||
#endif
|
||||
/** Voltage pump disable */
|
||||
bool voltage_pump_disable;
|
||||
/**
|
||||
* The DAC behaves as in normal mode when the chip enters STANDBY sleep
|
||||
* mode
|
||||
*/
|
||||
bool run_in_standby;
|
||||
#if (SAMC21)
|
||||
/** Dither mode enable data */
|
||||
bool dither_mode;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DAC event enable/disable structure.
|
||||
*
|
||||
* Event flags for the DAC module. This is used to enable and
|
||||
* disable events via \ref dac_enable_events() and \ref dac_disable_events().
|
||||
*/
|
||||
struct dac_events {
|
||||
/** Start a new DAC conversion */
|
||||
bool on_event_start_conversion;
|
||||
/** Enable event generation on data buffer empty */
|
||||
bool generate_event_on_buffer_empty;
|
||||
#if (SAMC21)
|
||||
/** Enable the falling edge of the input event for DAC1 */
|
||||
bool generate_event_on_chan_falling_edge;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief DAC channel configuration structure
|
||||
*
|
||||
* Configuration for a DAC channel. This structure should be initialized by the
|
||||
* \ref dac_chan_get_config_defaults() function before being modified by the
|
||||
* user application.
|
||||
*/
|
||||
struct dac_chan_config {
|
||||
#if !defined(__DOXYGEN__)
|
||||
/** Dummy value to ensure the struct has at least one member */
|
||||
uint8_t _dummy;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* \name Configuration and Initialization (Channel)
|
||||
* @{
|
||||
*/
|
||||
|
||||
void dac_chan_enable_output_buffer(
|
||||
struct dac_module *const dev_inst,
|
||||
const enum dac_channel channel);
|
||||
|
||||
void dac_chan_disable_output_buffer(
|
||||
struct dac_module *const dev_inst,
|
||||
const enum dac_channel channel);
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* \page asfdoc_sam0_dac_extra Extra Information for DAC Driver
|
||||
*
|
||||
* \section asfdoc_sam0_dac_extra_acronyms Acronyms
|
||||
* The table below presents the acronyms used in this module:
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th>Acronym</th>
|
||||
* <th>Description</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>ADC</td>
|
||||
* <td>Analog-to-Digital Converter</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>AC</td>
|
||||
* <td>Analog Comparator</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>DAC</td>
|
||||
* <td>Digital-to-Analog Converter</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>LSB</td>
|
||||
* <td>Least Significant Bit</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>MSB</td>
|
||||
* <td>Most Significant Bit</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>DMA</td>
|
||||
* <td>Direct Memory Access</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_extra_dependencies Dependencies
|
||||
* This driver has the following dependencies:
|
||||
*
|
||||
* - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver"
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_extra_errata Errata
|
||||
* There are no errata related to this driver.
|
||||
*
|
||||
*
|
||||
* \section asfdoc_sam0_dac_extra_history Module History
|
||||
* An overview of the module history is presented in the table below, with
|
||||
* details on the enhancements and fixes made to the module since its first
|
||||
* release. The current version of this corresponds to the newest version in
|
||||
* the table.
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th>Changelog</th>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Add configuration for using 14-bit hardware dithering (SAMC21 support)</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Added new configuration parameters \c databuf_protection_bypass,
|
||||
* \c voltage_pump_disable. Added new callback functions
|
||||
* \c dac_chan_write_buffer_wait,
|
||||
* \c dac_chan_write_buffer_job, \c dac_chan_write_job,
|
||||
* \c dac_get_job_status, \c dac_abort_job and new callback type
|
||||
* \c DAC_CALLBACK_TRANSFER_COMPLETE for DAC conversion job</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>Initial Release</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
||||
/**
|
||||
* \page asfdoc_sam0_dac_exqsg Examples for DAC Driver
|
||||
*
|
||||
* This is a list of the available Quick Start guides (QSGs) and example
|
||||
* applications for \ref asfdoc_sam0_dac_group. QSGs are simple examples with
|
||||
* step-by-step instructions to configure and use this driver in a selection of
|
||||
* use cases. Note that a QSG can be compiled as a standalone application or be
|
||||
* added to the user application.
|
||||
*
|
||||
* - \subpage asfdoc_sam0_dac_basic_use_case
|
||||
* \if DAC_CALLBACK_MODE
|
||||
* - \subpage asfdoc_sam0_dac_basic_use_case_callback
|
||||
* \endif
|
||||
* \if DAC_DMA_USE_MODE_SELECTION
|
||||
* - \subpage asfdoc_sam0_adc_dma_use_case_dac_in_dma
|
||||
* \endif
|
||||
*
|
||||
* \if DAC_DMA_USE_MODE_SELECTION
|
||||
* \page asfdoc_sam0_adc_dma_use_case_dac_in_dma Quick Start Guide for Using DMA with ADC/DAC
|
||||
* For this examples, see
|
||||
* \ref asfdoc_sam0_adc_dma_use_case
|
||||
* \endif
|
||||
*
|
||||
* \page asfdoc_sam0_dac_document_revision_history Document Revision History
|
||||
*
|
||||
* <table>
|
||||
* <tr>
|
||||
* <th>Doc. Rev.</td>
|
||||
* <th>Date</td>
|
||||
* <th>Comments</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>42110E</td>
|
||||
* <td>09/2015</td>
|
||||
* <td>Add SAM C21 and SAM DA1 support</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>42110D</td>
|
||||
* <td>12/2014</td>
|
||||
* <td>Add SAM D10/D11 support</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>42110C</td>
|
||||
* <td>01/2014</td>
|
||||
* <td>Add SAM D21 support</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>42110B</td>
|
||||
* <td>06/2013</td>
|
||||
* <td>Added additional documentation on the event system. Corrected
|
||||
* documentation typos.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>42110A</td>
|
||||
* <td>06/2013</td>
|
||||
* <td>Initial document release</td>
|
||||
* </tr>
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* DAC_FEATURE_H_INCLUDED */
|
||||
|
218
atmel-samd/asf/sam0/drivers/dac/docimg/dac_block_diagram.svg
Normal file
218
atmel-samd/asf/sam0/drivers/dac/docimg/dac_block_diagram.svg
Normal file
@ -0,0 +1,218 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="svg2985"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
width="500"
|
||||
height="290"
|
||||
sodipodi:docname="dac_block_diagram.gif">
|
||||
<metadata
|
||||
id="metadata2991">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs2989" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1397"
|
||||
inkscape:window-height="1023"
|
||||
id="namedview2987"
|
||||
showgrid="false"
|
||||
inkscape:zoom="2.168"
|
||||
inkscape:cx="250"
|
||||
inkscape:cy="145"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="100"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2985" />
|
||||
<image
|
||||
width="500"
|
||||
height="290"
|
||||
xlink:href="data:image/png;base64,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
|
||||
YII=
|
||||
"
|
||||
id="image2993"
|
||||
x="0"
|
||||
y="0" />
|
||||
</svg>
|
After Width: | Height: | Size: 14 KiB |
1303
atmel-samd/asf/sam0/drivers/dac/docimg/dac_block_diagram_saml.svg
Normal file
1303
atmel-samd/asf/sam0/drivers/dac/docimg/dac_block_diagram_saml.svg
Normal file
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 95 KiB |
@ -32,6 +32,7 @@
|
||||
#include "py/runtime.h"
|
||||
|
||||
#include "adc.h"
|
||||
#include "mpdac.h"
|
||||
#include "pin.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE
|
||||
@ -39,6 +40,7 @@
|
||||
STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&adc_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DAC), MP_ROM_PTR(&dac_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pin_type) },
|
||||
};
|
||||
|
||||
|
@ -56,6 +56,8 @@
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_REPL_AUTO_INDENT (1)
|
||||
#define MICROPY_HW_ENABLE_DAC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (1)
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
|
152
atmel-samd/mpdac.c
Normal file
152
atmel-samd/mpdac.c
Normal file
@ -0,0 +1,152 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
//
|
||||
// #include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
// #include "timer.h"
|
||||
#include "mpdac.h"
|
||||
// #include "dma.h"
|
||||
// #include "pin.h"
|
||||
// #include "genhdr/pins.h"
|
||||
|
||||
#include "asf/sam0/drivers/dac/dac.h"
|
||||
|
||||
/// \moduleref machine
|
||||
/// \class DAC - digital to analog conversion
|
||||
///
|
||||
/// The DAC is used to output analog values (a specific voltage) on pin PA02
|
||||
/// (Arduino Zero A0, Feather MO Bluefruit A0).
|
||||
/// The voltage will be between 0 and 3.3V.
|
||||
///
|
||||
/// *This module will undergo changes to the API.*
|
||||
///
|
||||
/// Example usage:
|
||||
///
|
||||
/// from machine import DAC
|
||||
///
|
||||
/// dac = DAC() # create DAC 1 on pin PA02
|
||||
/// dac.write(512) # write a value to the DAC (makes PA02 1.65V)
|
||||
/// dac.write_mv(1650) # Also results in PA02 being 1.65V
|
||||
|
||||
/******************************************************************************/
|
||||
// Micro Python bindings
|
||||
|
||||
typedef struct _dac_obj_t {
|
||||
mp_obj_base_t base;
|
||||
struct dac_module dac_instance;
|
||||
} dac_obj_t;
|
||||
|
||||
// create the dac object
|
||||
|
||||
/// \classmethod \constructor()
|
||||
/// Construct a new DAC object for pin PA02.
|
||||
STATIC mp_obj_t dac_make_new(const mp_obj_type_t *type, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, true);
|
||||
|
||||
dac_obj_t *dac = m_new_obj(dac_obj_t);
|
||||
dac->base.type = &dac_type;
|
||||
|
||||
struct dac_config config_dac;
|
||||
dac_get_config_defaults(&config_dac);
|
||||
config_dac.reference = DAC_REFERENCE_AVCC;
|
||||
enum status_code status = dac_init(&dac->dac_instance, DAC, &config_dac);
|
||||
if (status != STATUS_OK) {
|
||||
// Throw error.
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
struct dac_chan_config config_dac_chan;
|
||||
dac_chan_get_config_defaults(&config_dac_chan);
|
||||
dac_chan_set_config(&dac->dac_instance, DAC_CHANNEL_0, &config_dac_chan);
|
||||
dac_chan_enable(&dac->dac_instance, DAC_CHANNEL_0);
|
||||
|
||||
dac_enable(&dac->dac_instance);
|
||||
|
||||
// return object
|
||||
return dac;
|
||||
}
|
||||
|
||||
/// \method deinit()
|
||||
/// Turn off the DAC, enable other use of pin.
|
||||
STATIC mp_obj_t dac_del(mp_obj_t self_in) {
|
||||
dac_obj_t *self = self_in;
|
||||
|
||||
dac_disable(&self->dac_instance);
|
||||
dac_chan_disable(&self->dac_instance, DAC_CHANNEL_0);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(dac_del_obj, dac_del);
|
||||
|
||||
/// \method write(value)
|
||||
/// Direct access to the DAC output (10 bit).
|
||||
STATIC mp_obj_t dac_write(mp_obj_t self_in, mp_obj_t val) {
|
||||
dac_obj_t *self = self_in;
|
||||
|
||||
dac_chan_write(&self->dac_instance, DAC_CHANNEL_0, mp_obj_get_int(val));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(dac_write_obj, dac_write);
|
||||
|
||||
/// \method write_mv(value)
|
||||
/// Direct access to the DAC output by specifying millivolts.
|
||||
STATIC mp_obj_t dac_write_mv(mp_obj_t self_in, mp_obj_t val_mv) {
|
||||
dac_obj_t *self = self_in;
|
||||
// TODO(tannewt): Sanity check that the mv value is less than the reference
|
||||
// voltage.
|
||||
// Dividing by 3301 instead of 3300 ensures that val_mv of 3300 actually
|
||||
// produces a value of 1023 instead of 1024 which is out of range of the
|
||||
// DAC.
|
||||
uint16_t val = ((uint32_t) mp_obj_get_int(val_mv)) * 1024 / 3301;
|
||||
|
||||
dac_chan_write(&self->dac_instance, DAC_CHANNEL_0, val);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(dac_write_mv_obj, dac_write_mv);
|
||||
|
||||
STATIC const mp_map_elem_t dac_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR___del__), (mp_obj_t)&dac_del_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write), (mp_obj_t)&dac_write_obj },
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_write_mv), (mp_obj_t)&dac_write_mv_obj },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(dac_locals_dict, dac_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t dac_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_DAC,
|
||||
.make_new = dac_make_new,
|
||||
.locals_dict = (mp_obj_t)&dac_locals_dict,
|
||||
};
|
27
atmel-samd/mpdac.h
Normal file
27
atmel-samd/mpdac.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
extern const mp_obj_type_t dac_type;
|
Loading…
Reference in New Issue
Block a user