1
0
Эх сурвалжийг харах

将“龙芯1c库”中的GPIO相关接口移植到RT-Thread

勤为本 7 жил өмнө
parent
commit
0940301981

+ 40 - 0
bsp/ls1cdev/drivers/led.c

@@ -0,0 +1,40 @@
+// led接口
+// 使用低电平点亮led,高电平熄灭led
+
+
+#include "ls1c_gpio.h"
+
+
+// 初始化led
+// @led_gpio led所在gpio引脚
+void led_init(unsigned int led_gpio)
+{
+    gpio_init(led_gpio, gpio_mode_output);
+    gpio_set(led_gpio, gpio_level_high);        // 指示灯默认熄灭
+
+    return ;
+}
+
+
+// 点亮led
+// @led_gpio led所在gpio引脚
+void led_on(unsigned int led_gpio)
+{
+    gpio_set(led_gpio, gpio_level_low);
+
+    return ;
+}
+
+
+// 熄灭led
+// @led_gpio
+void led_off(unsigned int led_gpio)
+{
+    gpio_set(led_gpio, gpio_level_high);
+
+    return ;
+}
+
+
+
+

+ 27 - 0
bsp/ls1cdev/drivers/led.h

@@ -0,0 +1,27 @@
+// led接口
+// 使用低电平点亮led,高电平熄灭led
+
+#ifndef __OPENLOONGSON_LED_H
+#define __OPENLOONGSON_LED_H
+
+
+// 初始化led
+// @led_gpio led所在gpio引脚
+void led_init(unsigned int led_gpio);
+
+
+// 点亮led
+// @led_gpio led所在gpio引脚
+void led_on(unsigned int led_gpio);
+
+
+// 熄灭led
+// @led_gpio
+void led_off(unsigned int led_gpio);
+
+
+
+
+
+#endif
+

+ 10 - 0
bsp/ls1cdev/libraries/SConscript

@@ -0,0 +1,10 @@
+from building import *
+
+cwd = GetCurrentDir()
+src = Glob('*.c')
+
+CPPPATH = [cwd]
+
+group = DefineGroup('Libraries', src, depend = [''], CPPPATH = CPPPATH)
+
+Return('group')

+ 155 - 0
bsp/ls1cdev/libraries/ls1c_clock.c

