Zenembed
403 subscribers
83 photos
1 video
40 links
Новости, обзоры и анонсы одного блогера и фрилансера.

Блог: https://zenembed.com
Фриланс: https://work.zenembed.com

Вопросы, предложения: @zenls
Download Telegram
Channel created
Наконец то свершилось. Я полностью переработал верстку блога и теперь в нем 2 языка. По умолчанию стоит английский. Я даже перевел одну статью. Переключается язык справа вверху.

Новый же канал будет посвящен анонсам новых материалов на сайте, а так-же небольшим обзорам интересных для меня вещей и новостей посвященных разработки электроники.

Следите за обновлениями, дальше точно будет что-то интересное.
🔥8
Сегодня по почте получил отладочную плату от Nuvoton c с контроллером Cortex-M23. Вероятно когда ни будь напишу про работу с данными контроллера статью в блог.

Если вы тоже хотите попробовать данную плату то можете запросить, пока это бесплатно.
🔥3
Сегодня занимался выпаиванием и тестированием вакуумно-люминесцентных индикаторов (VFD). Эти индикаторы излучают приятный синий свет и относительно легко подключаются. Для работы требуется два напряжения: 3-4 В на катод (около 150 мА) и 20-30 В на сетку и анод (менее 10 мА). Управление сегментом и сеткой осуществляется переключением 20 В. В отсутствие документации, пины определял методом перебора.

В планах создать часы с использованием этих индикаторов, так что следите за обновлениями!
🔥511
В продолжение ко вчерашнему посту.

Изначально я планировал выпаять дисплеи с помощью стола с подогревом. Однако выяснилось, что старые платы из гетинакса трескаются и лопаются при нагреве до 300 градусов. Не советую повторять мой опыт — теперь на моем нагревательном столе осталось пятно, которое я не могу оттереть. Хотя, возможно, проблема в канифоли, с помощью которой эти дисплеи были закреплены.
😁1🤯1
Вышла отладка от OLIMEX - GateMate A1-EVB.

Данная борда базируется на GateMate CCGM1A1 FPGA. Эта fpga примечательна тем, что ее разработка поддерживается немецким правительством, а тулчейн можно полностью собрать из исходного кода. Наконец то наступило будущее без жирнющих и лагучих IDE.

Про работу с открытым стеком можно почитать у меня в блоге на примере FPGA от Lattice.
Сегодня на канале всем известного Мединцева вышло новое видео — Шаблоны и код. Обработка ситуаций периферийных блоков. Сразу заспойлерю: про шаблоны не будет сказано вообще ничего.

Но я не об этом. В видео обсуждается проблема: при управлении периферией часто нужно выполнять несколько действий, и в случае, если какое-то действие не проходит, прекратить выполнение. Данная проблема иллюстрируется следующим примером:

if (HAL_SPI_Init(&hspi1) == HAL_OK)
{
if (HAL_SPI_Transmit(&hspi1, tdata, sizeof(tdata), 10) == HAL_OK)
{
if (HAL_SPI_Receive(&hspi1, rdata, sizeof(rdata), 10) == HAL_OK)
{
// xzhzxklxklkchlxzkclkzxl
}
}
}


Далее предлагается действительно уникальное решение, которого я никогда не видел раньше — использование while и break:

do
{
if (HAL_SPI_Init(&hspi1) != HAL_OK) break;
if (HAL_SPI_Transmit(&hspi1, tdata, sizeof(tdata), 10) != HAL_OK) break;
if (HAL_SPI_Receive(&hspi1, rdata, sizeof(rdata), 10) != HAL_OK) break;
// Полезное действие
}
while (0);


Мне кажется данное решение странным, и я его не буду использовать, однако на вкус и цвет.

Тогда возникает логичный вопрос: что же использовать? Ответ на этот вопрос можно найти в самом неожиданном месте — в ядре Linux. Там данная проблема успешно решается уже как 30 лет. Для единообразия предлагаю посмотреть пример с SPI и для STM32 — функцию stm32_spi_transfer_one_dma. И что же там используется? goto. Почему я считаю, что данный вариант лучше? Он по умолчанию подразумевает, что вы не просто прерываете исполнение, а можете еще и деинициализировать то, что инициализировалось правильно до ошибки. Если показать это на примере из начала, то будет выглядеть так:

