1 /*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2017-09-06 勤为本 first version
9 * 2021-02-02 michael5hzg@gmail.com adapt to ls1b
10 */
11
12 // 一些常用的、共用的接口
13
14 /*
15 * 将指定寄存器的指定位置1
16 * @reg 寄存器地址
17 * @bit 需要置1的那一bit
18 */
reg_set_one_bit(volatile unsigned int * reg,unsigned int bit)19 void reg_set_one_bit(volatile unsigned int *reg, unsigned int bit)
20 {
21 unsigned int temp, mask;
22
23 mask = 1 << bit;
24 temp = *reg;
25 temp |= mask;
26 *reg = temp;
27
28 return ;
29 }
30
31
32 /*
33 * 将指定寄存器的指定位清零
34 * @reg 寄存器地址
35 * @bit 需要清零的那一bit
36 */
reg_clr_one_bit(volatile unsigned int * reg,unsigned int bit)37 void reg_clr_one_bit(volatile unsigned int *reg, unsigned int bit)
38 {
39 unsigned int temp, mask;
40
41 mask = 1 << bit;
42 temp = *reg;
43 temp &= ~mask;
44 *reg = temp;
45
46 return ;
47 }
48
49
50
51 /*
52 * 获取指定寄存器的指定位的值
53 * @reg 寄存器地址
54 * @bit 需要读取值的那一bit
55 * @ret 指定位的值
56 */
reg_get_bit(volatile unsigned int * reg,unsigned int bit)57 unsigned int reg_get_bit(volatile unsigned int *reg, unsigned int bit)
58 {
59 unsigned int temp;
60
61 temp = *reg;
62 temp = (temp >> bit) & 1;
63
64 return temp;
65 }
66
67
68 /*
69 * 向寄存器中写入8bit(一个字节)数据
70 * @data 待写入的数据
71 * @addr 寄存器地址
72 */
reg_write_8(unsigned char data,volatile unsigned char * addr)73 void reg_write_8(unsigned char data, volatile unsigned char *addr)
74 {
75 *addr = data;
76 }
77
78
79 /*
80 * 从寄存器读出8bit(一个字节)数据
81 * @addr 寄存器地址
82 * @ret 读出的数据
83 */
reg_read_8(volatile unsigned char * addr)84 unsigned char reg_read_8(volatile unsigned char *addr)
85 {
86 return (*addr);
87 }
88
89
90 /*
91 * 向寄存器中写一个32bit的数据
92 * @data 待写入的数据
93 * @addr 寄存器地址
94 */
reg_write_32(unsigned int data,volatile unsigned int * addr)95 void reg_write_32(unsigned int data, volatile unsigned int *addr)
96 {
97 *addr = data;
98 }
99
100
101 /*
102 * 从寄存器读出一个32bit数据
103 * @addr 寄存器地址
104 * @ret 读出的数据
105 */
reg_read_32(volatile unsigned int * addr)106 unsigned int reg_read_32(volatile unsigned int *addr)
107 {
108 return (*addr);
109 }
110
111
112
113 /**
114 * ffs - find first bit set
115 * @x: the word to search
116 *
117 * This is defined the same way as
118 * the libc and compiler builtin ffs routines, therefore
119 * differs in spirit from the above ffz (man ffs).
120 */
ls1b_ffs(int x)121 int ls1b_ffs(int x)
122 {
123 int r = 1;
124
125 if (!x)
126 return 0;
127 if (!(x & 0xffff)) {
128 x >>= 16;
129 r += 16;
130 }
131 if (!(x & 0xff)) {
132 x >>= 8;
133 r += 8;
134 }
135 if (!(x & 0xf)) {
136 x >>= 4;
137 r += 4;
138 }
139 if (!(x & 3)) {
140 x >>= 2;
141 r += 2;
142 }
143 if (!(x & 1)) {
144 x >>= 1;
145 r += 1;
146 }
147 return r;
148 }
149
150
151 /*
152 * fls - find last (most-significant) bit set
153 * @x: the word to search
154 *
155 * This is defined the same way as ffs.
156 * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
157 */
ls1b_fls(int x)158 int ls1b_fls(int x)
159 {
160 int r = 32;
161
162 if (!x)
163 return 0;
164 if (!(x & 0xffff0000u))
165 {
166 x <<= 16;
167 r -= 16;
168 }
169 if (!(x & 0xff000000u))
170 {
171 x <<= 8;
172 r -= 8;
173 }
174 if (!(x & 0xf0000000u))
175 {
176 x <<= 4;
177 r -= 4;
178 }
179 if (!(x & 0xc0000000u))
180 {
181 x <<= 2;
182 r -= 2;
183 }
184 if (!(x & 0x80000000u))
185 {
186 x <<= 1;
187 r -= 1;
188 }
189
190 return r;
191 }
192
193
194