1 /**************************************************************************//**
2 * @file ebi.c
3 * @version V3.00
4 * @brief External Bus Interface(EBI) driver source file
5 *
6 * @copyright SPDX-License-Identifier: Apache-2.0
7 * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8 *****************************************************************************/
9 #include "NuMicro.h"
10
11
12 /** @addtogroup Standard_Driver Standard Driver
13 @{
14 */
15
16 /** @addtogroup EBI_Driver EBI Driver
17 @{
18 */
19
20 /** @addtogroup EBI_EXPORTED_FUNCTIONS EBI Exported Functions
21 @{
22 */
23
24 /**
25 * @brief Initialize EBI for specify Bank
26 *
27 * @param[in] u32Bank Bank number for EBI. Valid values are:
28 * - \ref EBI_BANK0
29 * - \ref EBI_BANK1
30 * - \ref EBI_BANK2
31 * @param[in] u32DataWidth Data bus width. Valid values are:
32 * - \ref EBI_BUSWIDTH_8BIT
33 * - \ref EBI_BUSWIDTH_16BIT
34 * @param[in] u32TimingClass Default timing configuration. Valid values are:
35 * - \ref EBI_TIMING_FASTEST
36 * - \ref EBI_TIMING_VERYFAST
37 * - \ref EBI_TIMING_FAST
38 * - \ref EBI_TIMING_NORMAL
39 * - \ref EBI_TIMING_SLOW
40 * - \ref EBI_TIMING_VERYSLOW
41 * - \ref EBI_TIMING_SLOWEST
42 * @param[in] u32BusMode Set EBI bus operate mode. Valid values are:
43 * - \ref EBI_OPMODE_NORMAL
44 * - \ref EBI_OPMODE_CACCESS
45 * - \ref EBI_OPMODE_ADSEPARATE
46 * @param[in] u32CSActiveLevel CS is active High/Low. Valid values are:
47 * - \ref EBI_CS_ACTIVE_HIGH
48 * - \ref EBI_CS_ACTIVE_LOW
49 *
50 * @return None
51 *
52 * @details This function is used to open specify EBI bank with different bus width, timing setting and \n
53 * active level of CS pin to access EBI device.
54 * @note Write Buffer Enable(WBUFEN) and Extend Time Of ALE(TALE) are only available in EBI bank0 control register.
55 */
EBI_Open(uint32_t u32Bank,uint32_t u32DataWidth,uint32_t u32TimingClass,uint32_t u32BusMode,uint32_t u32CSActiveLevel)56 void EBI_Open(uint32_t u32Bank, uint32_t u32DataWidth, uint32_t u32TimingClass, uint32_t u32BusMode, uint32_t u32CSActiveLevel)
57 {
58 uint32_t u32Index0 = (uint32_t)&EBI->CTL0 + (u32Bank * 0x10UL);
59 uint32_t u32Index1 = (uint32_t)&EBI->TCTL0 + (u32Bank * 0x10UL);
60 volatile uint32_t *pu32EBICTL, *pu32EBITCTL;
61 uint32_t pu32Index0, pu32Index1;
62
63 if((__PC()&NS_OFFSET) == NS_OFFSET)
64 {
65 pu32Index0 = (u32Index0 | NS_OFFSET);
66 pu32Index1 = (u32Index1 | NS_OFFSET);
67 }
68 else
69 {
70 pu32Index0 = u32Index0;
71 pu32Index1 = u32Index1;
72 }
73
74 pu32EBICTL = (uint32_t *)(pu32Index0);
75 pu32EBITCTL = (uint32_t *)(pu32Index1);
76
77 if(u32DataWidth == EBI_BUSWIDTH_8BIT)
78 {
79 *pu32EBICTL &= ~EBI_CTL_DW16_Msk;
80 }
81 else
82 {
83 *pu32EBICTL |= EBI_CTL_DW16_Msk;
84 }
85
86 *pu32EBICTL |= u32BusMode;
87
88 switch(u32TimingClass)
89 {
90 case EBI_TIMING_FASTEST:
91 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
92 (EBI_MCLKDIV_1 << EBI_CTL_MCLKDIV_Pos) |
93 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk;
94 *pu32EBITCTL = 0x0UL;
95 break;
96
97 case EBI_TIMING_VERYFAST:
98 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
99 (EBI_MCLKDIV_1 << EBI_CTL_MCLKDIV_Pos) |
100 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
101 (0x3U << EBI_CTL_TALE_Pos) ;
102 *pu32EBITCTL = 0x03003318UL;
103 break;
104
105 case EBI_TIMING_FAST:
106 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
107 (EBI_MCLKDIV_2 << EBI_CTL_MCLKDIV_Pos) |
108 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk;
109 *pu32EBITCTL = 0x0UL;
110 break;
111
112 case EBI_TIMING_NORMAL:
113 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
114 (EBI_MCLKDIV_2 << EBI_CTL_MCLKDIV_Pos) |
115 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
116 (0x3UL << EBI_CTL_TALE_Pos) ;
117 *pu32EBITCTL = 0x03003318UL;
118 break;
119
120 case EBI_TIMING_SLOW:
121 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
122 (EBI_MCLKDIV_2 << EBI_CTL_MCLKDIV_Pos) |
123 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
124 (0x7UL << EBI_CTL_TALE_Pos) ;
125 *pu32EBITCTL = 0x07007738UL;
126 break;
127
128 case EBI_TIMING_VERYSLOW:
129 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
130 (EBI_MCLKDIV_4 << EBI_CTL_MCLKDIV_Pos) |
131 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
132 (0x7UL << EBI_CTL_TALE_Pos) ;
133 *pu32EBITCTL = 0x07007738UL;
134 break;
135
136 case EBI_TIMING_SLOWEST:
137 *pu32EBICTL = (*pu32EBICTL & ~(EBI_CTL_MCLKDIV_Msk | EBI_CTL_TALE_Msk)) |
138 (EBI_MCLKDIV_8 << EBI_CTL_MCLKDIV_Pos) |
139 (u32CSActiveLevel << EBI_CTL_CSPOLINV_Pos) | EBI_CTL_EN_Msk |
140 (0x7UL << EBI_CTL_TALE_Pos) ;
141 *pu32EBITCTL = 0x07007738UL;
142 break;
143
144 default:
145 *pu32EBICTL &= ~EBI_CTL_EN_Msk;
146 break;
147 }
148 }
149
150 /**
151 * @brief Disable EBI on specify Bank
152 *
153 * @param[in] u32Bank Bank number for EBI. Valid values are:
154 * - \ref EBI_BANK0
155 * - \ref EBI_BANK1
156 * - \ref EBI_BANK2
157 *
158 * @return None
159 *
160 * @details This function is used to close specify EBI function.
161 */
EBI_Close(uint32_t u32Bank)162 void EBI_Close(uint32_t u32Bank)
163 {
164 uint32_t u32Index = (uint32_t)&EBI->CTL0 + (u32Bank * 0x10UL);
165 volatile uint32_t *pu32EBICTL;
166 uint32_t pu32Index;
167
168 if((__PC()&NS_OFFSET) == NS_OFFSET)
169 {
170 pu32Index = (u32Index | NS_OFFSET);
171 }
172 else
173 {
174 pu32Index = u32Index;
175 }
176
177 pu32EBICTL = (uint32_t *)(pu32Index);
178
179 *pu32EBICTL &= ~EBI_CTL_EN_Msk;
180 }
181
182 /**
183 * @brief Set EBI Bus Timing for specify Bank
184 *
185 * @param[in] u32Bank Bank number for EBI. Valid values are:
186 * - \ref EBI_BANK0
187 * - \ref EBI_BANK1
188 * - \ref EBI_BANK2
189 * @param[in] u32TimingConfig Configure EBI timing settings, includes TACC, TAHD, W2X and R2R setting.
190 * @param[in] u32MclkDiv Divider for MCLK. Valid values are:
191 * - \ref EBI_MCLKDIV_1
192 * - \ref EBI_MCLKDIV_2
193 * - \ref EBI_MCLKDIV_4
194 * - \ref EBI_MCLKDIV_8
195 * - \ref EBI_MCLKDIV_16
196 * - \ref EBI_MCLKDIV_32
197 * - \ref EBI_MCLKDIV_64
198 * - \ref EBI_MCLKDIV_128
199 *
200 * @return None
201 *
202 * @details This function is used to configure specify EBI bus timing for access EBI device.
203 */
EBI_SetBusTiming(uint32_t u32Bank,uint32_t u32TimingConfig,uint32_t u32MclkDiv)204 void EBI_SetBusTiming(uint32_t u32Bank, uint32_t u32TimingConfig, uint32_t u32MclkDiv)
205 {
206 uint32_t u32Index0 = (uint32_t)&EBI->CTL0 + (u32Bank * 0x10UL);
207 uint32_t u32Index1 = (uint32_t)&EBI->TCTL0 + (u32Bank * 0x10UL);
208 volatile uint32_t *pu32EBICTL, *pu32EBITCTL;
209 uint32_t pu32Index0, pu32Index1;
210
211 if((__PC()&NS_OFFSET) == NS_OFFSET)
212 {
213 pu32Index0 = (u32Index0 | NS_OFFSET);
214 pu32Index1 = (u32Index1 | NS_OFFSET);
215 }
216 else
217 {
218 pu32Index0 = u32Index0;
219 pu32Index1 = u32Index1;
220 }
221
222 pu32EBICTL = (uint32_t *)(pu32Index0);
223 pu32EBITCTL = (uint32_t *)(pu32Index1);
224
225 *pu32EBICTL = (*pu32EBICTL & ~EBI_CTL_MCLKDIV_Msk) | (u32MclkDiv << EBI_CTL_MCLKDIV_Pos);
226 *pu32EBITCTL = u32TimingConfig;
227 }
228
229 /**@}*/ /* end of group EBI_EXPORTED_FUNCTIONS */
230
231 /**@}*/ /* end of group EBI_Driver */
232
233 /**@}*/ /* end of group Standard_Driver */
234