ARMEBS4  revision-26.06.2015
stm32_usart.c
Go to the documentation of this file.
1 /**
2  * \file heivs/stm32_usart.c
3  * \brief usart bus
4  * \author marc dot pignat at hevs dot ch
5  */
6 
7 #include "heivs/stm32_usart.h"
8 #include "heivs/time.h"
9 #include "heivs/bsp.h"
10 #include "stm32/stm32f4xx_usart.h"
11 #include "stm32/stm32f4xx_rcc.h"
12 
13 static status_e init(const struct heivs_bus_t *bus)
14 {
15  struct usart_bus_private_t *usart = (struct usart_bus_private_t*)bus->priv;
16  USART_InitTypeDef USART_InitStruct;
17  status_e status;
18 
19  status = gpio_setup_list(usart->gpios, ARRAY_SIZE(usart->gpios));
20  if (status != NO_ERROR)
21  {
22  return status;
23  }
24 
25  switch ((uint32_t)usart->ctrl)
26  {
27  case (uint32_t)USART1:
28  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
29  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, ENABLE);
30  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART1, DISABLE);
31  break;
32  case (uint32_t)USART2:
33  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
34  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, ENABLE);
35  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART2, DISABLE);
36  break;
37  case (uint32_t)USART3:
38  RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
39  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, ENABLE);
40  RCC_APB1PeriphResetCmd(RCC_APB1Periph_USART3, DISABLE);
41  break;
42  case (uint32_t)UART4:
43  RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);
44  RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, ENABLE);
45  RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART4, DISABLE);
46  break;
47  case (uint32_t)UART5:
48  RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
49  RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, ENABLE);
50  RCC_APB1PeriphResetCmd(RCC_APB1Periph_UART5, DISABLE);
51  break;
52  case (uint32_t)USART6:
53  RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART6, ENABLE);
54  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, ENABLE);
55  RCC_APB2PeriphResetCmd(RCC_APB2Periph_USART6, DISABLE);
56  break;
57  }
58 
59  USART_InitStruct.USART_BaudRate = usart->speed;
60  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
61  USART_InitStruct.USART_StopBits = USART_StopBits_1;
62  USART_InitStruct.USART_Parity = USART_Parity_No;
63  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
64  USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
65  USART_Init(usart->ctrl, &USART_InitStruct);
66  USART_Cmd(usart->ctrl, ENABLE);
67 
68  return NO_ERROR;
69 }
70 
71 static status_e suspend(const struct heivs_bus_t *bus)
72 {
73  (void)bus;
74  return ERROR_NOT_YET_IMPLEMENTED;
75 }
76 
77 static status_e read(const struct heivs_bus_t *bus, uint32_t address, uint8_t *data, size_t len, size_t *rlen)
78 {
79  struct usart_bus_private_t *usart = (struct usart_bus_private_t*)bus->priv;
80  size_t i;
81 
82  (void)address;
83 
84  *rlen = 0;
85  for (i = 0 ; i < len ; i++)
86  {
87  timeout_t timeout = time_set_timeout_ms(100);
88  while (!(usart->ctrl->SR & USART_SR_RXNE))
89  {
90  if (time_elapsed(timeout))
91  {
92  return ERROR_TIMEOUT;
93  }
94  }
95  data[i] = usart->ctrl->DR;
96  *rlen = *rlen + 1;
97  }
98 
99  return NO_ERROR;
100 }
101 
102 static status_e write(const struct heivs_bus_t *bus, uint32_t address, const uint8_t *data, size_t len)
103 {
104  struct usart_bus_private_t *usart = (struct usart_bus_private_t*)bus->priv;
105 
106  size_t i;
107 
108  (void)address;
109 
110  for (i = 0 ; i < len ; i++)
111  {
112  timeout_t timeout = time_set_timeout_ms((10*1000/usart->speed)+1);
113  while (!(usart->ctrl->SR & USART_SR_TC))
114  {
115  if (time_elapsed(timeout))
116  {
117  return ERROR_TIMEOUT;
118  }
119  }
120  usart->ctrl->DR = data[i];
121  }
122  return NO_ERROR;
123 }
124 
125 static status_e writeread(const struct heivs_bus_t *bus, uint32_t address, const uint8_t *src, size_t src_len, uint8_t *dst, size_t dst_len, size_t *rlen)
126 {
127  (void)bus;
128  (void)address;
129  (void)src;
130  (void)src_len;
131  (void)dst;
132  (void)dst_len;
133  (void)rlen;
134  return ERROR_NOT_SUPPORTED;
135 }
136 
137 static const struct usart_bus_private_t bus_priv[BSP_USART_BUS_COUNT] =
138 {
139 #if BSP_USART_BUS_COUNT > 0
140  {
141  .ctrl = BSP_USART_BUS0_CTRL,
142  .gpios =
143  {
144  BSP_USART_BUS0_GPIO_TX,
145  BSP_USART_BUS0_GPIO_RX,
146  },
147  .speed = BSP_USART_BUS0_SPEED,
148  },
149 #endif
150 #if BSP_USART_BUS_COUNT > 1
151  {
152  .ctrl = BSP_USART_BUS1_CTRL,
153  .gpios =
154  {
155  BSP_USART_BUS1_GPIO_TX,
156  BSP_USART_BUS1_GPIO_RX,
157  },
158  .speed = BSP_USART_BUS1_SPEED,
159  },
160 #endif
161 #if BSP_USART_BUS_COUNT > 2
162  {
163  .ctrl = BSP_USART_BUS2_CTRL,
164  .gpios =
165  {
166  BSP_USART_BUS2_GPIO_TX,
167  BSP_USART_BUS2_GPIO_RX,
168  },
169  .speed = BSP_USART_BUS2_SPEED,
170  },
171 #endif
172 #if BSP_USART_BUS_COUNT > 3
173  {
174  .ctrl = BSP_USART_BUS3_CTRL,
175  .gpios =
176  {
177  BSP_USART_BUS3_GPIO_TX,
178  BSP_USART_BUS3_GPIO_RX,
179  },
180  .speed = BSP_USART_BUS3_SPEED,
181  },
182 #endif
183 #if BSP_USART_BUS_COUNT > 4
184  {
185  .ctrl = BSP_USART_BUS4_CTRL,
186  .gpios =
187  {
188  BSP_USART_BUS4_GPIO_TX,
189  BSP_USART_BUS4_GPIO_RX,
190  },
191  .speed = BSP_USART_BUS4_SPEED,
192  },
193 #endif
194 #if BSP_USART_BUS_COUNT > 5
195  {
196  .ctrl = BSP_USART_BUS5_CTRL,
197  .gpios =
198  {
199  BSP_USART_BUS5_GPIO_TX,
200  BSP_USART_BUS5_GPIO_RX,
201  },
202  .speed = BSP_USART_BUS5_SPEED,
203  },
204 #endif
205 };
206 
207 static struct heivs_bus_var_t bus_var[BSP_USART_BUS_COUNT];
208 
210 {
211  #ifndef BSP_USART_BUS0_NAME
212  #define BSP_USART_BUS0_NAME "bus_usart[0]"
213  #endif
214 #if BSP_USART_BUS_COUNT > 0
215  {
216  .name = BSP_USART_BUS0_NAME,
217  .priv = &bus_priv[0],
218  .var = &bus_var[0],
219 
220  ._init = init,
221  ._read = read,
222  ._write = write,
223  ._suspend = suspend,
224  ._writeread = writeread,
225  },
226 #endif
227 #if BSP_USART_BUS_COUNT > 1
228  #ifndef BSP_USART_BUS1_NAME
229  #define BSP_USART_BUS1_NAME "bus_usart[1]"
230  #endif
231  {
232  .name = BSP_USART_BUS1_NAME,
233  .priv = &bus_priv[1],
234  .var = &bus_var[1],
235 
236  ._init = init,
237  ._read = read,
238  ._write = write,
239  ._suspend = suspend,
240  ._writeread = writeread,
241  },
242 #endif
243 #if BSP_USART_BUS_COUNT > 2
244  #ifndef BSP_USART_BUS2_NAME
245  #define BSP_USART_BUS2_NAME "bus_usart[2]"
246  #endif
247  {
248  .name = BSP_USART_BUS2_NAME,
249  .priv = &bus_priv[2],
250  .var = &bus_var[2],
251 
252  ._init = init,
253  ._read = read,
254  ._write = write,
255  ._suspend = suspend,
256  ._writeread = writeread,
257  },
258 #endif
259 #if BSP_USART_BUS_COUNT > 3
260  #ifndef BSP_USART_BUS3_NAME
261  #define BSP_USART_BUS3_NAME "bus_usart[3]"
262  #endif
263  {
264  .name = BSP_USART_BUS3_NAME,
265  .priv = &bus_priv[3],
266  .var = &bus_var[3],
267 
268  ._init = init,
269  ._read = read,
270  ._write = write,
271  ._suspend = suspend,
272  ._writeread = writeread,
273  },
274 #endif
275 #if BSP_USART_BUS_COUNT > 4
276  #ifndef BSP_USART_BUS4_NAME
277  #define BSP_USART_BUS4_NAME "bus_usart[4]"
278  #endif
279  {
280  .name = BSP_USART_BUS4_NAME,
281  .priv = &bus_priv[4],
282  .var = &bus_var[4],
283 
284  ._init = init,
285  ._read = read,
286  ._write = write,
287  ._suspend = suspend,
288  ._writeread = writeread,
289  },
290 #endif
291 #if BSP_USART_BUS_COUNT > 5
292  #ifndef BSP_USART_BUS5_NAME
293  #define BSP_USART_BUS5_NAME "bus_usart[5]"
294  #endif
295  {
296  .name = BSP_USART_BUS5_NAME,
297  .priv = &bus_priv[5],
298  .var = &bus_var[5],
299 
300  .init = init,
301  ._read = read,
302  ._write = write,
303  ._suspend = suspend,
304  ._writeread = writeread,
305  },
306 #endif
307 #if BSP_USART_BUS_COUNT > 6
308  #error this CPU has no 7 usart buses
309 #endif
310 };
311 
This file contains all the functions prototypes for the RCC firmware library.
__IO uint16_t DR
Definition: stm32f4xx.h:910
No comment.
Definition: error.h:64
Bus handler.
Definition: bus.h:92
uint32_t speed
Baudrate.
Definition: stm32_usart.h:28
const char * name
Definition: bus.h:102
const void * priv
Definition: bus.h:107
BSP - Board Support Package.
ssize_t read(int fd, void *buf, size_t count)
simple time abstraction
Variable part of the bus description.
Definition: bus.h:79
static uint32_t time_elapsed(timeout_t timeout)
Is this time passed?
Definition: time.h:71
USART_TypeDef * ctrl
Controller.
Definition: stm32_usart.h:26
const struct heivs_bus_t bus_usart[BSP_USART_BUS_COUNT]
All USART busses.
Definition: stm32_usart.c:209
Function is not available.
Definition: error.h:65
This file contains all the functions prototypes for the USART firmware library.
#define USART_SR_TC
Definition: stm32f4xx.h:6357
USART specific data.
Definition: stm32_usart.h:24
#define USART_SR_RXNE
Definition: stm32f4xx.h:6356
__IO uint16_t SR
Definition: stm32f4xx.h:908
Timeout structure.
Definition: time.h:34
const struct gpio_t gpios[2]
Gpios.
Definition: stm32_usart.h:27
ssize_t write(int fd, const void *buf, size_t count)
usart bus
timeout_t time_set_timeout_ms(uint32_t ms)
Set an obscure time at least ms milliseconds in the future.
Definition: time.c:15
status_e gpio_setup_list(const struct gpio_t gpio[], size_t len)
Setup an array of gpio.
Definition: stm32_gpio.c:47
status_e
Known errors.
Definition: error.h:21
#define ARRAY_SIZE(x)
Number of elements in the array.
Definition: utils.h:19
No error.
Definition: error.h:28
#define BSP_USART_BUS_COUNT
Usart buses count.
Definition: bsp_armebs4.h:47
USART Init Structure definition.