首页 > 其他分享 >全志R128 SDK HAL 模块开发指南——CCU

全志R128 SDK HAL 模块开发指南——CCU

时间:2024-03-22 10:58:05浏览次数:19  
标签:reset HAL clk CCU R128 CLK ccu hal

CCU

介绍 RTOS 中CCU 驱动的接口及使用方法,为 CCU 的使用者提供参考。

模块介绍

CCU 驱动主要实现设备驱动的底层细节,并为上层提供一套标准的API 接口以供使用。

模块配置

其menuconfig 的配置如下:

Kernel Setup --->
    Drivers Setup --->
        SoC HAL Drivers --->
            CCMU devices --->
                [*] enable ccmu-ng driver
                [*] enbale ccmu-ng hal APIs Test command

源码结构

.
│  common_ccmu.h
│  hal_clk.c
│  hal_reset.c
│  Kconfig
│  Makefile
│  platform_ccmu.h
│  platform_rst.h
│
├─sunxi
│  │  clk.c
│  │  clk.h
│  │  clk_factors.c
│  │  clk_factors.h
│  │  clk_periph.c
│  │  clk_periph.h
│  │  Makefile
│  │  platform_clk.h
│  │
│  └─sun8iw21p1             # sun8iw21p1平台实现(老平台,目前使用ng驱动)
│          clk_sun8iw21.c
│          clk_sun8iw21.h
│          Makefile
│
└─sunxi-ng                  # sunxi-ng 驱动实现
        ccu-sun20iw2-aon.c
        ccu-sun20iw2-aon.h
        ccu-sun20iw2-r.c
        ccu-sun20iw2-r.h
        ccu-sun20iw2.c
        ccu-sun20iw2.h
        ccu.c
        ccu.h
        ccu_common.c
        ccu_common.h
        ccu_div.c
        ccu_div.h
        ccu_frac.c
        ccu_frac.h
        ccu_gate.c
        ccu_gate.h
        ccu_mp.c
        ccu_mp.h
        ccu_mult.c
        ccu_mult.h
        ccu_mux.c
        ccu_mux.h
        ccu_nk.c
        ccu_nk.h
        ccu_nkm.c
        ccu_nkm.h
        ccu_nkmp.c
        ccu_nkmp.h
        ccu_nm.c
        ccu_nm.h
        ccu_phase.c
        ccu_phase.h
        ccu_reset.c
        ccu_reset.h
        ccu_sdm.c
        ccu_sdm.h
        clk-divider.c
        clk-fixed-factor.c
        clk-fixed-rate.c
        clk-fixed-rate.h
        clk.c
        clk.h
        Makefile
        rst-sun20iw2-aon.h
        rst-sun20iw2-r.h
        rst-sun20iw2.h
        type.h

模块接口说明

头文件

#include <hal_clk.h>
#include <hal_reset.h>
#include <ccmu/common_ccmu.h>

返回值定义枚举

typedef enum
{

    HAL_CLK_STATUS_DISABLED = -1,
    HAL_CLK_STATUS_ENABLED = 0,
    HAL_CLK_STATUS_ERROR_CLK_FACTOR_REFUSED = -11,
    HAL_CLK_STATUS_ERROR_CLK_NEED_DISABLED  = -10,
    HAL_CLK_STATUS_ERROR_CLK_PARENT_DISABLED  = -9,
    HAL_CLK_STATUS_ERROR_CLK_ENABLED_FAILED  = -8,
    HAL_CLK_STATUS_ERROR_CLK_ROUND_FAILED = -7,
    HAL_CLK_STATUS_ERROR_CLK_SET_RATE_REFUSED = -6,
    HAL_CLK_STATUS_ERROR_CLK_NOT_FOUND  = -5,
    HAL_CLK_STATUS_ERROT_CLK_UNDEFINED  = -4,
    HAL_CLK_STATUS_UNINITIALIZED = -3,        /**< Uninitialized clock driver. */
    HAL_CLK_STATUS_INVALID_PARAMETER = -2,    /**< Invalid parameter. */
    HAL_CLK_STATUS_ERROR = -1,                /**< Unknown error. */
    HAL_CLK_STATUS_OK = 0,                    /**< Successful. */
} hal_clk_status_t;

