Нашёл ответ на свой вопрос. I2C на плате сделан программный..
Всем привет.
Занимаюсь реализацией TUI через UART на STM32F1xx с HAL. Описание функциональности:
- Неблокирующий ввод
- Завершение ввода при нажатии Enter
- При нажатии на Backspace предыдущий символ удаляется (при наличии)
- Видимые символы отображаются
Вывод также хочется реализовать через прерывания, если вызов функции был сделан не из обработчика другого прерывания (в таком случае реализуется блокирующий вывод).
При написании кода использую кольцевой буфер (ring/circular buffer) для хранения строк. Он представляет из себя отдельную библиотеку.
Вот код проекта:
static UART_HandleTypeDef *console_uart = NULL;
static char line_buffer[CONSOLE_MAX_RX_DATA_LENGTH];
static uint16_t line_len = 0;
// TX Buffer
static ring_buffer_t tx_buffer;
static volatile uint8_t tx_busy = 0;
static volatile uint8_t tx_byte;
// RX Buffer
static ring_buffer_t rx_buffer;
static volatile uint8_t rx_byte;
static volatile uint8_t rx_ready = 0;
static void console_rx_callback(UART_HandleTypeDef *);
static void console_tx_callback(UART_HandleTypeDef *);
uint8_t console_init(UART_HandleTypeDef *huart) {
if (huart == NULL || console_uart != NULL) {
return 1;
}
console_uart = huart;
ring_buffer_init(&tx_buffer);
tx_busy = 0;
ring_buffer_init(&rx_buffer);
rx_ready = 0;
HAL_UART_RegisterCallback(
console_uart,
HAL_UART_RX_COMPLETE_CB_ID,
console_rx_callback
);
HAL_UART_RegisterCallback(
console_uart,
HAL_UART_TX_COMPLETE_CB_ID,
console_tx_callback
);
HAL_UART_Receive_IT(console_uart, (uint8_t *) &rx_byte, 1);
return 0;
}
void console_print(const char *str) {
HAL_UART_Transmit(console_uart, (uint8_t *) str, strlen(str), 10);
// ring_buffer_write(&tx_buffer, (uint8_t *) str, strlen(str));
// if (tx_busy == 0) {
// tx_busy = 1;
// tx_byte = ring_buffer_pop(&tx_buffer);
// HAL_UART_Transmit_IT(console_uart, &tx_byte, 1);
// }
}
void console_clear() {
console_print("\033[2J\033[H");
}
// Берет на себя всю обработку символов: backspace, enter и echo
void console_poll() {
while (ring_buffer_get_length(&rx_buffer) > 0 && rx_ready == 0) {
uint8_t ch = ring_buffer_pop(&rx_buffer);
if ((ch == '\b' || ch == 0x7F) && line_len > 0) {
line_len--;
console_print("\b \b");
}
else if (ch == '\r' || ch == '\n') {
line_buffer[line_len] = '\0';
rx_ready = 1;
console_print("\r\n");
return;
}
else if (line_len < CONSOLE_MAX_RX_DATA_LENGTH - 1) {
line_buffer[line_len++] = ch;
char echo[2] = {ch, 0};
console_print(echo);
}
}
}
uint8_t console_ready() {
return rx_ready;
}
void console_read(char *buffer) {
if (buffer == NULL || rx_ready == 0) {
return;
}
strcpy(buffer, line_buffer);
rx_ready = 0;
line_len = 0;
line_buffer[0] = '\0';
}
static void console_tx_callback(UART_HandleTypeDef *console) {
if (ring_buffer_get_length(&tx_buffer) == 0) {
tx_busy = 0;
}
else {
tx_byte = ring_buffer_pop(&tx_buffer);
HAL_UART_Transmit_IT(console_uart, &tx_byte, 1);
}
}
static void console_rx_callback(UART_HandleTypeDef *console) {
ring_buffer_push(&rx_buffer, rx_byte);
HAL_UART_Receive_IT(console_uart, &rx_byte, 1);
}
Использование в приложении примерно такое:
while(1) {
console_poll();
if (console_ready()) {
console_read(consoleBuffer);
// Действия с console buffer
}
}
При подключении через утилиту screen на скорости 115200 выводит следующее (вводил просто '?'):
Rebooeot system ?. menu cm>> Unknoan oy en symenu cm
То есть вывод максимально ломаный.
Знающие люди, подскажите, пожалуйста, что не так с этим кодом и в чем именно проблема. Нейронки не помогают, а в DMA сейчас не планирую лезть - хочу сперва разобраться с прерываниями.
Благодарю за любую помощь, спасибо!
Доброго времени суток!
Контроллер STM32H743
Из-за больших накладных расходов быстродействия вынужден перейти с библиотек HAL на прямую работу с регистрами. На HAL всё работает нормально. Настройки SPI оставил от HAL.
Столкнулся с проблемой.
Код прост как мычание:
uint8_t Data = 0xAA;
SPI4->TXDR = Data; // Запись байта в регистр данных
while(((SPI4->SR) & SPI_SR_EOT) != SPI_SR_EOT){}; // Ожидание завершения передачи
Проблема в том, что программа не выходит из цикла ожидания конца передачи. Подозреваю, что передача данных и не начиналась.
Возможно ещё что-то надо настроить для корректной работы SPI. Подскажите, где я ошибся?
@asdal Приветствую!
Нужно полный код инициализации посмотреть.
Либо, попробуй по-быстрому заменить проверку флага SPI_SR_EOT на SPI_SR_TXC.
@asdal Приветствую!
Нужно полный код инициализации посмотреть.
Либо, попробуй по-быстрому заменить проверку флага SPI_SR_EOT на SPI_SR_TXC.
Код инициализации я не писал, решил, что настройки от HAL сгодятся. Там то всё работает.
А флага SPI_SR_TXC в743-м вообще нет. Компилятор ошибку даёт.
Скинь плз весь проект на почту, если есть возможность, я завтра с ПК посмотрю.