2022-10-10 07:17:22 -04:00
/*
* SPDX - FileCopyrightText : 2019 - 2022 Espressif Systems ( Shanghai ) CO LTD
*
* SPDX - License - Identifier : Apache - 2.0
*/
# pragma once
# include "driver/dac_types.h"
# include "esp_err.h"
# ifdef __cplusplus
extern " C " {
# endif
# if SOC_DAC_SUPPORTED
/**
* @ brief DAC channel mask
*
*/
typedef enum {
DAC_CHANNEL_MASK_CH0 = BIT ( 0 ) , /*!< DAC channel 0 is GPIO25(ESP32) / GPIO17(ESP32S2) */
DAC_CHANNEL_MASK_CH1 = BIT ( 1 ) , /*!< DAC channel 1 is GPIO26(ESP32) / GPIO18(ESP32S2) */
DAC_CHANNEL_MASK_ALL = BIT ( 0 ) | BIT ( 1 ) , /*!< Both DAC channel 0 and channel 1 */
} dac_channel_mask_t ;
2022-11-03 00:13:58 -04:00
typedef struct dac_continuous_s * dac_continuous_handle_t ; /*!< DAC continuous channel handle */
2022-10-10 07:17:22 -04:00
/**
* @ brief DAC continuous channels ' configurations
*
*/
typedef struct {
dac_channel_mask_t chan_mask ; /*!< DAC channels' mask for selecting which channels are used */
uint32_t desc_num ; /*!< The number of DMA descriptor, at least 2 descriptors are required
* The number of descriptors is directly proportional to the max data buffer size while converting in cyclic output
* but only need to ensure it is greater than ' 1 ' in acyclic output
* Typically , suggest to set the number bigger than 5 , in case the DMA stopped while sending a short buffer
*/
size_t buf_size ; /*!< The DMA buffer size, should be within 32~4092 bytes. Each DMA buffer will be attached to a DMA descriptor,
* i . e . the number of DMA buffer will be equal to the DMA descriptor number
* The DMA buffer size is not allowed to be greater than 4092 bytes
* The total DMA buffer size equal to ` desc_num * buf_size `
* Typically , suggest to set the size to the multiple of 4
*/
uint32_t freq_hz ; /*!< The frequency of DAC conversion in continuous mode, unit: Hz
* The supported range is related to the target and the clock source .
* For the clock ` DAC_DIGI_CLK_SRC_DEFAULT ` : the range is 19.6 KHz to several MHz on ESP32
* and 77 Hz to several MHz on ESP32 - S2 .
* For the clock ` DAC_DIGI_CLK_SRC_APLL ` : the range is 648 Hz to several MHz on ESP32
* and 6 Hz to several MHz on ESP32 - S2 .
* Typically not suggest to set the frequency higher than 2 MHz , otherwise the severe distortion will appear
*/
int8_t offset ; /*!< The offset of the DAC digital data. Range -128~127 */
2022-11-03 00:13:58 -04:00
dac_continuous_digi_clk_src_t clk_src ; /*!< The clock source of digital controller, which can affect the range of supported frequency
2022-10-10 07:17:22 -04:00
* Currently ` DAC_DIGI_CLK_SRC_DEFAULT ` and ` DAC_DIGI_CLK_SRC_APLL ` are available
*/
2022-11-03 00:13:58 -04:00
dac_continuous_channel_mode_t chan_mode ; /*!< The channel mode of continuous mode, only take effect when multiple channels enabled, depends converting the buffer alternately or simultaneously */
} dac_continuous_config_t ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Event structure used in DAC event queue
*/
typedef struct {
void * buf ; /*!< The pointer of DMA buffer that just finished sending */
2022-11-03 00:13:58 -04:00
size_t buf_size ; /*!< The writable buffer size of the DMA buffer, equal to 'dac_continuous_config_t::buf_size' */
2022-10-10 07:17:22 -04:00
size_t write_bytes ; /*!< The number of bytes that be written successfully */
} dac_event_data_t ;
/**
* @ brief DAC event callback
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle DAC channel handle , created from ` dac_continuous_new_channels ( ) `
2022-10-10 07:17:22 -04:00
* @ param [ in ] event DAC event data
2022-11-03 00:13:58 -04:00
* @ param [ in ] user_data User registered context , passed from ` dac_continuous_register_event_callback ( ) `
2022-10-10 07:17:22 -04:00
*
* @ return Whether a high priority task has been waken up by this callback function
*/
2022-11-03 00:13:58 -04:00
typedef bool ( * dac_isr_callback_t ) ( dac_continuous_handle_t handle , const dac_event_data_t * event , void * user_data ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Group of DAC callbacks
* @ note The callbacks are all running under ISR environment
* @ note When CONFIG_DAC_ISR_IRAM_SAFE is enabled , the callback itself and functions called by it should be placed in IRAM .
* The variables used in the function should be in the SRAM as well .
*/
typedef struct {
dac_isr_callback_t on_convert_done ; /**< Callback of data conversion done event
* An event data buffer previously loaded to the driver has been output and converted .
* The event data includes DMA buffer address and size that just finished converting .
*/
dac_isr_callback_t on_stop ; /**< Callback of finished sending all the data.
* All loaded event data buffers are converted . Driver is pending for new data buffers to be loaded .
* The event data will be NULL in this callback .
*/
} dac_event_callbacks_t ;
/**
* @ brief Allocate new DAC channels in continuous mode
* @ note The DAC channels can ' t be registered to continuous mode separately
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] cont_cfg Continuous mode configuration
2022-10-10 07:17:22 -04:00
* @ param [ out ] ret_handle The returned continuous mode handle
* @ return
* - ESP_ERR_INVALID_ARG The input parameter is invalid
* - ESP_ERR_INVALID_STATE The DAC channel has been registered already
* - ESP_ERR_NOT_FOUND Not found the available dma peripheral , might be occupied
* - ESP_ERR_NO_MEM No memory for the DAC continuous mode resources
* - ESP_OK Allocate the new DAC continuous mode success
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_new_channels ( const dac_continuous_config_t * cont_cfg , dac_continuous_handle_t * ret_handle ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Delete the DAC continuous handle
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ return
* - ESP_ERR_INVALID_ARG The input parameter is invalid
* - ESP_ERR_INVALID_STATE The channels have already been deregistered or not disabled
* - ESP_OK Delete the continuous channels success
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_del_channels ( dac_continuous_handle_t handle ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Enabled the DAC continuous mode
* @ note Must enable the channels before
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ return
* - ESP_ERR_INVALID_ARG The input parameter is invalid
* - ESP_ERR_INVALID_STATE The channels have been enabled already
* - ESP_OK Enable the continuous output success
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_enable ( dac_continuous_handle_t handle ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Disable the DAC continuous mode
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ return
* - ESP_ERR_INVALID_ARG The input parameter is invalid
* - ESP_ERR_INVALID_STATE The channels have been enabled already
* - ESP_OK Disable the continuous output success
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_disable ( dac_continuous_handle_t handle ) ;
2022-10-10 07:17:22 -04:00
/**
2022-11-03 00:13:58 -04:00
* @ brief Write DAC data continuously
* @ note The data in buffer will only be converted one time ,
* This function will be blocked until all data loaded or timeout
* then the DAC output will keep outputting the voltage of the last data in the buffer
2022-10-10 07:17:22 -04:00
* @ note Specially , on ESP32 , the data bit width of DAC continuous data is fixed to 16 bits while only the high 8 bits are available ,
* The driver will help to expand the inputted buffer automatically by default ,
* you can also align the data to 16 bits manually by clearing ` CONFIG_DAC_DMA_AUTO_16BIT_ALIGN ` in menuconfig .
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ param [ in ] buf The digital data buffer to convert
* @ param [ in ] buf_size The buffer size of digital data buffer
* @ param [ out ] bytes_loaded The bytes that has been loaded into DMA buffer , can be NULL if don ' t need it
2022-11-03 00:13:58 -04:00
* @ param [ in ] timeout_ms The timeout time in millisecond , set a minus value means will block forever
2022-10-10 07:17:22 -04:00
* @ return
* - ESP_ERR_INVALID_ARG The input parameter is invalid
* - ESP_ERR_INVALID_STATE The DAC continuous mode has not been enabled yet
2022-11-03 00:13:58 -04:00
* - ESP_ERR_TIMEOUT Waiting for semaphore or message queue timeout
2022-10-10 07:17:22 -04:00
* - ESP_OK Success to output the acyclic DAC data
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_write ( dac_continuous_handle_t handle , uint8_t * buf , size_t buf_size , size_t * bytes_loaded , int timeout_ms ) ;
2022-10-10 07:17:22 -04:00
/**
2022-11-03 00:13:58 -04:00
* @ brief Write DAC continuous data cyclically
* @ note The data in buffer will be converted cyclically using DMA once this function is called ,
* This function will return once the data loaded into DMA buffers .
* @ note The buffer size of cyclically output is limited by the descriptor number and
* dma buffer size while initializing the continuous mode .
* Concretely , in order to load all the data into descriptors ,
* the cyclic buffer size is not supposed to be greater than ` desc_num * buf_size `
2022-10-10 07:17:22 -04:00
* @ note Specially , on ESP32 , the data bit width of DAC continuous data is fixed to 16 bits while only the high 8 bits are available ,
* The driver will help to expand the inputted buffer automatically by default ,
* you can also align the data to 16 bits manually by clearing ` CONFIG_DAC_DMA_AUTO_16BIT_ALIGN ` in menuconfig .
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ param [ in ] buf The digital data buffer to convert
* @ param [ in ] buf_size The buffer size of digital data buffer
* @ param [ out ] bytes_loaded The bytes that has been loaded into DMA buffer , can be NULL if don ' t need it
* @ return
* - ESP_ERR_INVALID_ARG The input parameter is invalid
* - ESP_ERR_INVALID_STATE The DAC continuous mode has not been enabled yet
* - ESP_OK Success to output the acyclic DAC data
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_write_cyclically ( dac_continuous_handle_t handle , uint8_t * buf , size_t buf_size , size_t * bytes_loaded ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Set event callbacks for DAC continuous mode
*
* @ note User can deregister a previously registered callback by calling this function and setting the callback member in the ` callbacks ` structure to NULL .
* @ note When CONFIG_DAC_ISR_IRAM_SAFE is enabled , the callback itself and functions called by it should be placed in IRAM .
* The variables used in this function , including the ` user_data ` , should be in the internal RAM as well .
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ param [ in ] callbacks Group of callback functions , input NULL to clear the former callbacks
* @ param [ in ] user_data User data , which will be passed to callback functions directly
* @ return
* - ESP_OK Set event callbacks successfully
* - ESP_ERR_INVALID_ARG Set event callbacks failed because of invalid argument
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_register_event_callback ( dac_continuous_handle_t handle , const dac_event_callbacks_t * callbacks , void * user_data ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Start the async writing
* @ note When the asynchronous writing start , the DAC will keep outputting ' 0 ' until the data are loaded into the DMA buffer .
* To loaded the data into DMA buffer , ' on_convert_done ' callback is required ,
2022-11-03 00:13:58 -04:00
* which can be registered by ' dac_continuous_register_event_callback ' before enabling
2022-10-10 07:17:22 -04:00
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ return
* - ESP_OK Start asynchronous writing successfully
* - ESP_ERR_INVALID_ARG The handle is NULL
* - ESP_ERR_INVALID_STATE The channel is not enabled or the ' on_convert_done ' callback is not registered
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_start_async_writing ( dac_continuous_handle_t handle ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Stop the sync writing
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ return
* - ESP_OK Stop asynchronous writing successfully
* - ESP_ERR_INVALID_ARG The handle is NULL
* - ESP_ERR_INVALID_STATE Asynchronous writing has not started
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_stop_async_writing ( dac_continuous_handle_t handle ) ;
2022-10-10 07:17:22 -04:00
/**
* @ brief Write DAC data asynchronously
* @ note This function can be called when the asynchronous writing started , and it can be called in the callback directly
* but recommend to writing data in a task , referring to : example : ` peripherals / dac / dac_continuous / dac_audio `
*
2022-11-03 00:13:58 -04:00
* @ param [ in ] handle The DAC continuous channel handle that obtained from ' dac_continuous_new_channels '
2022-10-10 07:17:22 -04:00
* @ param [ in ] dma_buf The DMA buffer address , it can be acquired from ' dac_event_data_t ' in the ' on_convert_done ' callback
* @ param [ in ] dma_buf_len The DMA buffer length , it can be acquired from ' dac_event_data_t ' in the ' on_convert_done ' callback
* @ param [ in ] data The data that need to be written
* @ param [ in ] data_len The data length the need to be written
* @ param [ out ] bytes_loaded The bytes number that has been loaded / written into the DMA buffer
* @ return
* - ESP_OK Write the data into DMA buffer successfully
* - ESP_ERR_INVALID_ARG NULL pointer
* - ESP_ERR_INVALID_STATE The channels haven ' t start the asynchronous writing
* - ESP_ERR_NOT_FOUND The param ' dam_buf ' not match any existed DMA buffer
*/
2022-11-03 00:13:58 -04:00
esp_err_t dac_continuous_write_asynchronously ( dac_continuous_handle_t handle ,
uint8_t * dma_buf ,
size_t dma_buf_len ,
const uint8_t * data ,
size_t data_len ,
size_t * bytes_loaded ) ;
2022-10-10 07:17:22 -04:00
# endif // SOC_DAC_SUPPORTED
# ifdef __cplusplus
}
# endif