时钟类型定义枚举

typedef enum
{
    HAL_SUNXI_FIXED_CCU = 0,
    HAL_SUNXI_RTC_CCU,
    HAL_SUNXI_CCU,
    HAL_SUNXI_AON_CCU,
    HAL_SUNXI_R_CCU,
    HAL_SUNXI_DSP,
    HAL_SUNXI_CCU_NUMBER,
} hal_clk_type_t;

初始化CCU驱动

函数原型

void hal_clock_init(void);

参数:

返回值:

判断指定时钟是否已经打开

函数原型

hal_clk_status_t hal_clock_is_enabled(hal_clk_t clk);

参数:

  • clk:clk id

返回值:

  • HAL_CLK_STATUS_ENABLED:打开
  • HAL_CLK_STATUS_DISABLED:关闭

获得指定的时钟句柄

函数原型

hal_clk_t hal_clock_get(hal_clk_type_t type, hal_clk_id_t id);

参数:

  • type:时钟类型
  • id:时钟id

返回值:

  • 时钟句柄 hal_clk_t

释放指定时钟句柄

函数原型

hal_clk_status_t hal_clock_put(hal_clk_t clk);

参数:

  • clk:要操作的时钟句柄

返回值:

  • 0:成功
  • 负数:失败

打开指定时钟

函数原型

hal_clk_status_t hal_clock_enable(hal_clk_t clk);

参数:

  • clk:时钟id

返回值:

  • 0:成功
  • 负数:失败

关闭指定时钟

函数原型

hal_clk_status_t hal_clock_disable(hal_clk_t clk);

参数:

  • clk:时钟id

返回值:

  • 0:成功
  • 负数:失败

重新计算指定时钟的频率

函数原型

u32 hal_clk_recalc_rate(hal_clk_t clk);

参数:

  • clk:时钟id

返回值:

  • 0:成功
  • 负数:失败

设置一个跟指定频率最接近的时钟频

函数原型

u32 hal_clk_round_rate(hal_clk_t clk, u32 rate);

参数:

  • clk:时钟id
  • rate:频率

返回值:

  • 0:成功
  • 负数:失败

获取指定时钟频率

可能非实时

函数原型

u32 hal_clk_get_rate(hal_clk_t clk);

参数:

  • clk:时钟id

返回值:

  • 0:成功
  • 负数:失败

设置指定时钟的频

函数原型

hal_clk_status_t hal_clk_set_rate(hal_clk_t clk,  u32 rate);

参数:

  • clk:时钟id
  • rate:频率

返回值:

  • 0:成功
  • 负数:失败

设置指定时钟的父时钟

函数原型

hal_clk_status_t hal_clk_set_parent(hal_clk_t clk, hal_clk_t parent);

参数:

  • clk:时钟id
  • parent:父时钟id

返回值:

  • 0:成功
  • 负数:失败

获取指定时钟的父时钟

函数原型

hal_clk_t hal_clk_get_parent(hal_clk_t clk);

参数:

  • clk:时钟id

返回值:

  • 0:成功
  • 负数:失败

模块使用范例

#include <stdlib.h>
#include <hal_log.h>
#include <hal_cmd.h>
#include <hal_clk.h>
#include <hal_reset.h>
#include <ccmu/common_ccmu.h>
#include "../../source/ccmu/sunxi-ng/ccu-sun20iw2-aon.h"

#ifndef CLK_RTC_NUMBER
#define CLK_RTC_NUMBER 0
#endif

int clk_number[] = {
	CLK_SRC_NUMBER,
	CLK_RTC_NUMBER,
	CLK_NUMBER,
	CLK_AON_NUMBER,
	CLK_R_NUMBER,
	0
};

