dac: update API and file format aligning to the rule

This commit is contained in:
laokaiyao
2022-11-03 12:13:58 +08:00
parent 54d0d870a6
commit 2cccf3a804
30 changed files with 278 additions and 279 deletions
+14 -14
View File
@@ -32,11 +32,11 @@ DAC File Structure
- ``dac.h``: The top header file of legacy DAC driver, only included in the apps which use legacy driver API
- ``dac_oneshot.h``: The top header file of new DAC driver, should be included in the apps which use the new driver API with oneshot mode.
- ``dac_cosine.h``: The top header file of new DAC driver, should be included in the apps which use the new driver API with cosine mode.
- ``dac_conti.h``: The top header file of new DAC driver, should be included in the apps which use the new driver API with continuous mode.
- ``dac_continuous.h``: The top header file of new DAC driver, should be included in the apps which use the new driver API with continuous mode.
.. note::
The legacy driver can't coexist with the new driver. Including ``dac.h`` to use the legacy driver or ``dac_oneshot.h``, ``dac_cosine.h`` and ``dac_conti.h`` to use the new driver. The legacy driver might be removed in future.
The legacy driver can't coexist with the new driver. Including ``dac.h`` to use the legacy driver or ``dac_oneshot.h``, ``dac_cosine.h`` and ``dac_continuous.h`` to use the new driver. The legacy driver might be removed in future.
Functional Overview
-------------------
@@ -44,21 +44,21 @@ Functional Overview
Resources Management
^^^^^^^^^^^^^^^^^^^^
The DAC on {IDF_TARGET_NAME} has two channels, due to the software resources are separate, they could be managed by the :cpp:type:`dac_oneshot_handle_t`, :cpp:type:`dac_cosine_handle_t`:cpp:type:`dac_conti_handle_t` according to the usage. Of cause, registering different modes on a same DAC channel is not allowed.
The DAC on {IDF_TARGET_NAME} has two channels, due to the software resources are separate, they could be managed by the :cpp:type:`dac_oneshot_handle_t`, :cpp:type:`dac_cosine_handle_t`:cpp:type:`dac_continuous_handle_t` according to the usage. Of cause, registering different modes on a same DAC channel is not allowed.
Direct Voltage Output (One-shot/Direct Mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The DAC channels in the group can convert a 8-bit digital value into the analog every time calling :cpp:func:`dac_oneshot_output_voltage` (it can be called in ISR), and then the analog voltage will be kept on the DAC channel until next conversion start. To start to convert the voltage, the DAC channels need to be registered by :cpp:func:`dac_new_oneshot_channel` first, and the channel will be enabled after it is registered.
The DAC channels in the group can convert a 8-bit digital value into the analog every time calling :cpp:func:`dac_oneshot_output_voltage` (it can be called in ISR), and then the analog voltage will be kept on the DAC channel until next conversion start. To start to convert the voltage, the DAC channels need to be registered by :cpp:func:`dac_oneshot_new_channel` first, and the channel will be enabled after it is registered.
Continuous Wave Output (Continuous/DMA Mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
DAC channels can convert digital data continuously via the DMA. There are three ways to writing DAC data:
1. Normal writing (synchronous): It can transmit the data one time and keep blocking until all data has been loaded into the DMA buffer, and the voltage will be kept according to the last conversion value while no more data inputted, usually it is used to transport a long signal like an audio. To convert data continuously, the continuous channel handle need to be allocated by calling :cpp:func:`dac_new_conti_channels` and the DMA conversion should be enabled by :cpp:func:`dac_conti_enable`, then data can be written by :cpp:func:`dac_conti_write` synchronously. Referring to :example:`peripherals/dac/dac_continuous/dac_audio` for example.
2. Cyclical writing: It can convert a piece of data cyclically without blocking, no more operation needed after the data are loaded into the DMA buffer,but note that the inputted buffer size is limited by the descriptor number and the DMA buffer size, usually it is used to transport some short signal that need to be repeated, for example, a sine wave. To achieve cyclical writing, :cpp:func:`dac_conti_write_cyclically` can be called after the DAC continuous mode is enabled. For the cyclical writing example, please refer to :example:`peripherals/dac/dac_continuous/signal_generator`
3. Asynchronous writing: It can transmit the data asynchronously based on the event callback. Thus :cpp:member:`dac_event_callbacks_t::on_convert_done` must be registered to use asynchronous mode, and then users can get the :cpp:type:`dac_event_data_t` in the callback which contains the DMA buffer address and length, allowing user to load the data into it directly. As mentioned, to use the asynchronous writing, :cpp:func:`dac_conti_register_event_callback` need to be called to register the :cpp:member:`dac_event_callbacks_t::on_convert_done` before enabling, and then calling :cpp:func:`dac_conti_start_async_writing` to start the asynchronous writing, note that once the asynchronous writing started, the callback function will be triggered continuously, :cpp:func:`dac_conti_write_asynchronously` can help to load the data either in a separate task or the callback directly. For the asynchronous example, please refer to :example:`peripherals/dac/dac_continuous/dac_audio` as well.
1. Normal writing (synchronous): It can transmit the data one time and keep blocking until all data has been loaded into the DMA buffer, and the voltage will be kept according to the last conversion value while no more data inputted, usually it is used to transport a long signal like an audio. To convert data continuously, the continuous channel handle need to be allocated by calling :cpp:func:`dac_continuous_new_channels` and the DMA conversion should be enabled by :cpp:func:`dac_continuous_enable`, then data can be written by :cpp:func:`dac_continuous_write` synchronously. Referring to :example:`peripherals/dac/dac_continuous/dac_audio` for example.
2. Cyclical writing: It can convert a piece of data cyclically without blocking, no more operation needed after the data are loaded into the DMA buffer,but note that the inputted buffer size is limited by the descriptor number and the DMA buffer size, usually it is used to transport some short signal that need to be repeated, for example, a sine wave. To achieve cyclical writing, :cpp:func:`dac_continuous_write_cyclically` can be called after the DAC continuous mode is enabled. For the cyclical writing example, please refer to :example:`peripherals/dac/dac_continuous/signal_generator`
3. Asynchronous writing: It can transmit the data asynchronously based on the event callback. Thus :cpp:member:`dac_event_callbacks_t::on_convert_done` must be registered to use asynchronous mode, and then users can get the :cpp:type:`dac_event_data_t` in the callback which contains the DMA buffer address and length, allowing user to load the data into it directly. As mentioned, to use the asynchronous writing, :cpp:func:`dac_continuous_register_event_callback` need to be called to register the :cpp:member:`dac_event_callbacks_t::on_convert_done` before enabling, and then calling :cpp:func:`dac_continuous_start_async_writing` to start the asynchronous writing, note that once the asynchronous writing started, the callback function will be triggered continuously, :cpp:func:`dac_continuous_write_asynchronously` can help to load the data either in a separate task or the callback directly. For the asynchronous example, please refer to :example:`peripherals/dac/dac_continuous/dac_audio` as well.
.. only:: esp32
@@ -66,8 +66,8 @@ DAC channels can convert digital data continuously via the DMA. There are three
The clock of DAC digital controller comes from I2S0 as well, so there are two kinds of clock source can be selected:
- :cpp:enumerator:`dac_conti_digi_clk_src_t::DAC_DIGI_CLK_SRC_PLL_D2` can support frequency between 19.6 KHz to several MHz. It is the default clock which can also be selected by :cpp:enumerator:`dac_conti_digi_clk_src_t::DAC_DIGI_CLK_SRC_DEFAULT`.
- :cpp:enumerator:`dac_conti_digi_clk_src_t::DAC_DIGI_CLK_SRC_APLL` can support frequency between 648 Hz to several MHz, however, it might be occupied by other peripherals, then it may not provide the required frequency. But it doesn't mean APLL is not available in this case, it can still work as long as it can be divided to the target DAC DMA frequency correctly.
- :cpp:enumerator:`dac_continuous_digi_clk_src_t::DAC_DIGI_CLK_SRC_PLL_D2` can support frequency between 19.6 KHz to several MHz. It is the default clock which can also be selected by :cpp:enumerator:`dac_continuous_digi_clk_src_t::DAC_DIGI_CLK_SRC_DEFAULT`.
- :cpp:enumerator:`dac_continuous_digi_clk_src_t::DAC_DIGI_CLK_SRC_APLL` can support frequency between 648 Hz to several MHz, however, it might be occupied by other peripherals, then it may not provide the required frequency. But it doesn't mean APLL is not available in this case, it can still work as long as it can be divided to the target DAC DMA frequency correctly.
.. only:: esp32s2
@@ -75,14 +75,14 @@ DAC channels can convert digital data continuously via the DMA. There are three
The clock source of DAC digital controller are:
- :cpp:enumerator:`dac_conti_digi_clk_src_t::DAC_DIGI_CLK_SRC_APB` can support frequency between 77 Hz to several MHz. It is the default clock which can also be selected by :cpp:enumerator:`dac_conti_digi_clk_src_t::DAC_DIGI_CLK_SRC_DEFAULT`.
- :cpp:enumerator:`dac_conti_digi_clk_src_t::DAC_DIGI_CLK_SRC_APLL` can support frequency between 6 Hz to several MHz, however, it might be occupied by other peripherals, then it may not provide the required frequency. But it doesn't mean APLL is not available in this case, it can still work as long as it can be divided to the target DAC DMA frequency correctly.
- :cpp:enumerator:`dac_continuous_digi_clk_src_t::DAC_DIGI_CLK_SRC_APB` can support frequency between 77 Hz to several MHz. It is the default clock which can also be selected by :cpp:enumerator:`dac_continuous_digi_clk_src_t::DAC_DIGI_CLK_SRC_DEFAULT`.
- :cpp:enumerator:`dac_continuous_digi_clk_src_t::DAC_DIGI_CLK_SRC_APLL` can support frequency between 6 Hz to several MHz, however, it might be occupied by other peripherals, then it may not provide the required frequency. But it doesn't mean APLL is not available in this case, it can still work as long as it can be divided to the target DAC DMA frequency correctly.
Cosine Wave Output (Cosine Mode)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The DAC peripheral has one cosine wave generator, it can generate cosine wave on the channels, users can specify the frequency, amplitude and phase of the cosine wave. To output the cosine wave, please acquire the DAC to cosine mode handle by :cpp:func:`dac_new_cosine_channel` first, and then start the cosine wave generator by :cpp:func:`dac_cosine_start`.
The DAC peripheral has one cosine wave generator, it can generate cosine wave on the channels, users can specify the frequency, amplitude and phase of the cosine wave. To output the cosine wave, please acquire the DAC to cosine mode handle by :cpp:func:`dac_cosine_new_channel` first, and then start the cosine wave generator by :cpp:func:`dac_cosine_start`.
Currently, the source clock of the cosine wave generator only comes from ``RTC_FAST`` which can be chosen by :cpp:enumerator:`dac_cosine_clk_src_t::DAC_COSINE_CLK_SRC_RTC_FAST`, it is also the default clock source which is same as :cpp:enumerator:`dac_cosine_clk_src_t::DAC_COSINE_CLK_SRC_RTC_DEFAULT`.
@@ -91,7 +91,7 @@ Power Management
When the power management is enabled (i.e. :ref:`CONFIG_PM_ENABLE` is on), the system will adjust or stop the source clock of DAC before going into light sleep, thus potentially influence to the DAC signals may lead the data conversion goes wrong.
When using DAC driver in continuous mode, it can prevent the system from changing or stopping the source clock in DMA or cosine wave mode by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_APB_FREQ_MAX` and when the source clock is APLL (only in DMA mode), it will be set to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_NO_LIGHT_SLEEP`. Whenever the DAC is converting (i.e. DMA or cosine wave generator is working), the driver will guarantee that the power management lock is acquired after calling :cpp:func:`dac_conti_enable`. Likewise, the driver will release the lock when :cpp:func:`dac_conti_disable` is called.
When using DAC driver in continuous mode, it can prevent the system from changing or stopping the source clock in DMA or cosine wave mode by acquiring a power management lock. When the source clock is generated from APB, the lock type will be set to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_APB_FREQ_MAX` and when the source clock is APLL (only in DMA mode), it will be set to :cpp:enumerator:`esp_pm_lock_type_t::ESP_PM_NO_LIGHT_SLEEP`. Whenever the DAC is converting (i.e. DMA or cosine wave generator is working), the driver will guarantee that the power management lock is acquired after calling :cpp:func:`dac_continuous_enable`. Likewise, the driver will release the lock when :cpp:func:`dac_continuous_disable` is called.
IRAM Safe
^^^^^^^^^
@@ -136,6 +136,6 @@ API Reference
.. include-build-file:: inc/dac_oneshot.inc
.. include-build-file:: inc/dac_cosine.inc
.. include-build-file:: inc/dac_conti.inc
.. include-build-file:: inc/dac_continuous.inc
.. include-build-file:: inc/components/driver/include/driver/dac_types.inc
.. include-build-file:: inc/components/hal/include/hal/dac_types.inc