From d22df879ace32d18a6fed07427a14f2f3b92b009 Mon Sep 17 00:00:00 2001 From: 勤为本 <1207280597@qq.com> Date: Tue, 18 Jul 2017 11:28:02 +0800 Subject: 将“龙芯1c库â€�中硬件pwm相关接å�£ç§»æ¤�到RT-Thread MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/ls1cdev/libraries/ls1c_pwm.c | 197 +++++++++++++++++++++++++++++++++++++++ bsp/ls1cdev/libraries/ls1c_pwm.h | 77 +++++++++++++++ 2 files changed, 274 insertions(+) create mode 100644 bsp/ls1cdev/libraries/ls1c_pwm.c create mode 100644 bsp/ls1cdev/libraries/ls1c_pwm.h (limited to 'bsp') diff --git a/bsp/ls1cdev/libraries/ls1c_pwm.c b/bsp/ls1cdev/libraries/ls1c_pwm.c new file mode 100644 index 0000000000..01ffc6f3a9 --- /dev/null +++ b/bsp/ls1cdev/libraries/ls1c_pwm.c @@ -0,0 +1,197 @@ +// ·â×°Ó²¼þpwm½Ó¿Ú + +#include "ls1c_public.h" +#include "ls1c_pin.h" +#include "ls1c_pwm.h" +#include "ls1c_clock.h" +#include "ls1c_regs.h" + + + +// pwmµÄ×î´óÖÜÆÚ +#define PWM_MAX_PERIOD (0xFFFFFF) // ¼ÆÊýÆ÷µÄÖµ + + + +/* + * ¸ù¾Ýgpio»ñÈ¡ÏàÓ¦pwmµÄ»ùµØÖ· + * @gpio pwmÒý½Å + * @ret pwm»ùµØÖ· + */ +unsigned int pwm_get_reg_base(unsigned int gpio) +{ + unsigned int reg_base = 0; + + switch (gpio) + { + case LS1C_PWM0_GPIO06: + case LS1C_PWM0_GPIO04: + reg_base = LS1C_REG_BASE_PWM0; + break; + + case LS1C_PWM1_GPIO92: + case LS1C_PWM1_GPIO05: + reg_base = LS1C_REG_BASE_PWM1; + break; + + case LS1C_PWM2_GPIO52: + case LS1C_PWM2_GPIO46: + reg_base = LS1C_REG_BASE_PWM2; + break; + + case LS1C_PWM3_GPIO47: + case LS1C_PWM3_GPIO53: + reg_base = LS1C_REG_BASE_PWM3; + break; + } + + return reg_base; +} + + +/* + * ½ûÖ¹pwm + * @pwm_info PWMnµÄÏêϸÐÅÏ¢ + */ +void pwm_disable(pwm_info_t *pwm_info) +{ + unsigned int pwm_reg_base = 0; + + // ¼ì²éÈë²Î + if (NULL == pwm_info) + { + return ; + } + + pwm_reg_base = pwm_get_reg_base(pwm_info->gpio); + reg_write_32(0, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_CTRL)); + + return ; +} + + + +/* + * ʹÄÜPWM + * @pwm_info PWMnµÄÏêϸÐÅÏ¢ + */ +void pwm_enable(pwm_info_t *pwm_info) +{ + unsigned int pwm_reg_base = 0; + unsigned int ctrl = 0; + + // ¼ì²éÈë²Î + if (NULL == pwm_info) + { + return ; + } + + // »ñÈ¡»ùµØÖ· + pwm_reg_base = pwm_get_reg_base(pwm_info->gpio); + + // ÇåÁã¼ÆÊýÆ÷ + reg_write_32(0, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_CNTR)); + + // ÉèÖÿØÖƼĴæÆ÷ + ctrl = (0 << LS1C_PWM_INT_LRC_EN) + | (0 << LS1C_PWM_INT_HRC_EN) + | (0 << LS1C_PWM_CNTR_RST) + | (0 << LS1C_PWM_INT_SR) + | (0 << LS1C_PWM_INTEN) + | (0 << LS1C_PWM_OE) + | (1 << LS1C_PWM_CNT_EN); + if (PWM_MODE_PULSE == pwm_info->mode) // µ¥Âö³å + { + ctrl |= (1 << LS1C_PWM_SINGLE); + } + else // Á¬ÐøÂö³å + { + ctrl &= ~(1 << LS1C_PWM_SINGLE); + } + reg_write_32(ctrl, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_CTRL)); + + return ; +} + + + +/* + * ³õʼ»¯PWMn + * @pwm_info PWMnµÄÏêϸÐÅÏ¢ + */ +void pwm_init(pwm_info_t *pwm_info) +{ + unsigned int gpio; + unsigned long pwm_clk = 0; // pwmÄ£¿éµÄʱÖÓÆµÂÊ + unsigned long tmp = 0; + unsigned int pwm_reg_base = 0; + unsigned long period = 0; + + // ÅжÏÈë²Î + if (NULL == pwm_info) + { + // Èë²Î·Ç·¨£¬ÔòÖ±½Ó·µ»Ø + return ; + } + gpio = pwm_info->gpio; + + // ÅäÖÃÏàÓ¦Òý½ÅÓÃ×÷pwm£¬¶ø·Çgpio + pin_set_purpose(gpio, PIN_PURPOSE_OTHER); + + // ¸´Óà + switch (gpio) + { + // ²»ÐèÒª¸´Óà + case LS1C_PWM0_GPIO06: + case LS1C_PWM1_GPIO92: + break; + + case LS1C_PWM0_GPIO04: // gpio04µÄµÚÈý¸´Óà + pin_set_remap(LS1C_PWM0_GPIO04, PIN_REMAP_THIRD); + break; + + case LS1C_PWM1_GPIO05: // gpio05µÄµÚÈý¸´Óà + pin_set_remap(LS1C_PWM1_GPIO05, PIN_REMAP_THIRD); + break; + + case LS1C_PWM2_GPIO52: // gpio52µÄµÚËĸ´Óà + pin_set_remap(LS1C_PWM2_GPIO52, PIN_REMAP_FOURTH); + break; + + case LS1C_PWM2_GPIO46: // gpio46µÄµÚËĸ´Óà + pin_set_remap(LS1C_PWM2_GPIO46, PIN_REMAP_FOURTH); + break; + + case LS1C_PWM3_GPIO47: // gpio47µÄµÚËĸ´Óà + pin_set_remap(LS1C_PWM3_GPIO47, PIN_REMAP_FOURTH); + break; + + case LS1C_PWM3_GPIO53: // gpio53µÄµÚËĸ´Óà + pin_set_remap(LS1C_PWM3_GPIO53, PIN_REMAP_FOURTH); + break; + + default: + break; + } + + // ¸ù¾ÝÕ¼¿Õ±ÈºÍpwmÖÜÆÚ¼ÆËã¼Ä´æÆ÷HRCºÍLRCµÄÖµ + // Á½¸ö64λÊýÏà³Ë£¬Ö»Äܵõ½µÍ32룬linuxÏÂÈ´¿ÉÒԵõ½64λ½á¹û£¬ + // Ôݲ»Çå³þÔ­Òò£¬Óø¡µãÔËËã´úÌæ + pwm_clk = clk_get_apb_rate(); + period = (1.0 * pwm_clk * pwm_info->period_ns) / 1000000000; + period = MIN(period, PWM_MAX_PERIOD); // ÏÞÖÆÖÜÆÚ²»Äܳ¬¹ý×î´óÖµ + tmp = period - (period * pwm_info->duty); + + // д¼Ä´æÆ÷HRCºÍLRC + pwm_reg_base = pwm_get_reg_base(gpio); + reg_write_32(--tmp, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_HRC)); + reg_write_32(--period, (volatile unsigned int *)(pwm_reg_base + LS1C_PWM_LRC)); + + // дÖ÷¼ÆÊýÆ÷ + pwm_enable(pwm_info); + + return ; +} + + + diff --git a/bsp/ls1cdev/libraries/ls1c_pwm.h b/bsp/ls1cdev/libraries/ls1c_pwm.h new file mode 100644 index 0000000000..aa9daeeb0c --- /dev/null +++ b/bsp/ls1cdev/libraries/ls1c_pwm.h @@ -0,0 +1,77 @@ + + +#ifndef __OPENLOONGSON_PWM_H +#define __OPENLOONGSON_PWM_H + + +// pwmÒý½Å¶¨Òå +#define LS1C_PWM0_GPIO06 (6) // gpio06ÓÃ×÷pwm0 +#define LS1C_PWM0_GPIO04 (4) // gpio04¸´ÓÃΪpwm0 +#define LS1C_PWM1_GPIO92 (92) // gpio92ÓÃ×÷pwm1 +#define LS1C_PWM1_GPIO05 (5) // gpio05¸´ÓÃΪpwm1 +#define LS1C_PWM2_GPIO52 (52) // gpio52¸´ÓÃΪpwm2 +#define LS1C_PWM2_GPIO46 (46) // gpio46¸´ÓÃΪpwm2 +#define LS1C_PWM3_GPIO47 (47) // gpio47¸´ÓÃΪpwm3 +#define LS1C_PWM3_GPIO53 (53) // gpio53¸´ÓÃΪpwm3 +// ...»¹ÓÐһЩgpio¿ÉÒÔ¸´ÓÃΪgpioµÄ£¬ÓÐÐèÒª¿ÉÒÔ×Ô¼ºÌí¼Ó + + + +// pwm¿ØÖƼĴæÆ÷µÄÿ¸öbit +#define LS1C_PWM_INT_LRC_EN (11) // µÍÂö³å¼ÆÊýÆ÷ÖжÏʹÄÜ +#define LS1C_PWM_INT_HRC_EN (10) // ¸ßÂö³å¼ÆÊýÆ÷ÖжÏʹÄÜ +#define LS1C_PWM_CNTR_RST (7) // ʹÄÜCNTR¼ÆÊýÆ÷ÇåÁã +#define LS1C_PWM_INT_SR (6) // ÖжÏ״̬λ +#define LS1C_PWM_INTEN (5) // ÖжÏʹÄÜλ +#define LS1C_PWM_SINGLE (4) // µ¥Âö³å¿ØÖÆÎ» +#define LS1C_PWM_OE (3) // Âö³åÊä³öʹÄÜ +#define LS1C_PWM_CNT_EN (0) // Ö÷¼ÆÊýÆ÷ʹÄÜ + + +// Ó²¼þpwm¹¤×÷ģʽ +enum +{ + // Õý³£Ä£Ê½--Á¬ÐøÊä³öpwm²¨ÐÎ + PWM_MODE_NORMAL = 0, + + // µ¥Âö³åģʽ£¬Ã¿´Îµ÷ÓÃÖ»·¢ËÍÒ»¸öÂö³å£¬µ÷Óüä¸ô±ØÐë´óÓÚpwmÖÜÆÚ + PWM_MODE_PULSE +}; + + +// Ó²¼þpwmÐÅÏ¢ +typedef struct +{ + unsigned int gpio; // PWMnËùÔÚµÄgpio + unsigned int mode; // ¹¤×÷ģʽ(µ¥Âö³å¡¢Á¬ÐøÂö³å) + float duty; // pwmµÄÕ¼¿Õ±È + unsigned long period_ns; // pwmÖÜÆÚ(µ¥Î»ns) +}pwm_info_t; + + + + +/* + * ³õʼ»¯PWMn + * @pwm_info PWMnµÄÏêϸÐÅÏ¢ + */ +void pwm_init(pwm_info_t *pwm_info); + + +/* + * ½ûÖ¹pwm + * @pwm_info PWMnµÄÏêϸÐÅÏ¢ + */ +void pwm_disable(pwm_info_t *pwm_info); + + + +/* + * ʹÄÜPWM + * @pwm_info PWMnµÄÏêϸÐÅÏ¢ + */ +void pwm_enable(pwm_info_t *pwm_info); + + +#endif + -- cgit v1.3.1