@@ -0,0 +1,155 @@
+/*************************************************************************
+ *
+ * 时钟相关函数
+ *
+ *************************************************************************/
+
+
+#include "ls1c_regs.h"
+#include "ls1c_public.h"
+
+
+// 晶振的频率
+#define AHB_CLK                 (24000000)
+#define APB_CLK                 (AHB_CLK)
+
+
+// START_FREQ寄存器bits
+#define M_PLL_SHIFT             (8)
+#define M_PLL                   (0xff << M_PLL_SHIFT)       // PLL倍频系数的整数部分
+#define FRAC_N_SHIFT            (16)
+#define FRAC_N                  (0xff << FRAC_N_SHIFT)      // PLL倍频系数的小数部分
+#define DIV_SDRAM_SHIFT         (0)
+#define DIV_SDRAM               (0x3  << DIV_SDRAM_SHIFT)
+
+// CLK_DIV_PARAM寄存器bits
+#define DIV_PIX_EN              (0x1  << 31)
+#define DIV_PIX                 (0x7f << 24)
+#define DIV_CAM_EN              (0x1  << 23)
+#define DIV_CAM                 (0x7f << 16)
+#define DIV_CPU_EN              (0x1  << 15)
+#define DIV_CPU                 (0x7f << 8)
+#define DIV_PIX_VALID           (0x1  << 5)
+#define DIV_PIX_SEL             (0x1  << 4)
+#define DIV_CAM_VALID           (0x1  << 3)
+#define DIV_CAM_SEL             (0x1  << 2)
+#define DIV_CPU_VALID           (0x1  << 1)
+#define DIV_CPU_SEL             (0x1  << 0)
+
+#define DIV_PIX_SHIFT           (24)
+#define DIV_CAM_SHIFT           (16)
+#define DIV_CPU_SHIFT           (8)
+
+
+/*
+ * 获取PLL频率
+ * @ret PLL频率
+ */
+unsigned long clk_get_pll_rate(void)
+{
+    unsigned int ctrl;
+    unsigned long pll_rate = 0;
+
+    ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ);
+    pll_rate = (((ctrl & M_PLL) >> M_PLL_SHIFT) + ((ctrl & FRAC_N) >> FRAC_N_SHIFT)) * APB_CLK / 4;
+    
+    return pll_rate;
+}
+
+
+/*
+ * 获取CPU频率
+ * @ret CPU频率
+ */
+unsigned long clk_get_cpu_rate(void)
+{
+    unsigned long pll_rate, cpu_rate;
+    unsigned int ctrl;
+
+    pll_rate = clk_get_pll_rate();
+    ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM);
+
+    // 选择时钟来源
+    if (DIV_CPU_SEL & ctrl)     // pll分频作为时钟信号
+    {
+        if (DIV_CPU_EN & ctrl)
+        {
+            cpu_rate = pll_rate / ((ctrl & DIV_CPU) >> DIV_CPU_SHIFT);
+        }
+        else
+        {
+            cpu_rate = pll_rate / 2;
+        }
+    }
+    else                        // bypass模式,晶振作为时钟输入
+    {
+        cpu_rate = APB_CLK;
+    }
+
+    return cpu_rate;
+}
+
+
+/*
+ * 获取DDR频率
+ * @ret DDR频率
+ */
+unsigned long clk_get_ddr_rate(void)
+{
+    unsigned long cpu_rate = 0;
+    unsigned long ddr_rate = 0;
+    unsigned int ctrl;
+
+    cpu_rate = clk_get_cpu_rate();
+    ctrl = reg_read_32((volatile unsigned int *)LS1C_START_FREQ);
+    ctrl = (ctrl & DIV_SDRAM) >> DIV_SDRAM_SHIFT;
+
+    switch (ctrl)
+    {
+        case 0:
+            ddr_rate = cpu_rate / 2;
+            break;
+
+        case 1:
+            ddr_rate = cpu_rate / 4;
+            break;
+
+        case 2:
+        case 3:
+            ddr_rate = cpu_rate / 3;
+            break;
+    }
+
+    return ddr_rate;
+}
+
+
+/*
+ * 获取APB频率
+ * @ret APB频率
+ */
+unsigned long clk_get_apb_rate(void)
+{
+    return clk_get_ddr_rate();
+}
+
+
+/*
+ * 获取DC频率
+ * @ret DC频率
+ */
+unsigned long clk_get_dc_rate(void)
+{
+    unsigned long pll_rate, dc_rate;
+    unsigned int ctrl;
+
+    pll_rate = clk_get_pll_rate();
+    ctrl = reg_read_32((volatile unsigned int *)LS1C_CLK_DIV_PARAM);
+
+    dc_rate = pll_rate / ((ctrl & DIV_PIX) >> DIV_PIX_SHIFT);
+
+    return dc_rate;
+}
+
+
+

+ 51 - 0
bsp/ls1cdev/libraries/ls1c_clock.h

@@ -0,0 +1,51 @@
+/*************************************************************************
+ *
+ * 时钟相关头文件
+ *
+ *************************************************************************/
+
+
+#ifndef __OPENLOONGSON_CLOCK_H
+#define __OPENLOONGSON_CLOCK_H
+
+
+
+/*
+ * 获取PLL频率
+ * @ret PLL频率
+ */
+unsigned long clk_get_pll_rate(void);
+
+
+/*
+ * 获取CPU频率
+ * @ret CPU频率
+ */
+unsigned long clk_get_cpu_rate(void);
+
+
+
+/*
+ * 获取DDR频率
+ * @ret DDR频率
+ */
+unsigned long clk_get_ddr_rate(void);
+
+
+/*
+ * 获取APB频率
+ * @ret APB频率
+ */
+unsigned long clk_get_apb_rate(void);
+
+
+/*
+ * 获取DC频率
+ * @ret DC频率
+ */
+unsigned long clk_get_dc_rate(void);
+
+
+
+#endif
+

+ 80 - 0
bsp/ls1cdev/libraries/ls1c_delay.c

