EFM32 Gecko Software Documentation  efm32g-doc-5.1.2
displaypalemlib.c
Go to the documentation of this file.
1 /**************************************************************************/
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "em_device.h"
25 #include "em_cmu.h"
26 #include "em_gpio.h"
27 #include "em_usart.h"
28 #include "bsp.h"
29 #include "udelay.h"
30 
31 /* DISPLAY driver inclustions */
32 #include "displayconfigall.h"
33 #include "displaypal.h"
34 
35 #ifdef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE
36 
37 #if defined(RTCC_PRESENT) && (RTCC_COUNT > 0) && !defined(PAL_CLOCK_RTC)
38 #define PAL_CLOCK_RTCC
39 #include "em_rtcc.h"
40 #else
41 #define PAL_CLOCK_RTC
42 #include "em_rtc.h"
43 #endif
44 
45 #ifdef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
46 #include "em_prs.h"
47 #endif
48 
49 #endif
50 
53 /*******************************************************************************
54  ******************************** STATICS ************************************
55  ******************************************************************************/
56 
57 #ifdef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE
58 #ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
59 /* GPIO port and pin used for the PAL_GpioPinAutoToggle function. */
60 static unsigned int gpioPortNo;
61 static unsigned int gpioPinNo;
62 #endif
63 
64 static void palClockSetup(CMU_Clock_TypeDef clock);
65 
66 #if defined(PAL_CLOCK_RTCC)
67 static void rtccSetup(unsigned int frequency);
68 #else
69 static void rtcSetup(unsigned int frequency);
70 #endif
71 
72 #endif
73 
74 /*******************************************************************************
75  ************************** GLOBAL FUNCTIONS **************************
76  ******************************************************************************/
77 
78 /**************************************************************************/
87 EMSTATUS PAL_SpiInit (void)
88 {
89  EMSTATUS status = PAL_EMSTATUS_OK;
91 
92  /* Initialize USART for SPI transaction */
93  CMU_ClockEnable( PAL_SPI_USART_CLOCK, true );
94  usartInit.baudrate = PAL_SPI_BAUDRATE;
95 
96  USART_InitSync( PAL_SPI_USART_UNIT, &usartInit );
97 
98 #if defined( USART_ROUTEPEN_TXPEN )
99 
100  PAL_SPI_USART_UNIT->ROUTEPEN = USART_ROUTEPEN_TXPEN
101  | USART_ROUTEPEN_CLKPEN;
102  PAL_SPI_USART_UNIT->ROUTELOC0 = ( PAL_SPI_USART_UNIT->ROUTELOC0 &
103  ~( _USART_ROUTELOC0_TXLOC_MASK | _USART_ROUTELOC0_CLKLOC_MASK ) )
104  | ( PAL_SPI_USART_LOCATION_TX << _USART_ROUTELOC0_TXLOC_SHIFT )
105  | ( PAL_SPI_USART_LOCATION_SCLK << _USART_ROUTELOC0_CLKLOC_SHIFT );
106 
107 #else
108 
109  PAL_SPI_USART_UNIT->ROUTE = (USART_ROUTE_CLKPEN | USART_ROUTE_TXPEN | PAL_SPI_USART_LOCATION);
110 
111 #endif
112 
113  return status;
114 }
115 
116 
117 /**************************************************************************/
125 EMSTATUS PAL_SpiShutdown (void)
126 {
127  EMSTATUS status = PAL_EMSTATUS_OK;
128 
129  /* Disable the USART device used for SPI. */
130  USART_Enable( PAL_SPI_USART_UNIT, usartDisable);
131 
132  /* Disable the USART clock. */
133  CMU_ClockEnable( PAL_SPI_USART_CLOCK, false );
134 
135  return status;
136 }
137 
138 
139 /**************************************************************************/
147 EMSTATUS PAL_SpiTransmit (uint8_t* data, unsigned int len)
148 {
149  EMSTATUS status = PAL_EMSTATUS_OK;
150 
151  while (len>0)
152  {
153  /* Send only one byte if len==1 or data pointer is not aligned at a 16 bit
154  word location in memory. */
155  if ((len == 1) || ((unsigned int)data & 0x1))
156  {
157  USART_Tx( PAL_SPI_USART_UNIT, *(uint8_t*)data );
158  len --;
159  data ++;
160  }
161  else
162  {
163  USART_TxDouble( PAL_SPI_USART_UNIT, *(uint16_t*)data );
164  len -= 2;
165  data += 2;
166  }
167  }
168 
169  /* Wait for transfer to finish */
170  while (!(PAL_SPI_USART_UNIT->STATUS & USART_STATUS_TXC)) ;
171 
172  return status;
173 }
174 
175 
176 /**************************************************************************/
184 EMSTATUS PAL_TimerInit (void)
185 {
186  EMSTATUS status = PAL_EMSTATUS_OK;
187 
189 
190  return status;
191 }
192 
193 
194 /**************************************************************************/
202 EMSTATUS PAL_TimerShutdown (void)
203 {
204  EMSTATUS status = PAL_EMSTATUS_OK;
205 
206  /* Nothing to do since the UDELAY_Delay does not use any resources after
207  the UDELAY_Calibrate has been called. The UDELAY_Calibrate uses the
208  RTC to calibrate the delay loop, and restores the RTC after use. */
209 
210  return status;
211 }
212 
213 
214 /**************************************************************************/
221 EMSTATUS PAL_TimerMicroSecondsDelay(unsigned int usecs)
222 {
223  EMSTATUS status = PAL_EMSTATUS_OK;
224 
225  UDELAY_Delay(usecs);
226 
227  return status;
228 }
229 
230 
231 #ifdef PAL_TIMER_REPEAT_FUNCTION
232 /**************************************************************************/
242 EMSTATUS PAL_TimerRepeat (void(*pFunction)(void*),
243  void* argument,
244  unsigned int frequency)
245 {
246  if (0 != PAL_TIMER_REPEAT_FUNCTION(pFunction, argument, frequency))
248  else
249  return EMSTATUS_OK;
250 }
251 #endif
252 
253 
254 /**************************************************************************/
262 EMSTATUS PAL_GpioInit (void)
263 {
264  EMSTATUS status = PAL_EMSTATUS_OK;
265 
266  /* Enable the GPIO clock in order to access the GPIO module. */
268 
269  return status;
270 }
271 
272 
273 /**************************************************************************/
281 EMSTATUS PAL_GpioShutdown (void)
282 {
283  EMSTATUS status = PAL_EMSTATUS_OK;
284 
285  /* Enable the GPIO clock in order to access the GPIO module. */
286  CMU_ClockEnable( cmuClock_GPIO, false );
287 
288  return status;
289 }
290 
291 
292 /***************************************************************************/
313 EMSTATUS PAL_GpioPinModeSet(unsigned int port,
314  unsigned int pin,
315  PAL_GpioMode_t mode,
316  unsigned int platformSpecific)
317 {
318  EMSTATUS status = PAL_EMSTATUS_OK;
319  GPIO_Mode_TypeDef emGpioMode;
320 
321  /* Convert PAL pin mode to GPIO_Mode_TypeDef defined in em_gpio.h. */
322  switch (mode)
323  {
324  case palGpioModePushPull:
325  emGpioMode = gpioModePushPull;
326  break;
327  default:
329  }
330 
331  GPIO_PinModeSet((GPIO_Port_TypeDef) port, pin, emGpioMode, platformSpecific);
332 
333  return status;
334 }
335 
336 
337 /***************************************************************************/
354 EMSTATUS PAL_GpioPinOutSet(unsigned int port, unsigned int pin)
355 {
356  EMSTATUS status = PAL_EMSTATUS_OK;
357 
358  GPIO_PinOutSet((GPIO_Port_TypeDef) port, pin);
359 
360  return status;
361 }
362 
363 
364 /***************************************************************************/
381 EMSTATUS PAL_GpioPinOutClear(unsigned int port, unsigned int pin)
382 {
383  EMSTATUS status = PAL_EMSTATUS_OK;
384 
385  GPIO_PinOutClear((GPIO_Port_TypeDef) port, pin);
386 
387  return status;
388 }
389 
390 
391 /***************************************************************************/
408 EMSTATUS PAL_GpioPinOutToggle(unsigned int port, unsigned int pin)
409 {
410  EMSTATUS status = PAL_EMSTATUS_OK;
411 
413 
414  return status;
415 }
416 
417 
418 #ifdef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE
419 /**************************************************************************/
427 EMSTATUS PAL_GpioPinAutoToggle (unsigned int gpioPort,
428  unsigned int gpioPin,
429  unsigned int frequency)
430 {
431  EMSTATUS status = EMSTATUS_OK;
432 
433 #ifdef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
434 
435  /* Setup PRS to drive the GPIO pin which is connected to the
436  display com inversion pin (EXTCOMIN) using the RTC COMP0 signal or
437  RTCC CCV1 signal as source. */
438 #if defined(PAL_CLOCK_RTCC)
439  uint32_t source = PRS_CH_CTRL_SOURCESEL_RTCC;
440  uint32_t signal = PRS_CH_CTRL_SIGSEL_RTCCCCV1;
441 #else
442  uint32_t source = PRS_CH_CTRL_SOURCESEL_RTC;
443  uint32_t signal = PRS_CH_CTRL_SIGSEL_RTCCOMP0;
444 #endif
445 
446  /* Enable PRS clock */
448 
449  /* Set up PRS to trigger from an RTC compare match */
450  PRS_SourceAsyncSignalSet(LCD_AUTO_TOGGLE_PRS_CH, source, signal);
451 
452  /* This outputs the PRS pulse on the EXTCOMIN pin */
453 #if defined(_SILICON_LABS_32B_PLATFORM_2)
454  LCD_AUTO_TOGGLE_PRS_ROUTELOC();
455  PRS->ROUTEPEN |= LCD_AUTO_TOGGLE_PRS_ROUTEPEN;
456 #else
457  PRS->ROUTE = ( PRS->ROUTE & ~_PRS_ROUTE_LOCATION_MASK )
458  | LCD_AUTO_TOGGLE_PRS_ROUTE_LOC;
459  PRS->ROUTE |= LCD_AUTO_TOGGLE_PRS_ROUTE_PEN;
460 #endif
461 
462 #else
463  /* Store GPIO pin data. */
464  gpioPortNo = gpioPort;
465  gpioPinNo = gpioPin;
466 #endif
467 
468  /* Setup GPIO pin. */
469  GPIO_PinModeSet((GPIO_Port_TypeDef)gpioPort, gpioPin, gpioModePushPull, 0 );
470 
471 #if defined(PAL_CLOCK_RTCC)
472  /* Setup RTCC to to toggle PRS or generate interrupts at given frequency. */
473  rtccSetup(frequency);
474 #else
475  /* Setup RTC to to toggle PRS or generate interrupts at given frequency. */
476  rtcSetup(frequency);
477 #endif
478 
479  return status;
480 }
481 
482 
483 #ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
484 #if defined(PAL_CLOCK_RTC)
485 /**************************************************************************/
490 void RTC_IRQHandler(void)
491 {
492  /* Clear interrupt source */
494 
495  /* Toggle GPIO pin. */
496  GPIO_PinOutToggle((GPIO_Port_TypeDef)gpioPortNo, gpioPinNo );
497 }
498 #endif /* PAL_CLOCK_RTC */
499 
500 #if defined(PAL_CLOCK_RTCC)
501 /**************************************************************************/
506 void RTCC_IRQHandler(void)
507 {
508  /* Clear interrupt source */
509  RTCC_IntClear(RTCC_IF_CC1);
510 
511  /* Toggle GPIO pin. */
512  GPIO_PinOutToggle((GPIO_Port_TypeDef)gpioPortNo, gpioPinNo );
513 }
514 #endif /* PAL_CLOCK_RTCC */
515 #endif /* INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY */
516 
517 
518 /**************************************************************************/
523 static void palClockSetup(CMU_Clock_TypeDef clock)
524 {
525  /* Enable LE domain registers */
526  CMU_ClockEnable(cmuClock_CORELE, true);
527 
528 #if ( defined(PAL_CLOCK_RTC) && defined(PAL_RTC_CLOCK_LFXO) ) \
529  || ( defined(PAL_CLOCK_RTCC) && defined(PAL_RTCC_CLOCK_LFXO) )
530  /* LFA with LFXO setup is relatively time consuming. Therefore, check if it
531  already enabled before calling. */
532  if ( !(CMU->STATUS & CMU_STATUS_LFXOENS) )
533  {
534  CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
535  }
536  if ( cmuSelect_LFXO != CMU_ClockSelectGet(clock) )
537  {
539  }
540 #elif ( defined(PAL_CLOCK_RTC) && defined(PAL_RTC_CLOCK_LFRCO) ) \
541  || ( defined(PAL_CLOCK_RTCC) && defined(PAL_RTCC_CLOCK_LFRCO) )
542  /* Enable LF(A|E)CLK in CMU (will also enable LFRCO oscillator if not enabled) */
544 #elif ( defined(PAL_CLOCK_RTC) && defined(PAL_RTC_CLOCK_ULFRCO) ) \
545  || ( defined(PAL_CLOCK_RTCC) && defined(PAL_RTCC_CLOCK_ULFRCO) )
546  /* Enable LF(A|E)CLK in CMU (will also enable ULFRCO oscillator if not enabled) */
547  CMU_ClockSelectSet(clock, cmuSelect_ULFRCO);
548 #else
549 #error No clock source for RTC defined.
550 #endif
551 }
552 
553 
554 #if defined(PAL_CLOCK_RTC)
555 /**************************************************************************/
559 static void rtcSetup(unsigned int frequency)
560 {
562 
563  palClockSetup(cmuClock_LFA);
564 
565  /* Set the prescaler. */
567 
568  /* Enable RTC clock */
570 
571  /* Initialize RTC */
572  rtcInit.enable = false; /* Do not start RTC after initialization is complete. */
573  rtcInit.debugRun = false; /* Halt RTC when debugging. */
574  rtcInit.comp0Top = true; /* Wrap around on COMP0 match. */
575 
576  RTC_Init(&rtcInit);
577 
578  /* Interrupt at given frequency. */
579  RTC_CompareSet(0, ((CMU_ClockFreqGet(cmuClock_RTC) / frequency) - 1) & _RTC_COMP0_MASK );
580 
581 #ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
582  /* Enable interrupt */
583  NVIC_EnableIRQ(RTC_IRQn);
585 #endif
587  /* Start Counter */
588  RTC_Enable(true);
589 }
590 #endif /* PAL_CLOCK_RTC */
591 
592 
593 #if defined(PAL_CLOCK_RTCC)
594 /**************************************************************************/
598 static void rtccSetup(unsigned int frequency)
599 {
600  RTCC_Init_TypeDef rtccInit = RTCC_INIT_DEFAULT;
601  rtccInit.presc = rtccCntPresc_1;
602 
603  palClockSetup(cmuClock_LFE);
604  /* Enable RTCC clock */
605  CMU_ClockEnable(cmuClock_RTCC, true);
606 
607  /* Initialize RTC */
608  rtccInit.enable = false; /* Do not start RTC after initialization is complete. */
609  rtccInit.debugRun = false; /* Halt RTC when debugging. */
610  rtccInit.cntWrapOnCCV1 = true; /* Wrap around on CCV1 match. */
611  RTCC_Init(&rtccInit);
612 
613  /* Interrupt at given frequency. */
614  RTCC_CCChConf_TypeDef ccchConf = RTCC_CH_INIT_COMPARE_DEFAULT;
615  ccchConf.compMatchOutAction = rtccCompMatchOutActionToggle;
616  RTCC_ChannelInit(1, &ccchConf);
617  RTCC_ChannelCCVSet(1, (CMU_ClockFreqGet(cmuClock_RTCC) / frequency) - 1);
618 
619 #ifndef INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE_HW_ONLY
620  /* Enable interrupt */
621  NVIC_EnableIRQ(RTCC_IRQn);
622  RTCC_IntEnable(RTCC_IEN_CC1);
623 #endif
624 
625  RTCC->CNT = _RTCC_CNT_RESETVALUE;
626  /* Start Counter */
627  RTCC_Enable(true);
628 }
629 #endif /* PAL_CLOCK_RTCC */
630 #endif /* INCLUDE_PAL_GPIO_PIN_AUTO_TOGGLE */
631 
#define _RTC_COMP0_MASK
Definition: efm32g_rtc.h:94
Clock management unit (CMU) API.
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
Select reference clock/oscillator used for a clock branch.
Definition: em_cmu.c:2521
void USART_Tx(USART_TypeDef *usart, uint8_t data)
Transmit one 4-9 bit frame.
Definition: em_usart.c:1084
#define PAL_EMSTATUS_INVALID_PARAM
Definition: displaypal.h:35
Board support package API definitions.
GPIO_Port_TypeDef
Definition: em_gpio.h:345
void USART_InitSync(USART_TypeDef *usart, const USART_InitSync_TypeDef *init)
Init USART for synchronous mode.
Definition: em_usart.c:640
#define PRS
__STATIC_INLINE void GPIO_PinOutToggle(GPIO_Port_TypeDef port, unsigned int pin)
Toggle a single pin in GPIO port data out register.
Definition: em_gpio.h:881
void RTC_CounterReset(void)
Restart RTC counter from zero.
Definition: em_rtc.c:370
__STATIC_INLINE void RTC_IntClear(uint32_t flags)
Clear one or more pending RTC interrupts.
Definition: em_rtc.h:123
#define PRS_CH_CTRL_SIGSEL_RTCCOMP0
Definition: efm32g_prs.h:219
void UDELAY_Calibrate(void)
Calibrates the microsecond delay loop.
Definition: udelay.c:71
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define USART_ROUTE_CLKPEN
Universal synchronous/asynchronous receiver/transmitter (USART/UART) peripheral API.
void RTC_CompareSet(unsigned int comp, uint32_t value)
Set RTC compare register value.
Definition: em_rtc.c:161
#define EMSTATUS_OK
Definition: emstatus.h:25
GPIO_Mode_TypeDef
Definition: em_gpio.h:421
Platform Abstraction Layer (PAL) interface for DISPLAY driver.
void GPIO_PinModeSet(GPIO_Port_TypeDef port, unsigned int pin, GPIO_Mode_TypeDef mode, unsigned int out)
Set the mode for a GPIO pin.
Definition: em_gpio.c:269
#define CMU_STATUS_LFXOENS
Definition: efm32g_cmu.h:470
General Purpose IO (GPIO) peripheral API.
Microsecond delay routine.
Real Time Counter (RTCC) peripheral API.
CMU_Clock_TypeDef
Definition: em_cmu.h:257
bool debugRun
Definition: em_rtc.h:63
__STATIC_INLINE void RTC_IntEnable(uint32_t flags)
Enable one or more RTC interrupts.
Definition: em_rtc.h:158
__STATIC_INLINE void GPIO_PinOutSet(GPIO_Port_TypeDef port, unsigned int pin)
Set a single pin in GPIO data out register to 1.
Definition: em_gpio.h:856
bool comp0Top
Definition: em_rtc.h:64
void RTC_Init(const RTC_Init_TypeDef *init)
Initialize RTC.
Definition: em_rtc.c:305
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1453
#define PAL_EMSTATUS_OK
Definition: displaypal.h:34
#define USART_STATUS_TXC
Definition: efm32g_usart.h:413
Real Time Counter (RTC) peripheral API.
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
Enable/disable oscillator.
Definition: em_cmu.c:3594
Main configuration file for the DISPLAY driver software stack.
void RTC_Enable(bool enable)
Enable/disable RTC.
Definition: em_rtc.c:217
#define CMU
#define PRS_CH_CTRL_SOURCESEL_RTC
Definition: efm32g_prs.h:279
#define RTC_INIT_DEFAULT
Definition: em_rtc.h:68
#define RTC_IF_COMP0
Definition: efm32g_rtc.h:116
__STATIC_INLINE void GPIO_PinOutClear(GPIO_Port_TypeDef port, unsigned int pin)
Set a single pin in GPIO data out port register to 0.
Definition: em_gpio.h:811
void USART_Enable(USART_TypeDef *usart, USART_Enable_TypeDef enable)
Enable/disable USART/UART receiver and/or transmitter.
Definition: em_usart.c:527
#define USART_ROUTE_TXPEN
Definition: efm32g_usart.h:992
#define RTC_IEN_COMP0
Definition: efm32g_rtc.h:173
#define USART_INITSYNC_DEFAULT
Definition: em_usart.h:498
uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock)
Get clock frequency for a clock point.
Definition: em_cmu.c:1550
Peripheral Reflex System (PRS) peripheral API.
void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div)
Set clock divisor/prescaler.
Definition: em_cmu.c:1244
void USART_TxDouble(USART_TypeDef *usart, uint16_t data)
Transmit two 4-9 bit frames, or one 10-16 bit frame.
Definition: em_usart.c:1120
void UDELAY_Delay(uint32_t usecs)
Microsecond active wait delay routine.
Definition: udelay.c:284
#define PAL_EMSTATUS_REPEAT_FAILED
Definition: displaypal.h:36
#define cmuClkDiv_2
Definition: em_cmu.h:150
CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
Get currently selected reference clock used for a clock branch.
Definition: em_cmu.c:2146