2 #include <twr_scheduler.h>
3 #include <twr_system.h>
6 static void _twr_atci_uart_active_test(
void);
7 static void _twr_atci_uart_active_test_task(
void *param);
12 size_t commands_length;
17 uint8_t read_fifo_buffer[128];
21 bool (*uart_active_callback)(void);
29 memset(&_twr_atci, 0,
sizeof(_twr_atci));
31 _twr_atci.commands = commands;
33 _twr_atci.commands_length = length;
35 _twr_atci.rx_length = 0;
37 _twr_atci.rx_error =
false;
39 _twr_atci.write_response =
true;
41 twr_fifo_init(&_twr_atci.read_fifo, _twr_atci.read_fifo_buffer,
sizeof(_twr_atci.read_fifo_buffer));
53 size_t len =
twr_uart_write(TWR_ATCI_UART, message, strlen(message));
57 static size_t _twr_atci_printf(
const char *format, va_list ap,
size_t maxlen)
59 size_t length = vsnprintf(_twr_atci.tx_buffer, maxlen, format, ap);
61 if (length > maxlen) {
78 size_t length = _twr_atci_printf(format, ap,
sizeof(_twr_atci.tx_buffer));
94 size_t length = _twr_atci_printf(format, ap,
sizeof(_twr_atci.tx_buffer) - 2);
97 _twr_atci.tx_buffer[length++] =
'\r';
98 _twr_atci.tx_buffer[length++] =
'\n';
100 return twr_uart_write(TWR_ATCI_UART, _twr_atci.tx_buffer, length);
105 if (!_twr_atci.ready)
113 for (
size_t i = 0; i < length; i++)
115 byte = ((
char *)buffer)[i];
117 char upper = (
byte >> 4) & 0xf;
118 char lower =
byte & 0x0f;
120 _twr_atci.tx_buffer[on_write++] = upper < 10 ? upper +
'0' : upper - 10 +
'A';
121 _twr_atci.tx_buffer[on_write++] = lower < 10 ? lower +
'0' : lower - 10 +
'A';
124 return twr_uart_write(TWR_ATCI_UART, _twr_atci.tx_buffer, on_write);
129 _twr_atci.write_response =
false;
146 for (
size_t i = 0; i < _twr_atci.commands_length; i++)
155 for (
size_t i = 0; i < _twr_atci.commands_length; i++)
157 twr_atci_printfln(
"AT%s %s", _twr_atci.commands[i].command, _twr_atci.commands[i].hint);
162 static bool _twr_atci_process_line(
void)
164 if (_twr_atci.rx_length < 2 || _twr_atci.rx_buffer[0] !=
'A' || _twr_atci.rx_buffer[1] !=
'T')
169 if (_twr_atci.rx_length == 2)
174 _twr_atci.rx_buffer[_twr_atci.rx_length] = 0;
176 char *line = _twr_atci.rx_buffer + 2;
178 size_t length = _twr_atci.rx_length - 2;
184 for (
size_t i = 0; i < _twr_atci.commands_length; i++)
186 command = _twr_atci.commands + i;
188 command_len = strlen(command->command);
190 if (length < command_len)
195 if (strncmp(line, command->command, command_len) != 0)
200 if (command_len == length)
202 if (command->action != NULL)
204 return command->action();
207 else if (line[command_len] ==
'=')
209 if ((line[command_len + 1]) ==
'?' && (command_len + 2 == length))
211 if (command->help != NULL)
213 return command->help();
217 if (command->set != NULL)
220 .txt = line + command_len + 1,
221 .length = length - command_len - 1,
225 return command->set(¶m);
228 else if (line[command_len] ==
'?' && command_len + 1 == length)
230 if (command->read != NULL)
232 return command->read();
246 static void _twr_atci_process_character(
char character)
248 if (character ==
'\n')
250 if (!_twr_atci.rx_error && _twr_atci.rx_length > 0)
252 bool response = _twr_atci_process_line();
254 if (_twr_atci.write_response)
267 _twr_atci.write_response =
true;
270 else if (_twr_atci.rx_error)
275 _twr_atci.rx_length = 0;
276 _twr_atci.rx_error =
false;
278 else if (character ==
'\r')
282 else if (character ==
'\x1b')
284 _twr_atci.rx_length = 0;
285 _twr_atci.rx_error =
false;
287 else if (_twr_atci.rx_length ==
sizeof(_twr_atci.rx_buffer) - 1)
289 _twr_atci.rx_error =
true;
291 else if (!_twr_atci.rx_error)
293 _twr_atci.rx_buffer[_twr_atci.rx_length++] = character;
306 static uint8_t buffer[16];
315 for (
size_t i = 0; i < length; i++)
317 _twr_atci_process_character((
char) buffer[i]);
329 while (param->offset < param->length)
331 c = param->txt[param->offset];
355 if (((param->length - param->offset) < 2) || (length < 1) || (str == NULL))
360 if (param->txt[param->offset++] !=
'"')
368 for (i = 0; (i < length) && (param->offset < param->length); i++)
370 c = param->txt[param->offset++];
379 if ((c <
' ') || (c ==
',') || (c >
'~'))
392 if (((param->length - param->offset) < 2) || (*length < 1) || (buffer == NULL))
397 if (param->txt[param->offset++] !=
'"')
404 size_t max_i = *length * 2;
408 for (i = 0; (i < max_i) && (param->offset < param->length); i++)
410 c = param->txt[param->offset++];
419 if ((c >=
'0') && (c <=
'9'))
423 else if ((c >=
'A') && (c <=
'F'))
427 else if ((c >=
'a') && (c <=
'f'))
443 ((uint8_t *) buffer)[l] = temp << 4;
447 ((uint8_t *) buffer)[l++] |= temp;
456 return param->txt[param->offset++] ==
',';
461 return param->txt[param->offset++] ==
'"';
466 _twr_atci.uart_active_callback = callback;
467 _twr_atci.scan_interval = scan_interval;
469 if (callback == NULL)
471 if (_twr_atci.vbus_sense_test_task_id)
475 _twr_atci.vbus_sense_test_task_id = 0;
480 if (_twr_atci.vbus_sense_test_task_id == 0)
482 _twr_atci.vbus_sense_test_task_id =
twr_scheduler_register(_twr_atci_uart_active_test_task, NULL, scan_interval);
486 _twr_atci_uart_active_test();
489 static void _twr_atci_uart_active_test(
void)
491 if ((_twr_atci.uart_active_callback == NULL) || _twr_atci.uart_active_callback())
493 if (!_twr_atci.ready)
503 _twr_atci.ready =
true;
512 _twr_atci.ready =
false;
519 static void _twr_atci_uart_active_test_task(
void *param)
523 _twr_atci_uart_active_test();
bool twr_atci_get_buffer_from_hex_string(twr_atci_param_t *param, void *buffer, size_t *length)
Decode HEX string to buffer and move parsing cursor forward.
bool twr_atci_skip_response(void)
Skip response, use in callback in twr_atci_command_t.
bool twr_atci_is_comma(twr_atci_param_t *param)
Check if the character at cursor is comma.
size_t twr_atci_printf(const char *format,...)
Prinf message.
bool twr_atci_clac_action(void)
Helper for clac action.
bool twr_atci_help_action(void)
Helper for help action.
bool twr_atci_is_quotation_mark(twr_atci_param_t *param)
Check if the character at cursor is quotation mark (")
size_t twr_atci_print(const char *message)
Print message.
void twr_atci_write_error(void)
Write ERROR.
bool twr_atci_get_uint(twr_atci_param_t *param, uint32_t *value)
Parse string to uint and move parsing cursor forward.
void twr_atci_init(const twr_atci_command_t *commands, int length)
Initialize.
bool twr_atci_get_string(twr_atci_param_t *param, char *str, size_t length)
Copy string and move parsing cursor forward.
void twr_atci_write_ok(void)
Write OK.
size_t twr_atci_print_buffer_as_hex(const void *buffer, size_t length)
Print buffer as HEX string.
size_t twr_atci_println(const char *message)
Print message and add CR LF.
void twr_atci_set_uart_active_callback(bool(*callback)(void), twr_tick_t scan_interval)
Set callback function for scan if uart is active. Used for low-power when USB is disconnected (defaul...
size_t twr_atci_printfln(const char *format,...)
Prinf message and add CR LF.
void twr_fifo_init(twr_fifo_t *fifo, void *buffer, size_t size)
Initialize FIFO buffer.
void twr_scheduler_plan_current_relative(twr_tick_t tick)
Schedule current task to tick relative from current spin.
void twr_scheduler_unregister(twr_scheduler_task_id_t task_id)
Unregister specified task.
size_t twr_scheduler_task_id_t
Task ID assigned by scheduler.
twr_scheduler_task_id_t twr_scheduler_register(void(*task)(void *), void *param, twr_tick_t tick)
Register task in scheduler.
uint64_t twr_tick_t
Timestamp data type.
twr_uart_channel_t
UART channels.
void twr_uart_init(twr_uart_channel_t channel, twr_uart_baudrate_t baudrate, twr_uart_setting_t setting)
Initialize UART channel.
void twr_uart_set_async_fifo(twr_uart_channel_t channel, twr_fifo_t *write_fifo, twr_fifo_t *read_fifo)
Set buffers for async transfers.
size_t twr_uart_write(twr_uart_channel_t channel, const void *buffer, size_t length)
Write data to UART channel (blocking call)
bool twr_uart_async_read_start(twr_uart_channel_t channel, twr_tick_t timeout)
Start async reading.
twr_uart_event_t
Callback events.
void twr_uart_set_event_handler(twr_uart_channel_t channel, void(*event_handler)(twr_uart_channel_t, twr_uart_event_t, void *), void *event_param)
Set callback function.
size_t twr_uart_async_read(twr_uart_channel_t channel, void *buffer, size_t length)
Get data that has been received in async mode.
void twr_uart_deinit(twr_uart_channel_t channel)
Deinitialize UART channel.
@ TWR_UART_EVENT_ASYNC_READ_DATA
Event is reading done.
@ TWR_UART_BAUDRATE_115200
UART baudrat 115200 bps.
@ TWR_UART_SETTING_8N1
8N1: 8 data bits, none parity bit, 1 stop bit
Structure of FIFO instance.