@@ -0,0 +1,80 @@
+// 软件延时源文件
+
+
+#include "ls1c_clock.h"
+
+
+
+
+/*
+ * 延时指定时间,单位ms
+ * @j 延时时间,单位ms
+ */
+void delay_ms(int j)
+{
+    int k_max = clk_get_cpu_rate()/1000/3;  // 除以1000表示ms,除以3为测试所得的经验(可以理解为最内层循环执行一次需要的时钟个数)
+    int k = k_max;
+
+    for ( ; j > 0; j--)
+    {
+        for (k = k_max; k > 0; k--)
+        {
+            __asm__ ("nop");        // 注意,这里必须用内联汇编,否则会被优化掉
+        }
+    }
+
+    return ;
+}
+
+
+/*
+ * 延时指定时间,单位us
+ * @n 延时时间,单位us
+ */
+void delay_us(int n)
+{
+    int count_1us = clk_get_cpu_rate() / 1000000 / 3;   // 延时1us的循环次数
+    int count_max;                                      // 延时n微秒的循环次数
+    int tmp;
+
+    // 根据延时长短微调(注意,这里是手动优化的,cpu频率改变了可能需要重新优化,此时cpu频率为252Mhz)
+    if (10 >= n)                // <=10us
+    {
+        count_1us -= 35;
+    }
+    else if (100 >= n)          // <= 100us
+    {
+        count_1us -= 6;
+    }
+    else                        // > 100us
+    {
+        count_1us -= 1;
+    }
+    count_max = n * count_1us;
+
+    // 延时
+    for (tmp = count_max; tmp > 0; tmp--)
+    {
+        __asm__ ("nop");        // 注意,这里必须用内联汇编,否则会被优化掉            
+    }
+
+    return ;
+}
+
+
+/*
+ * 延时指定时间,单位s
+ * @i 延时时间,单位s
+ */
+void delay_s(int i)
+{
+    for ( ; i > 0; i--)
+    {
+        delay_ms(1000);
+    }
+
+    return ;
+}
+
+
+

+ 34 - 0
bsp/ls1cdev/libraries/ls1c_delay.h

@@ -0,0 +1,34 @@
+// 软件延时头文件
+
+
+
+#ifndef __OPENLOONGSON_DELAY_H
+#define __OPENLOONGSON_DELAY_H
+
+
+
+/*
+ * 延时指定时间,单位ms
+ * @j 延时时间,单位ms
+ */
+void delay_ms(int j);
+
+
+/*
+ * 延时指定时间,单位us
+ * @n 延时时间,单位us
+ */
+void delay_us(int n);
+
+
+/*
+ * 延时指定时间,单位s
+ * @i 延时时间,单位s
+ */
+void delay_s(int i);
+
+
+
+
+#endif
+

+ 207 - 0
bsp/ls1cdev/libraries/ls1c_gpio.c

