1 /******************************************************************************
2  * Copyright (c) 2022 Telink Semiconductor (Shanghai) Co., Ltd. ("TELINK")
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************/
18 
19 /********************************************************************************************************
20  * @file	sys.h
21  *
22  * @brief	This is the header file for B91
23  *
24  * @author	Driver Group
25  *
26  *******************************************************************************************************/
27 /**	@page SYS
28  *
29  *	Introduction
30  *	===============
31  *	Clock init and system timer delay.
32  *
33  *	API Reference
34  *	===============
35  *	Header File: sys.h
36  */
37 
38 #ifndef SYS_H_
39 #define SYS_H_
40 #include "bit.h"
41 #include "reg_include/stimer_reg.h"
42 
43 
44 /**********************************************************************************************************************
45  *                                         global constants                                                           *
46  *********************************************************************************************************************/
47 
48 /**********************************************************************************************************************
49  *                                           global macro                                                             *
50  *********************************************************************************************************************/
51 /*
52  * brief instruction delay
53  */
54 
55 #define	_ASM_NOP_					__asm__("nop")
56 
57 #define	CLOCK_DLY_1_CYC				_ASM_NOP_
58 #define	CLOCK_DLY_2_CYC				_ASM_NOP_;_ASM_NOP_
59 #define	CLOCK_DLY_3_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
60 #define	CLOCK_DLY_4_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
61 #define	CLOCK_DLY_5_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
62 #define	CLOCK_DLY_6_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
63 #define	CLOCK_DLY_7_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
64 #define	CLOCK_DLY_8_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
65 #define	CLOCK_DLY_9_CYC				_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
66 #define	CLOCK_DLY_10_CYC			_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_;_ASM_NOP_
67 
68 #define FLASH_R_BASE_ADDR   		0x20000000
69 #define REG_RW_BASE_ADDR  			0x80000000
70 #define REG_ADDR8(a)				(*(volatile unsigned char*)(REG_RW_BASE_ADDR | (a)))
71 #define REG_ADDR16(a)				(*(volatile unsigned short*)(REG_RW_BASE_ADDR | (a)))
72 #define REG_ADDR32(a)				(*(volatile unsigned long*)(REG_RW_BASE_ADDR | (a)))
73 
74 #define write_reg8(addr,v)			(*(volatile unsigned char*)(REG_RW_BASE_ADDR | (addr)) = (unsigned char)(v))
75 #define write_reg16(addr,v)			(*(volatile unsigned short*)(REG_RW_BASE_ADDR | (addr)) = (unsigned short)(v))
76 #define write_reg32(addr,v)			(*(volatile unsigned long*)(REG_RW_BASE_ADDR | (addr)) = (unsigned long)(v))
77 
78 #define read_reg8(addr)				(*(volatile unsigned char*)(REG_RW_BASE_ADDR | (addr)))
79 #define read_reg16(addr)            (*(volatile unsigned short*)(REG_RW_BASE_ADDR | (addr)))
80 #define read_reg32(addr)            (*(volatile unsigned long*)(REG_RW_BASE_ADDR | (addr)))
81 
82 #define write_sram8(addr,v)			(*(volatile unsigned char*)( (addr)) = (unsigned char)(v))
83 #define write_sram16(addr,v)		(*(volatile unsigned short*)( (addr)) = (unsigned short)(v))
84 #define write_sram32(addr,v)		(*(volatile unsigned long*)( (addr)) = (unsigned long)(v))
85 
86 #define read_sram8(addr)			(*(volatile unsigned char*)((addr)))
87 #define read_sram16(addr)           (*(volatile unsigned short*)((addr)))
88 #define read_sram32(addr)           (*(volatile unsigned long*)((addr)))
89 #define TCMD_UNDER_BOTH				0xc0
90 #define TCMD_UNDER_RD				0x80
91 #define TCMD_UNDER_WR				0x40
92 
93 #define TCMD_MASK					0x3f
94 
95 #define TCMD_WRITE					0x3
96 #define TCMD_WAIT					0x7
97 #define TCMD_WAREG					0x8
98 //#if 1 //optimize
99 /*
100  * IRAM area:0x00000~0x1FFFF BIT(19) is 0,BIT(16~0) 128K is address offset
101  * DRAM area:0x80000~0x9FFFF BIT(19) is 1,BIT(16~0) 128K is address offset
102  * ILM area:0xc0000000~0xc0020000 BIT(31~19) is 3,BIT(21) is 0, BIT(20~17) do not care  BIT(16~0) 128K is address offset 128K is address offset
103  * DLM area:0xc0200000~0xc0220000 BIT(31~19) is 3,BIT(21) is 1, BIT(20~17) do not care  BIT(16~0) 128K is address offset 128K is address offset
104  * BIT(19) is used to distinguish from IRAM to DRAM, BIT(21) is used to distinguish from ILM to DLM.
105  * so we can write it as follow
106  * #define  convert_ram_addr_cpu2bus  (((((addr))&0x80000)? ((addr)| 0xc0200000) : ((addr)|0xc0000000)))
107  * BIT(20~17) are invalid address line ,IRAM address is less than 0x80000, (address-0x80000)must borrow from BIT(21)
108  *   #define convert(addr) ((addr)-0x80000+0xc0200000)
109  *  to simplify
110  *  #define convert(addr) ((addr)+0xc0180000)
111  * */
112 #define convert_ram_addr_cpu2bus(addr)  ((unsigned int)(addr)+0xc0180000)
113 //#else  //no optimize
114 //#define  convert_ram_addr_cpu2bus  (((((unsigned int)(addr)) >=0x80000)?(((unsigned int)(addr))-0x80000+0xc0200000) : (((unsigned int)(addr)) + 0xc0000000)))
115 //#endif
116 
117 #define convert_ram_addr_bus2cpu(addr)  (((((unsigned int)(addr)) >=0xc0200000)?(((unsigned int)(addr)) + 0x80000-0xc0200000) : (((unsigned int)(addr)) - 0xc0000000)))
118 
119 /**********************************************************************************************************************
120  *                                         global data type                                                           *
121  *********************************************************************************************************************/
122 
123 /**
124  * @brief 	Power type for different application
125  */
126 typedef enum{
127 	LDO_1P4_LDO_1P8 	= 0x00,	/**< 1.4V-LDO & 1.8V-LDO mode */
128 	DCDC_1P4_LDO_1P8	= 0x01,	/**< 1.4V-DCDC & 1.8V-LDO mode */
129 	DCDC_1P4_DCDC_1P8	= 0x03,	/**< 1.4V-DCDC & 1.8V-DCDC mode */
130 }power_mode_e;
131 
132 /**
133  * @brief 	The maximum voltage that the chip can withstand is 3.6V.
134  * 			When the vbat power supply voltage is lower than 3.6V, it is configured as VBAT_MAX_VALUE_LESS_THAN_3V6 mode,
135  * 			bypass is turned on, and the vbat voltage directly supplies power to the chip.
136  * 			When the vbat power supply voltage may be higher than 3.6V, it is configured as VBAT_MAX_VALUE_GREATER_THAN_3V6 mode,
137  * 			the bypass is closed, and the vbat voltage passes through an LDO to supply power to the chip.
138  */
139 typedef enum{
140 	VBAT_MAX_VALUE_GREATER_THAN_3V6	= 0x00,	/*VBAT may be greater than 3.6V. */
141 	VBAT_MAX_VALUE_LESS_THAN_3V6	= BIT(3),	/*VBAT must be below 3.6V. */
142 }vbat_type_e;
143 
144 /**
145  * @brief command table for special registers
146  */
147 typedef struct tbl_cmd_set_t {
148 	unsigned int  	adr;
149 	unsigned char	dat;
150 	unsigned char	cmd;
151 } tbl_cmd_set_t;
152 
153 
154 /**********************************************************************************************************************
155  *                                     global variable declaration                                                    *
156  *********************************************************************************************************************/
157 
158 extern unsigned int g_chip_version;
159 
160 /**********************************************************************************************************************
161  *                                      global function prototype                                                     *
162  *********************************************************************************************************************/
163 /**
164  * @brief      This function reboot mcu.
165  * @return     none
166  */
sys_reboot(void)167 static inline void sys_reboot(void)
168 {
169 	write_reg8(0x1401ef, 0x20);
170 }
171 /**
172  * @brief   	This function serves to initialize system.
173  * @param[in]	power_mode - power mode(LDO/DCDC/LDO_DCDC)
174  * @param[in]	vbat_v		- vbat voltage type: 0 vbat may be greater than 3.6V,  1 vbat must be below 3.6V.
175  * @return  	none
176  */
177 void sys_init(power_mode_e power_mode, vbat_type_e vbat_v);
178 
179 /**
180  * @brief      This function performs a series of operations of writing digital or analog registers
181  *             according to a command table
182  * @param[in]  pt    - pointer to a command table containing several writing commands
183  * @param[in]  size  - number of commands in the table
184  * @return     number of commands are carried out
185  */
186 
187 int write_reg_table(const tbl_cmd_set_t * pt, int size);
188 
189 #endif
190