dvk.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. /**************************************************************************//**
  2. * @file
  3. * @brief EFM32GG_DK3750 board support package
  4. * @author Energy Micro AS
  5. * @version 1.2.2
  6. ******************************************************************************
  7. * @section License
  8. * <b>(C) Copyright 2011 Energy Micro AS, http://www.energymicro.com</b>
  9. ******************************************************************************
  10. *
  11. * This source code is the property of Energy Micro AS. The source and compiled
  12. * code may only be used on Energy Micro "EFM32" microcontrollers.
  13. *
  14. * This copyright notice may not be removed from the source code nor changed.
  15. *
  16. * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Energy Micro AS has no
  17. * obligation to support this Software. Energy Micro AS is providing the
  18. * Software "AS IS", with no express or implied warranties of any kind,
  19. * including, but not limited to, any implied warranties of merchantability
  20. * or fitness for any particular purpose or warranties against infringement
  21. * of any proprietary rights of a third party.
  22. *
  23. * Energy Micro AS will not be liable for any consequential, incidental, or
  24. * special damages, or any other relief, or for any claim by any third party,
  25. * arising from your use of this Software.
  26. *
  27. *****************************************************************************/
  28. /***************************************************************************//**
  29. * @addtogroup BSP
  30. * @{
  31. ******************************************************************************/
  32. #include "efm32.h"
  33. #include "efm32_gpio.h"
  34. #include "efm32_cmu.h"
  35. #include "dvk.h"
  36. #include "dvk_bcregisters.h"
  37. /** Keep intialization mode */
  38. DVK_Init_TypeDef dvkOperationMode;
  39. /**************************************************************************//**
  40. * @brief Initialize EMF32GG_DK3750 board support package functionality
  41. * @param[in] mode Initialize in EBI or SPI mode
  42. *****************************************************************************/
  43. void DVK_init(DVK_Init_TypeDef mode)
  44. {
  45. bool ret = false;
  46. if (mode == DVK_Init_EBI)
  47. {
  48. dvkOperationMode = mode;
  49. DVK_busControlMode(DVK_BusControl_EBI);
  50. ret = DVK_EBI_init();
  51. }
  52. if (mode == DVK_Init_SPI)
  53. {
  54. dvkOperationMode = mode;
  55. DVK_busControlMode(DVK_BusControl_SPI);
  56. ret = DVK_SPI_init();
  57. }
  58. if (ret == false)
  59. {
  60. /* Unable to access board control, this is an abornomal situation. */
  61. /* Try to restart kit and reprogram EFM32 with a standard example */
  62. /* as this is most likely caused by a peripheral misconfiguration. */
  63. while (1) ;
  64. }
  65. DVK_setEnergyMode(0);
  66. }
  67. /**************************************************************************//**
  68. * @brief Disable EFM32GG_DK3750 board support package functionality
  69. *****************************************************************************/
  70. void DVK_disable(void)
  71. {
  72. if (dvkOperationMode == DVK_Init_EBI)
  73. {
  74. DVK_EBI_disable();
  75. }
  76. if (dvkOperationMode == DVK_Init_SPI)
  77. {
  78. DVK_SPI_disable();
  79. }
  80. DVK_busControlMode(DVK_BusControl_OFF);
  81. }
  82. /**************************************************************************//**
  83. * @brief Configure Board Controller bus decode logic
  84. * @param[in] mode Mode of operation for decode logic
  85. *****************************************************************************/
  86. void DVK_busControlMode(DVK_BusControl_TypeDef mode)
  87. {
  88. /* Configure GPIO pins for Board Bus mode */
  89. /* Note: Inverter on GPIO lines to BC, so signals are active low */
  90. CMU_ClockEnable(cmuClock_GPIO, true);
  91. switch (mode)
  92. {
  93. case DVK_BusControl_OFF:
  94. /* Configure board for OFF mode on PB15 MCU_EBI_CONNECT */
  95. GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
  96. /* Configure board for OFF mode on PD13 MCU_SPI_CONNECT */
  97. GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1);
  98. break;
  99. case DVK_BusControl_DIRECT:
  100. /* Configure board for DIRECT on PB15 MCU_EBI_CONNECT */
  101. GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0);
  102. /* Configure board for DIRECT on PD13 MCU_SPI_CONNECT */
  103. GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0);
  104. break;
  105. case DVK_BusControl_SPI:
  106. /* Configure board for SPI mode on PB15 MCU_EBI_CONNECT */
  107. GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 1);
  108. /* Configure board for SPI mode on PD13 MCU_SPI_CONNECT */
  109. GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 0);
  110. break;
  111. case DVK_BusControl_EBI:
  112. default:
  113. /* Configure board for EBI mode on PB15 MCU_EBI_CONNECT */
  114. GPIO_PinModeSet(gpioPortB, 15, gpioModePushPull, 0);
  115. /* Configure board for EBI mode on PD13 MCU_SPI_CONNECT */
  116. GPIO_PinModeSet(gpioPortD, 13, gpioModePushPull, 1);
  117. break;
  118. }
  119. }
  120. /**************************************************************************//**
  121. * @brief Set board LEDs
  122. *
  123. * @param[in] leds
  124. * 16 bits enabling or disabling individual board LEDs
  125. *****************************************************************************/
  126. void DVK_setLEDs(uint16_t leds)
  127. {
  128. DVK_writeRegister(&BC_REGISTER->UIF_LEDS, leds);
  129. }
  130. /**************************************************************************//**
  131. * @brief Get board LED configuration
  132. *
  133. * @return
  134. * 16 bits of LED status
  135. *****************************************************************************/
  136. uint16_t DVK_getLEDs(void)
  137. {
  138. return DVK_readRegister(&BC_REGISTER->UIF_LEDS);
  139. }
  140. /**************************************************************************//**
  141. * @brief DK3750 Peripheral Access Control
  142. * Enable or disable access to on-board peripherals through switches
  143. * and SPI switch where applicable
  144. * @param[in] perf
  145. * Which peripheral to configure
  146. * @param[in] enable
  147. * If true, sets up access to peripheral, if false disables it
  148. *****************************************************************************/
  149. void DVK_peripheralAccess(DVK_Peripheral_TypeDef perf, bool enable)
  150. {
  151. uint16_t perfControl;
  152. perfControl = DVK_readRegister(&BC_REGISTER->PERICON);
  153. /* Enable or disable the specificed peripheral by setting board control switch */
  154. if (enable)
  155. {
  156. switch (perf)
  157. {
  158. case DVK_RS232_SHUTDOWN:
  159. perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
  160. break;
  161. case DVK_RS232_UART:
  162. perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
  163. perfControl &= ~(1 << BC_PERICON_RS232_LEUART_SHIFT);
  164. perfControl |= (1 << BC_PERICON_RS232_UART_SHIFT);
  165. break;
  166. case DVK_RS232_LEUART:
  167. perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
  168. perfControl &= ~(1 << BC_PERICON_RS232_UART_SHIFT);
  169. perfControl |= (1 << BC_PERICON_RS232_LEUART_SHIFT);
  170. break;
  171. case DVK_I2C:
  172. perfControl |= (1 << BC_PERICON_I2C_SHIFT);
  173. break;
  174. case DVK_ETH:
  175. /* Enable SPI interface */
  176. DVK_spiControl(DVK_SPI_Ethernet);
  177. /* Enable Ethernet analog switches */
  178. perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
  179. perfControl |= (1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
  180. break;
  181. case DVK_I2S:
  182. /* Direct SPI interface to I2S DAC */
  183. DVK_spiControl(DVK_SPI_Audio);
  184. /* Also make surea Audio out is connected for I2S operation */
  185. perfControl |= (1 << BC_PERICON_AUDIO_OUT_SHIFT);
  186. perfControl |= (1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
  187. perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
  188. perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
  189. break;
  190. case DVK_TRACE:
  191. perfControl |= (1 << BC_PERICON_TRACE_SHIFT);
  192. break;
  193. case DVK_TOUCH:
  194. perfControl |= (1 << BC_PERICON_TOUCH_SHIFT);
  195. break;
  196. case DVK_AUDIO_IN:
  197. perfControl |= (1 << BC_PERICON_AUDIO_IN_SHIFT);
  198. break;
  199. case DVK_AUDIO_OUT:
  200. perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
  201. perfControl |= (1 << BC_PERICON_AUDIO_OUT_SHIFT);
  202. break;
  203. case DVK_ANALOG_DIFF:
  204. perfControl |= (1 << BC_PERICON_ANALOG_DIFF_SHIFT);
  205. break;
  206. case DVK_ANALOG_SE:
  207. perfControl |= (1 << BC_PERICON_ANALOG_SE_SHIFT);
  208. break;
  209. case DVK_MICROSD:
  210. perfControl |= (1 << BC_PERICON_SPI_SHIFT);
  211. break;
  212. case DVK_TFT:
  213. /* Enable SPI to SSD2119 */
  214. DVK_spiControl(DVK_SPI_Display);
  215. /* Enable SPI analog switch */
  216. perfControl |= (1 << BC_PERICON_I2S_ETH_SHIFT);
  217. break;
  218. }
  219. }
  220. else
  221. {
  222. switch (perf)
  223. {
  224. case DVK_RS232_SHUTDOWN:
  225. perfControl &= ~(1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
  226. break;
  227. case DVK_RS232_UART:
  228. perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
  229. perfControl &= ~(1 << BC_PERICON_RS232_UART_SHIFT);
  230. break;
  231. case DVK_RS232_LEUART:
  232. perfControl |= (1 << BC_PERICON_RS232_SHUTDOWN_SHIFT);
  233. perfControl &= ~(1 << BC_PERICON_RS232_LEUART_SHIFT);
  234. break;
  235. case DVK_I2C:
  236. perfControl &= ~(1 << BC_PERICON_I2C_SHIFT);
  237. break;
  238. case DVK_ETH:
  239. /* Enable Ethernet analog switches */
  240. perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
  241. perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
  242. break;
  243. case DVK_I2S:
  244. /* Also make surea Audio out is connected for I2S operation */
  245. perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SHIFT);
  246. perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
  247. perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
  248. perfControl &= ~(1 << BC_PERICON_I2S_ETH_SEL_SHIFT);
  249. break;
  250. case DVK_TRACE:
  251. perfControl &= ~(1 << BC_PERICON_TRACE_SHIFT);
  252. break;
  253. case DVK_TOUCH:
  254. perfControl &= ~(1 << BC_PERICON_TOUCH_SHIFT);
  255. break;
  256. case DVK_AUDIO_IN:
  257. perfControl &= ~(1 << BC_PERICON_AUDIO_IN_SHIFT);
  258. break;
  259. case DVK_AUDIO_OUT:
  260. perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SEL_SHIFT);
  261. perfControl &= ~(1 << BC_PERICON_AUDIO_OUT_SHIFT);
  262. break;
  263. case DVK_ANALOG_DIFF:
  264. perfControl &= ~(1 << BC_PERICON_ANALOG_DIFF_SHIFT);
  265. break;
  266. case DVK_ANALOG_SE:
  267. perfControl &= ~(1 << BC_PERICON_ANALOG_SE_SHIFT);
  268. break;
  269. case DVK_MICROSD:
  270. perfControl &= ~(1 << BC_PERICON_SPI_SHIFT);
  271. break;
  272. case DVK_TFT:
  273. /* Disable SPI analog switch */
  274. perfControl &= ~(1 << BC_PERICON_I2S_ETH_SHIFT);
  275. break;
  276. }
  277. }
  278. /* Write back register */
  279. DVK_writeRegister(&BC_REGISTER->PERICON, perfControl);
  280. }
  281. /**************************************************************************//**
  282. * @brief Get status of push buttons on kit
  283. *
  284. * @return
  285. * Button state, each bit representing each push button PB0-PB4
  286. *****************************************************************************/
  287. uint16_t DVK_getPushButtons(void)
  288. {
  289. uint16_t tmp;
  290. tmp = DVK_readRegister(&BC_REGISTER->UIF_PB);
  291. return (~tmp) & 0x000F;
  292. }
  293. /**************************************************************************//**
  294. * @brief Configure SPI for correct peripheral
  295. *
  296. * @param[in] device
  297. * Device to enable SPI bus for
  298. *****************************************************************************/
  299. void DVK_spiControl(DVK_SpiControl_TypeDef device)
  300. {
  301. switch (device)
  302. {
  303. case DVK_SPI_Audio:
  304. DVK_writeRegister(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_AUDIO);
  305. break;
  306. case DVK_SPI_Ethernet:
  307. DVK_writeRegister(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_ETHERNET);
  308. break;
  309. case DVK_SPI_Display:
  310. DVK_writeRegister(&BC_REGISTER->SPI_DEMUX, BC_SPI_DEMUX_SLAVE_DISPLAY);
  311. break;
  312. }
  313. }
  314. /**************************************************************************//**
  315. * @brief Inform AEM/Board Controller about what energy mode we are currently
  316. * entering. This information can be used for better visual feedback of
  317. * EFM32GG activity for the board controller and PC applications
  318. * @param energyMode What energy mode we are going to use next
  319. *****************************************************************************/
  320. void DVK_setEnergyMode(uint16_t energyMode)
  321. {
  322. DVK_writeRegister(&BC_REGISTER->EM, energyMode);
  323. }
  324. /**************************************************************************//**
  325. * @brief Enable "Control" buttons/joystick/dip switch interrupts
  326. * @param flags Board control interrupt flags, INTEN_<something>
  327. *****************************************************************************/
  328. void DVK_enableInterrupt(uint16_t flags)
  329. {
  330. uint16_t tmp;
  331. /* Add flags to interrupt enable register */
  332. tmp = DVK_readRegister(&BC_REGISTER->INTEN);
  333. tmp |= flags;
  334. DVK_writeRegister(&BC_REGISTER->INTEN, tmp);
  335. }
  336. /**************************************************************************//**
  337. * @brief Disable "Control" buttons/joystick/dip switch interrupts
  338. * @param flags Board control interrupt flags, BC_INTEN_<something>
  339. *****************************************************************************/
  340. void DVK_disableInterrupt(uint16_t flags)
  341. {
  342. uint16_t tmp;
  343. /* Clear flags from interrupt enable register */
  344. tmp = DVK_readRegister(&BC_REGISTER->INTEN);
  345. flags = ~(flags);
  346. tmp &= flags;
  347. DVK_writeRegister(&BC_REGISTER->INTEN, tmp);
  348. }
  349. /**************************************************************************//**
  350. * @brief Clear interrupts
  351. * @param flags Board control interrupt flags, BC_INTEN_<something>
  352. *****************************************************************************/
  353. void DVK_clearInterruptFlags(uint16_t flags)
  354. {
  355. uint16_t tmp;
  356. tmp = DVK_readRegister(&BC_REGISTER->INTFLAG);
  357. tmp &= ~(flags);
  358. DVK_writeRegister(&BC_REGISTER->INTFLAG, tmp);
  359. }
  360. /**************************************************************************//**
  361. * @brief Read interrupt flags
  362. * @return Returns currently triggered interrupts
  363. *****************************************************************************/
  364. uint16_t DVK_getInterruptFlags(void)
  365. {
  366. return DVK_readRegister(&BC_REGISTER->INTFLAG);
  367. }
  368. /**************************************************************************//**
  369. * @brief Get joystick button status
  370. * @return Joystick controller status
  371. *****************************************************************************/
  372. uint16_t DVK_getJoystick(void)
  373. {
  374. uint16_t joyStick = 0;
  375. joyStick = ~(DVK_readRegister(&BC_REGISTER->UIF_JOYSTICK)) & 0x001f;
  376. return joyStick;
  377. }
  378. /**************************************************************************//**
  379. * @brief Get dipswitch status
  380. * The DIP switches are free for user programmable purposes
  381. * @return Dip switch
  382. *****************************************************************************/
  383. uint16_t DVK_getDipSwitch(void)
  384. {
  385. return DVK_readRegister(&BC_REGISTER->UIF_DIP) & 0x000f;
  386. }
  387. /**************************************************************************//**
  388. * @brief Configure display control
  389. *****************************************************************************/
  390. void DVK_displayControl(DVK_Display_TypeDef option)
  391. {
  392. uint16_t tmp;
  393. switch (option)
  394. {
  395. case DVK_Display_EBI:
  396. DVK_writeRegister(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_EBI);
  397. break;
  398. case DVK_Display_SPI:
  399. DVK_writeRegister(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_SPI);
  400. break;
  401. case DVK_Display_BC:
  402. DVK_writeRegister(&BC_REGISTER->ARB_CTRL, BC_ARB_CTRL_BC);
  403. break;
  404. case DVK_Display_PowerEnable:
  405. tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
  406. tmp |= (BC_DISPLAY_CTRL_POWER_ENABLE);
  407. DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
  408. break;
  409. case DVK_Display_PowerDisable:
  410. tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
  411. tmp &= ~(BC_DISPLAY_CTRL_POWER_ENABLE);
  412. DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
  413. break;
  414. case DVK_Display_ResetAssert:
  415. tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
  416. tmp |= (BC_DISPLAY_CTRL_RESET);
  417. DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
  418. break;
  419. case DVK_Display_ResetRelease:
  420. tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
  421. tmp &= ~(BC_DISPLAY_CTRL_RESET);
  422. DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
  423. break;
  424. case DVK_Display_Mode8080:
  425. tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
  426. tmp &= ~(BC_DISPLAY_CTRL_MODE_GENERIC);
  427. DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
  428. break;
  429. case DVK_Display_ModeGeneric:
  430. tmp = DVK_readRegister(&BC_REGISTER->DISPLAY_CTRL);
  431. tmp |= (BC_DISPLAY_CTRL_MODE_GENERIC);
  432. DVK_writeRegister(&BC_REGISTER->DISPLAY_CTRL, tmp);
  433. break;
  434. default:
  435. /* Unknown command */
  436. while (1) ;
  437. }
  438. }
  439. /** @} (end group BSP) */