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