DIY Logging Volt/Ampmeter
usart.c
Go to the documentation of this file.
1 /***************************************************************************//**
2  * @file usart.c
3  * @brief U(S)ART functionality for high-precision logging voltage/current meter.
4  * @version 1.1
5  * @author Brecht Van Eeckhoudt
6  *
7  * ******************************************************************************
8  *
9  * @section Versions
10  *
11  * @li v1.0: Initial version.
12  * @li v1.1: Compared floats more reliably (and faster?) and implemented data-check to hopefully fix max/min logic.
13  *
14  * ******************************************************************************
15  *
16  * @todo
17  * **Future improvements:**@n
18  * - Add overflow catch if data.voltage/current are negative values?
19  * - `data.current > 9.9999`, `data.voltage > 99.999` (these checks are as of v1.1 of this file unnecessary...)
20  * - Increase baudrate for USART2/3 communication?
21  * - Add separate USART1 handler? (`USART_HandleContinuousReception();`)
22  * - Check if we really did receive the openLog startup-message `12<`.
23  *
24  * ******************************************************************************
25  *
26  * @section License
27  *
28  * **Copyright (C) 2021 - Brecht Van Eeckhoudt**
29  *
30  * This program is free software: you can redistribute it and/or modify
31  * it under the terms of the **GNU General Public License** as published by
32  * the Free Software Foundation, either **version 3** of the License, or
33  * (at your option) any later version.
34  *
35  * This program is distributed in the hope that it will be useful,
36  * but WITHOUT ANY WARRANTY; without even the implied warranty of
37  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38  * GNU General Public License for more details.
39  *
40  * *A copy of the GNU General Public License can be found in the `LICENSE`
41  * file along with this source code.*
42  *
43  * @n
44  *
45  * Some methods also use code obtained from examples from STMicroelectronics.
46  *
47  * @li https://github.com/STMicroelectronics/STM32CubeF1/tree/master/Projects/STM32F103RB-Nucleo/Examples_LL/USART/USART_Communication_Rx_IT_Continuous
48  *
49  * **Copyright (c) 2020 STMicroelectronics. All rights reserved.**
50  *
51  * These sections are licensed by ST under BSD 3-Clause license, the "License";
52  * One may not use these example files except in compliance with the License.
53  * One may obtain a copy of the License at: opensource.org/licenses/BSD-3-Clause
54  *
55  ******************************************************************************/
56 
57 
58 #include "usart.h" /* Include corresponding header file */
59 
60 #include <stdint.h> /* (u)intXX_t */
61 #include "stm32f1xx_ll_bus.h" /* Low-Level Clock Management */
62 #include "stm32f1xx_ll_gpio.h" /* Low-Level General Purpose IO (GPIO) peripheral API */
63 #include "stm32f1xx_ll_usart.h" /* Low-Level Universal synchr./asynchr. receiver/transmitter (USART/UART) Peripheral API */
64 #include "SEGGER_RTT.h" /* Segger RTT functionality (debugging) */
65 
66 #include "util.h" /* Utility functionality */
67 #include "main.h" /* Pin mapping */
68 #include "conversion.h" /* Conversion and settings */
69 
70 
71 /* Local definitions */
72 #define RX_BUFFER_SIZE 8
73 #define RX_BUFFER_SIZE_UART1 3
74 #define BAUDRATE_METER 9600 /* Baudrate of volt/currentmeter */
75 #define BAUDRATE_LOGGER 115200 /* Baudrate of external datalogger */
76 
77 
78 /* Local variables */
79 
80 /* USART1 RX buffers for storing received data */
87 
88 /* USART2 RX buffers for storing received data */
95 
96 /* USART3 RX buffers for storing received data */
103 
104 
105 /* Local prototypes */
106 // None
107 
108 
109 /**************************************************************************//**
110  * @brief
111  * This function monitors USART1/2/3 buffer filling indication and
112  * moves data around accordingly.
113  *****************************************************************************/
115 {
116  /* Checks if USART1 Buffer full indication has been set */
118  {
119  /* Call user Callback in charge of consuming data from filled USART2 buffer */
120  SEGGER_RTT_printf(0, "Current USART1 RX buffer full: [%s], Reception will go on in alternate buffer.\n\r", pBufferReadyForUser_USART1);
121 
122  /* Signal logic that the logger has correctly started up */
123  settings.loggerReady = 1;
124 
125  /* Reset USART1 indication */
127  }
128 
129  /* Checks if USART2 Buffer full indication has been set */
131  {
132  /** Format of the data coming from the meters:
133  * - Byte 0 = 0xFA
134  * - Byte 1 = 0xFB
135  * - Byte 2 = Device address (default: 0x00)
136  * - Byte 3 - 6 = Measurement (~float value)
137  * - Byte 7 = CRC check (SUM of bytes 3 - 6)
138  */
139 
141 
142  /* Only use the bytes if the data is valid */
143  if ((pBufferReadyForUser_USART2[0] == 0xFA) && (pBufferReadyForUser_USART2[1] == 0xFB) && (pBufferReadyForUser_USART2[7] == checksum))
144  {
146 
147  if (data.voltage < 99.999) /* Meter reads max 50V ... */
148  {
149  /* Convert floats to uint16_t (voltage has 3 decimal places: *1000) */
150  uint16_t oldVolt = FLOAT_TO_INT(data.oldVolt*1000);
151  uint16_t voltage = FLOAT_TO_INT(data.voltage*1000);
152  uint16_t minVoltage = FLOAT_TO_INT(data.minVoltage*1000);
153  uint16_t maxVoltage = FLOAT_TO_INT(data.maxVoltage*1000);
154 
155  if (oldVolt != voltage)
156  {
158  data.newVolt = 1;
159  }
160 
161  /* Update min/max fields if necessary */
162  if (voltage < minVoltage)
163  {
165  data.newMinVolt = 1;
166  }
167  else if (data.firstVolt)
168  {
170  data.newMinVolt = 1;
171  data.firstVolt = 0;
172  }
173 
174  if (voltage > maxVoltage)
175  {
177  data.newMaxVolt = 1;
178  }
179 
180  data.voltReceived = 1;
181  }
182  }
183 
184  /* Reset USART2 indication */
186 
187  }
188 
189  /* Checks if USART3 Buffer full indication has been set */
191  {
192  /** Format of the data coming from the meters:
193  * - Byte 0 = 0xFA
194  * - Byte 1 = 0xFB
195  * - Byte 2 = Device address (default: 0x00)
196  * - Byte 3 - 6 = Measurement (~float value)
197  * - Byte 7 = CRC check (SUM of bytes 3 - 6)
198  */
199 
201 
202  /* Only use the bytes if the data is valid */
203  if ((pBufferReadyForUser_USART3[0] == 0xFA) && (pBufferReadyForUser_USART3[1] == 0xFB) && (pBufferReadyForUser_USART3[7] == checksum))
204  {
206 
207  if (data.current < 9.9999) /* Meter reads max 5A ... */
208  {
209  /* Convert floats to uint16_t (current has 4 decimal places: *10000) */
210  uint16_t oldCurr = FLOAT_TO_INT(data.oldCurr*10000);
211  uint16_t current = FLOAT_TO_INT(data.current*10000);
212  uint16_t minCurrent = FLOAT_TO_INT(data.minCurrent*10000);
213  uint16_t maxCurrent = FLOAT_TO_INT(data.maxCurrent*10000);
214 
215  if (oldCurr != current)
216  {
218  data.newCurr = 1;
219  }
220 
221  /* Update min/max fields if necessary */
222  if (current < minCurrent)
223  {
225  data.newMinCurr = 1;
226  }
227  else if (data.firstCurr)
228  {
230  data.newMinCurr = 1;
231  data.firstCurr = 0;
232  }
233 
234  if (current > maxCurrent)
235  {
237  data.newMaxCurr = 1;
238  }
239 
240  data.currReceived = 1;
241  }
242  }
243 
244  /* Reset USART3indication */
246  }
247 
248  /* Set values if the voltmeter is powered down */
249  if (!LL_GPIO_IsInputPinSet(V_ENin_GPIO_Port, V_ENin_Pin))
250  {
251  data.voltage = 0.0;
252 
253  /* Convert floats to uint16_t (voltage has 3 decimal places: *1000) */
254  uint16_t oldVolt = FLOAT_TO_INT(data.oldVolt*1000);
255  uint16_t voltage = FLOAT_TO_INT(data.voltage*1000);
256 
257  if (oldVolt != voltage)
258  {
260  data.newVolt = 1;
261  }
262 
263  data.voltReceived = 1;
264  }
265 
266  /* Set values if the current meter is powered down */
267  if (!LL_GPIO_IsInputPinSet(A_ENin_GPIO_Port, A_ENin_Pin))
268  {
269  data.current = 0.0;
270 
271  /* Convert floats to uint16_t (current has 4 decimal places: *10000) */
272  uint16_t oldCurr = FLOAT_TO_INT(data.oldCurr*10000);
273  uint16_t current = FLOAT_TO_INT(data.current*10000);
274 
275  if (oldCurr != current)
276  {
278  data.newCurr = 1;
279  }
280 
281  data.currReceived = 1;
282  }
283 }
284 
285 
286 /**************************************************************************//**
287  * @brief
288  * Send a byte (`uint8_t`) command to USART2.
289  *
290  * @details
291  * This method also resets `uwNbReceivedChars_USART2` just in case.
292  *
293  * @param[in] command
294  * Pointer to the byte-array containing the commands.
295  *
296  * @param[in] bytes
297  * Amount of bytes to send.
298  *****************************************************************************/
299 void USART2_SendCommand(uint8_t *command, uint8_t bytes)
300 {
301  /* Send characters one per one, until last char to be sent */
302  for (uint32_t index = 0; index < bytes; index++)
303  {
304  /* Wait for TXE flag to be raised */
305  while (!LL_USART_IsActiveFlag_TXE(USART2));
306 
307  /* Write character in Transmit Data register.
308  TXE flag is cleared by writing data in DR register */
309  LL_USART_TransmitData8(USART2, command[index]);
310  }
311 
312  /* Wait for TC flag to be raised for last char */
313  while (!LL_USART_IsActiveFlag_TC(USART2));
314 
315  /* Reset buffer mechanism */
317 // uwBufferReadyIndication_USART2 = 0; // TODO Maybe use this when using contiuous output?
318 }
319 
320 
321 /**************************************************************************//**
322  * @brief
323  * Send a byte (`uint8_t`) command to USART3.
324  *
325  * @details
326  * This method also resets `uwNbReceivedChars_USART3` just in case.
327  *
328  * @param[in] command
329  * Pointer to the byte-array containing the commands.
330  *
331  * @param[in] bytes
332  * Amount of bytes to send.
333  *****************************************************************************/
334 void USART3_SendCommand(uint8_t *command, uint8_t bytes)
335 {
336  /* Send characters one per one, until last char to be sent */
337  for (uint32_t index = 0; index < bytes; index++)
338  {
339  /* Wait for TXE flag to be raised */
340  while (!LL_USART_IsActiveFlag_TXE(USART3));
341 
342  /* Write character in Transmit Data register.
343  TXE flag is cleared by writing data in DR register */
344  LL_USART_TransmitData8(USART3, command[index]);
345  }
346 
347  /* Wait for TC flag to be raised for last char */
348  while (!LL_USART_IsActiveFlag_TC(USART3));
349 
350  /* Reset buffer mechanism */
352 // uwBufferReadyIndication_USART3 = 0; // TODO Maybe use this when using contiuous output?
353 }
354 
355 
356 /**************************************************************************//**
357  * @brief
358  * USART1 Initialization Function.
359  *
360  * @details
361  * @li Baudrate = BAUDRATE_LOGGER
362  * @li PA9 = USART1_TX
363  * @li PA10 = USART1_RX
364  *****************************************************************************/
365 void USART1_INIT(void)
366 {
367  LL_USART_InitTypeDef USART_InitStruct = {0};
368  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
369 
370  /* Peripheral clock enable */
371  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
372  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
373 
374  /**USART1 GPIO Configuration
375  PA9 ------> USART1_TX
376  PA10 ------> USART1_RX
377  */
378  GPIO_InitStruct.Pin = LL_GPIO_PIN_9;
379  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
380  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
381  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
382  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
383 
384  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
385  GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
386  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
387 
388  /* USART1 interrupt Init */
391 
392  /* UART1 Configuration */
393  USART_InitStruct.BaudRate = BAUDRATE_LOGGER;
394  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
395  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
396  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
397  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
398  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
399  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
400  LL_USART_Init(USART1, &USART_InitStruct);
401  LL_USART_ConfigAsyncMode(USART1);
402  LL_USART_Enable(USART1);
403 
404  /* Initiate buffer mechanism */
409 
410  /* Clear Overrun flag, in case characters have already been sent to USART */
411  LL_USART_ClearFlag_ORE(USART1);
412 
413  /* Enable RXNE and Error interrupts */
414  LL_USART_EnableIT_RXNE(USART1);
415  LL_USART_EnableIT_ERROR(USART1);
416 }
417 
418 
419 /**************************************************************************//**
420  * @brief
421  * USART2 Initialization Function.
422  *
423  * @details
424  * @li Baudrate = BAUDRATE_METER
425  * @li PA2 = USART2_TX
426  * @li PA3 = USART2_RX
427  *****************************************************************************/
428 void USART2_INIT(void)
429 {
430  LL_USART_InitTypeDef USART_InitStruct = {0};
431  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
432 
433  /* Peripheral clock enable */
434  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART2);
435  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
436 
437  /**USART2 GPIO Configuration
438  PA2 ------> USART2_TX
439  PA3 ------> USART2_RX
440  */
441  GPIO_InitStruct.Pin = LL_GPIO_PIN_2;
442  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
443  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
444  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
445  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
446 
447  GPIO_InitStruct.Pin = LL_GPIO_PIN_3;
448  GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
449  LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
450 
451  /* USART2 interrupt Init */
454 
455  /* UART2 Configuration */
456  USART_InitStruct.BaudRate = BAUDRATE_METER;
457  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
458  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
459  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
460  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
461  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
462  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
463  LL_USART_Init(USART2, &USART_InitStruct);
464  LL_USART_ConfigAsyncMode(USART2);
465  LL_USART_Enable(USART2);
466 
467  /* Initiate buffer mechanism */
472 
473  /* Clear Overrun flag, in case characters have already been sent to USART */
474  LL_USART_ClearFlag_ORE(USART2);
475 
476  /* Enable RXNE and Error interrupts */
477  LL_USART_EnableIT_RXNE(USART2);
478  LL_USART_EnableIT_ERROR(USART2);
479 }
480 
481 
482 /**************************************************************************//**
483  * @brief
484  * USART3 Initialization Function.
485  *
486  * @details
487  * @li Baudrate = BAUDRATE_METER
488  * @li PB10 = USART3_TX
489  * @li PB11 = USART3_RX
490  *****************************************************************************/
491 void USART3_INIT(void)
492 {
493  LL_USART_InitTypeDef USART_InitStruct = {0};
494  LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
495 
496  /* Peripheral clock enable */
497  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USART3);
498  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
499 
500  /**USART3 GPIO Configuration
501  PB10 ------> USART3_TX
502  PB11 ------> USART3_RX
503  */
504  GPIO_InitStruct.Pin = LL_GPIO_PIN_10;
505  GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
506  GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_HIGH;
507  GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
508  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
509 
510  GPIO_InitStruct.Pin = LL_GPIO_PIN_11;
511  GPIO_InitStruct.Mode = LL_GPIO_MODE_FLOATING;
512  LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
513 
514  /* USART3 interrupt Init */
517 
518  /* UART3 Configuration */
519  USART_InitStruct.BaudRate = BAUDRATE_METER;
520  USART_InitStruct.DataWidth = LL_USART_DATAWIDTH_8B;
521  USART_InitStruct.StopBits = LL_USART_STOPBITS_1;
522  USART_InitStruct.Parity = LL_USART_PARITY_NONE;
523  USART_InitStruct.TransferDirection = LL_USART_DIRECTION_TX_RX;
524  USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE;
525  USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16;
526  LL_USART_Init(USART3, &USART_InitStruct);
527  LL_USART_ConfigAsyncMode(USART3);
528  LL_USART_Enable(USART3);
529 
530  /* Initiate buffer mechanism */
535 
536  /* Clear Overrun flag, in case characters have already been sent to USART */
537  LL_USART_ClearFlag_ORE(USART3);
538 
539  /* Enable RXNE and Error interrupts */
540  LL_USART_EnableIT_RXNE(USART3);
541  LL_USART_EnableIT_ERROR(USART3);
542 }
543 
544 
545 /**************************************************************************//**
546  * @brief
547  * Print a string (char array) to USARTx.
548  *
549  * @note
550  * If the input is not a string (ex.: `"Hello world!"`) but a char array,
551  * the input message (array) needs to end with NULL (`"\0"`)!
552  *
553  * @param[in] message
554  * The string to print to USARTx.
555  *****************************************************************************/
556 void USART1_print(char *message)
557 {
558  /* "message[i] != 0" makes "uint32_t length = strlen(message)"
559  * not necessary (given string MUST be terminated by NULL for this to work) */
560  for (uint32_t i = 0; message[i] != 0; i++)
561  {
562  /* Wait for TXE flag to be raised */
563  while (!LL_USART_IsActiveFlag_TXE(USART1));
564 
565  /* Write character in Transmit Data register.
566  TXE flag is cleared by writing data in DR register */
567  LL_USART_TransmitData8(USART1, message[i]);
568  }
569 }
570 
571 
572 /**************************************************************************//**
573  * @brief
574  * Print a string (char array) to USART1.
575  *
576  * @param[in] string
577  * The string to print to USART1.
578  *
579  * @param[in] size
580  * Length of the string in bytes.
581  *****************************************************************************/
582 //void USART1_SendData(char *string, uint32_t size)
583 //{
584 // uint32_t index = 0;
585 // char *pchar = string;
586 //
587 // /* Send characters one per one, until last char to be sent */
588 // for (index = 0; index < size; index++)
589 // {
590 // /* Wait for TXE flag to be raised */
591 // while (!LL_USART_IsActiveFlag_TXE(USART1));
592 //
593 // /* Write character in Transmit Data register.
594 // TXE flag is cleared by writing data in DR register */
595 // LL_USART_TransmitData8(USART1, *pchar++);
596 // }
597 //
598 // /* Wait for TC flag to be raised for last char */
599 // while (!LL_USART_IsActiveFlag_TC(USART1));
600 //}
601 
602 
603 /**************************************************************************//**
604  * @brief
605  * Print a string (char array) to USART2.
606  *
607  * @param[in] string
608  * The string to print to USART2.
609  *
610  * @param[in] size
611  * Length of the string in bytes.
612  *****************************************************************************/
613 //void USART2_SendData(uint8_t *string, uint32_t size)
614 //{
615 // uint32_t index = 0;
616 // uint8_t *pchar = string;
617 //
618 // /* Send characters one per one, until last char to be sent */
619 // for (index = 0; index < size; index++)
620 // {
621 // /* Wait for TXE flag to be raised */
622 // while (!LL_USART_IsActiveFlag_TXE(USART2));
623 //
624 // /* Write character in Transmit Data register.
625 // TXE flag is cleared by writing data in DR register */
626 // LL_USART_TransmitData8(USART2, *pchar++);
627 // }
628 //
629 // /* Wait for TC flag to be raised for last char */
630 // while (!LL_USART_IsActiveFlag_TC(USART2));
631 //}
632 
633 
634 /**************************************************************************//**
635  * @brief
636  * Print a string (char array) to USART3.
637  *
638  * @param[in] string
639  * The string to print to USART3.
640  *
641  * @param[in] size
642  * Length of the string in bytes.
643  *****************************************************************************/
644 //void USART3_SendData(uint8_t *string, uint32_t size)
645 //{
646 // uint32_t index = 0;
647 // uint8_t *pchar = string;
648 //
649 // /* Send characters one per one, until last char to be sent */
650 // for (index = 0; index < size; index++)
651 // {
652 // /* Wait for TXE flag to be raised */
653 // while (!LL_USART_IsActiveFlag_TXE(USART3));
654 //
655 // /* Write character in Transmit Data register.
656 // TXE flag is cleared by writing data in DR register */
657 // LL_USART_TransmitData8(USART3, *pchar++);
658 // }
659 //
660 // /* Wait for TC flag to be raised for last char */
661 // while (!LL_USART_IsActiveFlag_TC(USART3));
662 //}
663 
664 
665 /**************************************************************************//**
666  * @brief
667  * Function called from USART1 IRQ Handler when RXNE flag is set. @n
668  * Function is in charge of reading character received on USART1 RX line.
669  *****************************************************************************/
671 {
672  uint8_t *ptemp;
673 
674  /* Read Received character. RXNE flag is cleared by reading of DR register */
676 
677  /* Checks if Buffer full indication has been set */
679  {
680  /* Set Buffer swap indication */
682 
683  /* Swap buffers for next bytes to be received */
688  }
689 }
690 
691 
692 /**************************************************************************//**
693  * @brief
694  * Function called from USART2 IRQ Handler when RXNE flag is set. @n
695  * Function is in charge of reading character received on USART2 RX line.
696  *****************************************************************************/
698 {
699  uint8_t *ptemp;
700 
701  /* Read Received character. RXNE flag is cleared by reading of DR register */
703 
704  /* Checks if Buffer full indication has been set */
706  {
707  /* Set Buffer swap indication */
709 
710  /* Swap buffers for next bytes to be received */
715  }
716 }
717 
718 
719 /**************************************************************************//**
720  * @brief
721  * Function called from USART3 IRQ Handler when RXNE flag is set. @n
722  * Function is in charge of reading character received on USART3 RX line.
723  *****************************************************************************/
725 {
726  uint8_t *ptemp;
727 
728  /* Read Received character. RXNE flag is cleared by reading of DR register */
730 
731  /* Checks if Buffer full indication has been set */
733  {
734  /* Set Buffer swap indication */
736 
737  /* Swap buffers for next bytes to be received */
742  }
743 }
744 
745 
746 /**************************************************************************//**
747  * @brief
748  * Function called in case of error detected in USART1 IT Handler.
749  *****************************************************************************/
751 {
752  __IO uint32_t sr_reg;
753 
754  /* Disable USART1_IRQn */
756 
757  /* Error handling example :
758  - Read USART SR register to identify flag that leads to IT raising
759  - Perform corresponding error handling treatment according to flag
760  */
761  sr_reg = LL_USART_ReadReg(USART1, SR);
762  if (sr_reg & LL_USART_SR_NE)
763  {
764  /* case Noise Error flag is raised : Clear NF Flag */
765  LL_USART_ClearFlag_NE(USART1);
766  }
767  else
768  {
769  SEGGER_RTT_WriteString(0, RTT_CTRL_TEXT_BRIGHT_RED"Error: "RTT_CTRL_RESET"USART1_Error_Callback\n\r");
770  while(1);
771  }
772 }
773 
774 
775 /**************************************************************************//**
776  * @brief
777  * Function called in case of error detected in USART2 IT Handler.
778  *****************************************************************************/
780 {
781  __IO uint32_t sr_reg;
782 
783  /* Disable USART2_IRQn */
785 
786  /* Error handling example :
787  - Read USART SR register to identify flag that leads to IT raising
788  - Perform corresponding error handling treatment according to flag
789  */
790  sr_reg = LL_USART_ReadReg(USART2, SR);
791  if (sr_reg & LL_USART_SR_NE)
792  {
793  /* case Noise Error flag is raised : Clear NF Flag */
794  LL_USART_ClearFlag_NE(USART2);
795  }
796  else
797  {
798  SEGGER_RTT_WriteString(0, RTT_CTRL_TEXT_BRIGHT_RED"Error: "RTT_CTRL_RESET"USART2_Error_Callback\n\r");
799  while(1);
800  }
801 }
802 
803 
804 /**************************************************************************//**
805  * @brief
806  * Function called in case of error detected in USART3 IT Handler.
807  *****************************************************************************/
809 {
810  __IO uint32_t sr_reg;
811 
812  /* Disable USART3_IRQn */
814 
815  /* Error handling example :
816  - Read USART SR register to identify flag that leads to IT raising
817  - Perform corresponding error handling treatment according to flag
818  */
819  sr_reg = LL_USART_ReadReg(USART3, SR);
820  if (sr_reg & LL_USART_SR_NE)
821  {
822  /* case Noise Error flag is raised : Clear NF Flag */
823  LL_USART_ClearFlag_NE(USART3);
824  }
825  else
826  {
827  SEGGER_RTT_WriteString(0, RTT_CTRL_TEXT_BRIGHT_RED"Error: "RTT_CTRL_RESET"USART3_Error_Callback\n\r");
828  while(1);
829  }
830 }
pBufferReadyForUser_USART1
uint8_t * pBufferReadyForUser_USART1
Definition: usart.c:85
uwBufferReadyIndication_USART3
__IO uint32_t uwBufferReadyIndication_USART3
Definition: usart.c:100
Data_t::oldVolt
float oldVolt
Definition: conversion.h:55
USART2_SendCommand
void USART2_SendCommand(uint8_t *command, uint8_t bytes)
Send a byte (uint8_t) command to USART2.
Definition: usart.c:299
BAUDRATE_METER
#define BAUDRATE_METER
Definition: usart.c:74
settings
struct Settings_t settings
NVIC_GetPriorityGrouping
#define NVIC_GetPriorityGrouping
Definition: core_armv8mbl.h:1189
Data_t::current
float current
Definition: conversion.h:64
USART2
#define USART2
Definition: stm32f103xb.h:655
USART2_INIT
void USART2_INIT(void)
USART2 Initialization Function.
Definition: usart.c:428
USART2_CharReception_Callback
void USART2_CharReception_Callback(void)
Function called from USART2 IRQ Handler when RXNE flag is set. Function is in charge of reading cha...
Definition: usart.c:697
aRXBufferB_USART1
uint8_t aRXBufferB_USART1[3]
Definition: usart.c:82
uwNbReceivedChars_USART3
__IO uint32_t uwNbReceivedChars_USART3
Definition: usart.c:99
uwBufferReadyIndication_USART2
__IO uint32_t uwBufferReadyIndication_USART2
Definition: usart.c:92
Data_t::newMaxVolt
uint8_t newMaxVolt
Definition: conversion.h:61
USART3_CharReception_Callback
void USART3_CharReception_Callback(void)
Function called from USART3 IRQ Handler when RXNE flag is set. Function is in charge of reading cha...
Definition: usart.c:724
aRXBufferB_USART3
uint8_t aRXBufferB_USART3[8]
Definition: usart.c:98
Data_t::maxCurrent
float maxCurrent
Definition: conversion.h:70
Data_t::maxVoltage
float maxVoltage
Definition: conversion.h:60
RX_BUFFER_SIZE_UART1
#define RX_BUFFER_SIZE_UART1
Definition: usart.c:73
USART3
#define USART3
Definition: stm32f103xb.h:656
V_ENin_GPIO_Port
#define V_ENin_GPIO_Port
Definition: main.h:117
uwBufferReadyIndication_USART1
__IO uint32_t uwBufferReadyIndication_USART1
Definition: usart.c:84
NVIC_EncodePriority
__STATIC_INLINE uint32_t NVIC_EncodePriority(uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority)
Encode Priority.
Definition: core_armv8mbl.h:1496
USART3_SendCommand
void USART3_SendCommand(uint8_t *command, uint8_t bytes)
Send a byte (uint8_t) command to USART3.
Definition: usart.c:334
data
struct Data_t data
USART1_print
void USART1_print(char *message)
Print a string (char array) to USARTx.
Definition: usart.c:556
Settings_t::loggerReady
volatile uint8_t loggerReady
Definition: conversion.h:167
Data_t::newMinVolt
uint8_t newMinVolt
Definition: conversion.h:59
Data_t::currReceived
uint8_t currReceived
Definition: conversion.h:63
stm32f1xx_ll_gpio.h
Header file of GPIO LL module.
stm32f1xx_ll_bus.h
Header file of BUS LL module.
RTT_CTRL_TEXT_BRIGHT_RED
#define RTT_CTRL_TEXT_BRIGHT_RED
Definition: SEGGER_RTT.h:385
uwNbReceivedChars_USART1
__IO uint32_t uwNbReceivedChars_USART1
Definition: usart.c:83
USART3_IRQn
@ USART3_IRQn
Definition: stm32f103xb.h:122
Data_t::voltage
float voltage
Definition: conversion.h:54
Data_t::newVolt
uint8_t newVolt
Definition: conversion.h:57
USART2_Error_Callback
void USART2_Error_Callback(void)
Function called in case of error detected in USART2 IT Handler.
Definition: usart.c:779
GPIOA
#define GPIOA
Definition: stm32f103xb.h:665
bytes_to_float
float bytes_to_float(uint8_t byte0, uint8_t byte1, uint8_t byte2, uint8_t byte3)
Convert four bytes into a float.
Definition: util.c:72
aRXBufferB_USART2
uint8_t aRXBufferB_USART2[8]
Definition: usart.c:90
pBufferReadyForUser_USART2
uint8_t * pBufferReadyForUser_USART2
Definition: usart.c:93
Data_t::newMinCurr
uint8_t newMinCurr
Definition: conversion.h:69
aRXBufferA_USART3
uint8_t aRXBufferA_USART3[8]
Definition: usart.c:97
USART1_INIT
void USART1_INIT(void)
USART1 Initialization Function.
Definition: usart.c:365
stm32f1xx_ll_usart.h
Header file of USART LL module.
usart.h
U(S)ART functionality for high-precision logging voltage/current meter.
aRXBufferA_USART2
uint8_t aRXBufferA_USART2[8]
Definition: usart.c:89
USART_HandleContinuousReception
void USART_HandleContinuousReception(void)
This function monitors USART1/2/3 buffer filling indication and moves data around accordingly.
Definition: usart.c:114
Data_t::newCurr
uint8_t newCurr
Definition: conversion.h:67
RTT_CTRL_RESET
#define RTT_CTRL_RESET
Definition: SEGGER_RTT.h:372
uwNbReceivedChars_USART2
__IO uint32_t uwNbReceivedChars_USART2
Definition: usart.c:91
A_ENin_Pin
#define A_ENin_Pin
Definition: main.h:118
USART1_IRQn
@ USART1_IRQn
Definition: stm32f103xb.h:120
Data_t::firstVolt
uint8_t firstVolt
Definition: conversion.h:56
SEGGER_RTT_WriteString
unsigned SEGGER_RTT_WriteString(unsigned BufferIndex, const char *s)
Definition: SEGGER_RTT.c:1215
Data_t::minVoltage
float minVoltage
Definition: conversion.h:58
conversion.h
Conversion and settings-related methods and structs for high-precision logging voltage/current meter.
NVIC_DisableIRQ
#define NVIC_DisableIRQ
Definition: core_armv8mbl.h:1192
Data_t::newMaxCurr
uint8_t newMaxCurr
Definition: conversion.h:71
aRXBufferA_USART1
uint8_t aRXBufferA_USART1[3]
Definition: usart.c:81
USART3_Error_Callback
void USART3_Error_Callback(void)
Function called in case of error detected in USART3 IT Handler.
Definition: usart.c:808
GPIOB
#define GPIOB
Definition: stm32f103xb.h:666
Data_t::voltReceived
uint8_t voltReceived
Definition: conversion.h:53
__IO
#define __IO
Definition: core_armv8mbl.h:196
NVIC_SetPriority
#define NVIC_SetPriority
Definition: core_armv8mbl.h:1197
Data_t::firstCurr
uint8_t firstCurr
Definition: conversion.h:66
USART1
#define USART1
Definition: stm32f103xb.h:675
Data_t::minCurrent
float minCurrent
Definition: conversion.h:68
main.h
Main header-file for the high-precision logging voltage/current meter project.
BAUDRATE_LOGGER
#define BAUDRATE_LOGGER
Definition: usart.c:75
V_ENin_Pin
#define V_ENin_Pin
Definition: main.h:116
A_ENin_GPIO_Port
#define A_ENin_GPIO_Port
Definition: main.h:119
RX_BUFFER_SIZE
#define RX_BUFFER_SIZE
Definition: usart.c:72
NVIC_EnableIRQ
#define NVIC_EnableIRQ
Definition: core_armv8mbl.h:1190
Data_t::oldCurr
float oldCurr
Definition: conversion.h:65
USART1_Error_Callback
void USART1_Error_Callback(void)
Function called in case of error detected in USART1 IT Handler.
Definition: usart.c:750
SEGGER_RTT_printf
int SEGGER_RTT_printf(unsigned BufferIndex, const char *sFormat,...)
Definition: SEGGER_RTT_printf.c:491
FLOAT_TO_INT
#define FLOAT_TO_INT(x)
Definition: conversion.h:48
SEGGER_RTT.h
pBufferReadyForUser_USART3
uint8_t * pBufferReadyForUser_USART3
Definition: usart.c:101
USART3_INIT
void USART3_INIT(void)
USART3 Initialization Function.
Definition: usart.c:491
pBufferReadyForReception_USART3
uint8_t * pBufferReadyForReception_USART3
Definition: usart.c:102
USART2_IRQn
@ USART2_IRQn
Definition: stm32f103xb.h:121
pBufferReadyForReception_USART1
uint8_t * pBufferReadyForReception_USART1
Definition: usart.c:86
util.h
Utility functionality for high-precision logging voltage/current meter.
pBufferReadyForReception_USART2
uint8_t * pBufferReadyForReception_USART2
Definition: usart.c:94
USART1_CharReception_Callback
void USART1_CharReception_Callback(void)
Print a string (char array) to USART1.
Definition: usart.c:670