acc_exploration_server_stm32.c
Go to the documentation of this file.
1 // Copyright (c) Acconeer AB, 2021-2025
2 // All rights reserved
3 // This file is subject to the terms and conditions defined in the file
4 // 'LICENSES/license_acconeer.txt', (BSD 3-Clause License) which is part
5 // of this source code package.
6 
7 #include <stdarg.h>
8 #include <stdbool.h>
9 #include <stdint.h>
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include "main.h"
14 
17 #include "acc_integration.h"
18 #include "acc_integration_log.h"
19 
20 #define MODULE "exploration_server_stm32"
21 
22 #define LOG_BUFFER_MAX_SIZE 150
23 
24 #define STM32_EXPLORATION_SERVER_MAX_BAUDRATE 2000000
25 
26 extern UART_HandleTypeDef EXPLORATION_SERVER_UART_HANDLE;
27 
28 static char *command_buffer = NULL;
29 static size_t command_buffer_size = 0;
30 
31 #define UART_DMA_BUFFER_SIZE (8192)
32 
33 static volatile bool uart_tx_active = false;
35 
37 
38 static void uart_wait_for_tx_done(void)
39 {
40  while (true)
41  {
42  __disable_irq();
43  bool active = uart_tx_active;
44  __enable_irq();
45  if (active)
46  {
47  __WFI();
48  }
49  else
50  {
51  break;
52  }
53  }
54 }
55 
56 /**
57  * @brief Write data to client (UART)
58  *
59  * @param[in] data pointer to data
60  * @param[in] size data size in bytes
61  */
62 static void write_to_client_uart(const void *data, uint32_t size)
63 {
64  const uint8_t *data8 = (const uint8_t *)data;
65 
66  size_t pos = 0;
67 
68  while (pos < size)
69  {
70  /* Wait for previous transmit to be done */
72 
73  size_t this_size = ((size - pos) < UART_DMA_BUFFER_SIZE) ? (size - pos) : UART_DMA_BUFFER_SIZE;
74  memcpy(uart_dma_buffer, &data8[pos], this_size);
75 
76  uart_tx_active = true;
77  HAL_UART_Transmit_DMA(&EXPLORATION_SERVER_UART_HANDLE, uart_dma_buffer, this_size);
78  pos += this_size;
79  }
80 }
81 
82 /**
83  * @brief Restart input of new command
84  */
85 static void restart_input(void)
86 {
88 
89  /**
90  * Stop previous reception
91  * Clear buffer
92  * Re-start receive after a line has been received.
93  */
94  HAL_UART_AbortReceive(&EXPLORATION_SERVER_UART_HANDLE);
95  HAL_UART_Receive_DMA(&EXPLORATION_SERVER_UART_HANDLE, (uint8_t *)command_buffer, command_buffer_size);
96 }
97 
98 static void set_baudrate(uint32_t baudrate)
99 {
100 
101  /* Wait for previous transmit to be done before changing baudrate */
103 
104  HAL_UART_AbortReceive(&EXPLORATION_SERVER_UART_HANDLE);
105  HAL_UART_DeInit(&EXPLORATION_SERVER_UART_HANDLE);
106  EXPLORATION_SERVER_UART_HANDLE.Init.BaudRate = baudrate;
107  if (HAL_UART_Init(&EXPLORATION_SERVER_UART_HANDLE) != HAL_OK)
108  {
109  Error_Handler();
110  }
111 
112  HAL_UART_Receive_DMA(&EXPLORATION_SERVER_UART_HANDLE, (uint8_t *)command_buffer, command_buffer_size);
113 }
114 
115 static uint32_t get_tick(void)
116 {
117  return acc_integration_get_time();
118 }
119 
120 /**
121  * @brief Server interface functions
122  */
125  .restart_input = restart_input,
126  .set_baudrate = set_baudrate,
128  .get_tick = get_tick,
129  .ticks_per_second = 1000,
130 };
131 
132 void acc_exploration_server_stm32_init(const char *hw, char *buffer, size_t buffer_size)
133 {
134 
138 }
139 
141 {
142  /**
143  * The embedded exploration server for STM32 can stream UART input data
144  * directly into the input buffer.
145  *
146  * Setup DMA into buffer with buffer_size.
147  */
148  HAL_UART_Receive_DMA(&EXPLORATION_SERVER_UART_HANDLE, (uint8_t *)command_buffer, command_buffer_size);
149 
150  while (true)
151  {
152  /* Default values */
154  int32_t ticks_until_next = 0;
155 
156  if (acc_exploration_server_process(&server_if, &state, &ticks_until_next))
157  {
158  switch (state)
159  {
161  /* Stop exploration server, not implemented for this target */
162  ACC_LOG_ERROR("Exploration server command 'stop_application' not supported.");
163  __WFI();
164  break;
166  /* Idle time, just wait for next interrupt */
167  __WFI();
168  break;
170  if (ticks_until_next > 1)
171  {
172  /* More than 1 tick to sleep, wait for next interrupt (at the most 1ms away) */
173  __WFI();
174  }
175 
176  break;
177  }
178  }
179  else
180  {
181  /* Error */
182  Error_Handler();
183  }
184  }
185 }
186 
187 void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
188 {
189  if (huart == &EXPLORATION_SERVER_UART_HANDLE)
190  {
191  /* Check framing error bit to detect break condition */
192  if ((huart->ErrorCode & HAL_UART_ERROR_FE) == HAL_UART_ERROR_FE)
193  {
194  HAL_NVIC_SystemReset();
195  }
196  }
197 }
198 
199 void HAL_UART_TxCpltCallback(UART_HandleTypeDef *h_uart)
200 {
201  if (h_uart == &EXPLORATION_SERVER_UART_HANDLE)
202  {
203  uart_tx_active = false;
204  }
205 }
206 
207 void acc_integration_log(acc_log_level_t level, const char *module, const char *format, ...)
208 {
209  char log_buffer[LOG_BUFFER_MAX_SIZE];
210  va_list ap;
211 
212  va_start(ap, format);
213  int ret = vsnprintf(log_buffer, LOG_BUFFER_MAX_SIZE, format, ap);
214 
215  va_end(ap);
216 
217  if (ret >= LOG_BUFFER_MAX_SIZE)
218  {
219  log_buffer[LOG_BUFFER_MAX_SIZE - 4] = '.';
220  log_buffer[LOG_BUFFER_MAX_SIZE - 3] = '.';
221  log_buffer[LOG_BUFFER_MAX_SIZE - 2] = '.';
222  log_buffer[LOG_BUFFER_MAX_SIZE - 1] = 0;
223  }
224 
225  acc_exploration_server_send_log(server_if.write, level, module, log_buffer);
226 }
227 
228 int acconeer_main(int argc, char *argv[]);
229 
230 int acconeer_main(int argc, char *argv[])
231 {
232  (void)argc;
233  (void)argv;
234 
235  printf("Acconeer Exploration Server\n");
236 
237  // Wait for host line break to end before starting exploration server
238  while (HAL_GPIO_ReadPin(UART_RX_GPIO_Port, UART_RX_Pin) == GPIO_PIN_RESET)
239  {
240  printf("Waiting for host line break to end...\n");
241  HAL_Delay(10);
242  }
243 
244  // Clear out any pending garbage and errors on the UART line by deinit/init
245  // it again. This avoids that the HAL_UART_ErrorCallback() is called (leading
246  // to an additional reset cycle) if the RX line was previously low.
247  HAL_UART_DeInit(&EXPLORATION_SERVER_UART_HANDLE);
248  if (HAL_UART_Init(&EXPLORATION_SERVER_UART_HANDLE) != HAL_OK)
249  {
250  Error_Handler();
251  }
252 
255 
256  return 0;
257 }
ACC_EXPLORATION_SERVER_STOPPED
@ ACC_EXPLORATION_SERVER_STOPPED
Definition: acc_exploration_server_base.h:17
exploration_server_command_buffer
static char exploration_server_command_buffer[4096]
Definition: acc_exploration_server_stm32.c:36
acc_exploration_server_stm32_main
void acc_exploration_server_stm32_main(void)
Start the stm32 exploration server.
Definition: acc_exploration_server_stm32.c:140
acc_exploration_server_stm32.h
LOG_BUFFER_MAX_SIZE
#define LOG_BUFFER_MAX_SIZE
Definition: acc_exploration_server_stm32.c:22
acc_integration_get_time
uint32_t acc_integration_get_time(void)
Get current time.
Definition: acc_integration_stm32.c:587
acc_exploration_server_base.h
set_baudrate
static void set_baudrate(uint32_t baudrate)
Definition: acc_exploration_server_stm32.c:98
buffer
void * buffer
Definition: i2c_example_cargo.c:40
vsnprintf
#define vsnprintf
Definition: printf.h:85
write_to_client_uart
static void write_to_client_uart(const void *data, uint32_t size)
Write data to client (UART)
Definition: acc_exploration_server_stm32.c:62
ACC_LOG_LEVEL_INFO
@ ACC_LOG_LEVEL_INFO
Definition: acc_definitions_common.h:30
STM32_EXPLORATION_SERVER_MAX_BAUDRATE
#define STM32_EXPLORATION_SERVER_MAX_BAUDRATE
Definition: acc_exploration_server_stm32.c:24
UART_RX_GPIO_Port
#define UART_RX_GPIO_Port
Definition: main.h:81
exploration_server_interface_t
Struct to handle input for acc_exploration_server_process_cmds.
Definition: acc_exploration_server_base.h:46
HAL_UART_TxCpltCallback
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *h_uart)
Definition: acc_exploration_server_stm32.c:199
acc_integration.h
ACC_LOG_ERROR
#define ACC_LOG_ERROR(...)
Definition: acc_integration_log.h:16
acc_exploration_server_stm32_init
void acc_exploration_server_stm32_init(const char *hw, char *buffer, size_t buffer_size)
Init the stm32 exploration server.
Definition: acc_exploration_server_stm32.c:132
acc_log_level_t
acc_log_level_t
This enum represents the different log levels for RSS.
Definition: acc_definitions_common.h:23
buffer_size
uint32_t buffer_size
Definition: i2c_example_cargo.c:41
acc_exploration_server_init
bool acc_exploration_server_init(char *buffer, size_t buffer_size, const char *hw, acc_log_level_t log_level)
Initialize the exploration server.
server_if
static const exploration_server_interface_t server_if
Server interface functions.
Definition: acc_exploration_server_stm32.c:123
uart_dma_buffer
static uint8_t uart_dma_buffer[(8192)]
Definition: acc_exploration_server_stm32.c:34
ACC_EXPLORATION_SERVER_STREAMING
@ ACC_EXPLORATION_SERVER_STREAMING
Definition: acc_exploration_server_base.h:16
acc_exploration_server_state_t
acc_exploration_server_state_t
Definition: acc_exploration_server_base.h:13
get_tick
static uint32_t get_tick(void)
Definition: acc_exploration_server_stm32.c:115
printf
#define printf
Definition: printf.h:60
uart_tx_active
static volatile bool uart_tx_active
Definition: acc_exploration_server_stm32.c:33
ACC_EXPLORATION_SERVER_WAITING
@ ACC_EXPLORATION_SERVER_WAITING
Definition: acc_exploration_server_base.h:15
uart_wait_for_tx_done
static void uart_wait_for_tx_done(void)
Definition: acc_exploration_server_stm32.c:38
EXPLORATION_SERVER_UART_HANDLE
UART_HandleTypeDef EXPLORATION_SERVER_UART_HANDLE
UART_DMA_BUFFER_SIZE
#define UART_DMA_BUFFER_SIZE
Definition: acc_exploration_server_stm32.c:31
acconeer_main
int acconeer_main(int argc, char *argv[])
Assembly test example.
Definition: acc_exploration_server_stm32.c:230
acc_exploration_server_send_log
bool acc_exploration_server_send_log(write_data_function_t write_func, acc_log_level_t level, const char *module, const char *buffer)
Sends a log as a json package.
acc_integration_log.h
HAL_UART_ErrorCallback
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
Definition: acc_exploration_server_stm32.c:187
main.h
: Header for main.c file. This file contains the common defines of the application.
Error_Handler
void Error_Handler(void)
command_buffer_size
static size_t command_buffer_size
Definition: acc_exploration_server_stm32.c:29
exploration_server_interface_t::write
write_data_function_t * write
Definition: acc_exploration_server_base.h:48
command_buffer
static char * command_buffer
Definition: acc_exploration_server_stm32.c:28
acc_exploration_server_process
bool acc_exploration_server_process(const exploration_server_interface_t *server_if, acc_exploration_server_state_t *state, int32_t *ticks_until_next)
The exploration server process function.
restart_input
static void restart_input(void)
Restart input of new command.
Definition: acc_exploration_server_stm32.c:85
acc_integration_log
void acc_integration_log(acc_log_level_t level, const char *module, const char *format,...)
Log function.
Definition: acc_exploration_server_stm32.c:207
UART_RX_Pin
#define UART_RX_Pin
Definition: main.h:80