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