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