@@ -0,0 +1,207 @@
+// 封装gpio接口
+
+
+#include "ls1c_public.h"
+#include "ls1c_regs.h"
+#include "ls1c_gpio.h"
+#include "ls1c_pin.h"
+
+
+/*
+ * 获取指定gpio的CFG寄存器
+ * @gpio gpio编号
+ * @ret CFG寄存器
+ */
+volatile unsigned int *gpio_get_cfg_reg(unsigned int gpio)
+{
+    volatile unsigned int *gpio_cfgx = NULL;            // GPIO_CFGx寄存器
+    unsigned int port = GPIO_GET_PORT(gpio);
+
+    switch (port)
+    {
+        case 0:
+            gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG0;
+            break;
+
+        case 1:
+            gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG1;
+            break;
+
+        case 2:
+            gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG2;
+            break;
+
+        case 3:
+            gpio_cfgx = (volatile unsigned int *)LS1C_GPIO_CFG3;
+            break;
+
+        default:
+            gpio_cfgx = NULL;
+            break;
+    }
+
+    return gpio_cfgx;
+}
+
+
+/*
+ * 获取指定gpio的EN寄存器
+ * @gpio gpio编号
+ * @ret EN寄存器
+ */
+volatile unsigned int *gpio_get_en_reg(unsigned int gpio)
+{
+    volatile unsigned int *gpio_enx = NULL;         // GPIO_ENx寄存器
+    unsigned int port = GPIO_GET_PORT(gpio);
+    
+    switch (port)
+    {
+        case 0:
+            gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN0;
+            break;
+
+        case 1:
+            gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN1;
+            break;
+
+        case 2:
+            gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN2;
+            break;
+
+        case 3:
+            gpio_enx = (volatile unsigned int *)LS1C_GPIO_EN3;
+            break;
+
+        default:
+            gpio_enx    = NULL;
+            return gpio_enx;
+    }
+
+    return gpio_enx;
+}
+
+/*
+ * gpio初始化
+ * @gpio gpio引脚,取值范围[0, 127]
+ * @mode gpio的工作模式(输入、输出)
+ *
+ * 例: 将gpio50初始化为输出
+ * gpio_init(50, gpio_mode_output);
+ */
+void gpio_init(unsigned int gpio, gpio_mode_t mode)
+{
+    volatile unsigned int *gpio_enx = NULL;        // GPIO_ENx寄存器
+    unsigned int pin = GPIO_GET_PIN(gpio);
+
+    // 将pin设为普通GPIO
+    pin_set_purpose(gpio, PIN_PURPOSE_GPIO);
+
+    // 设置gpio工作模式(输入、输出)
+    gpio_enx  = gpio_get_en_reg(gpio);
+    if (gpio_mode_output == mode)       // 输出
+    {
+        reg_clr_one_bit(gpio_enx, pin);
+    }
+    else                                // 输入
+    {
+        reg_set_one_bit(gpio_enx, pin);
+    }
+
+    return ;
+}
+
+
+/*
+ * 在指定gpio输出高电平或低电平
+ * @gpio gpio引脚,取值范围[0, 127]
+ * @level 电平值
+ *
+ * 例: 在gpio50上输出低电平
+ * gpio_set(50, gpio_level_low);
+ */
+void gpio_set(unsigned int gpio, gpio_level_t level)
+{
+    volatile unsigned int *gpio_outx = NULL;       // GPIO_OUTx寄存器
+    unsigned int port   = GPIO_GET_PORT(gpio);
+    unsigned int pin    = GPIO_GET_PIN(gpio);
+
+    // 获取寄存器地址
+    switch (port)
+    {
+        case 0:
+            gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT0;
+            break;
+
+        case 1:
+            gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT1;
+            break;
+
+        case 2:
+            gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT2;
+            break;
+
+        case 3:
+            gpio_outx = (volatile unsigned int *)LS1C_GPIO_OUT3;
+            break;
+
+        default:        // 正确的程序不应该走到这里,直接返回
+            return ;
+    }
+
+    // 输出
+    if (gpio_level_low == level)
+    {
+        reg_clr_one_bit(gpio_outx, pin);
+    }
+    else
+    {
+        reg_set_one_bit(gpio_outx, pin);
+    }
+
+    return ;
+}
+
+
+/*
+ * 读取指定gpio引脚的值
+ * @gpio gpio引脚,取值范围[0,127]
+ *
+ * 例: 读取gpio50引脚上的值
+ * gpio_level_t level;
+ * level = gpio_get(50);
+ */
+unsigned int gpio_get(unsigned int gpio)
+{
+    volatile unsigned int *gpio_inx = NULL;        // GPIO_INx寄存器
+    unsigned int port   = GPIO_GET_PORT(gpio);
+    unsigned int pin    = GPIO_GET_PIN(gpio);
+
+    // 获取寄存器地址
+    switch (port)
+    {
+        case 0:
+            gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN0;
+            break;
+
+        case 1:
+            gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN1;
+            break;
+
+        case 2:
+            gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN2;
+            break;
+
+        case 3:
+            gpio_inx = (volatile unsigned int *)LS1C_GPIO_IN3;
+            break;
+
+        default:        // 正常的流程不应该走到这里,直接返回
+            return 0;
+    }
+
+    // 读取
+    return reg_get_bit(gpio_inx, pin);
+}
+
+
+    

+ 79 - 0
bsp/ls1cdev/libraries/ls1c_gpio.h

