| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | // Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Licensed under the Apache License, Version 2.0 (the "License");
 | 
					
						
							|  |  |  | // you may not use this file except in compliance with the License.
 | 
					
						
							|  |  |  | // You may obtain a copy of the License at
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | //     http://www.apache.org/licenses/LICENSE-2.0
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // Unless required by applicable law or agreed to in writing, software
 | 
					
						
							|  |  |  | // distributed under the License is distributed on an "AS IS" BASIS,
 | 
					
						
							|  |  |  | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					
						
							|  |  |  | // See the License for the specific language governing permissions and
 | 
					
						
							|  |  |  | // limitations under the License.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "esp32-hal.h"
 | 
					
						
							|  |  |  | #include "freertos/FreeRTOS.h"
 | 
					
						
							|  |  |  | #include "freertos/task.h"
 | 
					
						
							|  |  |  | #include "freertos/semphr.h"
 | 
					
						
							|  |  |  | #include "rom/ets_sys.h"
 | 
					
						
							|  |  |  | #include "esp32-hal-matrix.h"
 | 
					
						
							|  |  |  | #include "soc/gpio_sd_reg.h"
 | 
					
						
							|  |  |  | #include "soc/gpio_sd_struct.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | #if CONFIG_DISABLE_HAL_LOCKS
 | 
					
						
							|  |  |  | #define SD_MUTEX_LOCK()
 | 
					
						
							|  |  |  | #define SD_MUTEX_UNLOCK()
 | 
					
						
							|  |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | #define SD_MUTEX_LOCK()    do {} while (xSemaphoreTake(_sd_sys_lock, portMAX_DELAY) != pdPASS)
 | 
					
						
							|  |  |  | #define SD_MUTEX_UNLOCK()  xSemaphoreGive(_sd_sys_lock)
 | 
					
						
							| 
									
										
										
										
											2016-11-18 15:07:25 +02:00
										 |  |  | xSemaphoreHandle _sd_sys_lock; | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  | static void _on_apb_change(void * arg, apb_change_ev_t ev_type, uint32_t old_apb, uint32_t new_apb){ | 
					
						
							|  |  |  |     if(old_apb == new_apb){ | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     uint32_t iarg = (uint32_t)arg; | 
					
						
							|  |  |  |     uint8_t channel = iarg; | 
					
						
							|  |  |  |     if(ev_type == APB_BEFORE_CHANGE){ | 
					
						
							|  |  |  |         SIGMADELTA.cg.clk_en = 0; | 
					
						
							|  |  |  |     } else { | 
					
						
							|  |  |  |         old_apb /= 1000000; | 
					
						
							|  |  |  |         new_apb /= 1000000; | 
					
						
							|  |  |  |         SD_MUTEX_LOCK(); | 
					
						
							|  |  |  |         uint32_t old_prescale = SIGMADELTA.channel[channel].prescale + 1; | 
					
						
							|  |  |  |         SIGMADELTA.channel[channel].prescale = ((new_apb * old_prescale) / old_apb) - 1; | 
					
						
							|  |  |  |         SIGMADELTA.cg.clk_en = 0; | 
					
						
							|  |  |  |         SIGMADELTA.cg.clk_en = 1; | 
					
						
							|  |  |  |         SD_MUTEX_UNLOCK(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | uint32_t sigmaDeltaSetup(uint8_t channel, uint32_t freq) //chan 0-7 freq 1220-312500
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     if(channel > 7) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | #if !CONFIG_DISABLE_HAL_LOCKS
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  |     static bool tHasStarted = false; | 
					
						
							|  |  |  |     if(!tHasStarted) { | 
					
						
							|  |  |  |         tHasStarted = true; | 
					
						
							|  |  |  |         _sd_sys_lock = xSemaphoreCreateMutex(); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2018-12-20 01:57:32 +01:00
										 |  |  |     uint32_t apb_freq = getApbFrequency(); | 
					
						
							|  |  |  |     uint32_t prescale = (apb_freq/(freq*256)) - 1; | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  |     if(prescale > 0xFF) { | 
					
						
							|  |  |  |         prescale = 0xFF; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     SD_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  |     SIGMADELTA.channel[channel].prescale = prescale; | 
					
						
							|  |  |  |     SIGMADELTA.cg.clk_en = 0; | 
					
						
							|  |  |  |     SIGMADELTA.cg.clk_en = 1; | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  |     SD_MUTEX_UNLOCK(); | 
					
						
							| 
									
										
										
										
											2019-01-09 10:07:54 +01:00
										 |  |  |     uint32_t iarg = channel; | 
					
						
							|  |  |  |     addApbChangeCallback((void*)iarg, _on_apb_change); | 
					
						
							| 
									
										
										
										
											2018-12-20 01:57:32 +01:00
										 |  |  |     return apb_freq/((prescale + 1) * 256); | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | void sigmaDeltaWrite(uint8_t channel, uint8_t duty) //chan 0-7 duty 8 bit
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     if(channel > 7) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2018-05-14 13:18:03 +02:00
										 |  |  |     duty -= 128; | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  |     SD_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  |     SIGMADELTA.channel[channel].duty = duty; | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  |     SD_MUTEX_UNLOCK(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | uint8_t sigmaDeltaRead(uint8_t channel) //chan 0-7
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     if(channel > 7) { | 
					
						
							|  |  |  |         return 0; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  |     SD_MUTEX_LOCK(); | 
					
						
							| 
									
										
										
										
											2018-05-14 13:18:03 +02:00
										 |  |  |     uint8_t duty = SIGMADELTA.channel[channel].duty + 128; | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  |     SD_MUTEX_UNLOCK(); | 
					
						
							|  |  |  |     return duty; | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | void sigmaDeltaAttachPin(uint8_t pin, uint8_t channel) //channel 0-7
 | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     if(channel > 7) { | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     pinMode(pin, OUTPUT); | 
					
						
							|  |  |  |     pinMatrixOutAttach(pin, GPIO_SD0_OUT_IDX + channel, false, false); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-01-09 17:57:17 +02:00
										 |  |  | void sigmaDeltaDetachPin(uint8_t pin) | 
					
						
							| 
									
										
										
										
											2016-10-20 00:31:03 +03:00
										 |  |  | { | 
					
						
							|  |  |  |     pinMatrixOutDetach(pin, false, false); | 
					
						
							|  |  |  | } |