электроника сәнгате
658 subscribers
658 photos
72 videos
56 files
330 links
сәлам дуслар! здесь схемотехника, pcb дизайн, микроконтроллеры, линукс встроенный и десктопный
Download Telegram
Какое-то время назад возникла задача читать логи U-Boot с проца rk3399 на одноплатнике ROCK Pi 4. Как оказалось бодрейт у debug порта достаточно нестандартный - 1.5Mbps, что не каждый USB-UART конвертер способен поддерживать, поэтому пришла идея создать свой конвертер на самой обычной отладочной плате NUCLEO-F429ZI у которой из коробки usb и конечно же USART :) (еще бы его не было). Ссылка на статью от rockpi

В общем хочу поделиться с вами этим проектом, тк считаю его достаточно полезным, чтобы вы не тратили свои деньги в чип-дип (или ждали долго с Китая), а также могли легко настроить нужный вам бодрейт.

Первая моя версия проекта лежит на гитхабе и она просто ужасна, я вызывал блокирующие функции USB стека в прерывании (это как минимимум). Всё работало, но здесь я с вами поделюсь как сделать это более правильно. В целом могу себя оправдать, что та версия была написана за пару часов, мне важно было быстро получить доступ к логам бутлоадера.

Первым делом настраиваем периферию UART, USB_DEVICE в режиме CDC (Communication Device Class), Таймер на 5-8 Гц и DMA на прием UART.
Включаем всё что нужно и прерывания тоже:
USART2->CR3 |= USART_CR3_DMAR;

TIM7->CR1 |= TIM_CR1_CEN;
TIM7->DIER |= TIM_DIER_UIE;

DMA1_Stream5->M0AR = uart_rx_buffer;
DMA1_Stream5->PAR = &(USART2->DR);
DMA1_Stream5->NDTR = UART_BUF_SIZE;
DMA1_Stream5->CR |= DMA_SxCR_HTIE | DMA_SxCR_TCIE | DMA_SxCR_EN;

Следующие переменные используются в прерываниях, поэтому важно задать им volatile, дабы избежать оптимизаций компилятора, которые могут игнорировать изменения в контексте прерываний.
uint8_t uart_rx_buffer[UART_BUF_SIZE];
volatile uint32_t uart_rx_head = 0; // Указатель на начало данных в кольцевом буффере
volatile uint32_t uart_rx_tail = 0; // Указатель на конец данных в кольцевом буффере

volatile uint8_t data_ready_flag = 0; //флаг что данные готовы к обработке

Обработчик прерывания DMA
void DMA1_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
if (DMA1->HISR & DMA_HISR_TCIF5) { // Прерывание DMA, что произошло полное копирование данных
DMA1->HIFCR = DMA_HIFCR_CTCIF5;
uart_rx_head = (uart_rx_head + UART_BUF_SIZE / 2) % UART_BUF_SIZE; // Обновляем указатель
data_ready_flag = 1;
}
if (DMA1->HISR & DMA_HISR_HTIF5) { // Прерывание DMA, что половина данных была положена в буффер
DMA1->HIFCR = DMA_HIFCR_CHTIF5;
uart_rx_head = (uart_rx_head + UART_BUF_SIZE / 2) % UART_BUF_SIZE;
data_ready_flag = 1;

}
/* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */

/* USER CODE END DMA1_Stream5_IRQn 1 */
}

Обработчик прерывания таймера, который нужен чтобы обрабатывать и отправлять оставшиеся в буффере данные.
void TIM7_IRQHandler(void)
{
/* USER CODE BEGIN TIM7_IRQn 0 */
__HAL_TIM_CLEAR_IT(&htim7, TIM_IT_UPDATE);
data_ready_flag = 1;
/* USER CODE END TIM7_IRQn 0 */
HAL_TIM_IRQHandler(&htim7);
/* USER CODE BEGIN TIM7_IRQn 1 */

/* USER CODE END TIM7_IRQn 1 */
}

Теперь напишем функцию отправки данных по usb для main цикла
👏3
void Process_UART_Data(void)
{
static uint8_t temp_buffer[UART_BUF_SIZE];
uint32_t data_length = 0;

if (data_ready_flag) {
data_ready_flag = 0;

// Выключаем прерывания, чтобы безопасно получить доступ к данным в буффере (так мы заверяем себя, что отправим актуальные данные)
__disable_irq();

// Рассчет количества байт для отправки
if (uart_rx_head >= uart_rx_tail) {
data_length = uart_rx_head - uart_rx_tail;
} else {
data_length = (UART_BUF_SIZE - uart_rx_tail) + uart_rx_head;
}

// Копируем данные во временный буффер
for (uint32_t i = 0; i < data_length; i++) {
temp_buffer[i] = uart_rx_buffer[(uart_rx_tail + i) % UART_BUF_SIZE];
}

// Обновим указатель на конец данных
uart_rx_tail = (uart_rx_tail + data_length) % UART_BUF_SIZE;

__enable_irq(); // Включаем прерывания

// Отправляем данные с помощью функции USB CDC
if (data_length > 0) {
uint8_t result = CDC_Transmit_FS(temp_buffer, data_length);
if (result != USBD_OK) {
Error_Handler(); // Затычка
}
}
}
}


Также могу описать как принимать и обрабатывать данные, т.к. в том же U-Boot можно вводить терминальные команды, а их соответственно нужно передавать через наш USB-UART конвертер. Но это уже если вам интересно :)
👍2
Media is too big
VIEW IN TELEGRAM
Explaining Docker in 60 seconds.

К сожалению, без аудиодорожки, но субтитры всё дублируют.
1
Forwarded from Господа Топологи (P|3O)
Когда все разумные решения исчерпаны в процессе отладки:
- Прошивка глючит!
- С прошивкой все в порядке, дело в аппаратной части!
А где-то в углу тихо плачет руководитель проекта... 😅
Forwarded from SCILab (NW)
Новое видео на канале.
Интерфейс CAN. Что нужно знать для использования и разработки. Практический пример кода.
Первоначально ролик создавался для слушателей нашей программы обучения как дополнительный материал с которого можно начинать освоение шины CAN.


Платформа - https://plvideo.ru/watch?v=X4OxNF_5q4S8

YouTube - https://youtu.be/xkZ5sTRkfzU

RuTube - https://rutube.ru/video/private/125bd75b80197e83aba8de4468f46555/?p=-rP4I_Pu4t95oBL_r_O42w
👍2
На одном из разобранных вейпов нашел решение которым не могу не поделиться.

Если делать платы 0.7mm - прямо на них можно рисовать USB-C разьем.

JLcPcb предлагает по умолчанию 1.6mm, а ближайшие толщины к целевой 0.6 и 0.8. Наверно это плата 0.6, а сверху ещё маска добавляет сотку.
🔥74
Вера не вывезла тарантиновский диалог, поэтому в пору обратиться к уважаемым подписчикам.

Ищу проектную работу, предпочтительно трассировка плат на микроконтроллерах. В целом могу брать любые задачи по схемотехнике/топологии средней сложности, включая силовые и ВЧ-тракты.

Могу так же в задачи организационного характера, такие как ведение библиотек, перевод ваших проектов в свободное ПО и тд.
Altium / KiCad.

А, еще для работы в РФ у меня открыта самозанятость, для работы в других странах так же проконсультирую по белым способам оплаты.
🔥8
Forwarded from Limowski' Precious Little Life (Limows 0xDD)
😁7
Forwarded from shelly
Creature
6