@@ -0,0 +1,79 @@
+
+
+#ifndef __OPENLOONGSON_GPIO_H
+#define __OPENLOONGSON_GPIO_H
+
+
+
+// 龙芯1c的gpio是按照0,1,2,3,4...这样的顺序编号的,
+// 但在操作寄存器的时候,又是按照每32个一组来分的
+// 这里利用这个特性,将每组的32个gpio叫做一个"port",每个gpio在每组中的索引叫"pin"
+// port = gpio / 32
+// pin  = gpio % 32
+// 例如GPIO50,port=1,pin=18
+#define GPIO_GET_PORT(gpio)                 ((gpio) / 32)
+#define GPIO_GET_PIN(gpio)                  ((gpio) % 32)
+
+
+// gpio的工作模式--输入、输出
+typedef enum{
+    gpio_mode_output = 0,       // 输出
+    gpio_mode_input = 1         // 输入
+}gpio_mode_t;
+
+
+//  gpio高低电平值
+typedef enum{
+    gpio_level_low = 0,         // 低电平
+    gpio_level_high = 1         // 高电平
+}gpio_level_t;
+
+
+
+
+/*
+ * 获取指定gpio的CFG寄存器
+ * @gpio gpio编号
+ * @ret CFG寄存器
+ */
+volatile unsigned int *gpio_get_cfg_reg(unsigned int gpio);
+
+/*
+ * gpio初始化
+ * @gpio gpio引脚,取值范围[0, 127]
+ * @mode gpio的工作模式(输入、输出)
+ *
+ * 例: 将gpio50初始化为输出
+ * gpio_init(50, gpio_mode_output);
+ */
+void gpio_init(unsigned int gpio, gpio_mode_t mode);
+
+
+/*
+ * 在指定gpio输出高电平或低电平
+ * @gpio gpio引脚,取值范围[0, 127]
+ * @level 电平值
+ *
+ * 例: 在gpio50上输出低电平
+ * gpio_set(50, gpio_level_low);
+ */
+void gpio_set(unsigned int gpio, gpio_level_t level);
+
+
+
+/*
+ * 读取指定gpio引脚的值
+ * @gpio gpio引脚,取值范围[0,127]
+ *
+ * 例: 读取gpio50引脚上的值
+ * gpio_level_t level;
+ * level = gpio_get(50);
+ */
+unsigned int gpio_get(unsigned int gpio);
+
+
+
+
+
+#endif
+

+ 143 - 0
bsp/ls1cdev/libraries/ls1c_pin.c

