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