int reset_number[] = {
	RST_BUS_NUMBER,
	RST_R_BUS_NUMBER,
	0,
};

char *strict_clks[] = {
	"pll-ddr0",
	"riscv",
	"pll-cpux",
	"pll-periph0-parent",
	"riscv-axi",
	"apb1",
	"fanout-27m",
	"fix-losc",
	"rc-16m",
	"ext-32k",
	"rc-hf",
	"pclk-spc-1",
	"pclk-spc-2",
	"pclk-spc",
	NULL,
};

char *clk_type_name[] = {
	"HAL_SUNXI_FIXED_CCU",
	"HAL_SUNXI_RTC_CCU",
	"HAL_SUNXI_CCU",
	"HAL_SUNXI_AON_CCU",
	"HAL_SUNXI_R_CCU",
};

int is_strict_clk(hal_clk_t clk)
{
	int i;
	for (i = 0; strict_clks[i] != NULL; i++)
	{
		if (!strcmp(clk->name, strict_clks[i]))
			return 1;
	}

	return 0;
}

int is_dcxo_clk(hal_clk_t clk)
{
	if (!strncmp(clk->name, "dcxo", 4))
		return 1;
	return 0;
}

int cmd_test_ng_ccmu(int argc, char **argv)
{
	int i, j;

	hal_clk_type_t clk_type;
	hal_clk_id_t   clk_id;
	hal_clk_t clk, p_clk;
	u32  old_rate;

	hal_reset_type_t reset_type;
	hal_reset_id_t  reset_id;
	hal_clk_status_t clk_status;
	struct reset_control *reset;
	int reset_status;
	u32 new_rate;
    
	printf("clock\t\t\t\t\t type\t\t\t\t\t parent\t\t\t\t\t rate\n");
	for (i = HAL_SUNXI_FIXED_CCU; i < HAL_SUNXI_CCU_NUMBER; i++)
	{
		clk_type = i;
		for (j = 0; j < clk_number[i]; j++)
		{
			clk_id = j;
			clk = hal_clock_get(clk_type, clk_id);
			if (!clk) {
				printf("fail to get clk\n");
				continue;
			}

			p_clk = hal_clk_get_parent(clk);

			old_rate = hal_clk_get_rate(clk);
			if (p_clk)
				printf("%-20s\t\t\t %-20s\t\t\t %-15s\t\t\t %d\n", clk->name, clk_type_name[i], p_clk->name, old_rate);
			else
				printf("%-20s\t\t\t %-20s\t\t\t NULL\t\t\t\t\t %d\n", clk->name, clk_type_name[i], old_rate);

		}
	}
	for (i = HAL_SUNXI_RESET; i < HAL_SUNXI_RESET_NUMBER; i++)
	{
		reset_type = i;
		for (j = 0; j < reset_number[i]; j++)
		{
			reset_id = j;

			printf("reset: get reset control, type:%d, id: %d\n", reset_type, reset_id);
			reset = hal_reset_control_get(reset_type, reset_id);

			printf("reset: control deassert\n");
			hal_reset_control_deassert(reset);

			reset_status = hal_reset_control_status(reset);
			printf("reset status: %s", reset_status ? "assert" : "deassert");

			printf("reset: put reset control, type:%d, id: %d\n", reset_type, reset_id);
			hal_reset_control_put(reset);
		}
	}
	return 0;
}

FINSH_FUNCTION_EXPORT_CMD(cmd_test_ng_ccmu, hal_ccmu, sunxi - ng ccmu hal APIs tests)

标签:reset,HAL,clk,CCU,R128,CLK,ccu,hal
From: https://blog.csdn.net/weixin_43094346/article/details/136932416