@@ -0,0 +1,143 @@
+// 引脚功能(普通gpio,pwm,复用等)相关接口
+
+
+#include "ls1c_public.h"
+#include "ls1c_regs.h"
+#include "ls1c_gpio.h"
+#include "ls1c_pin.h"
+
+
+/*
+ * 把指定pin设置为指定用途(普通gpio,非gpio)
+ * @gpio gpio引脚编号
+ * @purpose 用途
+ */
+void pin_set_purpose(unsigned int gpio, pin_purpose_t purpose)
+{
+    volatile unsigned int *gpio_cfgx;           // GPIO_CFGx寄存器
+    unsigned int pin = GPIO_GET_PIN(gpio);
+
+    gpio_cfgx = gpio_get_cfg_reg(gpio);
+    if (PIN_PURPOSE_GPIO == purpose)            // 引脚用作普通gpio
+    {
+        reg_set_one_bit(gpio_cfgx, pin);
+    }
+    else                                        // 引脚用作其它功能(非gpio)
+    {
+        reg_clr_one_bit(gpio_cfgx, pin);
+    }
+
+    return ;
+}
+
+
+
+/*
+ * 设置指定pin为第n复用
+ * @gpio gpio编号
+ * @remap 第n复用
+ */
+void pin_set_remap(unsigned int gpio, pin_remap_t remap)
+{
+    volatile unsigned int *reg = NULL;          // 复用寄存器
+    unsigned int port = GPIO_GET_PORT(gpio);
+    unsigned int pin  = GPIO_GET_PIN(gpio);
+
+    switch (port)
+    {
+        case 0:
+            switch (remap)
+            {
+                case PIN_REMAP_FIRST:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIRST0;
+                    break;
+                case PIN_REMAP_SECOND:
+                    reg = (volatile unsigned int *)LS1C_CBUS_SECOND0;
+                    break;
+                case PIN_REMAP_THIRD:
+                    reg = (volatile unsigned int *)LS1C_CBUS_THIRD0;
+                    break;
+                case PIN_REMAP_FOURTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FOURTH0;
+                    break;
+                case PIN_REMAP_FIFTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIFTH0;
+                    break;
+            }
+            break;
+
+        case 1:
+            switch (remap)
+            {
+                case PIN_REMAP_FIRST:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIRST1;
+                    break;
+                case PIN_REMAP_SECOND:
+                    reg = (volatile unsigned int *)LS1C_CBUS_SECOND1;
+                    break;
+                case PIN_REMAP_THIRD:
+                    reg = (volatile unsigned int *)LS1C_CBUS_THIRD1;
+                    break;
+                case PIN_REMAP_FOURTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FOURTH1;
+                    break;
+                case PIN_REMAP_FIFTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIFTH1;
+                    break;
+            }
+            break;
+
+        case 2:
+            switch (remap)
+            {
+                case PIN_REMAP_FIRST:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIRST2;
+                    break;
+                case PIN_REMAP_SECOND:
+                    reg = (volatile unsigned int *)LS1C_CBUS_SECOND2;
+                    break;
+                case PIN_REMAP_THIRD:
+                    reg = (volatile unsigned int *)LS1C_CBUS_THIRD2;
+                    break;
+                case PIN_REMAP_FOURTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FOURTH2;
+                    break;
+                case PIN_REMAP_FIFTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIFTH2;
+                    break;
+            }
+            break;
+
+        case 3:
+            switch (remap)
+            {
+                case PIN_REMAP_FIRST:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIRST3;
+                    break;
+                case PIN_REMAP_SECOND:
+                    reg = (volatile unsigned int *)LS1C_CBUS_SECOND3;
+                    break;
+                case PIN_REMAP_THIRD:
+                    reg = (volatile unsigned int *)LS1C_CBUS_THIRD3;
+                    break;
+                case PIN_REMAP_FOURTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FOURTH3;
+                    break;
+                case PIN_REMAP_FIFTH:
+                    reg = (volatile unsigned int *)LS1C_CBUS_FIFTH3;
+                    break;
+            }
+            break;
+
+        default:
+            return ;
+    }
+
+    // 置1
+    reg_set_one_bit(reg, pin);
+
+    return ;
+}
+
+
+

+ 43 - 0
bsp/ls1cdev/libraries/ls1c_pin.h

@@ -0,0 +1,43 @@
+// 引脚功能(普通gpio,pwm,复用等)相关接口
+
+#ifndef __OPENLOONGSON_PIN_H
+#define __OPENLOONGSON_PIN_H
+
+
+// 引脚用途
+typedef enum
+{
+    PIN_PURPOSE_GPIO = 0,               // 引脚用作普通gpio
+    PIN_PURPOSE_OTHER,                  // 引脚用作其它功能(非gpio)
+}pin_purpose_t;
+
+
+// 引脚复用
+typedef enum
+{
+    PIN_REMAP_FIRST = 0,                // 第一复用
+    PIN_REMAP_SECOND,                   // 第二复用
+    PIN_REMAP_THIRD,                    // 第三复用
+    PIN_REMAP_FOURTH,                   // 第四复用
+    PIN_REMAP_FIFTH,                    // 第五复用
+}pin_remap_t;
+
+
+/*
+ * 把指定pin设置为指定用途(普通gpio,非gpio)
+ * @gpio gpio引脚编号
+ * @purpose 用途
+ */
+void pin_set_purpose(unsigned int gpio, pin_purpose_t purpose);
+
+
+/*
+ * 设置指定pin为第n复用
+ * @gpio gpio编号
+ * @remap 第n复用
+ */
+void pin_set_remap(unsigned int gpio, pin_remap_t remap);
+
+
+#endif
+

+ 79 - 0
bsp/ls1cdev/libraries/ls1c_public.c

