1 /***************************************************************************//**
2 * @file
3 * @brief External Bus Interface (EBI) Peripheral API
4 *******************************************************************************
5 * # License
6 * <b>Copyright 2018 Silicon Laboratories Inc. www.silabs.com</b>
7 *******************************************************************************
8 *
9 * SPDX-License-Identifier: Zlib
10 *
11 * The licensor of this software is Silicon Laboratories Inc.
12 *
13 * This software is provided 'as-is', without any express or implied
14 * warranty. In no event will the authors be held liable for any damages
15 * arising from the use of this software.
16 *
17 * Permission is granted to anyone to use this software for any purpose,
18 * including commercial applications, and to alter it and redistribute it
19 * freely, subject to the following restrictions:
20 *
21 * 1. The origin of this software must not be misrepresented; you must not
22 * claim that you wrote the original software. If you use this software
23 * in a product, an acknowledgment in the product documentation would be
24 * appreciated but is not required.
25 * 2. Altered source versions must be plainly marked as such, and must not be
26 * misrepresented as being the original software.
27 * 3. This notice may not be removed or altered from any source distribution.
28 *
29 ******************************************************************************/
30
31 #include "em_ebi.h"
32 #if defined(EBI_COUNT) && (EBI_COUNT > 0)
33 #include "sl_assert.h"
34 #include "em_bus.h"
35
36 /***************************************************************************//**
37 * @addtogroup ebi EBI - External Bus Interface
38 * @brief EBI External Bus Interface (EBI) Peripheral API
39 * @details
40 * This module contains functions to control the EBI peripheral of Silicon
41 * Labs 32-bit MCUs and SoCs. The EBI is used for accessing external parallel
42 * devices. The devices appear as part of the internal memory map of the MCU.
43 * @{
44 ******************************************************************************/
45
46 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
47
48 /* The ROUTE register has been renamed in the newest platform so these register
49 * field names have been created to make it easier to work with both
50 * the new and the old names in a generic way. */
51 #if defined(_EBI_ROUTE_MASK)
52 #define _EBI_GENERIC_ALEPEN_SHIFT _EBI_ROUTE_ALEPEN_SHIFT
53 #define _EBI_GENERIC_BLPEN_SHIFT _EBI_ROUTE_BLPEN_SHIFT
54 #define _EBI_GENERIC_EBIPEN_SHIFT _EBI_ROUTE_EBIPEN_SHIFT
55 #define _EBI_GENERIC_CS0PEN_SHIFT _EBI_ROUTE_CS0PEN_SHIFT
56 #define _EBI_GENERIC_CS1PEN_SHIFT _EBI_ROUTE_CS1PEN_SHIFT
57 #define _EBI_GENERIC_CS2PEN_SHIFT _EBI_ROUTE_CS2PEN_SHIFT
58 #define _EBI_GENERIC_CS3PEN_SHIFT _EBI_ROUTE_CS3PEN_SHIFT
59 #define _EBI_GENERIC_RESETVALUE _EBI_ROUTE_RESETVALUE
60 #define EBI_GENERIC_ROUTE_REG EBI->ROUTE
61 #define _EBI_GENERIC_ALB_MASK _EBI_ROUTE_ALB_MASK
62 #define _EBI_GENERIC_APEN_MASK _EBI_ROUTE_APEN_MASK
63 #define EBI_GENERIC_TFTPEN EBI_ROUTE_TFTPEN
64 #else
65 #define _EBI_GENERIC_ALEPEN_SHIFT _EBI_ROUTEPEN_ALEPEN_SHIFT
66 #define _EBI_GENERIC_BLPEN_SHIFT _EBI_ROUTEPEN_BLPEN_SHIFT
67 #define _EBI_GENERIC_EBIPEN_SHIFT _EBI_ROUTEPEN_EBIPEN_SHIFT
68 #define _EBI_GENERIC_CS0PEN_SHIFT _EBI_ROUTEPEN_CS0PEN_SHIFT
69 #define _EBI_GENERIC_CS1PEN_SHIFT _EBI_ROUTEPEN_CS1PEN_SHIFT
70 #define _EBI_GENERIC_CS2PEN_SHIFT _EBI_ROUTEPEN_CS2PEN_SHIFT
71 #define _EBI_GENERIC_CS3PEN_SHIFT _EBI_ROUTEPEN_CS3PEN_SHIFT
72 #define _EBI_GENERIC_RESETVALUE _EBI_ROUTEPEN_RESETVALUE
73 #define EBI_GENERIC_ROUTE_REG EBI->ROUTEPEN
74 #define _EBI_GENERIC_ALB_MASK _EBI_ROUTEPEN_ALB_MASK
75 #define _EBI_GENERIC_NANDPEN_MASK _EBI_ROUTEPEN_NANDPEN_MASK
76 #define _EBI_GENERIC_APEN_MASK _EBI_ROUTEPEN_APEN_MASK
77 #define EBI_GENERIC_TFTPEN EBI_ROUTEPEN_TFTPEN
78 #endif
79
80 /***************************************************************************//**
81 * @brief
82 * Perform a single-bit write operation on an EBI route register.
83 *
84 * @param[in] bit
85 * bit Bit position to write, 0-31.
86 *
87 * @param[in] val
88 * 0 to clear bit and 1 to set bit.
89 ******************************************************************************/
EBI_RouteBitWrite(uint32_t bit,uint32_t val)90 __STATIC_INLINE void EBI_RouteBitWrite(uint32_t bit, uint32_t val)
91 {
92 BUS_RegBitWrite(&(EBI_GENERIC_ROUTE_REG), bit, val);
93 }
94 /** @endcond */
95
96 /***************************************************************************//**
97 * @brief
98 * Configure and enable the External Bus Interface.
99 *
100 * @param[in] ebiInit
101 * The EBI configuration structure.
102 *
103 * @note
104 * GPIO lines must be configured as a PUSH_PULL for the correct operation.
105 * GPIO and EBI clocks must be enabled in the CMU.
106 ******************************************************************************/
EBI_Init(const EBI_Init_TypeDef * ebiInit)107 void EBI_Init(const EBI_Init_TypeDef *ebiInit)
108 {
109 uint32_t ctrl = EBI->CTRL;
110
111 #if defined(_EFM32_GECKO_FAMILY)
112 /* Set polarity of address ready */
113 EBI_PolaritySet(ebiLineARDY, ebiInit->ardyPolarity);
114 /* Set polarity of address latch enable */
115 EBI_PolaritySet(ebiLineALE, ebiInit->alePolarity);
116 /* Set polarity of write enable */
117 EBI_PolaritySet(ebiLineWE, ebiInit->wePolarity);
118 /* Set polarity of read enable */
119 EBI_PolaritySet(ebiLineRE, ebiInit->rePolarity);
120 /* Set polarity of chip select lines */
121 EBI_PolaritySet(ebiLineCS, ebiInit->csPolarity);
122 #else
123 /* Enable Independent Timing for devices that support it. */
124 ctrl |= EBI_CTRL_ITS;
125
126 /* Set the polarity of address ready. */
127 EBI_BankPolaritySet(ebiInit->banks, ebiLineARDY, ebiInit->ardyPolarity);
128 /* Set the polarity of address latch enable. */
129 EBI_BankPolaritySet(ebiInit->banks, ebiLineALE, ebiInit->alePolarity);
130 /* Set polarity of write enable */
131 EBI_BankPolaritySet(ebiInit->banks, ebiLineWE, ebiInit->wePolarity);
132 /* Set polarity of read enable */
133 EBI_BankPolaritySet(ebiInit->banks, ebiLineRE, ebiInit->rePolarity);
134 /* Set polarity of chip select lines */
135 EBI_BankPolaritySet(ebiInit->banks, ebiLineCS, ebiInit->csPolarity);
136 /* Set polarity of byte lane line */
137 EBI_BankPolaritySet(ebiInit->banks, ebiLineBL, ebiInit->blPolarity);
138 #endif
139
140 /* Configure EBI mode and control settings. */
141 #if defined(_EFM32_GECKO_FAMILY)
142 ctrl &= ~(_EBI_CTRL_MODE_MASK
143 | _EBI_CTRL_ARDYEN_MASK
144 | _EBI_CTRL_ARDYTODIS_MASK
145 | _EBI_CTRL_BANK0EN_MASK
146 | _EBI_CTRL_BANK1EN_MASK
147 | _EBI_CTRL_BANK2EN_MASK
148 | _EBI_CTRL_BANK3EN_MASK);
149 if ( ebiInit->enable) {
150 if ( ebiInit->banks & EBI_BANK0 ) {
151 ctrl |= EBI_CTRL_BANK0EN;
152 }
153 if ( ebiInit->banks & EBI_BANK1 ) {
154 ctrl |= EBI_CTRL_BANK1EN;
155 }
156 if ( ebiInit->banks & EBI_BANK2 ) {
157 ctrl |= EBI_CTRL_BANK2EN;
158 }
159 if ( ebiInit->banks & EBI_BANK3 ) {
160 ctrl |= EBI_CTRL_BANK3EN;
161 }
162 }
163 ctrl |= ebiInit->mode;
164 ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDYEN_SHIFT);
165 ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTODIS_SHIFT);
166 #else
167 if (ebiInit->banks & EBI_BANK0) {
168 ctrl &= ~(_EBI_CTRL_MODE_MASK
169 | _EBI_CTRL_ARDYEN_MASK
170 | _EBI_CTRL_ARDYTODIS_MASK
171 | _EBI_CTRL_BL_MASK
172 | _EBI_CTRL_NOIDLE_MASK
173 | _EBI_CTRL_BANK0EN_MASK);
174 ctrl |= (ebiInit->mode << _EBI_CTRL_MODE_SHIFT);
175 ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDYEN_SHIFT);
176 ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTODIS_SHIFT);
177 ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL_SHIFT);
178 ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE_SHIFT);
179 if ( ebiInit->enable) {
180 ctrl |= EBI_CTRL_BANK0EN;
181 }
182 }
183 if (ebiInit->banks & EBI_BANK1) {
184 ctrl &= ~(_EBI_CTRL_BL1_MASK
185 | _EBI_CTRL_MODE1_MASK
186 | _EBI_CTRL_ARDY1EN_MASK
187 | _EBI_CTRL_ARDYTO1DIS_MASK
188 | _EBI_CTRL_NOIDLE1_MASK
189 | _EBI_CTRL_BANK1EN_MASK);
190 ctrl |= (ebiInit->mode << _EBI_CTRL_MODE1_SHIFT);
191 ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY1EN_SHIFT);
192 ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO1DIS_SHIFT);
193 ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL1_SHIFT);
194 ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE1_SHIFT);
195 if ( ebiInit->enable) {
196 ctrl |= EBI_CTRL_BANK1EN;
197 }
198 }
199 if (ebiInit->banks & EBI_BANK2) {
200 ctrl &= ~(_EBI_CTRL_BL2_MASK
201 | _EBI_CTRL_MODE2_MASK
202 | _EBI_CTRL_ARDY2EN_MASK
203 | _EBI_CTRL_ARDYTO2DIS_MASK
204 | _EBI_CTRL_NOIDLE2_MASK
205 | _EBI_CTRL_BANK2EN_MASK);
206 ctrl |= (ebiInit->mode << _EBI_CTRL_MODE2_SHIFT);
207 ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY2EN_SHIFT);
208 ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO2DIS_SHIFT);
209 ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL2_SHIFT);
210 ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE2_SHIFT);
211 if ( ebiInit->enable) {
212 ctrl |= EBI_CTRL_BANK2EN;
213 }
214 }
215 if (ebiInit->banks & EBI_BANK3) {
216 ctrl &= ~(_EBI_CTRL_BL3_MASK
217 | _EBI_CTRL_MODE3_MASK
218 | _EBI_CTRL_ARDY3EN_MASK
219 | _EBI_CTRL_ARDYTO3DIS_MASK
220 | _EBI_CTRL_NOIDLE3_MASK
221 | _EBI_CTRL_BANK3EN_MASK);
222 ctrl |= (ebiInit->mode << _EBI_CTRL_MODE3_SHIFT);
223 ctrl |= (ebiInit->ardyEnable << _EBI_CTRL_ARDY3EN_SHIFT);
224 ctrl |= (ebiInit->ardyDisableTimeout << _EBI_CTRL_ARDYTO3DIS_SHIFT);
225 ctrl |= (ebiInit->blEnable << _EBI_CTRL_BL3_SHIFT);
226 ctrl |= (ebiInit->noIdle << _EBI_CTRL_NOIDLE3_SHIFT);
227 if ( ebiInit->enable) {
228 ctrl |= EBI_CTRL_BANK3EN;
229 }
230 }
231 #endif
232
233 /* Configure timing. */
234 #if defined(_EFM32_GECKO_FAMILY)
235 EBI_ReadTimingSet(ebiInit->readSetupCycles,
236 ebiInit->readStrobeCycles,
237 ebiInit->readHoldCycles);
238 EBI_WriteTimingSet(ebiInit->writeSetupCycles,
239 ebiInit->writeStrobeCycles,
240 ebiInit->writeHoldCycles);
241 EBI_AddressTimingSet(ebiInit->addrSetupCycles,
242 ebiInit->addrHoldCycles);
243 #else
244 EBI_BankReadTimingSet(ebiInit->banks,
245 ebiInit->readSetupCycles,
246 ebiInit->readStrobeCycles,
247 ebiInit->readHoldCycles);
248 EBI_BankReadTimingConfig(ebiInit->banks,
249 ebiInit->readPageMode,
250 ebiInit->readPrefetch,
251 ebiInit->readHalfRE);
252 EBI_BankWriteTimingSet(ebiInit->banks,
253 ebiInit->writeSetupCycles,
254 ebiInit->writeStrobeCycles,
255 ebiInit->writeHoldCycles);
256 EBI_BankWriteTimingConfig(ebiInit->banks,
257 ebiInit->writeBufferDisable,
258 ebiInit->writeHalfWE);
259 EBI_BankAddressTimingSet(ebiInit->banks,
260 ebiInit->addrSetupCycles,
261 ebiInit->addrHoldCycles);
262 EBI_BankAddressTimingConfig(ebiInit->banks,
263 ebiInit->addrHalfALE);
264 #endif
265
266 /* Activate the new configuration. */
267 EBI->CTRL = ctrl;
268
269 /* Configure Address Latch Enable. */
270 switch (ebiInit->mode) {
271 case ebiModeD16A16ALE:
272 case ebiModeD8A24ALE:
273 /* Address Latch Enable. */
274 EBI_RouteBitWrite(_EBI_GENERIC_ALEPEN_SHIFT, 1);
275 break;
276 #if defined(EBI_CTRL_MODE_D16)
277 case ebiModeD16:
278 #endif
279 case ebiModeD8A8:
280 /* Make sure that Address Latch is disabled. */
281 EBI_RouteBitWrite(_EBI_GENERIC_ALEPEN_SHIFT, 0);
282 break;
283 }
284
285 #if !defined(_EFM32_GECKO_FAMILY)
286 /* Limit the pin enable. */
287 EBI_GENERIC_ROUTE_REG = (EBI_GENERIC_ROUTE_REG & ~_EBI_GENERIC_ALB_MASK) | ebiInit->aLow;
288 EBI_GENERIC_ROUTE_REG = (EBI_GENERIC_ROUTE_REG & ~_EBI_GENERIC_APEN_MASK) | ebiInit->aHigh;
289 #if defined(_EBI_ROUTE_LOCATION_MASK)
290 /* Location. */
291 EBI->ROUTE = (EBI->ROUTE & ~_EBI_ROUTE_LOCATION_MASK) | ebiInit->location;
292 #endif
293
294 /* Enable the EBI BL pin if necessary. */
295 if (ctrl & (_EBI_CTRL_BL_MASK | _EBI_CTRL_BL1_MASK | _EBI_CTRL_BL2_MASK | _EBI_CTRL_BL3_MASK)) {
296 EBI_RouteBitWrite(_EBI_GENERIC_BLPEN_SHIFT, ebiInit->blEnable);
297 }
298 #endif
299
300 /* Enable EBI pins EBI_WEn and EBI_REn. */
301 EBI_RouteBitWrite(_EBI_GENERIC_EBIPEN_SHIFT, 1);
302
303 /* Enable chip select lines. */
304 EBI_ChipSelectEnable(ebiInit->csLines, true);
305 }
306
307 /***************************************************************************//**
308 * @brief
309 * Disable External Bus Interface
310 ******************************************************************************/
EBI_Disable(void)311 void EBI_Disable(void)
312 {
313 /* Disable pins */
314 EBI_GENERIC_ROUTE_REG = _EBI_GENERIC_RESETVALUE;
315 /* Disable banks */
316 EBI->CTRL = _EBI_CTRL_RESETVALUE;
317 }
318
319 /***************************************************************************//**
320 * @brief
321 * Enable or disable EBI Bank.
322 *
323 * @param[in] banks
324 * Banks to reconfigure, mask of EBI_BANK<n> flags.
325 *
326 * @param[in] enable
327 * True to enable, false to disable.
328 ******************************************************************************/
EBI_BankEnable(uint32_t banks,bool enable)329 void EBI_BankEnable(uint32_t banks, bool enable)
330 {
331 if (banks & EBI_BANK0) {
332 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK0EN_SHIFT, enable);
333 }
334 if (banks & EBI_BANK1) {
335 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK1EN_SHIFT, enable);
336 }
337 if (banks & EBI_BANK2) {
338 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK2EN_SHIFT, enable);
339 }
340 if (banks & EBI_BANK3) {
341 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BANK3EN_SHIFT, enable);
342 }
343 }
344
345 /***************************************************************************//**
346 * @brief
347 * Return the base address of the EBI bank.
348 *
349 * @param[in] bank
350 * A bank to return the start address for.
351 *
352 * @return
353 * an absolute address of the bank.
354 ******************************************************************************/
EBI_BankAddress(uint32_t bank)355 uint32_t EBI_BankAddress(uint32_t bank)
356 {
357 #if defined (EBI_CTRL_ALTMAP)
358 if (EBI->CTRL & EBI_CTRL_ALTMAP) {
359 switch (bank) {
360 case EBI_BANK0:
361 return EBI_MEM_BASE;
362
363 case EBI_BANK1:
364 return EBI_MEM_BASE + 0x10000000UL;
365
366 case EBI_BANK2:
367 return EBI_MEM_BASE + 0x20000000UL;
368
369 case EBI_BANK3:
370 return EBI_MEM_BASE + 0x30000000UL;
371
372 default:
373 EFM_ASSERT(0);
374 break;
375 }
376 }
377 #endif
378 switch (bank) {
379 case EBI_BANK0:
380 return EBI_MEM_BASE;
381
382 case EBI_BANK1:
383 return EBI_MEM_BASE + 0x04000000UL;
384
385 case EBI_BANK2:
386 return EBI_MEM_BASE + 0x08000000UL;
387
388 case EBI_BANK3:
389 return EBI_MEM_BASE + 0x0C000000UL;
390
391 default:
392 EFM_ASSERT(0);
393 break;
394 }
395 return 0;
396 }
397
398 #if defined(_EBI_NANDCTRL_MASK)
399 /***************************************************************************//**
400 * @brief
401 * Enable or disable EBI NAND Flash Support
402 *
403 * @param[in] banks
404 * Banks to reconfigure, mask of EBI_BANK<n> flags.
405 *
406 * @param[in] enable
407 * True to enable, false to disable.
408 ******************************************************************************/
EBI_NANDFlashEnable(uint32_t banks,bool enable)409 void EBI_NANDFlashEnable(uint32_t banks, bool enable)
410 {
411 if (banks & EBI_BANK0) {
412 BUS_RegBitWrite(&(EBI->NANDCTRL), _EBI_NANDCTRL_BANKSEL_SHIFT, _EBI_NANDCTRL_BANKSEL_BANK0);
413 }
414 if (banks & EBI_BANK1) {
415 BUS_RegBitWrite(&(EBI->NANDCTRL), _EBI_NANDCTRL_BANKSEL_SHIFT, _EBI_NANDCTRL_BANKSEL_BANK1);
416 }
417 if (banks & EBI_BANK2) {
418 BUS_RegBitWrite(&(EBI->NANDCTRL), _EBI_NANDCTRL_BANKSEL_SHIFT, _EBI_NANDCTRL_BANKSEL_BANK2);
419 }
420 if (banks & EBI_BANK3) {
421 BUS_RegBitWrite(&(EBI->NANDCTRL), _EBI_NANDCTRL_BANKSEL_SHIFT, _EBI_NANDCTRL_BANKSEL_BANK3);
422 }
423 BUS_RegBitWrite(&(EBI->NANDCTRL), _EBI_NANDCTRL_EN_SHIFT, enable);
424 }
425 #endif
426
427 /***************************************************************************//**
428 * @brief
429 * Enable or disable EBI Chip Select.
430 *
431 * @param[in] cs
432 * ChipSelect lines to reconfigure, mask of EBI_CS<n> flags.
433 *
434 * @param[in] enable
435 * True to enable, false to disable.
436 ******************************************************************************/
EBI_ChipSelectEnable(uint32_t cs,bool enable)437 void EBI_ChipSelectEnable(uint32_t cs, bool enable)
438 {
439 if (cs & EBI_CS0) {
440 EBI_RouteBitWrite(_EBI_GENERIC_CS0PEN_SHIFT, enable);
441 }
442 if (cs & EBI_CS1) {
443 EBI_RouteBitWrite(_EBI_GENERIC_CS1PEN_SHIFT, enable);
444 }
445 if (cs & EBI_CS2) {
446 EBI_RouteBitWrite(_EBI_GENERIC_CS2PEN_SHIFT, enable);
447 }
448 if (cs & EBI_CS3) {
449 EBI_RouteBitWrite(_EBI_GENERIC_CS3PEN_SHIFT, enable);
450 }
451 }
452
453 /***************************************************************************//**
454 * @brief
455 * Configure EBI pin polarity.
456 *
457 * @param[in] line
458 * Which pin/line to configure.
459 *
460 * @param[in] polarity
461 * Active high or active low.
462 ******************************************************************************/
EBI_PolaritySet(EBI_Line_TypeDef line,EBI_Polarity_TypeDef polarity)463 void EBI_PolaritySet(EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity)
464 {
465 switch (line) {
466 case ebiLineARDY:
467 BUS_RegBitWrite(&EBI->POLARITY, _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
468 break;
469 case ebiLineALE:
470 BUS_RegBitWrite(&EBI->POLARITY, _EBI_POLARITY_ALEPOL_SHIFT, polarity);
471 break;
472 case ebiLineWE:
473 BUS_RegBitWrite(&EBI->POLARITY, _EBI_POLARITY_WEPOL_SHIFT, polarity);
474 break;
475 case ebiLineRE:
476 BUS_RegBitWrite(&EBI->POLARITY, _EBI_POLARITY_REPOL_SHIFT, polarity);
477 break;
478 case ebiLineCS:
479 BUS_RegBitWrite(&EBI->POLARITY, _EBI_POLARITY_CSPOL_SHIFT, polarity);
480 break;
481 #if defined(_EBI_POLARITY_BLPOL_MASK)
482 case ebiLineBL:
483 BUS_RegBitWrite(&EBI->POLARITY, _EBI_POLARITY_BLPOL_SHIFT, polarity);
484 break;
485 #endif
486 #if defined (_EBI_TFTPOLARITY_MASK)
487 case ebiLineTFTVSync:
488 BUS_RegBitWrite(&EBI->TFTPOLARITY, _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
489 break;
490 case ebiLineTFTHSync:
491 BUS_RegBitWrite(&EBI->TFTPOLARITY, _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
492 break;
493 case ebiLineTFTDataEn:
494 BUS_RegBitWrite(&EBI->TFTPOLARITY, _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
495 break;
496 case ebiLineTFTDClk:
497 BUS_RegBitWrite(&EBI->TFTPOLARITY, _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
498 break;
499 case ebiLineTFTCS:
500 BUS_RegBitWrite(&EBI->TFTPOLARITY, _EBI_TFTPOLARITY_CSPOL_SHIFT, polarity);
501 break;
502 #endif
503 default:
504 EFM_ASSERT(0);
505 break;
506 }
507 }
508
509 /***************************************************************************//**
510 * @brief
511 * Configure timing values of read bus accesses.
512 *
513 * @param[in] setupCycles
514 * A number of clock cycles for the address setup before REn is asserted.
515 *
516 * @param[in] strobeCycles
517 * The number of cycles the REn is held active. After the specified number of
518 * cycles, data is read. If set to 0, 1 cycle is inserted by hardware.
519 *
520 * @param[in] holdCycles
521 * The number of cycles CSn is held active after the REn is deasserted.
522 ******************************************************************************/
EBI_ReadTimingSet(uint32_t setupCycles,uint32_t strobeCycles,uint32_t holdCycles)523 void EBI_ReadTimingSet(uint32_t setupCycles, uint32_t strobeCycles, uint32_t holdCycles)
524 {
525 uint32_t readTiming;
526
527 /* Check that timings are within limits */
528 EFM_ASSERT(setupCycles <= _EBI_RDTIMING_RDSETUP_MASK >> _EBI_RDTIMING_RDSETUP_SHIFT);
529 EFM_ASSERT(strobeCycles <= _EBI_RDTIMING_RDSTRB_MASK >> _EBI_RDTIMING_RDSTRB_SHIFT);
530 EFM_ASSERT(holdCycles <= _EBI_RDTIMING_RDHOLD_MASK >> _EBI_RDTIMING_RDHOLD_SHIFT);
531
532 /* Configure timing values */
533 readTiming = (setupCycles << _EBI_RDTIMING_RDSETUP_SHIFT)
534 | (strobeCycles << _EBI_RDTIMING_RDSTRB_SHIFT)
535 | (holdCycles << _EBI_RDTIMING_RDHOLD_SHIFT);
536
537 EBI->RDTIMING = (EBI->RDTIMING
538 & ~(_EBI_RDTIMING_RDSETUP_MASK
539 | _EBI_RDTIMING_RDSTRB_MASK
540 | _EBI_RDTIMING_RDHOLD_MASK))
541 | readTiming;
542 }
543
544 /***************************************************************************//**
545 * @brief
546 * Configure timing values of write bus accesses.
547 *
548 * @param[in] setupCycles
549 * A number of clock cycles for the address setup before WEn is asserted.
550 *
551 * @param[in] strobeCycles
552 * A number of cycles WEn is held active. If set to 0, 1 cycle is inserted by hardware.
553 *
554 * @param[in] holdCycles
555 * A number of cycles CSn is held active after the WEn is deasserted.
556 ******************************************************************************/
EBI_WriteTimingSet(uint32_t setupCycles,uint32_t strobeCycles,uint32_t holdCycles)557 void EBI_WriteTimingSet(uint32_t setupCycles, uint32_t strobeCycles, uint32_t holdCycles)
558 {
559 uint32_t writeTiming;
560
561 /* Check that timings are within limits */
562 EFM_ASSERT(setupCycles <= _EBI_WRTIMING_WRSETUP_MASK >> _EBI_WRTIMING_WRSETUP_SHIFT);
563 EFM_ASSERT(strobeCycles <= _EBI_WRTIMING_WRSTRB_MASK >> _EBI_WRTIMING_WRSTRB_SHIFT);
564 EFM_ASSERT(holdCycles <= _EBI_WRTIMING_WRHOLD_MASK >> _EBI_WRTIMING_WRHOLD_SHIFT);
565
566 /* Configure timing values. */
567 writeTiming = (setupCycles << _EBI_WRTIMING_WRSETUP_SHIFT)
568 | (strobeCycles << _EBI_WRTIMING_WRSTRB_SHIFT)
569 | (holdCycles << _EBI_WRTIMING_WRHOLD_SHIFT);
570
571 EBI->WRTIMING = (EBI->WRTIMING
572 & ~(_EBI_WRTIMING_WRSETUP_MASK
573 | _EBI_WRTIMING_WRSTRB_MASK
574 | _EBI_WRTIMING_WRHOLD_MASK))
575 | writeTiming;
576 }
577
578 /***************************************************************************//**
579 * @brief
580 * Configure timing values of address latch bus accesses.
581 *
582 * @param[in] setupCycles
583 * Sets the number of cycles the address is held after ALE is asserted.
584 *
585 * @param[in] holdCycles
586 * Sets the number of cycles the address is driven onto the ADDRDAT bus before
587 * ALE is asserted. If set 0, 1 cycle is inserted by hardware.
588 ******************************************************************************/
EBI_AddressTimingSet(uint32_t setupCycles,uint32_t holdCycles)589 void EBI_AddressTimingSet(uint32_t setupCycles, uint32_t holdCycles)
590 {
591 uint32_t addressLatchTiming;
592
593 /* Check that timings are within limits */
594 EFM_ASSERT(setupCycles <= _EBI_ADDRTIMING_ADDRSETUP_MASK >> _EBI_ADDRTIMING_ADDRSETUP_SHIFT);
595 EFM_ASSERT(holdCycles <= _EBI_ADDRTIMING_ADDRHOLD_MASK >> _EBI_ADDRTIMING_ADDRHOLD_SHIFT);
596
597 /* Configure address latch timing values. */
598 addressLatchTiming = (setupCycles << _EBI_ADDRTIMING_ADDRSETUP_SHIFT)
599 | (holdCycles << _EBI_ADDRTIMING_ADDRHOLD_SHIFT);
600
601 EBI->ADDRTIMING = (EBI->ADDRTIMING
602 & ~(_EBI_ADDRTIMING_ADDRSETUP_MASK
603 | _EBI_ADDRTIMING_ADDRHOLD_MASK))
604 | addressLatchTiming;
605 }
606
607 #if defined(_EBI_TFTCTRL_MASK)
608 /***************************************************************************//**
609 * @brief
610 * Configure and initialize TFT Direct Drive.
611 *
612 * @param[in] ebiTFTInit
613 * The TFT Initialization structure.
614 ******************************************************************************/
EBI_TFTInit(const EBI_TFTInit_TypeDef * ebiTFTInit)615 void EBI_TFTInit(const EBI_TFTInit_TypeDef *ebiTFTInit)
616 {
617 uint32_t ctrl;
618
619 /* Configure the base address for the frame buffer offset to the EBI bank. */
620 EBI_TFTFrameBaseSet(ebiTFTInit->addressOffset);
621
622 /* Configure the display size and porch areas. */
623 EBI_TFTSizeSet(ebiTFTInit->hsize,
624 ebiTFTInit->vsize);
625 EBI_TFTHPorchSet(ebiTFTInit->hPorchFront,
626 ebiTFTInit->hPorchBack,
627 ebiTFTInit->hPulseWidth);
628 EBI_TFTVPorchSet(ebiTFTInit->vPorchFront,
629 ebiTFTInit->vPorchBack,
630 ebiTFTInit->vPulseWidth);
631
632 /* Configure timing settings. */
633 EBI_TFTTimingSet(ebiTFTInit->dclkPeriod,
634 ebiTFTInit->startPosition,
635 ebiTFTInit->setupCycles,
636 ebiTFTInit->holdCycles);
637
638 /* Configure line polarity settings. */
639 EBI_PolaritySet(ebiLineTFTCS, ebiTFTInit->csPolarity);
640 EBI_PolaritySet(ebiLineTFTDClk, ebiTFTInit->dclkPolarity);
641 EBI_PolaritySet(ebiLineTFTDataEn, ebiTFTInit->dataenPolarity);
642 EBI_PolaritySet(ebiLineTFTVSync, ebiTFTInit->vsyncPolarity);
643 EBI_PolaritySet(ebiLineTFTHSync, ebiTFTInit->hsyncPolarity);
644
645 /* Main control, EBI bank select, mask and blending configuration. */
646 ctrl = (uint32_t)ebiTFTInit->bank
647 | (uint32_t)ebiTFTInit->width
648 | (uint32_t)ebiTFTInit->colSrc
649 | (uint32_t)ebiTFTInit->interleave
650 | (uint32_t)ebiTFTInit->fbTrigger
651 | (uint32_t)(ebiTFTInit->shiftDClk == true
652 ? (1 << _EBI_TFTCTRL_SHIFTDCLKEN_SHIFT) : 0)
653 | (uint32_t)ebiTFTInit->maskBlend
654 | (uint32_t)ebiTFTInit->driveMode;
655
656 EBI->TFTCTRL = ctrl;
657
658 /* Enable TFT pins. */
659 if (ebiTFTInit->driveMode != ebiTFTDDModeDisabled) {
660 EBI_GENERIC_ROUTE_REG |= EBI_GENERIC_TFTPEN;
661 }
662 }
663
664 /***************************************************************************//**
665 * @brief
666 * Configure and initialize TFT size settings.
667 *
668 * @param[in] horizontal
669 * TFT display horizontal size in pixels.
670 * @param[in] vertical
671 * TFT display vertical size in pixels.
672 ******************************************************************************/
EBI_TFTSizeSet(uint32_t horizontal,uint32_t vertical)673 void EBI_TFTSizeSet(uint32_t horizontal, uint32_t vertical)
674 {
675 EFM_ASSERT((horizontal - 1) <= _EBI_TFTSIZE_HSZ_MASK >> _EBI_TFTSIZE_HSZ_SHIFT);
676 EFM_ASSERT((vertical - 1) <= _EBI_TFTSIZE_VSZ_MASK >> _EBI_TFTSIZE_VSZ_SHIFT);
677
678 EBI->TFTSIZE = ((horizontal - 1) << _EBI_TFTSIZE_HSZ_SHIFT)
679 | ((vertical - 1) << _EBI_TFTSIZE_VSZ_SHIFT);
680 }
681
682 /***************************************************************************//**
683 * @brief
684 * Configure and initialize Horizontal Porch Settings.
685 *
686 * @param[in] front
687 * Horizontal front porch size in pixels.
688 * @param[in] back
689 * Horizontal back porch size in pixels.
690 * @param[in] pulseWidth
691 * Horizontal synchronization pulse width. Set to required -1.
692 ******************************************************************************/
EBI_TFTHPorchSet(uint32_t front,uint32_t back,uint32_t pulseWidth)693 void EBI_TFTHPorchSet(uint32_t front, uint32_t back, uint32_t pulseWidth)
694 {
695 EFM_ASSERT(front <= _EBI_TFTHPORCH_HFPORCH_MASK >> _EBI_TFTHPORCH_HFPORCH_SHIFT);
696 EFM_ASSERT(back <= _EBI_TFTHPORCH_HBPORCH_MASK >> _EBI_TFTHPORCH_HBPORCH_SHIFT);
697 EFM_ASSERT((pulseWidth - 1) <= _EBI_TFTHPORCH_HSYNC_MASK >> _EBI_TFTHPORCH_HSYNC_SHIFT);
698
699 EBI->TFTHPORCH = (front << _EBI_TFTHPORCH_HFPORCH_SHIFT)
700 | (back << _EBI_TFTHPORCH_HBPORCH_SHIFT)
701 | ((pulseWidth - 1) << _EBI_TFTHPORCH_HSYNC_SHIFT);
702 }
703
704 /***************************************************************************//**
705 * @brief
706 * Configure Vertical Porch Settings.
707 *
708 * @param[in] front
709 * Vertical front porch size in pixels.
710 * @param[in] back
711 * Vertical back porch size in pixels.
712 * @param[in] pulseWidth
713 * Vertical synchronization pulse width. Set to required -1.
714 ******************************************************************************/
EBI_TFTVPorchSet(uint32_t front,uint32_t back,uint32_t pulseWidth)715 void EBI_TFTVPorchSet(uint32_t front, uint32_t back, uint32_t pulseWidth)
716 {
717 EFM_ASSERT(front <= _EBI_TFTVPORCH_VFPORCH_MASK >> _EBI_TFTVPORCH_VFPORCH_SHIFT);
718 EFM_ASSERT(back <= _EBI_TFTVPORCH_VBPORCH_MASK >> _EBI_TFTVPORCH_VBPORCH_SHIFT);
719 EFM_ASSERT((pulseWidth - 1) <= _EBI_TFTVPORCH_VSYNC_MASK >> _EBI_TFTVPORCH_VSYNC_SHIFT);
720
721 EBI->TFTVPORCH = (front << _EBI_TFTVPORCH_VFPORCH_SHIFT)
722 | (back << _EBI_TFTVPORCH_VBPORCH_SHIFT)
723 | ((pulseWidth - 1) << _EBI_TFTVPORCH_VSYNC_SHIFT);
724 }
725
726 /***************************************************************************//**
727 * @brief
728 * Configure TFT Direct Drive Timing Settings.
729 *
730 * @param[in] dclkPeriod
731 * DCLK period in internal cycles.
732 *
733 * @param[in] start
734 * A starting position of the external direct drive, relative to the DCLK inactive edge.
735 *
736 * @param[in] setup
737 * A number of cycles that RGB data is driven before the active edge of DCLK.
738 *
739 * @param[in] hold
740 * A number of cycles that RGB data is held after the active edge of DCLK.
741 ******************************************************************************/
EBI_TFTTimingSet(uint32_t dclkPeriod,uint32_t start,uint32_t setup,uint32_t hold)742 void EBI_TFTTimingSet(uint32_t dclkPeriod, uint32_t start, uint32_t setup, uint32_t hold)
743 {
744 /* Check that timings are within limits */
745 EFM_ASSERT(dclkPeriod <= _EBI_TFTTIMING_DCLKPERIOD_MASK >> _EBI_TFTTIMING_DCLKPERIOD_SHIFT);
746 EFM_ASSERT(start <= _EBI_TFTTIMING_TFTSTART_MASK >> _EBI_TFTTIMING_TFTSTART_SHIFT);
747 EFM_ASSERT(setup <= _EBI_TFTTIMING_TFTSETUP_MASK >> _EBI_TFTTIMING_TFTSETUP_SHIFT);
748 EFM_ASSERT(hold <= _EBI_TFTTIMING_TFTHOLD_MASK >> _EBI_TFTTIMING_TFTHOLD_SHIFT);
749
750 EBI->TFTTIMING = (dclkPeriod << _EBI_TFTTIMING_DCLKPERIOD_SHIFT)
751 | (start << _EBI_TFTTIMING_TFTSTART_SHIFT)
752 | (setup << _EBI_TFTTIMING_TFTSETUP_SHIFT)
753 | (hold << _EBI_TFTTIMING_TFTHOLD_SHIFT);
754 }
755 #endif
756
757 #if !defined(_EFM32_GECKO_FAMILY)
758 /***************************************************************************//**
759 * @brief
760 * Configure read operation parameters for a selected bank.
761 *
762 * @param[in] banks
763 * A mask of memory bank(s) to configure write timing for.
764 *
765 * @param[in] pageMode
766 * Enables or disables the half cycle WE strobe in the last strobe cycle.
767 *
768 * @param[in] prefetch
769 * Enables or disables the half cycle WE strobe in the last strobe cycle.
770 *
771 * @param[in] halfRE
772 * Enables or disables the half cycle WE strobe in the last strobe cycle.
773 ******************************************************************************/
EBI_BankReadTimingConfig(uint32_t banks,bool pageMode,bool prefetch,bool halfRE)774 void EBI_BankReadTimingConfig(uint32_t banks, bool pageMode, bool prefetch, bool halfRE)
775 {
776 /* Verify only valid banks are used */
777 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
778
779 /* Configure read operation parameters. */
780 if ( banks & EBI_BANK0 ) {
781 BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
782 BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
783 BUS_RegBitWrite(&EBI->RDTIMING, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
784 }
785 if ( banks & EBI_BANK1 ) {
786 BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
787 BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
788 BUS_RegBitWrite(&EBI->RDTIMING1, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
789 }
790 if ( banks & EBI_BANK2 ) {
791 BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
792 BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
793 BUS_RegBitWrite(&EBI->RDTIMING2, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
794 }
795 if ( banks & EBI_BANK3 ) {
796 BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_PAGEMODE_SHIFT, pageMode);
797 BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_PREFETCH_SHIFT, prefetch);
798 BUS_RegBitWrite(&EBI->RDTIMING3, _EBI_RDTIMING_HALFRE_SHIFT, halfRE);
799 }
800 }
801
802 /***************************************************************************//**
803 * @brief
804 * Configure timing values of read bus accesses.
805 *
806 * @param[in] banks
807 * A mask of memory bank(s) to configure timing for.
808 *
809 * @param[in] setupCycles
810 * A number of clock cycles for address setup before REn is asserted.
811 *
812 * @param[in] strobeCycles
813 * The number of cycles the REn is held active. After the specified number of
814 * cycles, data is read. If set to 0, 1 cycle is inserted by hardware.
815 *
816 * @param[in] holdCycles
817 * The number of cycles CSn is held active after the REn is deasserted.
818 ******************************************************************************/
EBI_BankReadTimingSet(uint32_t banks,uint32_t setupCycles,uint32_t strobeCycles,uint32_t holdCycles)819 void EBI_BankReadTimingSet(uint32_t banks, uint32_t setupCycles, uint32_t strobeCycles, uint32_t holdCycles)
820 {
821 uint32_t readTiming;
822
823 /* Verify only valid banks are used. */
824 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
825
826 /* Check that timings are within limits */
827 EFM_ASSERT(setupCycles <= _EBI_RDTIMING_RDSETUP_MASK >> _EBI_RDTIMING_RDSETUP_SHIFT);
828 EFM_ASSERT(strobeCycles <= _EBI_RDTIMING_RDSTRB_MASK >> _EBI_RDTIMING_RDSTRB_SHIFT);
829 EFM_ASSERT(holdCycles <= _EBI_RDTIMING_RDHOLD_MASK >> _EBI_RDTIMING_RDHOLD_SHIFT);
830
831 /* Configure timing values. */
832 readTiming = (setupCycles << _EBI_RDTIMING_RDSETUP_SHIFT)
833 | (strobeCycles << _EBI_RDTIMING_RDSTRB_SHIFT)
834 | (holdCycles << _EBI_RDTIMING_RDHOLD_SHIFT);
835
836 if (banks & EBI_BANK0) {
837 EBI->RDTIMING = (EBI->RDTIMING
838 & ~(_EBI_RDTIMING_RDSETUP_MASK
839 | _EBI_RDTIMING_RDSTRB_MASK
840 | _EBI_RDTIMING_RDHOLD_MASK))
841 | readTiming;
842 }
843 if (banks & EBI_BANK1) {
844 EBI->RDTIMING1 = (EBI->RDTIMING1
845 & ~(_EBI_RDTIMING1_RDSETUP_MASK
846 | _EBI_RDTIMING1_RDSTRB_MASK
847 | _EBI_RDTIMING1_RDHOLD_MASK))
848 | readTiming;
849 }
850 if (banks & EBI_BANK2) {
851 EBI->RDTIMING2 = (EBI->RDTIMING2
852 & ~(_EBI_RDTIMING2_RDSETUP_MASK
853 | _EBI_RDTIMING2_RDSTRB_MASK
854 | _EBI_RDTIMING2_RDHOLD_MASK))
855 | readTiming;
856 }
857 if (banks & EBI_BANK3) {
858 EBI->RDTIMING3 = (EBI->RDTIMING3
859 & ~(_EBI_RDTIMING3_RDSETUP_MASK
860 | _EBI_RDTIMING3_RDSTRB_MASK
861 | _EBI_RDTIMING3_RDHOLD_MASK))
862 | readTiming;
863 }
864 }
865
866 /***************************************************************************//**
867 * @brief
868 * Configure write operation parameters for a selected bank.
869 *
870 * @param[in] banks
871 * A mask of memory bank(s) to configure write timing for.
872 *
873 * @param[in] writeBufDisable
874 * If true, disable the write buffer.
875 *
876 * @param[in] halfWE
877 * Enables or disables half cycle WE strobe in the last strobe cycle.
878 ******************************************************************************/
EBI_BankWriteTimingConfig(uint32_t banks,bool writeBufDisable,bool halfWE)879 void EBI_BankWriteTimingConfig(uint32_t banks, bool writeBufDisable, bool halfWE)
880 {
881 /* Verify only valid banks are used. */
882 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
883
884 /* Configure write operation parameters. */
885 if ( banks & EBI_BANK0 ) {
886 BUS_RegBitWrite(&EBI->WRTIMING, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
887 BUS_RegBitWrite(&EBI->WRTIMING, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
888 }
889 if ( banks & EBI_BANK1 ) {
890 BUS_RegBitWrite(&EBI->WRTIMING1, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
891 BUS_RegBitWrite(&EBI->WRTIMING1, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
892 }
893 if ( banks & EBI_BANK2 ) {
894 BUS_RegBitWrite(&EBI->WRTIMING2, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
895 BUS_RegBitWrite(&EBI->WRTIMING2, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
896 }
897 if ( banks & EBI_BANK3 ) {
898 BUS_RegBitWrite(&EBI->WRTIMING3, _EBI_WRTIMING_WBUFDIS_SHIFT, writeBufDisable);
899 BUS_RegBitWrite(&EBI->WRTIMING3, _EBI_WRTIMING_HALFWE_SHIFT, halfWE);
900 }
901 }
902
903 /***************************************************************************//**
904 * @brief
905 * Configure timing values of write bus accesses.
906 *
907 * @param[in] banks
908 * A mask of memory bank(s) to configure write timing for.
909 *
910 * @param[in] setupCycles
911 * A number of clock cycles for address setup before WEn is asserted.
912 *
913 * @param[in] strobeCycles
914 * A number of cycles WEn is held active. If set to 0, 1 cycle is inserted by hardware.
915 *
916 * @param[in] holdCycles
917 * Number of cycles CSn is held active after WEn is deasserted.
918 ******************************************************************************/
EBI_BankWriteTimingSet(uint32_t banks,uint32_t setupCycles,uint32_t strobeCycles,uint32_t holdCycles)919 void EBI_BankWriteTimingSet(uint32_t banks, uint32_t setupCycles, uint32_t strobeCycles, uint32_t holdCycles)
920 {
921 uint32_t writeTiming;
922
923 /* Verify only valid banks are used.*/
924 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
925
926 /* Check that timings are within limits */
927 EFM_ASSERT(setupCycles <= _EBI_WRTIMING_WRSETUP_MASK >> _EBI_WRTIMING_WRSETUP_SHIFT);
928 EFM_ASSERT(strobeCycles <= _EBI_WRTIMING_WRSTRB_MASK >> _EBI_WRTIMING_WRSTRB_SHIFT);
929 EFM_ASSERT(holdCycles <= _EBI_WRTIMING_WRHOLD_MASK >> _EBI_WRTIMING_WRHOLD_SHIFT);
930
931 /* Configure timing values. */
932 writeTiming = (setupCycles << _EBI_WRTIMING_WRSETUP_SHIFT)
933 | (strobeCycles << _EBI_WRTIMING_WRSTRB_SHIFT)
934 | (holdCycles << _EBI_WRTIMING_WRHOLD_SHIFT);
935
936 if (banks & EBI_BANK0) {
937 EBI->WRTIMING = (EBI->WRTIMING
938 & ~(_EBI_WRTIMING_WRSETUP_MASK
939 | _EBI_WRTIMING_WRSTRB_MASK
940 | _EBI_WRTIMING_WRHOLD_MASK))
941 | writeTiming;
942 }
943 if (banks & EBI_BANK1) {
944 EBI->WRTIMING1 = (EBI->WRTIMING1
945 & ~(_EBI_WRTIMING1_WRSETUP_MASK
946 | _EBI_WRTIMING1_WRSTRB_MASK
947 | _EBI_WRTIMING1_WRHOLD_MASK))
948 | writeTiming;
949 }
950 if (banks & EBI_BANK2) {
951 EBI->WRTIMING2 = (EBI->WRTIMING2
952 & ~(_EBI_WRTIMING2_WRSETUP_MASK
953 | _EBI_WRTIMING2_WRSTRB_MASK
954 | _EBI_WRTIMING2_WRHOLD_MASK))
955 | writeTiming;
956 }
957 if (banks & EBI_BANK3) {
958 EBI->WRTIMING3 = (EBI->WRTIMING3
959 & ~(_EBI_WRTIMING3_WRSETUP_MASK
960 | _EBI_WRTIMING3_WRSTRB_MASK
961 | _EBI_WRTIMING3_WRHOLD_MASK))
962 | writeTiming;
963 }
964 }
965
966 /***************************************************************************//**
967 * @brief
968 * Configure address operation parameters for a selected bank.
969 *
970 * @param[in] banks
971 * A mask of memory bank(s) to configure write timing for.
972 *
973 * @param[in] halfALE
974 * Enables or disables the half cycle ALE strobe in the last strobe cycle.
975 ******************************************************************************/
EBI_BankAddressTimingConfig(uint32_t banks,bool halfALE)976 void EBI_BankAddressTimingConfig(uint32_t banks, bool halfALE)
977 {
978 /* Verify only valid banks are used */
979 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
980
981 if ( banks & EBI_BANK0 ) {
982 BUS_RegBitWrite(&EBI->ADDRTIMING, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
983 }
984 if ( banks & EBI_BANK1 ) {
985 BUS_RegBitWrite(&EBI->ADDRTIMING1, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
986 }
987 if ( banks & EBI_BANK2 ) {
988 BUS_RegBitWrite(&EBI->ADDRTIMING2, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
989 }
990 if ( banks & EBI_BANK3 ) {
991 BUS_RegBitWrite(&EBI->ADDRTIMING3, _EBI_ADDRTIMING_HALFALE_SHIFT, halfALE);
992 }
993 }
994
995 /***************************************************************************//**
996 * @brief
997 * Configure timing values of address latch bus accesses.
998 *
999 * @param[in] banks
1000 * A mask of memory bank(s) to configure address timing for.
1001 *
1002 * @param[in] setupCycles
1003 * Sets the number of cycles the address is held after ALE is asserted.
1004 *
1005 * @param[in] holdCycles
1006 * Sets the number of cycles the address is driven onto the ADDRDAT bus before
1007 * ALE is asserted. If set 0, 1 cycle is inserted by hardware.
1008 ******************************************************************************/
EBI_BankAddressTimingSet(uint32_t banks,uint32_t setupCycles,uint32_t holdCycles)1009 void EBI_BankAddressTimingSet(uint32_t banks, uint32_t setupCycles, uint32_t holdCycles)
1010 {
1011 uint32_t addressLatchTiming;
1012
1013 /* Verify only valid banks are used. */
1014 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
1015
1016 /* Check that timings are within limits */
1017 EFM_ASSERT(setupCycles <= _EBI_ADDRTIMING_ADDRSETUP_MASK >> _EBI_ADDRTIMING_ADDRSETUP_SHIFT);
1018 EFM_ASSERT(holdCycles <= _EBI_ADDRTIMING_ADDRHOLD_MASK >> _EBI_ADDRTIMING_ADDRHOLD_SHIFT);
1019
1020 /* Configure address latch timing values. */
1021 addressLatchTiming = (setupCycles << _EBI_ADDRTIMING_ADDRSETUP_SHIFT)
1022 | (holdCycles << _EBI_ADDRTIMING_ADDRHOLD_SHIFT);
1023
1024 if (banks & EBI_BANK0) {
1025 EBI->ADDRTIMING = (EBI->ADDRTIMING
1026 & ~(_EBI_ADDRTIMING_ADDRSETUP_MASK
1027 | _EBI_ADDRTIMING_ADDRHOLD_MASK))
1028 | addressLatchTiming;
1029 }
1030 if (banks & EBI_BANK1) {
1031 EBI->ADDRTIMING1 = (EBI->ADDRTIMING1
1032 & ~(_EBI_ADDRTIMING1_ADDRSETUP_MASK
1033 | _EBI_ADDRTIMING1_ADDRHOLD_MASK))
1034 | addressLatchTiming;
1035 }
1036 if (banks & EBI_BANK2) {
1037 EBI->ADDRTIMING2 = (EBI->ADDRTIMING2
1038 & ~(_EBI_ADDRTIMING2_ADDRSETUP_MASK
1039 | _EBI_ADDRTIMING2_ADDRHOLD_MASK))
1040 | addressLatchTiming;
1041 }
1042 if (banks & EBI_BANK3) {
1043 EBI->ADDRTIMING3 = (EBI->ADDRTIMING3
1044 & ~(_EBI_ADDRTIMING3_ADDRSETUP_MASK
1045 | _EBI_ADDRTIMING3_ADDRHOLD_MASK))
1046 | addressLatchTiming;
1047 }
1048 }
1049
1050 /***************************************************************************//**
1051 * @brief
1052 * Configure EBI pin polarity for selected bank(s) for devices with individual
1053 * timing support.
1054 *
1055 * @param[in] banks
1056 * A mask of memory bank(s) to configure polarity for.
1057 *
1058 * @param[in] line
1059 * Which pin/line to configure.
1060 *
1061 * @param[in] polarity
1062 * Active high, or active low.
1063 ******************************************************************************/
EBI_BankPolaritySet(uint32_t banks,EBI_Line_TypeDef line,EBI_Polarity_TypeDef polarity)1064 void EBI_BankPolaritySet(uint32_t banks, EBI_Line_TypeDef line, EBI_Polarity_TypeDef polarity)
1065 {
1066 uint32_t bankSet = 0;
1067 volatile uint32_t *polRegister = 0;
1068
1069 /* Verify that only valid banks are used. */
1070 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
1071
1072 while (banks) {
1073 if (banks & EBI_BANK0) {
1074 polRegister = &EBI->POLARITY;
1075 bankSet = EBI_BANK0;
1076 }
1077 if (banks & EBI_BANK1) {
1078 polRegister = &EBI->POLARITY1;
1079 bankSet = EBI_BANK1;
1080 }
1081 if (banks & EBI_BANK2) {
1082 polRegister = &EBI->POLARITY2;
1083 bankSet = EBI_BANK2;
1084 }
1085 if (banks & EBI_BANK3) {
1086 polRegister = &EBI->POLARITY3;
1087 bankSet = EBI_BANK3;
1088 }
1089
1090 /* What line to configure. */
1091 switch (line) {
1092 case ebiLineARDY:
1093 BUS_RegBitWrite(polRegister, _EBI_POLARITY_ARDYPOL_SHIFT, polarity);
1094 break;
1095 case ebiLineALE:
1096 BUS_RegBitWrite(polRegister, _EBI_POLARITY_ALEPOL_SHIFT, polarity);
1097 break;
1098 case ebiLineWE:
1099 BUS_RegBitWrite(polRegister, _EBI_POLARITY_WEPOL_SHIFT, polarity);
1100 break;
1101 case ebiLineRE:
1102 BUS_RegBitWrite(polRegister, _EBI_POLARITY_REPOL_SHIFT, polarity);
1103 break;
1104 case ebiLineCS:
1105 BUS_RegBitWrite(polRegister, _EBI_POLARITY_CSPOL_SHIFT, polarity);
1106 break;
1107 case ebiLineBL:
1108 BUS_RegBitWrite(polRegister, _EBI_POLARITY_BLPOL_SHIFT, polarity);
1109 break;
1110 case ebiLineTFTVSync:
1111 BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_VSYNCPOL_SHIFT, polarity);
1112 break;
1113 case ebiLineTFTHSync:
1114 BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_HSYNCPOL_SHIFT, polarity);
1115 break;
1116 case ebiLineTFTDataEn:
1117 BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DATAENPOL_SHIFT, polarity);
1118 break;
1119 case ebiLineTFTDClk:
1120 BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_DCLKPOL_SHIFT, polarity);
1121 break;
1122 case ebiLineTFTCS:
1123 BUS_RegBitWrite(&(EBI->TFTPOLARITY), _EBI_TFTPOLARITY_CSPOL_SHIFT, polarity);
1124 break;
1125 default:
1126 EFM_ASSERT(0);
1127 break;
1128 }
1129 banks = banks & ~bankSet;
1130 }
1131 }
1132
1133 /***************************************************************************//**
1134 * @brief
1135 * Configure Byte Lane Enable for select banks
1136 * timing support.
1137 *
1138 * @param[in] banks
1139 * A mask of memory bank(s) to configure polarity for.
1140 *
1141 * @param[in] enable
1142 * A flag
1143 ******************************************************************************/
EBI_BankByteLaneEnable(uint32_t banks,bool enable)1144 void EBI_BankByteLaneEnable(uint32_t banks, bool enable)
1145 {
1146 /* Verify only valid banks are used */
1147 EFM_ASSERT((banks & ~(EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3)) == 0);
1148
1149 /* Configure byte lane support for each selected bank */
1150 if (banks & EBI_BANK0) {
1151 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL_SHIFT, enable);
1152 }
1153 if (banks & EBI_BANK1) {
1154 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL1_SHIFT, enable);
1155 }
1156 if (banks & EBI_BANK2) {
1157 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL2_SHIFT, enable);
1158 }
1159 if (banks & EBI_BANK3) {
1160 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_BL3_SHIFT, enable);
1161 }
1162 }
1163
1164 /***************************************************************************//**
1165 * @brief
1166 * Configure the Alternate Address Map support.
1167 * Enables or disables 256 MB address range for all banks.
1168 *
1169 * @param[in] enable
1170 * Set or clear the address map extension.
1171 ******************************************************************************/
EBI_AltMapEnable(bool enable)1172 void EBI_AltMapEnable(bool enable)
1173 {
1174 BUS_RegBitWrite(&(EBI->CTRL), _EBI_CTRL_ALTMAP_SHIFT, enable);
1175 }
1176
1177 #endif
1178
1179 /** @} (end addtogroup ebi) */
1180
1181 #endif /* defined(EBI_COUNT) && (EBI_COUNT > 0) */
1182