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