相关文章

  • mdk的基础条叫 && c复习(hal库)
    文章目录11.11.21.31.41.52.c2.12.22.32.42.52.62.72.82.911.1设置了config里面的编码字体颜色用户关键词代码补全动态语法检测配置文件prop在mdk/uv4目录下可以用别人的(和游戏配置复制别人的似的)1.2整体tabshift+tab还有图形快捷键编译速度会变......
  • STM32 HAL库基于F103系列之异步通信
    硬件资源串口1(PA9/PA10连接在板载USB转串口芯片CH340C上面) 原理图USB转串口硬件部分的原理图 程序设计USART/UART异步通信配置步骤1、配置串口工作参数  HAL_UART_Init()2,串口底层初始化  HAL_UART_MspInit()   配置GPIO、NVIC、CLOCK等3,开启串口异步接......
  • STM32 HAL库 通过外部中断控制一个灯亮灭
    个人学习理解    在我们学习写代码的过程中,我们配合着开发指南中的程序设计的配置步骤并与我们的学习视频结合着、对比着学习,这能更加让我们对程序设计步骤理解得更加透彻。硬件了解1、LED灯LED0–PB5LED1–PE52、独立按键KEY0–PE4KEY1–PE3KEY2–......
  • 02_STM32软件+硬件SPI读写W25Q64(HAL库)
    目录1、SPI简介2、SPI时序单元2.1模式0(应用最多)2.2模式12.3 模式22.4 模式33、SPI移位示意图4、简单软件SPI代码(HAL库)5、简单硬件SPI读写W25Q64(HAL库)6、例程下载1、SPI简介2、SPI时序单元2.1模式0(应用最多)2.2模式12.3 模式2模式2与模式0类似,区别在......
  • 记一次 HalconControl 无法正常显示埋下的坑 关于Shown,Load,警钟长鸣
    最近在写一个视觉软件demo(基于Halcon) 根据MEF框架下进行 后台代码的解耦。首推这一款框架,在自动化,运动控制,视觉领域可运用范围极广。首先简单介绍一下什么是MEF,MEF,全称ManagedExtensibilityFramework(托管可扩展框架)。单从名字我们不难发现:MEF是专门致力于解决扩展性问题......
  • datawhale-动手学数据分析task4笔记
    动手学数据分析task4数据可视化matplotlib的图像都位于figure对象中,创建新的对象用plt.figure。plt.subplot()方法可以更方便地创建一个新figure,并返回一个含有以创建的subplot对象的numpy数组。'''参数说明:nrows=int,subplot的行数ncols=int,subplot的列数sharex=Bool......
  • 【Linux】linuxCNC+Qt+Opencascade+kdl+hal 实时6轴机器人控制器
    CNC机器人程序框架机器人模型笔记:debian重启后无法打开共享目录最新版搜狗输入法安装后不支持中文,需要安装旧版本的sogoupinyin_4.0.1.2800_x86_64.deb可用数控机器人在哪些领域应用有优势数控机器人在多个领域都展现出了显著的优势,特别是在需要高精度和......
  • HAL库&标准库,为什么更重视HAL库
    工作上使用英飞凌的芯片,英飞凌也提供了的类似ST的HAL库的SDL库,年前以太网外设出了点问题,最后查出了是产品上英飞凌SDL库没有及时更新,bug没修复。和同事讨论了为什么各大芯片厂商都在搞类似HAL库的这种高度封装的库首先为客户省去了开发底层驱动工程师的费用第二点我觉得比较重......
  • 程序流程的控制 Abort Exit Halt RunError Continue Break Sleep
    Break退出当前循环体,包括for,while,repeat等循环体;Continue用于从For语句,while语句或repeat语句强行结束本次循环,并开始下一次循环;Exit跳出当前代码块,也就是当前函数,跳出后是要继续向下执行的(如果有后续代码),若该代码为主程序,则终止该程序,若是函数或过程,则立即退出过程或......
  • WARNING: An illegal reflective access operation has occurred
    想了很久也没有弄明白是什么原因导致了控制台输出了这个警告,后面在网上查了查资料,发现是这么一回事:在JDK8之前(包括java8),Java允许通过反射机制访问所有的成员,这些成员的类型包括私有(private),公共(public),包(<package>)和受保护(protected)。JDK9新增的功能之一——模块系......