@@ -0,0 +1,79 @@
+// 一些常用的、共用的接口
+
+/*
+ * 将指定寄存器的指定位置1
+ * @reg 寄存器地址
+ * @bit 需要置1的那一bit
+ */
+void reg_set_one_bit(volatile unsigned int *reg, unsigned int bit)
+{
+    unsigned int temp, mask;
+
+    mask = 1 << bit;
+    temp = *reg;
+    temp |= mask;
+    *reg = temp;
+
+    return ;
+}
+
+
+/*
+ * 将指定寄存器的指定位清零
+ * @reg 寄存器地址
+ * @bit 需要清零的那一bit
+ */
+void reg_clr_one_bit(volatile unsigned int *reg, unsigned int bit)
+{
+    unsigned int temp, mask;
+
+    mask = 1 << bit;
+    temp = *reg;
+    temp &= ~mask;
+    *reg = temp;
+
+    return ;
+}
+
+
+
+/*
+ * 获取指定寄存器的指定位的值
+ * @reg 寄存器地址
+ * @bit 需要读取值的那一bit
+ * @ret 指定位的值
+ */
+unsigned int reg_get_bit(volatile unsigned int *reg, unsigned int bit)
+{
+    unsigned int temp;
+
+    temp = *reg;
+    temp = (temp >> bit) & 1;
+
+    return temp;
+}
+
+
+/*
+ * 向寄存器中写一个32bit的数据
+ * @data 待写入的数据
+ * @addr 寄存器地址
+ */
+void reg_write_32(unsigned int data, volatile unsigned int *addr)
+{
+    *addr = data;
+}
+
+
+/*
+ * 从寄存器读出一个32bit数据
+ * @addr 寄存器地址
+ * @ret 读出的数据
+ */
+unsigned int reg_read_32(volatile unsigned int *addr)
+{
+    return (*addr);
+}
+
+
+

+ 78 - 0
bsp/ls1cdev/libraries/ls1c_public.h

@@ -0,0 +1,78 @@
+// 一些常用的、共用的接口
+
+#ifndef __OPENLOONGSON_PUBLIC_H
+#define __OPENLOONGSON_PUBLIC_H
+
+
+#include <stdio.h>
+
+
+// pmon提供的打印函数,见main()函数
+struct callvectors {
+	int     (*open) (char *, int, int);
+	int     (*close) (int);
+	int     (*read) (int, void *, int);
+	int     (*write) (int, void *, int);
+	long long   (*lseek) (int, long long, int);
+	int     (*printf) (const char *, ...);
+	void    (*cacheflush) (void);
+	char    *(*gets) (char *);
+};
+#define	myprintf (*callvec->printf)
+#define	mygets   (*callvec->gets)
+extern struct callvectors *callvec;
+
+
+#define MIN(a, b)           ((a) > (b) ? (b) : (a))
+#define MAX(a, b)           ((a) > (b) ? (a) : (b))
+
+typedef enum
+{
+    FALSE=0, 
+    TRUE=1
+}BOOL;
+
+/*
+ * 将指定寄存器的指定位置1
+ * @reg 寄存器地址
+ * @bit 需要置1的那一bit
+ */
+void reg_set_one_bit(volatile unsigned int *reg, unsigned int bit);
+
+
+/*
+ * 将指定寄存器的指定位清零
+ * @reg 寄存器地址
+ * @bit 需要清零的那一bit
+ */
+void reg_clr_one_bit(volatile unsigned int *reg, unsigned int bit);
+
+
+/*
+ * 获取指定寄存器的指定位的值
+ * @reg 寄存器地址
+ * @bit 需要读取值的那一bit
+ * @ret 指定位的值
+ */
+unsigned int reg_get_bit(volatile unsigned int *reg, unsigned int bit);
+
+
+/*
+ * 向寄存器中写一个32bit的数据
+ * @data 待写入的数据
+ * @addr 寄存器地址
+ */
+void reg_write_32(unsigned int data, volatile unsigned int *addr);
+
+
+/*
+ * 从寄存器读出一个32bit数据
+ * @addr 寄存器地址
+ * @ret 读出的数据
+ */
+unsigned int reg_read_32(volatile unsigned int *addr);
+
+
+
+#endif
+

