1- // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
2- //
3- // Licensed under the Apache License, Version 2.0 (the "License");
4- // you may not use this file except in compliance with the License.
5- // You may obtain a copy of the License at
6-
7- // http://www.apache.org/licenses/LICENSE-2.0
8- //
9- // Unless required by applicable law or agreed to in writing, software
10- // distributed under the License is distributed on an "AS IS" BASIS,
11- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12- // See the License for the specific language governing permissions and
13- // limitations under the License.
14-
15-
1+ /*
2+ * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD
3+ *
4+ * SPDX-License-Identifier: Apache-2.0
5+ */
166
177#include "esp32-hal.h"
8+ #include "esp32-hal-periman.h"
189#include "soc/soc_caps.h"
19- #include "driver/sigmadelta.h"
20-
21- #define SOC_SIGMADELTA_CHANNEL_NUM (SOC_SDM_GROUPS * SOC_SDM_CHANNELS_PER_GROUP)
10+ #include "driver/sdm.h"
2211
23- static uint8_t duty_set [SOC_SIGMADELTA_CHANNEL_NUM ] = {0 };
24- static uint32_t prescaler_set [SOC_SIGMADELTA_CHANNEL_NUM ] = {0 };
25-
26- static void _on_apb_change (void * arg , apb_change_ev_t ev_type , uint32_t old_apb , uint32_t new_apb ){
27- if (old_apb == new_apb ){
28- return ;
12+ static bool sigmaDeltaDetachBus (void * bus ){
13+ esp_err_t err = sdm_channel_disable ((sdm_channel_handle_t )bus );
14+ if (err != ESP_OK ){
15+ log_w ("sdm_channel_disable failed with error: %d" , err );
2916 }
30- uint32_t iarg = (uint32_t )arg ;
31- uint8_t channel = iarg ;
32- if (ev_type == APB_AFTER_CHANGE ){
33- old_apb /= 1000000 ;
34- new_apb /= 1000000 ;
35- uint32_t old_prescale = prescaler_set [channel ] + 1 ;
36- uint32_t new_prescale = ((new_apb * old_prescale ) / old_apb ) - 1 ;
37- sigmadelta_set_prescale (channel ,new_prescale );
38- prescaler_set [channel ] = new_prescale ;
17+ err = sdm_del_channel ((sdm_channel_handle_t )bus );
18+ if (err != ESP_OK ){
19+ log_e ("sdm_del_channel failed with error: %d" , err );
20+ return false;
3921 }
22+ return true;
4023}
4124
42- uint32_t sigmaDeltaSetup (uint8_t pin , uint8_t channel , uint32_t freq ) //chan 0-x according to SOC, freq 1220-312500
25+ bool sigmaDeltaAttach (uint8_t pin , uint32_t freq ) //freq 1220-312500
4326{
44- if (channel >= SOC_SIGMADELTA_CHANNEL_NUM ){
45- return 0 ;
46- }
47-
48- uint32_t apb_freq = getApbFrequency ();
49- uint32_t prescale = (apb_freq /(freq * 256 )) - 1 ;
50- if (prescale > 0xFF ) {
51- prescale = 0xFF ;
27+ perimanSetBusDeinit (ESP32_BUS_TYPE_SIGMADELTA , sigmaDeltaDetachBus );
28+ sdm_channel_handle_t bus = (sdm_channel_handle_t )perimanGetPinBus (pin , ESP32_BUS_TYPE_SIGMADELTA );
29+ if (bus != NULL && !perimanSetPinBus (pin , ESP32_BUS_TYPE_INIT , NULL )){
30+ return false;
5231 }
53-
54- sigmadelta_config_t sigmadelta_cfg = {
55- .channel = channel ,
56- .sigmadelta_prescale = prescale ,
57- .sigmadelta_duty = 0 ,
58- .sigmadelta_gpio = pin ,
32+ bus = NULL ;
33+ sdm_config_t config = {
34+ .gpio_num = (int )pin ,
35+ .clk_src = SDM_CLK_SRC_DEFAULT ,
36+ .sample_rate_hz = freq ,
37+ .flags = {
38+ .invert_out = 0 ,
39+ .io_loop_back = 0
40+ }
5941 };
60- sigmadelta_config (& sigmadelta_cfg );
61-
62- prescaler_set [channel ] = prescale ;
63- uint32_t iarg = channel ;
64- addApbChangeCallback ((void * )iarg , _on_apb_change );
65-
66- return apb_freq /((prescale + 1 ) * 256 );
67- }
68-
69- void sigmaDeltaWrite (uint8_t channel , uint8_t duty ) //chan 0-x according to SOC duty 8 bit
70- {
71- if (channel >= SOC_SIGMADELTA_CHANNEL_NUM ){
72- return ;
42+ esp_err_t err = sdm_new_channel (& config , & bus );
43+ if (err != ESP_OK ){
44+ log_e ("sdm_new_channel failed with error: %d" , err );
45+ return false;
7346 }
74- duty -= 128 ;
75-
76- sigmadelta_set_duty (channel ,duty );
77- duty_set [channel ] = duty ;
47+ err = sdm_channel_enable (bus );
48+ if (err != ESP_OK ){
49+ sigmaDeltaDetachBus ((void * )bus );
50+ log_e ("sdm_channel_enable failed with error: %d" , err );
51+ return false;
52+ }
53+ if (!perimanSetPinBus (pin , ESP32_BUS_TYPE_SIGMADELTA , (void * )bus )){
54+ sigmaDeltaDetachBus ((void * )bus );
55+ return false;
56+ }
57+ return true;
7858}
7959
80- uint8_t sigmaDeltaRead (uint8_t channel ) //chan 0-x according to SOC
60+ bool sigmaDeltaWrite (uint8_t pin , uint8_t duty ) //chan 0-x according to SOC duty 8 bit
8161{
82- if (channel >= SOC_SIGMADELTA_CHANNEL_NUM ){
83- return 0 ;
62+ sdm_channel_handle_t bus = (sdm_channel_handle_t )perimanGetPinBus (pin , ESP32_BUS_TYPE_SIGMADELTA );
63+ if (bus != NULL ){
64+ int8_t d = duty - 128 ;
65+ esp_err_t err = sdm_channel_set_duty (bus , d );
66+ if (err != ESP_OK ){
67+ log_e ("sdm_channel_set_duty failed with error: %d" , err );
68+ return false;
69+ }
70+ return true;
71+ } else {
72+ log_e ("pin %u is not attached to SigmaDelta" );
8473 }
85- return duty_set [ channel ] + 128 ;
74+ return false ;
8675}
8776
88- void sigmaDeltaDetachPin (uint8_t pin )
77+ bool sigmaDeltaDetach (uint8_t pin )
8978{
90- pinMatrixOutDetach (pin , false, false);
79+ void * bus = perimanGetPinBus (pin , ESP32_BUS_TYPE_SIGMADELTA );
80+ if (bus != NULL ){
81+ // will call sigmaDeltaDetachBus
82+ return perimanSetPinBus (pin , ESP32_BUS_TYPE_INIT , NULL );
83+ } else {
84+ log_e ("pin %u is not attached to SigmaDelta" );
85+ }
86+ return false;
9187}
0 commit comments