if (HAL_SPI_Init(&hspi1) != HAL_OK)
goto SPI_INIT_ERROR;

if (HAL_SPI_Transmit(&hspi1, tdata, sizeof(tdata), 10) != HAL_OK)
goto SPI_TX_ERROR;

if (HAL_SPI_Receive(&hspi1, rdata, sizeof(rdata), 10) != HAL_OK)
goto SPI_RX_ERROR;

// Do something
return 0;

SPI_RX_ERROR:
SPI_TX_ERROR:
HAL_SPI_DeInit(&hspi1); // This is an example, I don't remember the exact name of the function.
SPI_INIT_ERROR:
return 1;


Обратите внимание, деинициализация будет проходить в обратном порядке относительно инициализации и ровно с того места, где возникла наша проблема. Это не единичный случай; этот паттерн используется повсеместно в ядре, в чем вы можете убедиться самостоятельно с помощью данного сервиса.

Вы можете возразить, что goto небезопасно и ненадежно, а в ядро коммитят сверхлюди, куда нам до них. Но специально для вас у данной проблемы тоже есть решение там, где его никто не ждал — ESP IDF. Опять возьмем код, связанный с SPI (хотя немного косвенно) — функцию soft_spi_transfer. Специально для удобства пользователя goto завернули в макрос ESP_GOTO_ON_FALSE.

Пара слов про вторую часть видео (я воздержусь от сомнений в чей-то адекватности). Вопрос интересный: можно ли делать бесконечную блокировку в коде? И я думаю, что да, но есть нюанс. Если мы работаем с устройством, сценарий которого подразумевает, что пользователь включает его, пользуется и выключает, я думаю, это вполне приемлемо. Мы можем проверить адекватность работы периферии один раз, когда устройство включается и собственно инициализирует эту периферию. В случае проблем в процессе работы пользователь может выключить и включить устройство и при старте увидеть сообщение о проблеме. Однако если к нашему девайсу не будет доступа и он должен работать месяцами без перезагрузки, тогда да, таймауты необходимы. Однако libopencm3 не запрещает вам сделать это самостоятельно в случае необходимости, просто сделав проверку доступности SPI до того, как что-то в него писать.
🔥62
Иногда появляется желание позаниматься какой-то ерундой, поэтому сейчас собрал счетчик рабочего времени на дисплеях DL2416T и STM32F411, да еще и на бредборде. Код выкладывать не буду потому что там трешак:


HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, 0);
HAL_Delay(500);
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, 1);
HAL_Delay(500);

sprintf(buff, "%2d-%02d-%02d", i / 3600, (i / 60) % 60, i % 60);
set_8char_display(buff);
i++;
❤‍🔥7🔥2🤩1
Компания ST добавила новую фичу в CubeMX, теперь вы можете генерировать уровень BSP для всех новых плат nucleo. О чем я хочу рассказать.

Все скрины сделаны для NUCLEO-C031C6 но я проверил это еще на 2х платах из списка.

В чем собственно суть: теперь если в CubeMX выбрать Board, а не MCU то появится менюшка как на первой картинке. Там мы можем выбрать генерировать ли демонстрационный код и переферию, для которой мы хотим уровень BSP. Если выбрать первую галочку, то получим примерно следущее:

  /* -- Sample board code to send message over COM1 port ---- */
printf("Welcome to STM32 world !\n\r");
/* -- Sample board code to switch on leds ---- */
BSP_LED_On(LED_GREEN);

while (1)
{

/* -- Sample board code for User push-button in interrupt mode ---- */
if (BspButtonState == BUTTON_PRESSED)
{
/* Update button state */
BspButtonState = BUTTON_RELEASED;
/* -- Sample board code to toggle leds ---- */
BSP_LED_Toggle(LED_GREEN);
/* ..... Perform your action ..... */
}
}


