123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /*
- * Copyright (C) 2018 Shanghai Eastsoft Microelectronics Co., Ltd.
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * 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
- *
- * 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.
- *
- * Change Logs:
- * Date Author Notes
- * 2019-03-11 wangyq the first version
- * 2019-11-01 wangyq update libraries
- * 2021-04-20 liuhy the second version
- */
- #include <rthw.h>
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <board.h>
- #include "es_conf_info_pwm.h"
- #ifdef RT_USING_PWM
- static void pwm_set_duty(timer_handle_t *timer_initstruct, timer_channel_t ch, uint32_t ns)
- {
- uint64_t tmp = (uint64_t)ald_cmu_get_pclk1_clock() * ns / 1000000000 /
- (timer_initstruct->init.prescaler + 1);
- if (ch == TIMER_CHANNEL_1)
- WRITE_REG(timer_initstruct->perh->CCVAL1, (uint32_t)tmp);
- else if (ch == TIMER_CHANNEL_2)
- WRITE_REG(timer_initstruct->perh->CCVAL2, (uint32_t)tmp);
- else if (ch == TIMER_CHANNEL_3)
- WRITE_REG(timer_initstruct->perh->CCVAL3, (uint32_t)tmp);
- else if (ch == TIMER_CHANNEL_4)
- WRITE_REG(timer_initstruct->perh->CCVAL4, (uint32_t)tmp);
- }
- static rt_err_t es32f0_pwm_control(struct rt_device_pwm *device, int cmd, void *arg)
- {
- rt_err_t ret = RT_EOK;
- uint64_t _arr,bus_speed,tmp;
- uint32_t _maxcnt,_ccep_ch_en = 0U;
- timer_channel_t pwm_channel;
- timer_oc_init_t tim_ocinit;
- timer_handle_t *timer_initstruct = (timer_handle_t *)device->parent.user_data;
- struct rt_pwm_configuration *cfg = (struct rt_pwm_configuration *)arg;
- RT_ASSERT(timer_initstruct != RT_NULL);
- /* select pwm output channel */
- if (1 == cfg->channel)
- {
- pwm_channel = TIMER_CHANNEL_1;
- _ccep_ch_en = timer_initstruct->perh->CCEP & TIMER_CCEP_CC1EN_MSK;
- }
- else if (2 == cfg->channel)
- {
- pwm_channel = TIMER_CHANNEL_2;
- _ccep_ch_en = timer_initstruct->perh->CCEP & TIMER_CCEP_CC2EN_MSK;
- }
- else if (3 == cfg->channel)
- {
- pwm_channel = TIMER_CHANNEL_3;
- _ccep_ch_en = timer_initstruct->perh->CCEP & TIMER_CCEP_CC3EN_MSK;
- }
- else if (4 == cfg->channel)
- {
- pwm_channel = TIMER_CHANNEL_4;
- _ccep_ch_en = timer_initstruct->perh->CCEP & TIMER_CCEP_CC4EN_MSK;
- }
- else
- return -RT_EINVAL;
- switch (cmd)
- {
- case PWM_CMD_ENABLE:
- ald_timer_pwm_start(timer_initstruct, pwm_channel);
- break;
- case PWM_CMD_DISABLE:
- ald_timer_pwm_stop(timer_initstruct, pwm_channel);
- break;
- case PWM_CMD_SET:
- /*当通道没开的时候:关通道,设置输出模式和极性,初始化通道*/
- if(!_ccep_ch_en)
- {
- tim_ocinit.oc_mode = ES_PWM_OC_MODE;
- tim_ocinit.oc_polarity = ES_PWM_OC_POLARITY;
- tim_ocinit.oc_fast_en = DISABLE;
- tim_ocinit.ocn_polarity = TIMER_OCN_POLARITY_HIGH;
- tim_ocinit.ocn_idle = TIMER_OCN_IDLE_RESET;
- tim_ocinit.oc_idle = TIMER_OC_IDLE_RESET;
- ald_timer_oc_config_channel(timer_initstruct, &tim_ocinit, pwm_channel);
- }
- bus_speed = (uint64_t)ald_cmu_get_pclk1_clock();
- /*外设的计数器最大值*/
- _maxcnt = 0xFFFF;
- /*当最大分频 <= _maxcnt时:估计大概的分频,加快速度 */
- tmp = bus_speed * (cfg->period)/1000000000/_maxcnt;
- timer_initstruct->init.prescaler = (tmp > 2U) ? (tmp - 2U) : 0U ; /*bus_speed < 500000000*/
- /* count registers max , auto adjust prescaler */
- do
- {
- _arr = bus_speed * (cfg->period) / 1000000000 /(++timer_initstruct->init.prescaler);
- }
- while (_arr > _maxcnt);
- WRITE_REG(timer_initstruct->perh->AR, (uint32_t)_arr);
- timer_initstruct->init.period = (uint32_t)_arr;
- /* update prescaler */
- WRITE_REG(timer_initstruct->perh->PRES, --timer_initstruct->init.prescaler);
- pwm_set_duty(timer_initstruct, pwm_channel, cfg->pulse);
- break;
- case PWM_CMD_GET:
- cfg->pulse = ald_timer_read_capture_value(timer_initstruct, pwm_channel) * 100 /
- READ_REG(timer_initstruct->perh->AR);
- break;
- default:
- break;
- }
- return ret;
- }
- const static struct rt_pwm_ops es32f0_pwm_ops =
- {
- es32f0_pwm_control
- };
- int rt_hw_pwm_init(void)
- {
- rt_err_t ret = RT_EOK;
- gpio_init_t gpio_initstructure;
- gpio_initstructure.mode = GPIO_MODE_OUTPUT;
- gpio_initstructure.odos = GPIO_PUSH_PULL;
- gpio_initstructure.pupd = GPIO_PUSH_UP;
- gpio_initstructure.odrv = GPIO_OUT_DRIVE_NORMAL;
- gpio_initstructure.flt = GPIO_FILTER_DISABLE;
- gpio_initstructure.type = GPIO_TYPE_TTL;
- #ifdef BSP_USING_AD16C4T0_PWM /* 4 channels */
- static struct rt_device_pwm ad16c4t0_pwm_dev;
- static timer_handle_t ad16c4t0_timer_initstruct;
- ad16c4t0_timer_initstruct.perh = AD16C4T0;
- ald_timer_pwm_init(&ad16c4t0_timer_initstruct);
- /* gpio initialization */
- #if defined(ES_AD16C4T0_CH1_GPIO_FUNC)&&defined(ES_AD16C4T0_CH1_GPIO_PORT)&&defined(ES_AD16C4T0_CH1_GPIO_PIN)
- gpio_initstructure.func = ES_AD16C4T0_CH1_GPIO_FUNC;
- ald_gpio_init(ES_AD16C4T0_CH1_GPIO_PORT, ES_AD16C4T0_CH1_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_AD16C4T0_CH2_GPIO_FUNC)&&defined(ES_AD16C4T0_CH2_GPIO_PORT)&&defined(ES_AD16C4T0_CH2_GPIO_PIN)
- gpio_initstructure.func = ES_AD16C4T0_CH2_GPIO_FUNC;
- ald_gpio_init(ES_AD16C4T0_CH2_GPIO_PORT, ES_AD16C4T0_CH2_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_AD16C4T0_CH3_GPIO_FUNC)&&defined(ES_AD16C4T0_CH3_GPIO_PORT)&&defined(ES_AD16C4T0_CH3_GPIO_FUNC)
- gpio_initstructure.func = ES_AD16C4T0_CH3_GPIO_FUNC;
- ald_gpio_init(ES_AD16C4T0_CH3_GPIO_PORT, ES_AD16C4T0_CH3_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_AD16C4T0_CH4_GPIO_FUNC)&&defined(ES_AD16C4T0_CH4_GPIO_PORT)&&defined(ES_AD16C4T0_CH4_GPIO_PIN)
- gpio_initstructure.func = ES_AD16C4T0_CH4_GPIO_FUNC;
- ald_gpio_init(ES_AD16C4T0_CH4_GPIO_PORT, ES_AD16C4T0_CH4_GPIO_PIN, &gpio_initstructure);
- #endif
- ret = rt_device_pwm_register(&ad16c4t0_pwm_dev, ES_DEVICE_NAME_AD16C4T0_PWM, &es32f0_pwm_ops,
- &ad16c4t0_timer_initstruct);
- #endif
- #ifdef BSP_USING_GP16C4T0_PWM /* 4 channels */
- static struct rt_device_pwm gp16c4t0_pwm_dev;
- static timer_handle_t gp16c4t0_timer_initstruct;
- gp16c4t0_timer_initstruct.perh = GP16C4T0;
- ald_timer_pwm_init(&gp16c4t0_timer_initstruct);
- /* gpio initialization */
- #if defined(ES_GP16C4T0_CH1_GPIO_FUNC)&&defined(ES_GP16C4T0_CH1_GPIO_PORT)&&defined(ES_GP16C4T0_CH1_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C4T0_CH1_GPIO_FUNC;
- ald_gpio_init(ES_GP16C4T0_CH1_GPIO_PORT, ES_GP16C4T0_CH1_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_GP16C4T0_CH2_GPIO_FUNC)&&defined(ES_GP16C4T0_CH2_GPIO_PORT)&&defined(ES_GP16C4T0_CH2_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C4T0_CH2_GPIO_FUNC;
- ald_gpio_init(ES_GP16C4T0_CH2_GPIO_PORT, ES_GP16C4T0_CH2_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_GP16C4T0_CH3_GPIO_FUNC)&&defined(ES_GP16C4T0_CH3_GPIO_PORT)&&defined(ES_GP16C4T0_CH3_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C4T0_CH3_GPIO_FUNC;
- ald_gpio_init(ES_GP16C4T0_CH3_GPIO_PORT, ES_GP16C4T0_CH3_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_GP16C4T0_CH4_GPIO_FUNC)&&defined(ES_GP16C4T0_CH4_GPIO_PORT)&&defined(ES_GP16C4T0_CH4_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C4T0_CH4_GPIO_FUNC;
- ald_gpio_init(ES_GP16C4T0_CH4_GPIO_PORT, ES_GP16C4T0_CH4_GPIO_PIN, &gpio_initstructure);
- #endif
- ret = rt_device_pwm_register(&gp16c4t0_pwm_dev, ES_DEVICE_NAME_GP16C4T0_PWM, &es32f0_pwm_ops,
- &gp16c4t0_timer_initstruct);
- #endif
- #ifdef BSP_USING_GP16C2T0_PWM /* 2 channels */
- static struct rt_device_pwm gp16c2t0_pwm_dev;
- static timer_handle_t gp16c2t0_timer_initstruct;
- gp16c2t0_timer_initstruct.perh = GP16C2T0;
- ald_timer_pwm_init(&gp16c2t0_timer_initstruct);
- /* gpio initialization */
- #if defined(ES_GP16C2T0_CH1_GPIO_FUNC)&&defined(ES_GP16C2T0_CH1_GPIO_PORT)&&defined(ES_GP16C2T0_CH1_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C2T0_CH1_GPIO_FUNC;
- ald_gpio_init(ES_GP16C2T0_CH1_GPIO_PORT, ES_GP16C2T0_CH1_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_GP16C2T0_CH2_GPIO_FUNC)&&defined(ES_GP16C2T0_CH2_GPIO_PORT)&&defined(ES_GP16C2T0_CH2_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C2T0_CH2_GPIO_FUNC;
- ald_gpio_init(ES_GP16C2T0_CH2_GPIO_PORT, ES_GP16C2T0_CH2_GPIO_PIN, &gpio_initstructure);
- #endif
- ret = rt_device_pwm_register(&gp16c2t0_pwm_dev, ES_DEVICE_NAME_GP16C2T0_PWM, &es32f0_pwm_ops,
- &gp16c2t0_timer_initstruct);
- #endif
- #ifdef BSP_USING_GP16C2T1_PWM /* 2 channels */
- static struct rt_device_pwm gp16c2t1_pwm_dev;
- static timer_handle_t gp16c2t1_timer_initstruct;
- gp16c2t1_timer_initstruct.perh = GP16C2T1;
- ald_timer_pwm_init(&gp16c2t1_timer_initstruct);
- /* gpio initialization */
- #if defined(ES_GP16C2T1_CH1_GPIO_FUNC)&&defined(ES_GP16C2T1_CH1_GPIO_PORT)&&defined(ES_GP16C2T1_CH1_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C2T1_CH1_GPIO_FUNC;
- ald_gpio_init(ES_GP16C2T1_CH1_GPIO_PORT, ES_GP16C2T1_CH1_GPIO_PIN, &gpio_initstructure);
- #endif
- #if defined(ES_GP16C2T1_CH2_GPIO_FUNC)&&defined(ES_GP16C2T1_CH2_GPIO_PORT)&&defined(ES_GP16C2T1_CH2_GPIO_PIN)
- gpio_initstructure.func = ES_GP16C2T1_CH2_GPIO_FUNC;
- ald_gpio_init(ES_GP16C2T1_CH2_GPIO_PORT, ES_GP16C2T1_CH2_GPIO_PIN, &gpio_initstructure);
- #endif
- ret = rt_device_pwm_register(&gp16c2t1_pwm_dev, ES_DEVICE_NAME_GP16C2T1_PWM, &es32f0_pwm_ops,
- &gp16c2t1_timer_initstruct);
- #endif
- return ret;
- }
- INIT_DEVICE_EXPORT(rt_hw_pwm_init);
- #endif
|