ARMEBS4  revision-26.06.2015
retarget_usart.c
Go to the documentation of this file.
1 /************************************************************************//**
2  * \file heivs/retarget_usart.c
3  * \author marc dot pignat at hevs dot ch
4  *
5  * \defgroup stdio_redir stdio redirection
6  * \ingroup stdio_h
7  * @{
8  *
9  * \brief stdio redirection for newlib
10  *
11  * Here is the low-level part of stdio (printf/scanf, puts, getc, ...) functions
12  *
13  ***************************************************************************/
14 
15 #include "heivs/config.h"
16 #if defined(USE_STDIO_USART)
17 
18 #include "heivs/retarget.h"
19 #include "heivs/stm32_usart.h"
20 #include "heivs/config.h"
21 
22 #if !(USE_STDIO_USART < BSP_USART_BUS_COUNT)
23 #error USE_STDIO_USART should be < BSP_USART_BUS_COUNT
24 #endif
25 
26 #include <stdio.h>
27 
28 static const uint32_t use_stdio_nobuf = USE_STDIO_NOBUF;
29 static const uint32_t use_stdio_echo = USE_STDIO_ECHO;
30 static const uint32_t auto_crlf = USE_STDIO_AUTO_CR_BEFORE_LF;
31 
32 /**
33  * \brief Initialization
34  *
35  * Initializte the usart \#USE_STDIO_USART.
36  *
37  * \see USE_STDIO_USART
38  */
39 void retarget_init()
40 {
41  const struct heivs_bus_t *bus = &bus_usart[USE_STDIO_USART];
42  #if USE_FREERTOS
43  /**
44  * stdio don't use the bus mutex.
45  *
46  * We want stdio to work even when the kernel has crashed
47  */
48  bus->var->mutex_ignore = 1;
49  #endif
50  bus_init(bus);
51 
52  if (use_stdio_nobuf)
53  {
54  setvbuf(stdout, NULL, _IONBF, 0);
55  setvbuf(stderr, NULL, _IONBF, 0);
56  setvbuf(stdin, NULL, _IONBF, 0);
57  }
58 }
59 
60 int _write(int fd, char *ptr, int len)
61 {
62  (void)fd;
63  const struct heivs_bus_t *bus = &bus_usart[USE_STDIO_USART];
64  int i;
65  bus_get(bus);
66 
67  if (auto_crlf)
68  {
69  for (i = 0 ; i < len ; i++)
70  {
71  char c = ptr[i];
72 
73  if (c == '\n')
74  {
75  char cr = '\r';
76  bus_write(bus, 0, &cr, 1);
77  }
78  bus_write(bus, 0, &c, 1);
79  }
80  }
81  else
82  {
83  bus_write(bus, 0, ptr, len);
84  }
85 
86  bus_release(bus);
87 
88  return len;
89 }
90 
91 int _read(int fd, char *ptr, int len)
92 {
93  size_t l;
94  const struct heivs_bus_t *bus = &bus_usart[USE_STDIO_USART];
95 
96  while (bus_get(bus) != NO_ERROR);
97 
98  do
99  {
100  status_e status;
101  l = len;
102  status = bus_read(bus, 0, ptr, len, &l);
103  if (status != NO_ERROR)
104  {
105  bus_get(bus);
106  }
107  } while (l == 0);
108 
109  bus_release(bus);
110 
111  if (use_stdio_echo)
112  {
113  _write(fd, ptr, l);
114  }
115 
116  return l;
117 }
118 
119 #endif /* defined(USE_STDIO_USART) */
120 
121 /************************************************************************//**
122  * @}
123  ***************************************************************************/
Bus handler.
Definition: bus.h:92
stdio redirection
status_e bus_release(const struct heivs_bus_t *bus)
Release exclusive access to the bus.
Definition: bus.c:149
libheivs configuration file
struct heivs_bus_var_t * var
Definition: bus.h:97
status_e bus_write(const struct heivs_bus_t *bus, uint32_t address, const void *data, size_t len)
Write data to the bus.
Definition: bus.c:243
const struct heivs_bus_t bus_usart[BSP_USART_BUS_COUNT]
All USART busses.
Definition: stm32_usart.c:209
status_e(* _read)(const struct heivs_bus_t *, uint32_t address, uint8_t *data, size_t len, size_t *rlen)
Definition: bus.h:132
#define USE_STDIO_USART
Use this usart number for stdio redirection.
Definition: config.h:168
status_e bus_init(const struct heivs_bus_t *bus)
initialize the bus
Definition: bus.c:59
status_e bus_read(const struct heivs_bus_t *bus, uint32_t address, void *data, size_t len, size_t *rlen)
Resume the bus (from low power mode)
Definition: bus.c:198
#define USE_STDIO_AUTO_CR_BEFORE_LF
Put a CR ('') before every LF (' ') on stdout (and stderr)
Definition: config.h:244
#define USE_STDIO_ECHO
Enable echo for stdio.
Definition: config.h:227
status_e bus_get(const struct heivs_bus_t *bus)
Get exclusive access to the bus.
Definition: bus.c:134
usart bus
status_e
Known errors.
Definition: error.h:21
No error.
Definition: error.h:28
#define USE_STDIO_NOBUF
Disable stdio buffering.
Definition: config.h:199