EFM32 Happy Gecko Software Documentation  efm32hg-doc-5.1.2
retargettft.c
Go to the documentation of this file.
1 /***************************************************************************/
17 #include <stdio.h>
18 #include <stdint.h>
19 #include "em_device.h"
20 #include "em_cmu.h"
21 #include "em_ebi.h"
22 #include "em_gpio.h"
23 #include "dmd/ssd2119/dmd_ssd2119.h"
24 #include "bsp.h"
25 #include "retargettft.h"
26 
27 #include "displayfont8x8.h"
28 #define fontBits chars_8x8_bits
30 #define CHARS 40
31 #define LINES 30
33 static uint8_t charBuffer[LINES][CHARS];
34 static uint8_t rgbColor[3];
37 static int xpos, ypos;
39 static bool fullUpdate = true;
40 static bool bufferReset = true;
41 static bool tftReset = true;
42 static bool LFtoCRLF = 0;
43 static bool initialized = false;
45 /* Static functions. */
46 static void tftTextReset(void);
47 static void tftTextScrollUp(void);
48 
49 
50 /**************************************************************************/
53 void RETARGET_TftInit(void)
54 {
55 #if !defined(__CROSSWORKS_ARM) && defined(__GNUC__)
56  setvbuf(stdout, NULL, _IONBF, 0); /*Set unbuffered mode for stdout (newlib)*/
57 #endif
58 
59  /* Reset the TFT text display state. */
60  tftTextReset();
61 }
62 
63 
64 /**************************************************************************/
68 void RETARGET_TftCrLf(int on)
69 {
70  if (on)
71  LFtoCRLF = true;
72  else
73  LFtoCRLF = false;
74 }
75 
76 
77 /**************************************************************************/
80 static void tftTextReset(void)
81 {
82  int x, y;
83  volatile int i;
84  EMSTATUS status;
85 
86  /* Initialize color for font */
87  /* Use \b for red text (bell/warning) */
88  rgbColor[0] = 0xff;
89  rgbColor[1] = 0xff;
90  rgbColor[2] = 0xff;
91 
92  /* Character buffer */
93  if (bufferReset)
94  {
95  /* Clear character buffer */
96  for (y = 0; y < LINES; y++)
97  {
98  for (x = 0; x < CHARS; x++)
99  {
100  charBuffer[y][x] = 0;
101  }
102  }
103  /* Set cursor position to upper left */
104  xpos = 0;
105  ypos = 0;
106  }
107 
108  /* Display controller */
109  if (tftReset)
110  {
111  /* Resetting display while SPI_DEMUX is set to display does not work */
113  {
115  }
116  /* Configure for EBI mode and reset display */
120  /* Short delay */
121  for (i = 0; i < 10000; i++) ;
122  /* Configure display for Direct Drive + SPI mode */
126 
127  /* Initialize graphics - abort on failure */
128  status = DMDIF_init(BC_SSD2119_BASE, BC_SSD2119_BASE + 2);
129  if (status == DMD_OK) status = DMD_init(0);
130  if ((status != DMD_OK) && (status != DMD_ERROR_DRIVER_ALREADY_INITIALIZED)) while (1) ;
131  /* Make sure display is configured with correct rotation */
132  if ((status == DMD_OK)) status = DMD_flipDisplay(1, 1);
133  }
134  initialized = true;
135 }
136 
137 /**************************************************************************/
140 static void tftTextScrollUp(void)
141 {
142  int y;
143  int x;
144 
145  /* copy all lines one line up */
146  for (y = 0; y < (LINES - 1); y++)
147  {
148  for (x = 0; x < CHARS; x++)
149  {
150  charBuffer[y][x] = charBuffer[y + 1][x];
151  }
152  }
153  /* clear last line */
154  for (x = 0; x < CHARS; x++)
155  {
156  charBuffer[LINES - 1][x] = 0;
157  }
158  xpos = 0;
159  ypos = LINES - 1;
160  fullUpdate = true;
161 }
162 
163 /***************************************************************************/
168 /**************************************************************************/
173 void RETARGET_TFTTX(int c)
174 {
175  /* check for CR */
176  if (c == '\r')
177  {
178  xpos = 0;
179  return;
180  }
181  /* check for LF */
182  if (c == '\n')
183  {
184  ypos = ypos + 1;
185  xpos = 0;
186  if (ypos >= LINES)
187  {
188  /* scroll characters one line up */
189  tftTextScrollUp();
190  ypos = (LINES - 1);
191  }
192  return;
193  }
194  /* check for bell character, changes color to red */
195  if (c == '\b')
196  {
197  if (rgbColor[1] == 0xff)
198  {
199  rgbColor[1] = 0x00;
200  rgbColor[2] = 0x00;
201  }
202  else
203  {
204  rgbColor[1] = 0xff;
205  rgbColor[2] = 0xff;
206  }
207  return;
208  }
209 
210  /* check for non-printable characters */
211  if (c < ' ' || c > '~')
212  {
213  c = ' ';
214  }
215  xpos = xpos + 1;
216  if (xpos >= CHARS)
217  {
218  xpos = 0;
219  ypos = ypos + 1;
220  }
221  if (ypos >= LINES)
222  {
223  tftTextScrollUp();
224  ypos = 29;
225  }
226  charBuffer[ypos][xpos] = c - ' ';
227 }
228 
229 
230 /**************************************************************************/
235 void RETARGET_TFTUpdate(bool fullFrame)
236 {
237  int x, y;
238  uint32_t pixelX, pixelY;
239  uint8_t c, bitField;
240  int i;
241 
242  /* Draw a full screen */
243  if (fullFrame)
244  {
245  for (y = 0; y < LINES; y++)
246  {
247  for (x = 0; x < CHARS; x++)
248  {
249  pixelX = x * 8;
250  pixelY = y * 8;
251 
252  c = charBuffer[y][x];
253  for (i = 0; i < 8; i++)
254  {
255  bitField = fontBits[c + 100 * i];
256  if (bitField == 0)
257  {
258  DMD_writeData(pixelX, pixelY + i, (uint8_t *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 8);
259  continue;
260  }
261 
262  if (bitField & 0x01)
263  {
264  DMD_writeColor(pixelX + 0, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
265  }
266  else
267  {
268  DMD_writeColor(pixelX + 0, pixelY + i, 0x00, 0x00, 0x00, 1);
269  }
270  if (bitField & 0x02)
271  {
272  DMD_writeColor(pixelX + 1, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
273  }
274  else
275  {
276  DMD_writeColor(pixelX + 1, pixelY + i, 0x00, 0x00, 0x00, 1);
277  }
278  if (bitField & 0x04)
279  {
280  DMD_writeColor(pixelX + 2, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
281  }
282  else
283  {
284  DMD_writeColor(pixelX + 2, pixelY + i, 0x00, 0x00, 0x00, 1);
285  }
286  if (bitField & 0x08)
287  {
288  DMD_writeColor(pixelX + 3, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
289  }
290  else
291  {
292  DMD_writeColor(pixelX + 3, pixelY + i, 0x00, 0x00, 0x00, 1);
293  }
294  if (bitField & 0x10)
295  {
296  DMD_writeColor(pixelX + 4, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
297  }
298  else
299  {
300  DMD_writeColor(pixelX + 4, pixelY + i, 0x00, 0x00, 0x00, 1);
301  }
302  if (bitField & 0x20)
303  {
304  DMD_writeColor(pixelX + 5, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
305  }
306  else
307  {
308  DMD_writeColor(pixelX + 5, pixelY + i, 0x00, 0x00, 0x00, 1);
309  }
310  if (bitField & 0x40)
311  {
312  DMD_writeColor(pixelX + 6, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
313  }
314  else
315  {
316  DMD_writeColor(pixelX + 6, pixelY + i, 0x00, 0x00, 0x00, 1);
317  }
318  if (bitField & 0x80)
319  {
320  DMD_writeColor(pixelX + 7, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
321  }
322  else
323  {
324  DMD_writeColor(pixelX + 7, pixelY + i, 0x00, 0x00, 0x00, 1);
325  }
326  }
327  }
328  }
329  }
330  else
331  {
332  /* Draw xpos, ypos only */
333  c = charBuffer[ypos][xpos];
334  pixelX = xpos * 8;
335  pixelY = ypos * 8;
336  for (i = 0; i < 8; i++)
337  {
338  bitField = fontBits[c + 100 * i];
339  if (bitField == 0)
340  {
341  DMD_writeData(pixelX, pixelY + i, (uint8_t *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 8);
342  continue;
343  }
344 
345  if (bitField & 0x01)
346 
347  {
348  DMD_writeColor(pixelX + 0, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
349  }
350  else
351  {
352  DMD_writeColor(pixelX + 0, pixelY + i, 0x00, 0x00, 0x00, 1);
353  }
354  if (bitField & 0x02)
355  {
356  DMD_writeColor(pixelX + 1, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
357  }
358  else
359  {
360  DMD_writeColor(pixelX + 1, pixelY + i, 0x00, 0x00, 0x00, 1);
361  }
362  if (bitField & 0x04)
363  {
364  DMD_writeColor(pixelX + 2, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
365  }
366  else
367  {
368  DMD_writeColor(pixelX + 2, pixelY + i, 0x00, 0x00, 0x00, 1);
369  }
370  if (bitField & 0x08)
371  {
372  DMD_writeColor(pixelX + 3, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
373  }
374  else
375  {
376  DMD_writeColor(pixelX + 3, pixelY + i, 0x00, 0x00, 0x00, 1);
377  }
378  if (bitField & 0x10)
379  {
380  DMD_writeColor(pixelX + 4, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
381  }
382  else
383  {
384  DMD_writeColor(pixelX + 4, pixelY + i, 0x00, 0x00, 0x00, 1);
385  }
386  if (bitField & 0x20)
387  {
388  DMD_writeColor(pixelX + 5, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
389  }
390  else
391  {
392  DMD_writeColor(pixelX + 5, pixelY + i, 0x00, 0x00, 0x00, 1);
393  }
394  if (bitField & 0x40)
395  {
396  DMD_writeColor(pixelX + 6, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
397  }
398  else
399  {
400  DMD_writeColor(pixelX + 6, pixelY + i, 0x00, 0x00, 0x00, 1);
401  }
402  if (bitField & 0x80)
403  {
404  DMD_writeColor(pixelX + 7, pixelY + i, rgbColor[0], rgbColor[1], rgbColor[2], 1);
405  }
406  else
407  {
408  DMD_writeColor(pixelX + 7, pixelY + i, 0x00, 0x00, 0x00, 1);
409  }
410  }
411  }
412 }
413 
416 /**************************************************************************/
422 {
423  return -1;
424 }
425 
426 /**************************************************************************/
432 {
433  if ((BSP_RegisterRead(&BC_REGISTER->UIF_AEM) == BC_UIF_AEM_EFM))
434  {
435  if ((BSP_RegisterRead(&BC_REGISTER->ARB_CTRL) != BC_ARB_CTRL_EBI) || (initialized == false))
436  {
437  if (initialized)
438  {
439  bufferReset = false;
440  tftReset = true;
441  tftTextReset();
442  }
443  else
444  {
445  bufferReset = true;
446  tftReset = true;
447  tftTextReset();
448  }
449  fullUpdate = true;
450  }
451  }
452 
453  /* Check for form feed - clear screen */
454  if (c == '\f')
455  {
456  bufferReset = true;
457  tftReset = false;
458  tftTextReset();
459  fullUpdate = true;
460  return c;
461  }
462 
463  /* Add CR or LF to CRLF if enabled */
464  if (LFtoCRLF && (c == '\n'))
465  {
466  RETARGET_TFTTX('\r');
467  }
468  RETARGET_TFTTX(c);
469 
470  if (LFtoCRLF && (c == '\r'))
471  {
472  RETARGET_TFTTX('\n');
473  }
474 
475  /* Update display */
477  fullUpdate = false;
478  return c;
479 }
Clock management unit (CMU) API.
int RETARGET_ReadChar(void)
Receive a byte No input method from TFT is possible, thus we always return -1.
Definition: retargettft.c:421
Board support package API definitions.
static bool tftReset
Definition: retargettft.c:41
static int xpos
Definition: retargettft.c:37
#define BC_SPI_DEMUX_SLAVE_AUDIO
void RETARGET_TftCrLf(int on)
Toggle LF to CRLF conversion.
Definition: retargettft.c:68
static void tftTextReset(void)
Reset TFT text display state.
Definition: retargettft.c:80
static uint8_t charBuffer[LINES][CHARS]
Definition: retargettft.c:33
8x8 font with all characters
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
void RETARGET_TFTTX(int c)
Transmit/display a character.
Definition: retargettft.c:173
#define CHARS
Definition: retargettft.c:30
void RETARGET_TftInit(void)
Intializes TFT text display.
Definition: retargettft.c:53
static bool initialized
Definition: retargettft.c:43
static uint8_t rgbColor[3]
Definition: retargettft.c:34
uint16_t BSP_RegisterRead(volatile uint16_t *addr)
Read from a board controller register.
Definition: bsp_dk_3201.c:687
static bool fullUpdate
Definition: retargettft.c:39
#define BC_UIF_AEM_EFM
External Bus Iterface (EBI) peripheral API.
static bool LFtoCRLF
Definition: retargettft.c:42
General Purpose IO (GPIO) peripheral API.
int RETARGET_WriteChar(char c)
Transmit single byte to the TFT.
Definition: retargettft.c:431
#define LINES
Definition: retargettft.c:31
static void tftTextScrollUp(void)
Scroll one line of characters up on the screen.
Definition: retargettft.c:140
void RETARGET_TFTUpdate(bool fullFrame)
Display framebuffer.
Definition: retargettft.c:235
#define fontBits
Definition: retargettft.c:28
int BSP_RegisterWrite(volatile uint16_t *addr, uint16_t data)
Write to a board controller register.
Definition: bsp_dk_3201.c:704
#define BC_ARB_CTRL_EBI
static int ypos
Definition: retargettft.c:37
int BSP_DisplayControl(BSP_Display_TypeDef option)
Configure display control.
Definition: bsp_dk_3201.c:251
#define BC_SPI_DEMUX_SLAVE_DISPLAY
static bool bufferReset
Definition: retargettft.c:40
#define BC_REGISTER
#define BC_SSD2119_BASE