bsp_dk_3201.c

Go to the documentation of this file.
00001 /***************************************************************************/
00018 #include "em_device.h"
00019 #include "em_cmu.h"
00020 #include "em_ebi.h"
00021 #include "em_gpio.h"
00022 #include "em_usart.h"
00023 #include "bsp_dk_bcreg_3201.h"
00024 #include "bsp.h"
00025 
00026 #if defined( BSP_DK_3201 )
00027 
00029 /* USART used for SPI access */
00030 #define BSP_SPI_USART_USED  USART2          
00031 #define BSP_SPI_USART_CLK   cmuClock_USART2 
00033 /* GPIO pins used fotr SPI pins, please refer to DK user guide. */
00034 #define BSP_PORT_SPI_TX     gpioPortC       
00035 #define BSP_PIN_SPI_TX      2               
00036 #define BSP_PORT_SPI_RX     gpioPortC       
00037 #define BSP_PIN_SPI_RX      3               
00038 #define BSP_PORT_SPI_CLK    gpioPortC       
00039 #define BSP_PIN_SPI_CLK     4               
00040 #define BSP_PORT_SPI_CS     gpioPortC       
00041 #define BSP_PIN_SPI_CS      5               
00044 typedef enum
00045 {
00046   BSP_SPI_Audio,    
00047   BSP_SPI_Ethernet, 
00048   BSP_SPI_Display,  
00049   BSP_SPI_OFF,      
00050 } BSP_SpiControl_TypeDef;
00051 
00053 typedef enum
00054 {
00055   BSP_Init_EBI,    
00056   BSP_Init_SPI,    
00057   BSP_Init_DIRECT, 
00058   BSP_Init_OFF,    
00059 } BSP_Init_TypeDef;
00060 
00061 static bool EbiInit(void);
00062 static void EbiDisable(void);
00063 static uint16_t SpiBcAccess(uint8_t addr, uint8_t rw, uint16_t data);
00064 static void SpiBcInit(void);
00065 static void SpiControl(BSP_SpiControl_TypeDef device);
00066 static void SpiBcDisable(void);
00067 static bool SpiInit(void);
00068 static uint16_t SpiRegisterRead(volatile uint16_t *addr);
00069 static void SpiRegisterWrite(volatile uint16_t *addr, uint16_t data);
00070 
00071 /* Keep intialization mode */
00072 static uint32_t bspOperationMode;
00073 static BSP_BusControl_TypeDef busMode = BSP_BusControl_Undefined;
00074 static volatile const uint16_t *lastAddr = 0; 
00075 static uint16_t bcFwVersion;
00076 
00079 /***************************************************************************/
00084 /***************************************************************************/
00089 /**************************************************************************/
00097 int BSP_Disable(void)
00098 {
00099   if (bspOperationMode == BSP_INIT_DK_EBI)
00100   {
00101     EbiDisable();
00102   }
00103   if (bspOperationMode == BSP_INIT_DK_SPI)
00104   {
00105     SpiBcDisable();
00106   }
00107   BSP_BusControlModeSet(BSP_BusControl_OFF);
00108 
00109   return BSP_STATUS_OK;
00110 }
00111 
00112 /**************************************************************************/
00127 int BSP_Init(uint32_t flags)
00128 {
00129   bool ret = false;
00130 
00131   if (flags & BSP_INIT_DK_EBI)
00132   {
00133     bspOperationMode = BSP_INIT_DK_EBI;
00134     BSP_BusControlModeSet(BSP_BusControl_EBI);
00135     ret = EbiInit();
00136   }
00137   if (flags & BSP_INIT_DK_SPI)
00138   {
00139     bspOperationMode = BSP_INIT_DK_SPI;
00140     BSP_BusControlModeSet(BSP_BusControl_SPI);
00141     ret = SpiInit();
00142   }
00143 
00144   if (ret == false)
00145   {
00146     /* Unable to access board control, this is an abornomal situation. */
00147     /* Try to restart kit and reprogram EFM32 with a standard example */
00148     /* as this is most likely caused by a peripheral misconfiguration. */
00149     while (1) ;
00150   }
00151 
00152   /* Inform AEM application that we are in Energy Mode 0 by default */
00153   BSP_RegisterWrite(&BC_REGISTER->EM, 0);
00154   
00155   /* Read out BC firmware version */
00156   bcFwVersion = BSP_RegisterRead(&BC_REGISTER->FW_VERSION);
00157 
00158   return BSP_STATUS_OK;
00159 }
00162 /***************************************************************************/
00167 /**************************************************************************/
00173 BSP_BusControl_TypeDef BSP_BusControlModeGet( void )
00174 {
00175   return busMode;
00176 }
00177 
00178 /**************************************************************************/
00187 int BSP_BusControlModeSet(BSP_BusControl_TypeDef mode)
00188 {
00189   int retVal = BSP_STATUS_OK;
00190 
00191   /* Configure GPIO pins for Board Bus mode */
00192   /* Note: Inverter on GPIO lines to BC, so signals are active low */
00193   CMU_ClockEnable(cmuClock_GPIO, true);
00194 
00195   busMode = mode;
00196 
00197   switch (mode)
00198   {
00199     case BSP_BusControl_OFF:
00200       /* Configure board for OFF mode on PB15 MCU_EBI_CONNECT */
00201       GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
00202       /* Configure board for OFF mode on PD13 MCU_SPI_CONNECT */
00203       GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1);
00204       break;
00205 
00206     case BSP_BusControl_DIRECT:
00207       /* Configure board for DIRECT on PB15 MCU_EBI_CONNECT */
00208       GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0);
00209       /* Configure board for DIRECT on PD13 MCU_SPI_CONNECT */
00210       GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0);
00211       break;
00212 
00213     case BSP_BusControl_SPI:
00214       /* Configure board for SPI mode on PB15 MCU_EBI_CONNECT */
00215       GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
00216       /* Configure board for SPI mode on PD13 MCU_SPI_CONNECT */
00217       GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0);
00218       break;
00219 
00220     case BSP_BusControl_EBI:
00221       /* Configure board for EBI mode on PB15 MCU_EBI_CONNECT */
00222       GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0);
00223       /* Configure board for EBI mode on PD13 MCU_SPI_CONNECT */
00224       GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1);
00225       break;
00226 
00227     default:
00228       retVal = BSP_STATUS_ILLEGAL_PARAM;
00229       break;
00230   }
00231   return retVal;
00232 }
00233 
00234 /**************************************************************************/
00238 uint32_t BSP_DipSwitchGet(void)
00239 {
00240   return BSP_RegisterRead(&BC_REGISTER->UIF_DIP) & 0x000f;
00241 }
00242 
00243 /**************************************************************************/
00251 int BSP_DisplayControl(BSP_Display_TypeDef option)
00252 {
00253   uint16_t tmp;
00254 
00255   switch (option)
00256   {
00257   case BSP_Display_EBI:
00258     BSP_RegisterWrite(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_EBI);
00259     break;
00260 
00261   case BSP_Display_SPI:
00262     BSP_RegisterWrite(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_SPI);
00263     break;
00264 
00265   case BSP_Display_BC:
00266     BSP_RegisterWrite(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_BC);
00267     break;
00268 
00269   case BSP_Display_PowerEnable:
00270     tmp  = BSP_RegisterRead(&BC_REGISTER->DISPLAY_CTRL);
00271     tmp |= (BC_DISPLAY_CTRL_POWER_ENABLE);
00272     BSP_RegisterWrite(&BC_REGISTER->DISPLAY_CTRL, tmp);
00273     break;
00274 
00275   case BSP_Display_PowerDisable:
00276     tmp  = BSP_RegisterRead(&BC_REGISTER->DISPLAY_CTRL);
00277     tmp &= ~(BC_DISPLAY_CTRL_POWER_ENABLE);
00278     BSP_RegisterWrite(&BC_REGISTER->DISPLAY_CTRL, tmp);
00279     break;
00280 
00281   case BSP_Display_ResetAssert:
00282     tmp  = BSP_RegisterRead(&BC_REGISTER->DISPLAY_CTRL);
00283     tmp |= (BC_DISPLAY_CTRL_RESET);
00284     BSP_RegisterWrite(&BC_REGISTER->DISPLAY_CTRL, tmp);
00285     break;
00286 
00287   case BSP_Display_ResetRelease:
00288     tmp  = BSP_RegisterRead(&BC_REGISTER->DISPLAY_CTRL);
00289     tmp &= ~(BC_DISPLAY_CTRL_RESET);
00290     BSP_RegisterWrite(&BC_REGISTER->DISPLAY_CTRL, tmp);
00291     break;
00292 
00293   case BSP_Display_Mode8080:
00294     tmp  = BSP_RegisterRead(&BC_REGISTER->DISPLAY_CTRL);
00295     tmp &= ~(BC_DISPLAY_CTRL_MODE_GENERIC);
00296     BSP_RegisterWrite(&BC_REGISTER->DISPLAY_CTRL, tmp);
00297     break;
00298 
00299   case BSP_Display_ModeGeneric:
00300     tmp  = BSP_RegisterRead(&BC_REGISTER->DISPLAY_CTRL);
00301     tmp |= (BC_DISPLAY_CTRL_MODE_GENERIC);
00302     BSP_RegisterWrite(&BC_REGISTER->DISPLAY_CTRL, tmp);
00303     break;
00304 
00305   default:
00306     /* Unknown command */
00307     while (1);
00308   }
00309 
00310   return BSP_STATUS_OK;
00311 }
00312 
00313 /**************************************************************************/
00323 int BSP_EbiExtendedAddressRange(bool enable)
00324 {
00325   if (enable)
00326   {
00327     BSP_RegisterWrite(&BC_REGISTER->EBI_CTRL, BC_EBI_CTRL_EXTADDR_MASK);
00328   }
00329   else
00330   {
00331     BSP_RegisterWrite(&BC_REGISTER->EBI_CTRL, 0);
00332   }
00333   return BSP_STATUS_OK;
00334 }
00335 
00336 
00337 /**************************************************************************/
00344 int BSP_EnergyModeSet(uint16_t energyMode)
00345 {
00346   BSP_RegisterWrite(&BC_REGISTER->EM, energyMode);
00347   return BSP_STATUS_OK;
00348 }
00349 
00350 /**************************************************************************/
00357 int BSP_InterruptDisable(uint16_t flags)
00358 {
00359   uint16_t tmp;
00360 
00361   /* Clear flags from interrupt enable register */
00362   tmp   = BSP_RegisterRead(&BC_REGISTER->INTEN);
00363   flags = ~(flags);
00364   tmp  &= flags;
00365   BSP_RegisterWrite(&BC_REGISTER->INTEN, tmp);
00366   return BSP_STATUS_OK;
00367 }
00368 
00369 /**************************************************************************/
00376 int BSP_InterruptEnable(uint16_t flags)
00377 {
00378   uint16_t tmp;
00379 
00380   /* Add flags to interrupt enable register */
00381   tmp  = BSP_RegisterRead(&BC_REGISTER->INTEN);
00382   tmp |= flags;
00383   BSP_RegisterWrite(&BC_REGISTER->INTEN, tmp);
00384   return BSP_STATUS_OK;
00385 }
00386 
00387 /**************************************************************************/
00394 int BSP_InterruptFlagsClear(uint16_t flags)
00395 { 
00396   uint16_t intFlags;
00397   
00398   /* Board control firmware version 257 and higher has a new interrupt architecture */
00399   if (bcFwVersion < 257)
00400   {      
00401     intFlags  = BSP_RegisterRead(&BC_REGISTER->INTFLAG);
00402     intFlags &= ~(flags);
00403     BSP_RegisterWrite(&BC_REGISTER->INTFLAG, intFlags);    
00404   }
00405   else
00406   {  
00407     BSP_RegisterWrite(&BC_REGISTER->INTCLEAR, flags);
00408   }
00409   return BSP_STATUS_OK;
00410 }
00411 
00412 /**************************************************************************/
00419 int BSP_InterruptFlagsSet(uint16_t flags)
00420 {
00421   BSP_RegisterWrite(&BC_REGISTER->INTSET, flags);  
00422   return BSP_STATUS_OK;  
00423 }
00424 
00425 /**************************************************************************/
00430 uint16_t BSP_InterruptFlagsGet(void)
00431 {
00432   return BSP_RegisterRead(&BC_REGISTER->INTFLAG);
00433 }
00434 
00435 /**************************************************************************/
00440 uint16_t BSP_JoystickGet(void)
00441 {
00442   return ~(BSP_RegisterRead(&BC_REGISTER->UIF_JOYSTICK)) & 0x001f;
00443 }
00444 
00445 /**************************************************************************/
00461 int BSP_PeripheralAccess(BSP_Peripheral_TypeDef perf, bool enable)
00462 {
00463   uint16_t perfControl;
00464 
00465   perfControl = BSP_RegisterRead(&BC_REGISTER->PERICON);
00466 
00467   /* Enable or disable the specified peripheral by setting board control switch */
00468   if (enable)
00469   {
00470     switch (perf)
00471     {
00472     case BSP_RS232_SHUTDOWN:
00473       perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
00474       break;
00475 
00476     case BSP_RS232_UART:
00477       perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
00478       perfControl &= ~(1 << BC_PERICON_RS232_LEUART_SHIFT);
00479       perfControl |= (1 << BC_PERICON_RS232_UART_SHIFT);
00480       break;
00481 
00482     case BSP_RS232_LEUART:
00483       perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
00484       perfControl &= ~(1 << BC_PERICON_RS232_UART_SHIFT);
00485       perfControl |= (1 << BC_PERICON_RS232_LEUART_SHIFT);
00486       break;
00487 
00488     case BSP_I2C:
00489       perfControl |= (1 << BC_PERICON_I2C_SHIFT);
00490       break;
00491 
00492     case BSP_ETH:
00493       /* Enable SPI interface */
00494       SpiControl(BSP_SPI_Ethernet);
00495 
00496       /* Enable Ethernet analog switches */
00497       perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
00498       perfControl |= (1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00499 
00500       /* Disable Analog Diff Input - pins PD0 and PD1 is shared */
00501       perfControl &= ~(1 << BC_PERICON_ANALOG_DIFF_SHIFT);
00502       /* Disable Touch Inputs - pin PD3 is shared */
00503       perfControl &= ~(1 << BC_PERICON_TOUCH_SHIFT);
00504       /* Disable Analog SE Input - pin PD2 is shared */
00505       perfControl &= ~(1 << BC_PERICON_ANALOG_SE_SHIFT);
00506       break;
00507 
00508     case BSP_I2S:
00509       /* Direct SPI interface to I2S DAC */
00510       SpiControl(BSP_SPI_Audio);
00511 
00512       /* Also make surea Audio out is connected for I2S operation */
00513       perfControl |= (1 << BC_PERICON_AUDIO_OUT_SHIFT);
00514       perfControl |= (1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
00515       perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
00516       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00517 
00518       /* Disable Analog Diff Input - pins PD0 and PD1 is shared */
00519       perfControl &= ~(1 << BC_PERICON_ANALOG_DIFF_SHIFT);
00520       /* Disable Touch Inputs - pin PD3 is shared */
00521       perfControl &= ~(1 << BC_PERICON_TOUCH_SHIFT);
00522       /* Disable Analog SE Input - pin PD2 is shared */
00523       perfControl &= ~(1 << BC_PERICON_ANALOG_SE_SHIFT);
00524       break;
00525 
00526     case BSP_TRACE:
00527       #if defined(ETM_PRESENT)
00528         perfControl |= (1 << BC_PERICON_TRACE_SHIFT);
00529         break;
00530       #else
00531         /* TRACE is not available on EFM32G890F128, application error */
00532         while (1) ;
00533       #endif
00534 
00535     case BSP_TOUCH:
00536       perfControl |= (1 << BC_PERICON_TOUCH_SHIFT);
00537       /* Disconnect SPI switch, pin PD3 is shared */
00538       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
00539       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00540       SpiControl(BSP_SPI_OFF);
00541       break;
00542 
00543     case BSP_AUDIO_IN:
00544       perfControl |= (1 << BC_PERICON_AUDIO_IN_SHIFT);
00545       break;
00546 
00547     case BSP_AUDIO_OUT:
00548       perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
00549       perfControl |= (1 << BC_PERICON_AUDIO_OUT_SHIFT);
00550       break;
00551 
00552     case BSP_ANALOG_DIFF:
00553       perfControl |= (1 << BC_PERICON_ANALOG_DIFF_SHIFT);
00554       /* Disconnect SPI switch, pin PD0 and PD1 is shared */
00555       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
00556       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00557       SpiControl(BSP_SPI_OFF);
00558       break;
00559 
00560     case BSP_ANALOG_SE:
00561       perfControl |= (1 << BC_PERICON_ANALOG_SE_SHIFT);
00562       /* Disconnect SPI switch, pin PD2 is shared */
00563       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
00564       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00565       SpiControl(BSP_SPI_OFF);
00566       break;
00567 
00568     case BSP_MICROSD:
00569       perfControl |= (1 << BC_PERICON_SPI_SHIFT);
00570       break;
00571 
00572     case BSP_TFT:
00573       /* Enable SPI to SSD2119 */
00574       SpiControl(BSP_SPI_Display);
00575       /* Enable SPI analog switch */
00576       perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
00577       /* Disable Analog Diff Input - pins D0 and D1 is shared */
00578       perfControl &= ~(1 << BC_PERICON_ANALOG_DIFF_SHIFT);
00579       /* Disable Touch Inputs - pin D3 is shared */
00580       perfControl &= ~(1 << BC_PERICON_TOUCH_SHIFT);
00581       /* Disable Analog SE Input - pin D2 is shared */
00582       perfControl &= ~(1 << BC_PERICON_ANALOG_SE_SHIFT);
00583       break;
00584     }
00585   }
00586   else
00587   {
00588     switch (perf)
00589     {
00590     case BSP_RS232_SHUTDOWN:
00591       perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
00592       break;
00593 
00594     case BSP_RS232_UART:
00595       perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
00596       perfControl &= ~(1 << BC_PERICON_RS232_UART_SHIFT);
00597       break;
00598 
00599     case BSP_RS232_LEUART:
00600       perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
00601       perfControl &= ~(1 << BC_PERICON_RS232_LEUART_SHIFT);
00602       break;
00603 
00604     case BSP_I2C:
00605       perfControl &= ~(1 << BC_PERICON_I2C_SHIFT);
00606       break;
00607 
00608     case BSP_ETH:
00609       /* Disable SPI interface */
00610       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
00611       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00612       SpiControl(BSP_SPI_OFF);
00613       break;
00614 
00615     case BSP_I2S:
00616       /* Disable SPI interface and audio out */
00617       perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SHIFT);
00618       perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
00619       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
00620       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00621       SpiControl(BSP_SPI_OFF);
00622       break;
00623 
00624     case BSP_TRACE:
00625       #if defined(ETM_PRESENT)
00626         perfControl &= ~(1 << BC_PERICON_TRACE_SHIFT);
00627         break;
00628       #else
00629         /* TRACE is not available on EFM32G890F128, application error */
00630         while (1) ;
00631       #endif
00632 
00633     case BSP_TOUCH:
00634       perfControl &= ~(1 << BC_PERICON_TOUCH_SHIFT);
00635       break;
00636 
00637     case BSP_AUDIO_IN:
00638       perfControl &= ~(1 << BC_PERICON_AUDIO_IN_SHIFT);
00639       break;
00640 
00641     case BSP_AUDIO_OUT:
00642       perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
00643       perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SHIFT);
00644       break;
00645 
00646     case BSP_ANALOG_DIFF:
00647       perfControl &= ~(1 << BC_PERICON_ANALOG_DIFF_SHIFT);
00648       break;
00649 
00650     case BSP_ANALOG_SE:
00651       perfControl &= ~(1 << BC_PERICON_ANALOG_SE_SHIFT);
00652       break;
00653 
00654     case BSP_MICROSD:
00655       perfControl &= ~(1 << BC_PERICON_SPI_SHIFT);
00656       break;
00657 
00658     case BSP_TFT:
00659       /* Disable SPI interface */
00660       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
00661       perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
00662       SpiControl(BSP_SPI_OFF);
00663       break;
00664     }
00665   }
00666   /* Write back register */
00667   BSP_RegisterWrite(&BC_REGISTER->PERICON, perfControl);
00668 
00669   return BSP_STATUS_OK;
00670 }
00671 
00672 /**************************************************************************/
00677 uint16_t BSP_PushButtonsGet(void)
00678 {
00679   return (~BSP_RegisterRead(&BC_REGISTER->UIF_PB)) & 0x000F;
00680 }
00681 
00682 /**************************************************************************/
00687 uint16_t BSP_RegisterRead(volatile uint16_t *addr)
00688 {
00689   if (bspOperationMode == BSP_INIT_DK_EBI)
00690   {
00691     return *addr;
00692   }
00693   else
00694   {
00695     return SpiRegisterRead(addr);
00696   }
00697 }
00698 
00699 /**************************************************************************/
00704 int BSP_RegisterWrite(volatile uint16_t *addr, uint16_t data)
00705 {
00706   if (bspOperationMode == BSP_INIT_DK_EBI)
00707   {
00708     *addr = data;
00709   }
00710   else
00711   {
00712     SpiRegisterWrite(addr, data);
00713   }
00714   return BSP_STATUS_OK;
00715 }
00721 static void EbiDisable(void)
00722 {
00723 #if defined(_EFM32_GECKO_FAMILY)
00724 
00725   /* Configure GPIO pins as disabled */
00726   GPIO_PinModeSet( gpioPortA,  0, gpioModeDisabled, 0 );
00727   GPIO_PinModeSet( gpioPortA,  1, gpioModeDisabled, 0 );
00728   GPIO_PinModeSet( gpioPortA,  2, gpioModeDisabled, 0 );
00729   GPIO_PinModeSet( gpioPortA,  3, gpioModeDisabled, 0 );
00730   GPIO_PinModeSet( gpioPortA,  4, gpioModeDisabled, 0 );
00731   GPIO_PinModeSet( gpioPortA,  5, gpioModeDisabled, 0 );
00732   GPIO_PinModeSet( gpioPortA,  6, gpioModeDisabled, 0 );
00733 
00734   GPIO_PinModeSet( gpioPortA, 15, gpioModeDisabled, 0 );
00735 
00736   GPIO_PinModeSet( gpioPortD,  9, gpioModeDisabled, 0 );
00737   GPIO_PinModeSet( gpioPortD, 10, gpioModeDisabled, 0 );
00738   GPIO_PinModeSet( gpioPortD, 11, gpioModeDisabled, 0 );
00739   GPIO_PinModeSet( gpioPortD, 12, gpioModeDisabled, 0 );
00740 
00741   GPIO_PinModeSet( gpioPortE,  8, gpioModeDisabled, 0 );
00742   GPIO_PinModeSet( gpioPortE,  9, gpioModeDisabled, 0 );
00743   GPIO_PinModeSet( gpioPortE, 10, gpioModeDisabled, 0 );
00744   GPIO_PinModeSet( gpioPortE, 11, gpioModeDisabled, 0 );
00745   GPIO_PinModeSet( gpioPortE, 12, gpioModeDisabled, 0 );
00746   GPIO_PinModeSet( gpioPortE, 13, gpioModeDisabled, 0 );
00747   GPIO_PinModeSet( gpioPortE, 14, gpioModeDisabled, 0 );
00748   GPIO_PinModeSet( gpioPortE, 15, gpioModeDisabled, 0 );
00749 
00750   GPIO_PinModeSet( gpioPortF, 2, gpioModeDisabled, 0 );
00751   GPIO_PinModeSet( gpioPortF, 3, gpioModeDisabled, 0 );
00752   GPIO_PinModeSet( gpioPortF, 4, gpioModeDisabled, 0 );
00753   GPIO_PinModeSet( gpioPortF, 5, gpioModeDisabled, 0 );
00754 
00755   /* EBI Byte Lane 0 support BL0/BL1 */
00756   GPIO_PinModeSet( gpioPortF, 6, gpioModeDisabled, 0 );
00757   GPIO_PinModeSet( gpioPortF, 7, gpioModeDisabled, 0 );
00758 
00759 #else
00760 
00761   /* Configure GPIO pins as disabled */
00762   /* EBI AD9..15 */
00763   GPIO_PinModeSet( gpioPortA,  0, gpioModeDisabled, 0 );
00764   GPIO_PinModeSet( gpioPortA,  1, gpioModeDisabled, 0 );
00765   GPIO_PinModeSet( gpioPortA,  2, gpioModeDisabled, 0 );
00766   GPIO_PinModeSet( gpioPortA,  3, gpioModeDisabled, 0 );
00767   GPIO_PinModeSet( gpioPortA,  4, gpioModeDisabled, 0 );
00768   GPIO_PinModeSet( gpioPortA,  5, gpioModeDisabled, 0 );
00769   GPIO_PinModeSet( gpioPortA,  6, gpioModeDisabled, 0 );
00770 
00771   /* EBI AD8 */
00772   GPIO_PinModeSet( gpioPortA, 15, gpioModeDisabled, 0 );
00773 
00774   /* EBI A16-A22 */
00775   GPIO_PinModeSet( gpioPortB,  0, gpioModeDisabled, 0 );
00776   GPIO_PinModeSet( gpioPortB,  1, gpioModeDisabled, 0 );
00777   GPIO_PinModeSet( gpioPortB,  2, gpioModeDisabled, 0 );
00778   GPIO_PinModeSet( gpioPortB,  3, gpioModeDisabled, 0 );
00779   GPIO_PinModeSet( gpioPortB,  4, gpioModeDisabled, 0 );
00780   GPIO_PinModeSet( gpioPortB,  5, gpioModeDisabled, 0 );
00781   GPIO_PinModeSet( gpioPortB,  6, gpioModeDisabled, 0 );
00782 
00783   /* EBI CS0-CS3 */
00784   GPIO_PinModeSet( gpioPortD,  9, gpioModeDisabled, 0 );
00785   GPIO_PinModeSet( gpioPortD, 10, gpioModeDisabled, 0 );
00786   GPIO_PinModeSet( gpioPortD, 11, gpioModeDisabled, 0 );
00787   GPIO_PinModeSet( gpioPortD, 12, gpioModeDisabled, 0 );
00788 
00789   /* EBI AD0..7 */
00790   GPIO_PinModeSet( gpioPortE,  8, gpioModeDisabled, 0 );
00791   GPIO_PinModeSet( gpioPortE,  9, gpioModeDisabled, 0 );
00792   GPIO_PinModeSet( gpioPortE, 10, gpioModeDisabled, 0 );
00793   GPIO_PinModeSet( gpioPortE, 11, gpioModeDisabled, 0 );
00794   GPIO_PinModeSet( gpioPortE, 12, gpioModeDisabled, 0 );
00795   GPIO_PinModeSet( gpioPortE, 13, gpioModeDisabled, 0 );
00796   GPIO_PinModeSet( gpioPortE, 14, gpioModeDisabled, 0 );
00797   GPIO_PinModeSet( gpioPortE, 15, gpioModeDisabled, 0 );
00798 
00799   /* EBI ARDY/WEN/REN/ALE */
00800   GPIO_PinModeSet( gpioPortF,  2, gpioModeDisabled, 0 );
00801   GPIO_PinModeSet( gpioPortF,  8, gpioModeDisabled, 0 );
00802   GPIO_PinModeSet( gpioPortF,  9, gpioModeDisabled, 0 );
00803   GPIO_PinModeSet( gpioPortC, 11, gpioModeDisabled, 0 );
00804 
00805   /* EBI Byte Lane 0 support BL0/BL1 */
00806   GPIO_PinModeSet( gpioPortF,  6, gpioModeDisabled, 0 );
00807   GPIO_PinModeSet( gpioPortF,  7, gpioModeDisabled, 0 );
00808 
00809 #endif
00810 
00811   /* Reset EBI configuration */
00812   EBI_Disable();
00813 
00814   /* Turn off EBI clock */
00815   CMU_ClockEnable(cmuClock_EBI, false);
00816 }
00817 
00818 /**************************************************************************/
00826 static bool EbiInit(void)
00827 {
00828   EBI_Init_TypeDef ebiConfig = EBI_INIT_DEFAULT;
00829 
00830   /* Enable clocks */
00831   CMU_ClockEnable(cmuClock_EBI, true);
00832   CMU_ClockEnable(cmuClock_GPIO, true);
00833 
00834 #if defined(_EFM32_GECKO_FAMILY)
00835 
00836   /* Configure LCD_SELECT (EBI and LCD cannot be shared) */
00837   GPIO_PinModeSet( gpioPortC, 12, gpioModePushPull, 1 );
00838 
00839   /* Configure GPIO pins as push pull */
00840   /* EBI AD9..15 */
00841   GPIO_PinModeSet( gpioPortA,  0, gpioModePushPull, 0 );
00842   GPIO_PinModeSet( gpioPortA,  1, gpioModePushPull, 0 );
00843   GPIO_PinModeSet( gpioPortA,  2, gpioModePushPull, 0 );
00844   GPIO_PinModeSet( gpioPortA,  3, gpioModePushPull, 0 );
00845   GPIO_PinModeSet( gpioPortA,  4, gpioModePushPull, 0 );
00846   GPIO_PinModeSet( gpioPortA,  5, gpioModePushPull, 0 );
00847   GPIO_PinModeSet( gpioPortA,  6, gpioModePushPull, 0 );
00848 
00849   /* EBI AD8 */
00850   GPIO_PinModeSet( gpioPortA, 15, gpioModePushPull, 0 );
00851 
00852   /* EBI CS0-CS3 */
00853   GPIO_PinModeSet( gpioPortD,  9, gpioModePushPull, 1 );
00854   GPIO_PinModeSet( gpioPortD, 10, gpioModePushPull, 1 );
00855   GPIO_PinModeSet( gpioPortD, 11, gpioModePushPull, 1 );
00856   GPIO_PinModeSet( gpioPortD, 12, gpioModePushPull, 1 );
00857 
00858   /* EBI AD0..7 */
00859   GPIO_PinModeSet( gpioPortE,  8, gpioModePushPull, 0 );
00860   GPIO_PinModeSet( gpioPortE,  9, gpioModePushPull, 0 );
00861   GPIO_PinModeSet( gpioPortE, 10, gpioModePushPull, 0 );
00862   GPIO_PinModeSet( gpioPortE, 11, gpioModePushPull, 0 );
00863   GPIO_PinModeSet( gpioPortE, 12, gpioModePushPull, 0 );
00864   GPIO_PinModeSet( gpioPortE, 13, gpioModePushPull, 0 );
00865   GPIO_PinModeSet( gpioPortE, 14, gpioModePushPull, 0 );
00866   GPIO_PinModeSet( gpioPortE, 15, gpioModePushPull, 0 );
00867 
00868   /* EBI ARDY/ALEN/Wen/Ren */
00869   GPIO_PinModeSet( gpioPortF,  2, gpioModeInput,    0 );
00870   GPIO_PinModeSet( gpioPortF,  3, gpioModePushPull, 0 );
00871   GPIO_PinModeSet( gpioPortF,  4, gpioModePushPull, 1 );
00872   GPIO_PinModeSet( gpioPortF,  5, gpioModePushPull, 1 );
00873 
00874   /* Byte Lanes */
00875   GPIO_PinModeSet( gpioPortF,  6, gpioModePushPull, 0 );
00876   GPIO_PinModeSet( gpioPortF,  7, gpioModePushPull, 0 );
00877 
00878   /* Configure EBI controller, changing default values */
00879   ebiConfig.mode = ebiModeD16A16ALE;
00880 
00881   /* --------------------------------------------------------- */
00882   /* Board Control Registers, Bank 0, Base Address 0x80000000  */
00883   /* FPGA Xilinx Spartan XC6SLX9 CSG324                        */
00884   /* --------------------------------------------------------- */
00885 
00886   /* ----------------------------------------------------- */
00887   /* TFT-LCD Registers, Bank1, Base Address 0x84000000     */
00888   /* URT USMH_8252MD_320X240_RGB                           */
00889   /* Solomon Systech SSD 2119                              */
00890   /* ----------------------------------------------------- */
00891 
00892   /* ---------------------------------------------------- */
00893   /* External 4MB PSRAM, Bank 2, Base Address 0x88000000  */
00894   /* Micron MT45W2MW16PGA-70 IT, 32Mb Cellular RAM        */
00895   /* ---------------------------------------------------- */
00896 
00897   /* ----------------------------------------- */
00898   /* NOR Flash, Bank3, Base Address 0x8c000000 */
00899   /* Spansion flash S29GLxxx_FBGA              */
00900   /* ----------------------------------------- */
00901 
00902   ebiConfig.banks   = EBI_BANK0 | EBI_BANK1 | EBI_BANK2 | EBI_BANK3;
00903   ebiConfig.csLines = EBI_CS0 | EBI_CS1 | EBI_CS2 | EBI_CS3;
00904 
00905   /* Address Setup and hold time */
00906   ebiConfig.addrHoldCycles  = 3;
00907   ebiConfig.addrSetupCycles = 3;
00908 
00909   /* Read cycle times */
00910   ebiConfig.readStrobeCycles = 7;
00911   ebiConfig.readHoldCycles   = 3;
00912   ebiConfig.readSetupCycles  = 3;
00913 
00914   /* Write cycle times */
00915   ebiConfig.writeStrobeCycles = 7;
00916   ebiConfig.writeHoldCycles   = 3;
00917   ebiConfig.writeSetupCycles  = 3;
00918 
00919   /* Address Latch Enable polarity is active high */
00920   ebiConfig.alePolarity = ebiActiveHigh;
00921 
00922   /* Configure EBI */
00923   EBI_Init(&ebiConfig);
00924 
00925 #else
00926 
00927   /* Giant or Leopard family. */
00928 
00929   /* Configure GPIO pins as push pull */
00930   /* EBI AD9..15 */
00931   GPIO_PinModeSet( gpioPortA,  0, gpioModePushPull, 0 );
00932   GPIO_PinModeSet( gpioPortA,  1, gpioModePushPull, 0 );
00933   GPIO_PinModeSet( gpioPortA,  2, gpioModePushPull, 0 );
00934   GPIO_PinModeSet( gpioPortA,  3, gpioModePushPull, 0 );
00935   GPIO_PinModeSet( gpioPortA,  4, gpioModePushPull, 0 );
00936   GPIO_PinModeSet( gpioPortA,  5, gpioModePushPull, 0 );
00937   GPIO_PinModeSet( gpioPortA,  6, gpioModePushPull, 0 );
00938 
00939   /* EBI AD8 */
00940   GPIO_PinModeSet( gpioPortA, 15, gpioModePushPull, 0 );
00941 
00942   /* EBI A16-A22 */
00943   GPIO_PinModeSet( gpioPortB,  0, gpioModePushPull, 0 );
00944   GPIO_PinModeSet( gpioPortB,  1, gpioModePushPull, 0 );
00945   GPIO_PinModeSet( gpioPortB,  2, gpioModePushPull, 0 );
00946   GPIO_PinModeSet( gpioPortB,  3, gpioModePushPull, 0 );
00947   GPIO_PinModeSet( gpioPortB,  4, gpioModePushPull, 0 );
00948   GPIO_PinModeSet( gpioPortB,  5, gpioModePushPull, 0 );
00949   GPIO_PinModeSet( gpioPortB,  6, gpioModePushPull, 0 );
00950 
00951   /* EBI CS0-CS3 */
00952   GPIO_PinModeSet( gpioPortD,  9, gpioModePushPull, 1 );
00953   GPIO_PinModeSet( gpioPortD, 10, gpioModePushPull, 1 );
00954   GPIO_PinModeSet( gpioPortD, 11, gpioModePushPull, 1 );
00955   GPIO_PinModeSet( gpioPortD, 12, gpioModePushPull, 1 );
00956 
00957   /* EBI AD0..7 */
00958   GPIO_PinModeSet( gpioPortE,  8, gpioModePushPull, 0 );
00959   GPIO_PinModeSet( gpioPortE,  9, gpioModePushPull, 0 );
00960   GPIO_PinModeSet( gpioPortE, 10, gpioModePushPull, 0 );
00961   GPIO_PinModeSet( gpioPortE, 11, gpioModePushPull, 0 );
00962   GPIO_PinModeSet( gpioPortE, 12, gpioModePushPull, 0 );
00963   GPIO_PinModeSet( gpioPortE, 13, gpioModePushPull, 0 );
00964   GPIO_PinModeSet( gpioPortE, 14, gpioModePushPull, 0 );
00965   GPIO_PinModeSet( gpioPortE, 15, gpioModePushPull, 0 );
00966 
00967   /* EBI ARDY/WEN/REN/ALE */
00968   GPIO_PinModeSet( gpioPortF,  2, gpioModeInput,    0 );
00969   GPIO_PinModeSet( gpioPortF,  8, gpioModePushPull, 0 );
00970   GPIO_PinModeSet( gpioPortF,  9, gpioModePushPull, 0 );
00971   GPIO_PinModeSet( gpioPortC, 11, gpioModePushPull, 0 );
00972 
00973   /* EBI Byte Lane 0 support BL0/BL1 */
00974   GPIO_PinModeSet( gpioPortF, 6, gpioModePushPull, 0 );
00975   GPIO_PinModeSet( gpioPortF, 7, gpioModePushPull, 0 );
00976 
00977   /* ---------------------------------------------------- */
00978   /* External 4MB PSRAM, Bank 2, Base Address 0x88000000  */
00979   /* Micron MT45W2MW16PGA-70 IT, 32Mb Cellular RAM        */
00980   /* ---------------------------------------------------- */
00981   ebiConfig.banks        = EBI_BANK2;
00982   ebiConfig.csLines      = EBI_CS2;
00983   ebiConfig.mode         = ebiModeD16A16ALE;
00984   ebiConfig.alePolarity  = ebiActiveHigh;
00985   ebiConfig.blEnable     = true;
00986   ebiConfig.noIdle       = true;
00987   ebiConfig.ardyEnable   = false;
00988   ebiConfig.addrHalfALE  = true;
00989   ebiConfig.readPrefetch = true;
00990   ebiConfig.aLow         = ebiALowA16;
00991   ebiConfig.aHigh        = ebiAHighA23;
00992   ebiConfig.location     = ebiLocation1;
00993 
00994   /* Address Setup and hold time */
00995   ebiConfig.addrHoldCycles  = 0;
00996   ebiConfig.addrSetupCycles = 0;
00997 
00998   /* Read cycle times */
00999   ebiConfig.readStrobeCycles = 4;
01000   ebiConfig.readHoldCycles   = 0;
01001   ebiConfig.readSetupCycles  = 0;
01002 
01003   /* Write cycle times */
01004   ebiConfig.writeStrobeCycles = 2;
01005   ebiConfig.writeHoldCycles   = 0;
01006   ebiConfig.writeSetupCycles  = 0;
01007 
01008   /* Configure EBI bank 2 - external PSRAM */
01009   EBI_Init(&ebiConfig);
01010 
01011   /* --------------------------------------------------------- */
01012   /* Board Control Registers, Bank 0, Base Address 0x80000000  */
01013   /* FPGA Xilinx Spartan XC6SLX9 CSG324                        */
01014   /* --------------------------------------------------------- */
01015   ebiConfig.banks       = EBI_BANK0;
01016   ebiConfig.csLines     = EBI_CS0;
01017   ebiConfig.mode        = ebiModeD16A16ALE;;
01018   ebiConfig.alePolarity = ebiActiveHigh;
01019   /* keep blEnable */
01020   ebiConfig.blEnable     = false;
01021   ebiConfig.addrHalfALE  = true;
01022   ebiConfig.readPrefetch = false;
01023   ebiConfig.noIdle       = true;
01024 
01025   /* keep alow/ahigh configuration */
01026   /* ebiConfig.aLow = ebiALowA0; - needs to be set for PSRAM */
01027   /* ebiConfig.aHigh = ebiAHighA0; - needs to be set for PSRAM */
01028 
01029   /* Address Setup and hold time */
01030   ebiConfig.addrHoldCycles  = 3;
01031   ebiConfig.addrSetupCycles = 3;
01032 
01033   /* Read cycle times */
01034   ebiConfig.readStrobeCycles = 7;
01035   ebiConfig.readHoldCycles   = 3;
01036   ebiConfig.readSetupCycles  = 3;
01037 
01038   /* Write cycle times */
01039   ebiConfig.writeStrobeCycles = 7;
01040   ebiConfig.writeHoldCycles   = 3;
01041   ebiConfig.writeSetupCycles  = 3;
01042 
01043   /* Configure EBI bank 0 */
01044   EBI_Init(&ebiConfig);
01045 
01046   /* ----------------------------------------------------- */
01047   /* TFT-LCD Registers, Bank1, Base Address 0x84000000     */
01048   /* URT USMH_8252MD_320X240_RGB                           */
01049   /* Solomon Systech SSD 2119                              */
01050   /* ----------------------------------------------------- */
01051   ebiConfig.banks   = EBI_BANK1;
01052   ebiConfig.csLines = EBI_CS1;
01053 
01054   /* Address Setup and hold time */
01055   ebiConfig.addrHoldCycles  = 1;
01056   ebiConfig.addrSetupCycles = 1;
01057 
01058   /* Read cycle times */
01059   ebiConfig.readStrobeCycles = 7;
01060   ebiConfig.readHoldCycles   = 3;
01061   ebiConfig.readSetupCycles  = 3;
01062 
01063   /* Write cycle times */
01064   ebiConfig.writeStrobeCycles = 2;
01065   ebiConfig.writeHoldCycles   = 1;
01066   ebiConfig.writeSetupCycles  = 1;
01067 
01068   /* Configure EBI bank 1 */
01069   EBI_Init(&ebiConfig);
01070 
01071   /* ----------------------------------------- */
01072   /* NOR Flash, Bank3, Base Address 0x8c000000 */
01073   /* Spansion flash S29GLxxx_FBGA              */
01074   /* ----------------------------------------- */
01075   ebiConfig.banks       = EBI_BANK3;
01076   ebiConfig.csLines     = EBI_CS3;
01077   ebiConfig.mode        = ebiModeD16A16ALE;
01078   ebiConfig.alePolarity = ebiActiveHigh;
01079 
01080   /* keep blEnable */
01081   ebiConfig.blEnable     = true;
01082   ebiConfig.addrHalfALE  = true;
01083   ebiConfig.readPrefetch = false;
01084   ebiConfig.noIdle       = true;
01085 
01086   /* Address Setup and hold time */
01087   ebiConfig.addrHoldCycles  = 0;
01088   ebiConfig.addrSetupCycles = 0;
01089 
01090   /* Read cycle times */
01091   ebiConfig.readStrobeCycles = 6;
01092   ebiConfig.readHoldCycles   = 0;
01093   ebiConfig.readSetupCycles  = 0;
01094 
01095   /* Write cycle times */
01096   ebiConfig.writeStrobeCycles = 5;
01097   ebiConfig.writeHoldCycles   = 0;
01098   ebiConfig.writeSetupCycles  = 0;
01099 
01100   /* Configure EBI bank 3 */
01101   EBI_Init(&ebiConfig);
01102 
01103   /* Enable extended address range */
01104   BSP_EbiExtendedAddressRange(true);
01105 #endif
01106 
01107   /* Verify connectivity to Board Control registers */
01108   if (BC_REGISTER->MAGIC != 0xef32)
01109   {
01110     return false;
01111   }
01112   else
01113   {
01114     return true;
01115   }
01116 }
01117 
01118 static uint16_t SpiBcAccess(uint8_t addr, uint8_t rw, uint16_t data)
01119 {
01120   uint16_t tmp;
01121 
01122   /* Enable CS */
01123   GPIO_PinOutClear(BSP_PORT_SPI_CS, BSP_PIN_SPI_CS);
01124 
01125   /* Write SPI address MSB */
01126   USART_Tx(BSP_SPI_USART_USED, (addr & 0x3) | rw << 3);
01127   /* Just ignore data read back */
01128   USART_Rx(BSP_SPI_USART_USED);
01129 
01130   /* Write SPI address  LSB */
01131   USART_Tx(BSP_SPI_USART_USED, data & 0xFF);
01132 
01133   tmp = (uint16_t) USART_Rx(BSP_SPI_USART_USED);
01134 
01135   /* SPI data MSB */
01136   USART_Tx(BSP_SPI_USART_USED, data >> 8);
01137   tmp |= (uint16_t) USART_Rx(BSP_SPI_USART_USED) << 8;
01138 
01139   /* Disable CS */
01140   GPIO_PinOutSet(BSP_PORT_SPI_CS, BSP_PIN_SPI_CS);
01141 
01142   return tmp;
01143 }
01144 
01145 static void SpiBcDisable(void)
01146 {
01147   /* Restore and disable USART */
01148   USART_Reset(BSP_SPI_USART_USED);
01149 
01150   GPIO_PinModeSet(BSP_PORT_SPI_TX, BSP_PIN_SPI_TX, gpioModeDisabled, 0);
01151   GPIO_PinModeSet(BSP_PORT_SPI_RX, BSP_PIN_SPI_RX, gpioModeDisabled, 0);
01152   GPIO_PinModeSet(BSP_PORT_SPI_CLK, BSP_PIN_SPI_CLK, gpioModeDisabled, 0);
01153   GPIO_PinModeSet(BSP_PORT_SPI_CS, BSP_PIN_SPI_CS, gpioModeDisabled, 0);
01154 
01155   /* Disable USART clock - we can't disable GPIO or HFPER as we don't know who else
01156    * might be using it */
01157   CMU_ClockEnable(BSP_SPI_USART_CLK, false);
01158 }
01159 
01160 static void SpiBcInit(void)
01161 {
01162   USART_InitSync_TypeDef bcinit = USART_INITSYNC_DEFAULT;
01163 
01164   /* Enable module clocks */
01165   CMU_ClockEnable(BSP_SPI_USART_CLK, true);
01166 
01167   /* Configure SPI pins */
01168   GPIO_PinModeSet(BSP_PORT_SPI_TX, BSP_PIN_SPI_TX, gpioModePushPull, 0);
01169   GPIO_PinModeSet(BSP_PORT_SPI_RX, BSP_PIN_SPI_RX, gpioModeInput, 0);
01170   GPIO_PinModeSet(BSP_PORT_SPI_CLK, BSP_PIN_SPI_CLK, gpioModePushPull, 0);
01171 
01172   /* Keep CS high to not activate slave */
01173   GPIO_PinModeSet(BSP_PORT_SPI_CS, BSP_PIN_SPI_CS, gpioModePushPull, 1);
01174 
01175   /* Configure to use SPI master with manual CS */
01176   /* For now, configure SPI for worst case 48/32MHz clock in order to work */
01177   /* for all configurations. */
01178 
01179   #if defined(_EFM32_GECKO_FAMILY)
01180     bcinit.refFreq  = 32000000;
01181   #else
01182     bcinit.refFreq  = 48000000;
01183   #endif
01184   bcinit.baudrate = 7000000;
01185 
01186   /* Initialize USART */
01187   USART_InitSync(BSP_SPI_USART_USED, &bcinit);
01188 
01189   /* Enable pins at default location */
01190   BSP_SPI_USART_USED->ROUTE = USART_ROUTE_TXPEN | USART_ROUTE_RXPEN | USART_ROUTE_CLKPEN;
01191 }
01192 
01193 static void SpiControl(BSP_SpiControl_TypeDef device)
01194 {
01195   switch (device)
01196   {
01197   case BSP_SPI_Audio:
01198     BSP_RegisterWrite(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_AUDIO);
01199     break;
01200 
01201   case BSP_SPI_Ethernet:
01202     BSP_RegisterWrite(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_ETHERNET);
01203     break;
01204 
01205   case BSP_SPI_Display:
01206     BSP_RegisterWrite(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_DISPLAY);
01207     break;
01208 
01209   case BSP_SPI_OFF:
01210     USART_Reset(USART1);
01211     CMU_ClockEnable(cmuClock_USART1, false);
01212     break;
01213   }
01214 }
01215 
01216 static bool SpiInit(void)
01217 {
01218   uint16_t bcMagic;
01219 
01220   /* Enable HF and GPIO clocks */
01221   CMU_ClockEnable(cmuClock_HFPER, true);
01222   CMU_ClockEnable(cmuClock_GPIO, true);
01223 
01224   SpiBcInit();
01225   /* Read "board control Magic" register to verify SPI is up and running */
01226   /*  if not FPGA is configured to be in EBI mode  */
01227   bcMagic = SpiRegisterRead(&BC_REGISTER->MAGIC);
01228   if (bcMagic != BC_MAGIC_VALUE)
01229   {
01230     return false;
01231   }
01232   else
01233   {
01234     return true;
01235   }
01236 }
01237 
01238 static uint16_t SpiRegisterRead(volatile uint16_t *addr)
01239 {
01240   uint16_t data;
01241 
01242   if (addr != lastAddr)
01243   {
01244     SpiBcAccess(0x00, 0, 0xFFFF & ((uint32_t) addr));           /* LSBs of address */
01245     SpiBcAccess(0x01, 0, 0xFF & ((uint32_t) addr >> 16));       /* MSBs of address */
01246     SpiBcAccess(0x02, 0, (0x0C000000 & (uint32_t) addr) >> 26); /* Chip select */
01247   }
01248   /* Read twice; when register address has changed we need two SPI transfer
01249    * to clock out valid data through board controller FIFOs */
01250   data     = SpiBcAccess(0x03, 1, 0);
01251   data     = SpiBcAccess(0x03, 1, 0);
01252 
01253   lastAddr = addr;
01254   return data;
01255 }
01256 
01257 static void SpiRegisterWrite(volatile uint16_t *addr, uint16_t data)
01258 {
01259   if (addr != lastAddr)
01260   {
01261     SpiBcAccess(0x00, 0, 0xFFFF & ((uint32_t) addr));           /* LSBs of address */
01262     SpiBcAccess(0x01, 0, 0xFF & ((uint32_t) addr >> 16));       /* MSBs of address */
01263     SpiBcAccess(0x02, 0, (0x0C000000 & (uint32_t) addr) >> 26); /* Chip select */
01264   }
01265   SpiBcAccess(0x03, 0, data);                                   /* Data */
01266   lastAddr = addr;
01267 }
01268 
01270 #endif  /* BSP_DK_3201 */