Само собой данный пример не заработал, притом не UART не кнопка, хотя-бы диод при старте загорается. (Я не стал глубоко лезть и разбираться где ошибка в генерации, не вижу в этом большого смысла, может быть когда нибудь исправят) Так-же попробовал NUCLEO-H7S3L8, на ней все сразу-же заработало.

Без выбора данной галочки будет генерирована только BSP. Но что-же это такое?

В меню с контроллером ноги задействованные для BSP будут помечены красным и не доступны для изменения, и изменение выбранной периферии тоже будет не доступно. Взглянем на получившийся код:

Drivers/BSP
└── STM32C0xx_Nucleo
├── LICENSE.txt
├── stm32c0xx_nucleo.c
├── stm32c0xx_nucleo_conf_template.h
├── stm32c0xx_nucleo_errno.h
└── stm32c0xx_nucleo.h


Хедеры .h представляют из себя набор бесконечных дефайнов, в сишном файле можно найти собственно реализацию функций BSP, например включение диода:

int32_t BSP_LED_On(Led_TypeDef Led)
{
int32_t ret = BSP_ERROR_NONE;

if (Led != LED4)
{
ret = BSP_ERROR_WRONG_PARAM;
}
else
{
HAL_GPIO_WritePin(LED_PORT[Led], LED_PIN[Led], GPIO_PIN_SET);
}

return ret;
}


Складывается ощущение что кому-то платили за количество написанных строк кода. Собственно все остальные функции примерно такие-же.

Плюсы:

- Если в самой первой менюшке убрать все галочки то все будет как раньше, однако отключить генерацию функций для занятых портов больше нельзя.
- Если выбрать генерирование BSP для serial порта то он сразу будет работать вместе с printf().

Минусы:

- Программа которая генерируется как пример. не всегда работает.
- Эта функция работает только с кнопками, светодиодами и UART (как писал выше, я проверил).
- Какое то запредельное количество новых и не очень полезных макросов и дефайнов в проекте.
- Непонятно что делать с нашим уровнем BSP (тут подразумевается что это просто пример и не нужно его использовать в своих решениях, но если мы решим что-то взять? подгонять наш код стайл под это?)
- Кнопка использует линию прерывания, что если я не хочу ее использовать?

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

#ifdef __GNUC__
int __io_putchar(int ch)
#else
int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
{
HAL_UART_Transmit(&hcom_uart [COM_ActiveLogPort], (uint8_t *) &ch, 1, COM_POLL_TIMEOUT);
return ch;
}
🔥61👍1
Википедия не перестает удивлять.

Будьте бдительны, следите за температурой процессора, превышение может привести к программным ошибкам и отключению устройства.
😁1🤯1🌭1
Кажется свершилось. Nvidia допилила поддержку вяленого на своих драйверах 555.58, так что пришло время слезать с иксов. Поддерживаются все карты начиная с GeForce 700 Series.
🔥6
Сегодня хочу рассказать вам о "Открытом курсе по схемотехнике для начинающих" от ядра. Я просмотрел первые две и последнюю лекции, и вот основные моменты, которые мне показались важными:

- Курс предназначен для новичков в схемотехнике, поэтому опытные разработчики, скорее всего, не найдут для себя ничего нового.
- В рамках курса можно получить базовые знания о пассивных компонентах и немного о цифровых схемах.
- Большое внимание уделяется тому, как физически собирать схемы на макетных платах и какие проблемы могут возникнуть при этом.
- После изучения теории сразу предлагается закрепить знания на практике.

В целом, я рекомендую посвятить несколько вечеров просмотру этого курса, если вы только начинаете осваивать схемотехнику. Если вам понравится такой формат обучения, то советую также обратить внимание на книгу с аналогичным подходом (упомянута на последнем прикрепленном изображении). В книге сделан акцент на практическую часть и сборку схем на макетных платах, при этом примеров и упражнений значительно больше.
6👍4