+ 88 - 0
bsp/ls1cdev/libraries/ls1c_regs.h

@@ -0,0 +1,88 @@
+// 龙芯1c外设寄存器
+
+
+#ifndef __OPENLOONGSON_LS1C_REGS_H
+#define __OPENLOONGSON_LS1C_REGS_H
+
+
+
+
+// 时钟相关寄存器地址
+#define LS1C_START_FREQ                     (0xbfe78030)
+#define LS1C_CLK_DIV_PARAM                  (0xbfe78034)
+
+
+// gpio相关寄存器地址
+#define LS1C_GPIO_CFG0                      (0xbfd010c0)
+#define LS1C_GPIO_EN0                       (0xbfd010d0)
+#define LS1C_GPIO_IN0                       (0xbfd010e0)
+#define LS1C_GPIO_OUT0                      (0xbfd010f0)
+
+#define LS1C_GPIO_CFG1                      (0xbfd010c4)
+#define LS1C_GPIO_EN1                       (0xbfd010d4)
+#define LS1C_GPIO_IN1                       (0xbfd010e4)
+#define LS1C_GPIO_OUT1                      (0xbfd010f4)
+
+#define LS1C_GPIO_CFG2                      (0xbfd010c8)
+#define LS1C_GPIO_EN2                       (0xbfd010d8)
+#define LS1C_GPIO_IN2                       (0xbfd010e8)
+#define LS1C_GPIO_OUT2                      (0xbfd010f8)
+
+#define LS1C_GPIO_CFG3                      (0xbfd010cc)
+#define LS1C_GPIO_EN3                       (0xbfd010dc)
+#define LS1C_GPIO_IN3                       (0xbfd010ec)
+#define LS1C_GPIO_OUT3                      (0xbfd010fc)
+
+
+
+// 复用相关寄存器
+#define LS1C_CBUS_FIRST0                    (0xbfd011c0)
+#define LS1C_CBUS_SECOND0                   (0xbfd011d0)
+#define LS1C_CBUS_THIRD0                    (0xbfd011e0)
+#define LS1C_CBUS_FOURTH0                   (0xbfd011f0)
+#define LS1C_CBUS_FIFTH0                    (0xbfd01200)
+
+#define LS1C_CBUS_FIRST1                    (0xbfd011c4)
+#define LS1C_CBUS_SECOND1                   (0xbfd011d4)
+#define LS1C_CBUS_THIRD1                    (0xbfd011e4)
+#define LS1C_CBUS_FOURTH1                   (0xbfd011f4)
+#define LS1C_CBUS_FIFTH1                    (0xbfd01204)
+
+#define LS1C_CBUS_FIRST2                    (0xbfd011c8)
+#define LS1C_CBUS_SECOND2                   (0xbfd011d8)
+#define LS1C_CBUS_THIRD2                    (0xbfd011e8)
+#define LS1C_CBUS_FOURTH2                   (0xbfd011f8)
+#define LS1C_CBUS_FIFTH2                    (0xbfd01208)
+
+#define LS1C_CBUS_FIRST3                    (0xbfd011cc)
+#define LS1C_CBUS_SECOND3                   (0xbfd011dc)
+#define LS1C_CBUS_THIRD3                    (0xbfd011ec)
+#define LS1C_CBUS_FOURTH3                   (0xbfd011fc)
+#define LS1C_CBUS_FIFTH3                    (0xbfd0120c)
+
+
+// PWM寄存器偏移
+#define LS1C_PWM_CNTR                       (0x0)
+#define LS1C_PWM_HRC                        (0x4)
+#define LS1C_PWM_LRC                        (0x8)
+#define LS1C_PWM_CTRL                       (0xC)
+// PWM基地址
+#define LS1C_REG_BASE_PWM0                  (0xbfe5c000)
+#define LS1C_REG_BASE_PWM1                  (0xbfe5c010)
+#define LS1C_REG_BASE_PWM2                  (0xbfe5c020)
+#define LS1C_REG_BASE_PWM3                  (0xbfe5c030)
+
+
+
+
+
+
+
+
+
+
+
+
+
+#endif
+