20 Commits

Author SHA1 Message Date
a5e46d4627 Расширить обмен по шинам, CAN-адаптеры и обработку графиков
Добавить очереди операций PBUS/SBUS, общую консоль, настройки Candle и SLCAN, декодеры DSView и обработку плотных графиков. Обновить протокол Бальзам и проверки общих компонентов.
2026-10-17 14:36:14 +03:00
95c8b8ac7d Поддержать компактные записи логгера УМП v4
Разрешить 12-словные записи в запросах RTU и CAN. Распознавать статус v4 и декодировать оставшиеся сигналы с сохранением поддержки архивов v2/v3.
2026-10-12 12:26:37 +03:00
bbb4bc2b9d Уточнить обработку плотных трендов и восстановление сигналов 2026-10-12 00:48:15 +03:00
20454ff7fa Добавить поддержку GAS 167 и УМП, улучшить обмен по CAN и последовательному порту 2026-10-11 21:23:21 +03:00
3c0f6fd9e6 Добавить загрузку F28335 по ProtoCAN и сервисные команды клиента 2026-10-11 03:24:44 +03:00
f1a7bcd8bc Support shared serial ports and optional verification in TMS flashing 2026-10-09 16:41:47 +03:00
86ece3ea90 Extract reusable byte work panel with configurable terminal addressing 2026-10-09 08:56:16 +03:00
fe9b5a246e Checkpoint EEPROM, firmware analysis and instrument protocol updates 2026-10-08 21:51:44 +03:00
b0c0c05cfa Add shared PySetTerminal with asynchronous cancellable macros 2026-10-08 18:34:41 +03:00
c011c2957b Track completed Single acquisitions and persist recent addresses 2026-10-07 12:32:29 +03:00
6047ceac89 Pause automatic waveform transfers on hardware Stop 2026-10-07 12:22:00 +03:00
79b0cde20e Add native QCustomPlot renderer and shared plot adapters 2026-10-07 11:33:14 +03:00
90046de7fd Добавить идентификацию прошивки и чтение EEPROM Бальзам-167 2026-10-05 17:48:23 +03:00
0e3d89e1ee Добавить протокол DEIF, диагностику CAN и сохранение сессий 2026-10-04 23:34:26 +03:00
6c08eece61 Улучшить две шкалы, навигацию и формулы графиков 2026-10-04 23:34:26 +03:00
c7294830f9 Add shared CAN monitor sessions, protocol selection and HEX/DEC display 2026-10-03 22:53:51 +03:00
427fc70100 docs: добавь поясняющие комментарии к модулям и инструментам 2026-10-02 16:46:19 +03:00
6cbce6c360 Согласовать демо логгера УМП с постинтервалом в десять процентов банка 2026-10-02 16:41:26 +03:00
3463e95eb3 Добавить общее перетаскивание графиков и независимые шкалы амплитуд 2026-10-02 16:41:26 +03:00
025a3fde28 Исправить порядок слов BALZAM CAN и добавить поддержку пульта МПУ 2026-10-02 16:41:25 +03:00
608 changed files with 60206 additions and 2134 deletions

View File

@@ -1,3 +1,7 @@
# Сборка библиотеки can_sensor. Состав исходников и публичные include-пути задают подключение
# к проекту потребителя. Файл также собирает и регистрирует хостовые проверки; запускать их
# следует через CTest из каталога сборки.
cmake_minimum_required(VERSION 3.13)
project(can_sensor C)

View File

@@ -1,3 +1,9 @@
/*
* Обмен настройками датчиков DS18B20 через однокадровые сообщения SETCAN. ROM идентифицирует
* датчик независимо от его позиции; прикладное состояние и отправка CAN предоставляются через
* интерфейс библиотеки.
*/
/**
* @file can_sensor.c
* @brief Однокадровый транспорт SETCAN SETTINGS для локаций DS18B20.

View File

@@ -1,3 +1,9 @@
/*
* Обмен настройками датчиков DS18B20 через однокадровые сообщения SETCAN. ROM идентифицирует
* датчик независимо от его позиции; прикладное состояние и отправка CAN предоставляются через
* интерфейс библиотеки.
*/
/**
* @file can_sensor.h
* @brief Портируемый транспорт SETTINGS для привязки DS18B20 к локации.

View File

@@ -1,3 +1,9 @@
/*
* Прямой bxCAN-порт датчиков для STM32F1 без HAL. Регистры контроллера обеспечивают передачу и
* приём SETCAN, а конфигурация платы задаёт подключение шины; это аппаратная реализация
* интерфейса can_sensor.
*/
/**
* @file can_sensor_stm32f1.c
* @brief Опросный порт can-sensor на bxCAN STM32F1 без STM32 HAL.

View File

@@ -1,3 +1,9 @@
/*
* Прямой bxCAN-порт датчиков для STM32F1 без HAL. Регистры контроллера обеспечивают передачу и
* приём SETCAN, а конфигурация платы задаёт подключение шины; это аппаратная реализация
* интерфейса can_sensor.
*/
/**
* @file can_sensor_stm32f1.h
* @brief Опросный порт can-sensor на bxCAN микроконтроллеров STM32F1.

View File

@@ -1,3 +1,9 @@
/*
* Конфигурация can-sensor для порта stm32f1. Макросы задают параметры сборки и ограничения,
* используемые исходниками этого модуля. Это образец для проекта: значения выводов, размеров
* памяти и параметров устройства необходимо согласовать с целевой платой.
*/
/**
* @file can_sensor_stm32f1_config.f103.template.h
* @brief Шаблон выводов CAN1 для STM32F103 без ремапа.

View File

@@ -1,3 +1,9 @@
/*
* Проверки can_sensor: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
#include "can_sensor.h"
#include <stdio.h>

View File

@@ -1,3 +1,7 @@
# Сборка библиотеки candle. Состав исходников и публичные include-пути задают подключение к
# проекту потребителя. Платформенные зависимости и условия сборки задаются здесь, а не в
# прикладных исходниках.
cmake_minimum_required(VERSION 3.15)
project(candle C)
if(NOT WIN32)
@@ -5,5 +9,5 @@ if(NOT WIN32)
endif()
add_library(candle SHARED candle.c candle_ctrl_req.c candle.def)
target_compile_definitions(candle PRIVATE UNICODE _UNICODE)
target_link_libraries(candle PRIVATE setupapi winusb ole32 advapi32)
target_link_libraries(candle PRIVATE setupapi winusb ole32 advapi32 cfgmgr32) # Configuration Manager сопоставляет интерфейсы CAN и DFU по родительскому USB-узлу.
target_include_directories(candle PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -19,6 +19,12 @@
*/
/*
* Доступ к CAN-адаптерам candleLight/gs_usb в Windows через WinUSB. Перечисление устройств,
* открытие канала и обмен кадрами образуют отдельный транспортный слой; он не интерпретирует
* прикладные регистры SETProtocol.
*/
#include "candle.h"
#include <stdarg.h>
@@ -28,6 +34,86 @@
#include "candle_defs.h"
#include "candle_ctrl_req.h"
#include "ch_9.h"
#include <cfgmgr32.h> /* Сопоставляет интерфейсы CAN и DFU по общему родительскому USB-устройству Windows. */
static DWORD candle_dfu_parent(const wchar_t *path, DEVINST *parent) /* Возвращает родителя интерфейса, чтобы команда не попала в другой подключённый адаптер. */
{ /* Начало поиска физического USB-устройства по пути выбранного CAN-интерфейса. */
HDEVINFO devices = SetupDiCreateDeviceInfoList(NULL, NULL); /* Создаёт временный набор SetupAPI без перечисления посторонних устройств. */
if (devices == INVALID_HANDLE_VALUE) return GetLastError(); /* Сохраняет причину отказа создания набора Windows. */
SP_DEVICE_INTERFACE_DATA iface = {0}; /* Подготавливает описание интерфейса для открытия по точному пути. */
iface.cbSize = sizeof(iface); /* Передаёт SetupAPI размер структуры текущей разрядности процесса. */
SP_DEVINFO_DATA info = {0}; /* Получает идентификатор узла PnP выбранного интерфейса. */
info.cbSize = sizeof(info); /* Указывает размер структуры устройства согласно контракту SetupAPI. */
DWORD size = 0, error = ERROR_SUCCESS; /* Хранит требуемое число байтов и итоговый код Windows. */
if (!SetupDiOpenDeviceInterfaceW(devices, path, 0, &iface)) error = GetLastError(); /* Открывает только заданный путь, сохраняя ошибку исчезнувшего устройства. */
if (!error) SetupDiGetDeviceInterfaceDetailW(devices, &iface, NULL, 0, &size, NULL); /* Узнаёт объём буфера переменной длины для пути USB-интерфейса. */
PSP_DEVICE_INTERFACE_DETAIL_DATA_W detail = size ? malloc(size) : NULL; /* Выделяет буфер только после успешного определения его размера. */
if (!error && !detail) error = size ? ERROR_NOT_ENOUGH_MEMORY : GetLastError(); /* Отличает нехватку памяти от ошибки поиска описания. */
if (detail) { /* Обрабатывает описание только при наличии выделенного буфера. */
detail->cbSize = sizeof(*detail); /* Согласует размер заголовка с архитектурой Win32 или Win64. */
if (!SetupDiGetDeviceInterfaceDetailW(devices, &iface, detail, size, NULL, &info)) error = GetLastError(); /* Получает узел интерфейса из SetupAPI. */
else if (CM_Get_Parent(parent, info.DevInst, 0) != CR_SUCCESS) error = ERROR_NOT_FOUND; /* Получает общий родительский узел составного USB-адаптера. */
free(detail); /* Освобождает описание после получения идентификатора родителя. */
} /* Завершает работу с описанием интерфейса. */
SetupDiDestroyDeviceInfoList(devices); /* Освобождает набор SetupAPI при любом результате поиска. */
return error; /* Возвращает ноль при успехе либо причину отказа Windows. */
} /* Завершает сопоставление интерфейса с физическим USB-устройством. */
uint32_t __stdcall candle_dev_enter_dfu(const wchar_t *can_path, uint8_t status[6]) /* Возвращает код Windows и шестибайтовый DFU_GETSTATUS согласно DFU 1.1. */
{ /* Начало отдельного сеанса управляющего интерфейса обновления. */
if (!can_path || !status) return ERROR_INVALID_PARAMETER; /* Запрещает отсутствие точного пути адаптера или выходного буфера статуса. */
memset(status, 0, 6); /* Исключает использование неинициализированных полей ответа при ошибке USB. */
DEVINST wanted_parent = 0; /* Запоминает физический адаптер, выбранный пользователем до остановки CAN. */
DWORD error = candle_dfu_parent(can_path, &wanted_parent); /* Ищет родителя по сохранённому пути CAN, не заменяя его первым найденным устройством. */
if (error) return error; /* Прерывает переход, если выбранный адаптер уже исчез из PnP. */
GUID guid = {0xc25b4308, 0x04d3, 0x11e6, {0xb3, 0xea, 0x60, 0x57, 0x18, 0x9e, 0x64, 0x43}}; /* GUID интерфейса обновления из дескриптора CANable 2.5. */
HDEVINFO devices = SetupDiGetClassDevsW(&guid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); /* Перечисляет только подключённые интерфейсы обновления CANable 2.5. */
if (devices == INVALID_HANDLE_VALUE) return GetLastError(); /* Возвращает отказ SetupAPI без попытки послать команду. */
error = ERROR_NOT_FOUND; /* Отсутствие интерфейса обновления не считается успешным входом в DFU. */
for (DWORD index = 0; ; ++index) { /* Проверяет интерфейсы до точного совпадения физического устройства. */
SP_DEVICE_INTERFACE_DATA iface = {0}; /* Создаёт независимое описание очередного DFU-интерфейса. */
iface.cbSize = sizeof(iface); /* Задаёт обязательный размер структуры SetupAPI. */
if (!SetupDiEnumDeviceInterfaces(devices, NULL, &guid, index, &iface)) { /* Завершает обход либо сообщает ошибку перечисления. */
if (GetLastError() != ERROR_NO_MORE_ITEMS) error = GetLastError(); /* Отличает штатный конец списка от отказа Windows. */
break; /* Выходит из обхода после исчерпания интерфейсов или ошибки. */
} /* Завершает проверку результата перечисления. */
DWORD size = 0; /* Хранит размер описания очередного интерфейса в байтах. */
SetupDiGetDeviceInterfaceDetailW(devices, &iface, NULL, 0, &size, NULL); /* Определяет буфер для полного пути интерфейса обновления. */
if (!size) { error = GetLastError(); break; } /* Не продолжает работу с неполным результатом SetupAPI. */
PSP_DEVICE_INTERFACE_DETAIL_DATA_W detail = malloc(size); /* Выделяет описание с достаточным местом для USB-пути. */
if (!detail) { error = ERROR_NOT_ENOUGH_MEMORY; break; } /* Не допускает обращения к отсутствующему буферу. */
detail->cbSize = sizeof(*detail); /* Сохраняет ABI описания интерфейса Windows. */
if (!SetupDiGetDeviceInterfaceDetailW(devices, &iface, detail, size, NULL, NULL)) { /* Получает путь, который можно передать CreateFileW. */
error = GetLastError(); free(detail); break; /* Сохраняет ошибку и освобождает буфер перед выходом. */
} /* Завершает чтение пути интерфейса. */
DEVINST parent = 0; /* Хранит родителя текущего кандидата на обновление. */
if (candle_dfu_parent(detail->DevicePath, &parent) || parent != wanted_parent) { /* Исключает каждый интерфейс другого физического адаптера. */
free(detail); continue; /* Освобождает описание неподходящего кандидата и продолжает поиск. */
} /* Завершает проверку принадлежности выбранному USB-адаптеру. */
HANDLE file = CreateFileW(detail->DevicePath, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); /* Эксклюзивно открывает интерфейс обновления выбранного устройства для WinUSB. */
free(detail); /* Путь больше не нужен после открытия системного дескриптора. */
if (file == INVALID_HANDLE_VALUE) { error = GetLastError(); break; } /* Не скрывает отсутствие доступа или занятость интерфейса. */
WINUSB_INTERFACE_HANDLE usb = NULL; /* Хранит отдельный WinUSB-сеанс интерфейса обновления без CAN bulk endpoint. */
error = ERROR_SUCCESS; /* Сбрасывает исходное отсутствие интерфейса после точного совпадения устройства. */
if (!WinUsb_Initialize(file, &usb)) error = GetLastError(); /* Проверяет наличие рабочего WinUSB-драйвера DFU runtime. */
USB_INTERFACE_DESCRIPTOR descriptor = {0}; /* Получает реальный номер и класс открытого интерфейса. */
if (!error && !WinUsb_QueryInterfaceSettings(usb, 0, &descriptor)) error = GetLastError(); /* Не предполагает, что произвольный WinUSB-интерфейс поддерживает DFU. */
if (!error && (descriptor.bInterfaceClass != 0xFE || descriptor.bInterfaceSubClass != 1 || descriptor.bInterfaceProtocol != 1)) error = ERROR_NOT_SUPPORTED; /* Проверяет класс приложения, подкласс DFU и runtime-протокол по DFU 1.1. */
ULONG timeout = 500, transferred = 0; /* Ограничивает управляющий USB-запрос 500 миллисекундами и учитывает длину ответа. */
if (!error && !WinUsb_SetPipePolicy(usb, 0, PIPE_TRANSFER_TIMEOUT, sizeof(timeout), &timeout)) error = GetLastError(); /* Устанавливает тайм-аут endpoint 0, чтобы отсутствующий ответ не блокировал программу. */
WINUSB_SETUP_PACKET packet = {0}; /* Обнуляет поля USB SETUP перед запросом перехода в загрузчик. */
packet.RequestType = 0x21; packet.Request = 0; packet.Value = 1000; packet.Index = descriptor.bInterfaceNumber; /* DFU_DETACH: class/interface OUT, запрос 0, ожидаемое время отключения 1000 мс. */
if (!error && !WinUsb_ControlTransfer(usb, packet, NULL, 0, &transferred, NULL)) error = GetLastError(); /* Отправляет DETACH и требует подтверждённой USB-транзакции. */
packet.RequestType = 0xA1; packet.Request = 3; packet.Value = 0; packet.Length = 6; /* DFU_GETSTATUS: class/interface IN, запрос 3, ответ ровно 6 байт по DFU 1.1. */
if (!error && !WinUsb_ControlTransfer(usb, packet, status, 6, &transferred, NULL)) error = GetLastError(); /* Проверяет результат до отложенного перехода прошивки через 300 мс. */
if (!error && transferred != 6) error = ERROR_INVALID_DATA; /* Не трактует укороченный ответ как подтверждение входа в загрузчик. */
if (usb) WinUsb_Free(usb); /* Освобождает WinUSB до появления загрузчика с другим VID/PID. */
CloseHandle(file); /* Освобождает файловый дескриптор после успеха и при любой ошибке USB. */
break; /* Не отправляет DETACH повторно и не переключается на другой адаптер при отказе. */
} /* Завершает поиск и обработку единственного выбранного адаптера. */
SetupDiDestroyDeviceInfoList(devices); /* Освобождает перечень интерфейсов при любом результате. */
return error; /* Статус прошивки возвращается отдельно от системной ошибки USB. */
} /* Завершает управление DFU runtime без записи flash или изменения образа. */
static bool candle_dev_interal_open(candle_handle hdev);
@@ -650,6 +736,30 @@ bool __stdcall DLL candle_dev_open(candle_handle hdev)
}
bool __stdcall DLL candle_dev_get_product(candle_handle hdev, wchar_t *product, uint32_t capacity) /* Читает USB Product String открытого адаптера в буфер UTF-16; capacity измеряется в wchar_t, включая завершающий ноль. */
{ /* Начало чтения отображаемого имени без изменения режима CAN. */
if (!product || !capacity) return false; /* Не пишет в отсутствующий либо пустой выходной буфер. */
product[0] = 0; /* Сохраняет пустую строку при любом отказе чтения дескриптора. */
candle_device_t *dev = (candle_device_t*)hdev; /* Получает уже открытый WinUSB-сеанс выбранного физического адаптера. */
if (!dev || !dev->winUSBHandle) return false; /* Не открывает устройство заново и не обращается к закрытому интерфейсу. */
USB_DEVICE_DESCRIPTOR descriptor = {0}; /* Получает индекс строки продукта из стандартного дескриптора устройства. */
ULONG received = 0; /* Хранит фактически полученное количество байтов управляющего ответа. */
if (!WinUsb_GetDescriptor(dev->winUSBHandle, 1, 0, 0, (PUCHAR)&descriptor, sizeof(descriptor), &received) || received != sizeof(descriptor)) return false; /* Тип 1 обозначает Device Descriptor по USB 2.0; неполный ответ не используется. */
UCHAR string_index = descriptor.iProduct; /* Для обычных адаптеров использует объявленный устройством индекс USB Product String. */
if (descriptor.idVendor == 0x1D50 && descriptor.idProduct == 0x606F) string_index = 2; /* В CANable Candlelight имя продукта имеет индекс 2; WinUSB может подменять iProduct индексом имени интерфейса, как описано в штатном примере проекта. */
if (!string_index) return false; /* Нулевой iProduct означает, что устройство не предоставляет имя продукта. */
UCHAR raw[256] = {0}; /* Буфер вмещает строковый дескриптор USB, чей однобайтовый bLength ограничен 255 байтами. */
USHORT language = 0x0409; /* Использует английский идентификатор USB как резервный вариант для устройств без списка языков. */
if (WinUsb_GetDescriptor(dev->winUSBHandle, 3, 0, 0, raw, sizeof(raw), &received) && received >= 4 && raw[0] >= 4 && raw[1] == 3) language = (USHORT)(raw[2] | ((USHORT)raw[3] << 8)); /* Тип 3 и индекс 0 возвращают список LANGID; выбирает первый язык, предоставленный адаптером. */
if (!WinUsb_GetDescriptor(dev->winUSBHandle, 3, string_index, language, raw, sizeof(raw), &received)) return false; /* Читает именно строку продукта на поддерживаемом устройством языке. */
if (received < 2 || raw[1] != 3 || raw[0] < 2 || raw[0] > received || (raw[0] & 1)) return false; /* Проверяет тип, размер и чётное число байтов UTF-16 перед копированием в выходной буфер. */
uint32_t count = (raw[0] - 2) / 2; /* Исключает двухбайтовый заголовок и переводит длину UTF-16LE из байтов в число кодовых единиц. */
if (count >= capacity) return false; /* Не обрезает индивидуальный номер в конце имени и оставляет место для завершающего нуля. */
for (uint32_t index = 0; index < count; ++index) product[index] = (wchar_t)(raw[2 + index * 2] | ((USHORT)raw[3 + index * 2] << 8)); /* Явно собирает кодовые единицы UTF-16LE без предположений о выравнивании массива байтов. */
product[count] = 0; /* Завершает строку для безопасного чтения через ctypes и отображения в Qt. */
return count > 0; /* Пустое имя оставляет интерфейсу стандартную резервную подпись адаптера. */
} /* Завершает получение настоящего имени из прошивки USB-адаптера. */
bool __stdcall DLL candle_dev_get_timestamp_us(candle_handle hdev, uint32_t *timestamp_us)
{
return candle_ctrl_get_timestamp(hdev, timestamp_us);
@@ -817,6 +927,38 @@ bool __stdcall DLL candle_channel_stop(candle_handle hdev, uint8_t ch)
return candle_ctrl_set_device_mode(dev, ch, CANDLE_DEVMODE_RESET, 0);
}
bool __stdcall DLL candle_channel_start_configured(candle_handle hdev, uint8_t ch, uint32_t flags) /* Новый вход сохраняет прежний ABI start и позволяет отключать HW_TIMESTAMP. */
{ /* Явно выбранные Python-флаги должны попасть в прошивку без автоматического дополнения. */
return candle_ctrl_set_device_mode((candle_device_t*)hdev, ch, CANDLE_DEVMODE_START, flags); /* Передаём точную маску после проверки возможностей на уровне транспорта. */
} /* Завершение запуска с явно заданными параметрами. */
bool __stdcall DLL candle_channel_get_data_capabilities(candle_handle hdev, uint8_t ch, candle_capability_t *cap) /* Экспортируем чтение FD-пределов для расчёта тайминга на любой частоте CAN. */
{ /* Общая форма capability позволяет повторно использовать валидатор номинального тайминга. */
return candle_ctrl_data_capability((candle_device_t*)hdev, ch, cap); /* USB-запрос возвращает реальные пределы выбранного канала. */
} /* Завершение получения возможностей быстрой фазы. */
bool __stdcall DLL candle_channel_set_termination(candle_handle hdev, uint8_t ch, uint32_t state) /* Значения 0 и 1 соответствуют OFF и ON стандарта gs_usb. */
{ /* Проверка исключает отправку неопределённого состояния в прошивку. */
return state <= 1 && candle_ctrl_termination((candle_device_t*)hdev, ch, &state, true); /* Выполняем запись только для допустимого состояния. */
} /* Завершение переключения терминатора. */
bool __stdcall DLL candle_channel_get_termination(candle_handle hdev, uint8_t ch, uint32_t *state) /* Чтение состояния не меняет топологию CAN. */
{ /* Используем тот же формат 32-битного значения, что и при записи. */
return candle_ctrl_termination((candle_device_t*)hdev, ch, state, false); /* false выбирает USB_DIR_IN и GET_TERMINATION. */
} /* Завершение чтения терминатора. */
bool __stdcall DLL candle_channel_get_diagnostics(candle_handle hdev, uint8_t ch, uint32_t *state, uint32_t *rxerr, uint32_t *txerr) /* Сохраняем счётчики, которые старый get_state отбрасывал. */
{ /* Диагностика выполняется только для уже открытого устройства. */
candle_device_state_t data = {0}; /* Полная структура протокола содержит три слова: состояние, RX и TX. */
if (!candle_ctrl_get_state((candle_device_t*)hdev, ch, &data)) { /* Не возвращаем нулевые счётчики как будто запрос был успешным. */
return false; /* Причина USB-отказа уже записана управляющим запросом. */
} /* Дальнейшее копирование относится только к подтверждённому ответу. */
*state = data.state; /* Сохраняем состояние Error-active, Warning, Passive, Bus-off, Stopped или Sleeping. */
*rxerr = data.rxerr; /* Счётчик ошибок приёма измеряется в единицах CAN-контроллера. */
*txerr = data.txerr; /* Счётчик ошибок передачи помогает отличать отсутствие ACK от ошибок приёма. */
return true; /* Все три выходных значения относятся к одному USB-ответу. */
} /* Завершение расширенной диагностики канала. */
/* Write len bytes from buf to the OUT pipe, aborting after 300 ms.
* Writes are serialised by writeMutex in CandleApiInterface so dev->txEvent
* is never accessed by two threads simultaneously. */
@@ -1011,14 +1153,13 @@ bool __stdcall DLL candle_fd_frame_read(candle_handle hdev, candle_fd_frame_t *f
}
dev->rxurbs[urb_num].pending = false;
/* Minimum: classic CAN header (12 bytes) + at least 8 data bytes = 20 bytes */
static const DWORD classic_min = sizeof(candle_frame_t) - 4;
if (bytes_transfered < classic_min) {
const DWORD header_size = 12; /* Заголовок gs_usb занимает 12 байт в Classic и FD; короткий FD может не содержать восьми байтов данных. */
if (bytes_transfered < header_size) { /* До чтения flags и DLC проверяем наличие полного заголовка. */
candle_prepare_read(dev, urb_num);
candle_logf(L"fd read too small urb=%u bytes=%lu min=%lu",
urb_num,
bytes_transfered,
classic_min);
header_size); /* Минимальная длина здесь относится к заголовку, а payload проверяется после определения формата. */
dev->last_error = CANDLE_ERR_READ_SIZE;
return false;
}
@@ -1041,6 +1182,11 @@ bool __stdcall DLL candle_fd_frame_read(candle_handle hdev, candle_fd_frame_t *f
if (is_fd_frame) {
/* can_dlc is at byte offset 8 in both classic and FD wire frames. */
const uint8_t raw_dlc = dev->rxurbs[urb_num].buf[8];
if (raw_dlc > 15) { /* FD DLC является четырёхбитным кодом и не может содержать значения выше 15. */
candle_prepare_read(dev, urb_num); /* Повреждённый USB-пакет не должен останавливать последующий приём. */
dev->last_error = CANDLE_ERR_READ_SIZE; /* Неверный DLC считается ошибкой формата входного кадра. */
return false; /* Не превращаем повреждённый DLC в пустой успешный FD-кадр. */
} /* Далее длина безопасно вычисляется по таблице CAN FD. */
const DWORD data_len = candle_dlc_to_len(raw_dlc);
const DWORD min_size = 12 + data_len; /* header + data, without timestamp */
@@ -1071,6 +1217,11 @@ bool __stdcall DLL candle_fd_frame_read(candle_handle hdev, candle_fd_frame_t *f
}
/* else: timestamp stays zero from memset above */
} else {
if (bytes_transfered < sizeof(candle_frame_t) - sizeof(uint32_t)) { /* Classic-пакет обязан содержать весь восьмибайтовый буфер данных, даже при меньшем DLC. */
candle_prepare_read(dev, urb_num); /* Возобновляем соответствующий URB после отклонения неполного пакета. */
dev->last_error = CANDLE_ERR_READ_SIZE; /* Не допускаем чтение неполученных данных из локальной структуры. */
return false; /* Повреждённый Classic-пакет не попадает в Python через FD API. */
} /* Минимальный размер Classic теперь проверен отдельно от коротких FD. */
/* Classic CAN frame — copy into FD struct, fixing the timestamp position */
candle_frame_t classic;
DWORD copy_len = (bytes_transfered < sizeof(classic)) ? bytes_transfered : sizeof(classic);

View File

@@ -1,4 +1,10 @@
; Доступ к CAN-адаптерам candleLight/gs_usb в Windows через WinUSB. Перечисление устройств,
; открытие канала и обмен кадрами образуют отдельный транспортный слой; он не интерпретирует
; прикладные регистры SETProtocol.
EXPORTS
candle_dev_get_product ; Имя продукта из USB-дескриптора прошивки для списка адаптеров SETGUI.
candle_dev_enter_dfu ; Переход через отдельный DFU runtime-интерфейс того же физического USB-адаптера.
candle_list_scan
candle_list_free
candle_list_length
@@ -27,3 +33,13 @@ EXPORTS
candle_frame_data
candle_frame_timestamp_us
candle_dev_last_error
candle_channel_start_configured ; Точная маска запуска с управляемыми аппаратными метками.
candle_channel_get_data_capabilities ; Пределы тайминга быстрой фазы CAN FD.
candle_channel_set_termination ; Переключение встроенного терминатора.
candle_channel_get_termination ; Чтение состояния встроенного терминатора.
candle_channel_get_diagnostics ; Состояние и счётчики ошибок CAN.
candle_channel_set_data_timing ; Тайминг фазы данных CAN FD.
candle_fd_frame_send ; Отправка полного кадра CAN FD до 64 байт.
candle_fd_frame_read ; Приём FD и Classic без обрезания данных.
candle_fd_frame_type ; Различение RX, TX echo и ошибок FD.
candle_fd_frame_id ; Получение CAN ID из структуры FD.

View File

@@ -20,6 +20,12 @@
*/
/*
* Доступ к CAN-адаптерам candleLight/gs_usb в Windows через WinUSB. Перечисление устройств,
* открытие канала и обмен кадрами образуют отдельный транспортный слой; он не интерпретирует
* прикладные регистры SETProtocol.
*/
#pragma once
#include <stdint.h>
#include <stdbool.h>
@@ -240,7 +246,9 @@ bool __stdcall DLL candle_list_length(candle_list_handle list, uint8_t *len);
bool __stdcall DLL candle_dev_get(candle_list_handle list, uint8_t dev_num, candle_handle *hdev);
bool __stdcall DLL candle_dev_get_state(candle_handle hdev, candle_devstate_t *state);
wchar_t * __stdcall DLL candle_dev_get_path(candle_handle hdev);
bool __stdcall DLL candle_dev_get_product(candle_handle hdev, wchar_t *product, uint32_t capacity); /* Возвращает USB Product String в UTF-16; capacity включает завершающий ноль и измеряется в wchar_t. */
bool __stdcall DLL candle_dev_open(candle_handle hdev);
uint32_t __stdcall DLL candle_dev_enter_dfu(const wchar_t *can_path, uint8_t status[6]); /* Переводит выбранный физический адаптер в DFU и возвращает Win32-код плюс ответ DFU_GETSTATUS. */
bool __stdcall DLL candle_dev_get_timestamp_us(candle_handle hdev, uint32_t *timestamp_us);
bool __stdcall DLL candle_dev_close(candle_handle hdev);
bool __stdcall DLL candle_dev_free(candle_handle hdev);
@@ -253,6 +261,11 @@ bool __stdcall DLL candle_channel_set_timing(candle_handle hdev, uint8_t ch, can
bool __stdcall DLL candle_channel_set_bitrate(candle_handle hdev, uint8_t ch, uint32_t bitrate);
bool __stdcall DLL candle_channel_start(candle_handle hdev, uint8_t ch, uint32_t flags);
bool __stdcall DLL candle_channel_stop(candle_handle hdev, uint8_t ch);
bool __stdcall DLL candle_channel_start_configured(candle_handle hdev, uint8_t ch, uint32_t flags); /* Запускаем с точной маской без принудительного включения аппаратных меток. */
bool __stdcall DLL candle_channel_get_data_capabilities(candle_handle hdev, uint8_t ch, candle_capability_t *cap); /* Возвращаем пределы тайминга быстрой фазы FD. */
bool __stdcall DLL candle_channel_set_termination(candle_handle hdev, uint8_t ch, uint32_t state); /* Состояние терминатора: 0 — выключен, 1 — включён. */
bool __stdcall DLL candle_channel_get_termination(candle_handle hdev, uint8_t ch, uint32_t *state); /* Чтение не меняет подключение встроенного резистора. */
bool __stdcall DLL candle_channel_get_diagnostics(candle_handle hdev, uint8_t ch, uint32_t *state, uint32_t *rxerr, uint32_t *txerr); /* Передаём состояние CAN и оба счётчика ошибок без потери данных ответа. */
bool __stdcall DLL candle_frame_send(candle_handle hdev, uint8_t ch, candle_frame_t *frame);
bool __stdcall DLL candle_frame_read(candle_handle hdev, candle_frame_t *frame, uint32_t timeout_ms);

View File

@@ -19,6 +19,11 @@
*/
/*
* Управляющие USB-запросы адаптера candleLight: конфигурация, временные параметры CAN и режим
* канала. Эти транзакции идут через control endpoint и отличаются от потока CAN-кадров.
*/
#include "candle_ctrl_req.h"
#include "ch_9.h"
@@ -34,8 +39,10 @@ enum {
CANDLE_TIMESTAMP_GET = 6,
/* 7: IDENTIFY, 8: GET_USER_ID, 9: SET_USER_ID (not used here) */
CANDLE_BREQ_DATA_BITTIMING = 10,
/* 11: SET_TERMINATION, not used here */
CANDLE_BREQ_GET_STATE = 12,
CANDLE_BREQ_BT_CONST_EXT = 11, /* Расширенные пределы номинальной и быстрой фазы согласно gs_usb. */
CANDLE_BREQ_SET_TERMINATION = 12, /* Запрос gs_usb 12 переключает встроенный резистор окончания шины. */
CANDLE_BREQ_GET_TERMINATION = 13, /* Запрос gs_usb 13 читает текущее состояние терминатора. */
CANDLE_BREQ_GET_STATE = 14, /* Стандартный GET_STATE имеет номер 14; номер 12 принадлежит терминатору. */
CANDLE_BREQ_BUS_OFF_RECOVERY = 32,
};
@@ -232,3 +239,22 @@ bool candle_ctrl_bus_off_recover(candle_device_t *dev, uint8_t channel)
dev->last_error = rc ? CANDLE_ERR_OK : CANDLE_ERR_SET_DEVICE_MODE;
return rc;
}
bool candle_ctrl_data_capability(candle_device_t *dev, uint8_t channel, candle_capability_t *cap) /* Структура gs_usb BT_CONST_EXT содержит десять общих и восемь быстрых полей uint32. */
{ /* Используем массив, поскольку протокол содержит только однородные 32-битные значения без отступов. */
uint32_t fields[18] = {0}; /* 18 полей по 4 байта образуют стандартный ответ размером 72 байта. */
bool rc = usb_control_msg(dev->winUSBHandle, CANDLE_BREQ_BT_CONST_EXT, USB_DIR_IN|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, channel, 0, fields, sizeof(fields)); /* Запрашиваем пределы именно выбранного CAN-канала. */
if (rc) { /* Выходная структура должна меняться только после успешного USB-ответа. */
memcpy(cap, fields, 2 * sizeof(uint32_t)); /* Маска функций и частота CAN общие для обеих фаз. */
memcpy(&cap->tseg1_min, &fields[10], 8 * sizeof(uint32_t)); /* Поля DTSEG1…DBRP_INC заменяют номинальные пределы структуры capability. */
} /* При отказе вызывающий код получит false и не использует нулевые пределы. */
dev->last_error = rc ? CANDLE_ERR_OK : CANDLE_ERR_GET_BITTIMING_CONST; /* Сохраняем диагностический код чтения аппаратных ограничений. */
return rc; /* Успех означает наличие полной структуры пределов быстрой фазы. */
} /* Завершение запроса расширенных возможностей FD. */
bool candle_ctrl_termination(candle_device_t *dev, uint8_t channel, uint32_t *state, bool write) /* Переключение терминатора использует стандартные SET=12 и GET=13. */
{ /* Состояние передаётся одним 32-битным словом согласно протоколу gs_usb. */
bool rc = usb_control_msg(dev->winUSBHandle, write ? CANDLE_BREQ_SET_TERMINATION : CANDLE_BREQ_GET_TERMINATION, (write ? USB_DIR_OUT : USB_DIR_IN)|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, channel, 0, state, sizeof(*state)); /* Номер CAN-канала передаётся в wValue, а wIndex равен нулю по спецификации. */
dev->last_error = rc ? CANDLE_ERR_OK : CANDLE_ERR_SET_DEVICE_MODE; /* Ошибка настройки доступна Python через candle_dev_last_error. */
return rc; /* Не выдаём успешное переключение при отказе USB-контроллера. */
} /* Завершение управления встроенным окончанием шины. */

View File

@@ -20,6 +20,11 @@
*/
/*
* Управляющие USB-запросы адаптера candleLight: конфигурация, временные параметры CAN и режим
* канала. Эти транзакции идут через control endpoint и отличаются от потока CAN-кадров.
*/
#pragma once
#include "candle_defs.h"
@@ -46,4 +51,6 @@ bool candle_ctrl_set_data_bittiming(candle_device_t *dev, uint8_t channel, candl
bool candle_ctrl_get_timestamp(candle_device_t *dev, uint32_t *current_timestamp);
bool candle_ctrl_get_state(candle_device_t *dev, uint8_t channel, candle_device_state_t *data);
bool candle_ctrl_bus_off_recover(candle_device_t *dev, uint8_t channel);
bool candle_ctrl_data_capability(candle_device_t *dev, uint8_t channel, candle_capability_t *cap); /* Читаем пределы быстрой фазы CAN FD отдельным запросом расширенной структуры. */
bool candle_ctrl_termination(candle_device_t *dev, uint8_t channel, uint32_t *state, bool write); /* Передаём состояние терминатора: 0 — выключен, 1 — включён. */

View File

@@ -20,6 +20,12 @@
*/
/*
* Двоичные структуры и константы gs_usb, общие для драйвера и USB-адаптера. Размеры полей и
* упаковка определяют совместимость с прошивкой: менять их как обычные внутренние структуры
* нельзя.
*/
#pragma once
#include <stdint.h>

View File

@@ -19,6 +19,11 @@
*/
/*
* Типы стандартных USB-дескрипторов и запросов из главы 9 спецификации USB. Драйвер использует
* их для описания устройства и конечных точек; это транспортные определения, а не формат CAN.
*/
#pragma once
#define USB_DIR_OUT 0 /* to device */

View File

@@ -1,3 +1,7 @@
# Сборка библиотеки ds18b20_ds2480. Состав исходников и публичные include-пути задают
# подключение к проекту потребителя. Файл также собирает и регистрирует хостовые проверки;
# запускать их следует через CTest из каталога сборки.
cmake_minimum_required(VERSION 3.13)
project(ds18b20_ds2480 C)
add_library(ds18b20_ds2480 STATIC ds2480.c ds18b20_ds2480.c)

View File

@@ -1,3 +1,9 @@
/*
* Команды DS18B20 поверх интерфейса DS2480B: адресация ROM, преобразование температуры и
* scratchpad. Транспортный статус следует проверять до использования результата; сырая
* температура сохраняет знаковое представление датчика.
*/
#include "ds18b20_ds2480.h"
#include <string.h>

View File

@@ -1,3 +1,9 @@
/*
* Команды DS18B20 поверх интерфейса DS2480B: адресация ROM, преобразование температуры и
* scratchpad. Транспортный статус следует проверять до использования результата; сырая
* температура сохраняет знаковое представление датчика.
*/
#ifndef DS18B20_DS2480_H
#define DS18B20_DS2480_H
#include "ds2480.h"

View File

@@ -1,3 +1,9 @@
/*
* UART-мост DS2480B для операций 1-Wire: сброс, обмен битами и байтами, поиск устройств и
* управление питанием. После ошибки связи состояние готовности сбрасывается, чтобы следующий
* обмен не продолжался в неизвестном режиме моста.
*/
#include "ds2480.h"
static ds2480_status fault(ds2480 *bus, ds2480_status status)

View File

@@ -1,3 +1,9 @@
/*
* UART-мост DS2480B для операций 1-Wire: сброс, обмен битами и байтами, поиск устройств и
* управление питанием. После ошибки связи состояние готовности сбрасывается, чтобы следующий
* обмен не продолжался в неизвестном режиме моста.
*/
#ifndef DS2480_H
#define DS2480_H

View File

@@ -1,3 +1,9 @@
/*
* Минимальный блокирующий пример: подготовить мост DS2480B, найти первый датчик, запустить
* преобразование и прочитать температуру. Обратные вызовы UART и задержек предоставляет плата;
* ожидание преобразования входит во время вызова.
*/
#include "ds18b20_ds2480.h"
/* board_port supplies the four callbacks documented in ds2480.h.

View File

@@ -1,3 +1,9 @@
/*
* UART-порт DS2480B для STM32F4. Подготовка линии и очистка ошибок USART отделены от команд
* датчика; после сбоя обмена мост должен пройти предусмотренное восстановление до продолжения
* работы с 1-Wire.
*/
#include "ds2480_stm32f4_hal.h"
#define RX_ERRORS (USART_SR_ORE | USART_SR_NE | USART_SR_FE | USART_SR_PE)

View File

@@ -1,3 +1,9 @@
/*
* UART-порт DS2480B для STM32F4. Подготовка линии и очистка ошибок USART отделены от команд
* датчика; после сбоя обмена мост должен пройти предусмотренное восстановление до продолжения
* работы с 1-Wire.
*/
#ifndef DS2480_STM32F4_HAL_H
#define DS2480_STM32F4_HAL_H

View File

@@ -1,3 +1,11 @@
/*
* Проверки stm32f4xx_hal: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Сценарии для навигации по файлу:
* test_clear
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
/* Host-only HAL model, never add this directory to a firmware include path. */
#ifndef TEST_STM32F4_HAL_H
#define TEST_STM32F4_HAL_H

View File

@@ -1,3 +1,11 @@
/*
* Проверки port: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Сценарии для навигации по файлу:
* test_clear
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
#include "ds2480_stm32f4_hal.h"
#include <assert.h>
#include <stdio.h>

View File

@@ -1,3 +1,9 @@
/*
* Проверки ds18b20_ds2480: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
#include "ds18b20_ds2480.h"
#include <stdio.h>
#include <stdlib.h>

View File

@@ -1,3 +1,7 @@
# Сборка библиотеки ds18b20. Состав исходников и публичные include-пути задают подключение к
# проекту потребителя. Файл также собирает и регистрирует хостовые проверки; запускать их
# следует через CTest из каталога сборки.
cmake_minimum_required(VERSION 3.13)
project(ds18b20 C)

View File

@@ -1,3 +1,9 @@
/*
* Работа с термометрами DS18B20: поиск по ROM, запуск преобразования, чтение температуры и
* настройка scratchpad. ROM является адресом устройства на общей шине; результат чтения нельзя
* считать действительным до проверки статуса обмена и CRC.
*/
/**
* @file ds18b20.h
* @brief Драйвер термометров DS18B20 поверх шины 1-Wire.

View File

@@ -1,3 +1,9 @@
/*
* Общие операции 1-Wire и обход дерева 64-битных ROM. Поиск разрешает коллизии побитно,
* поэтому обнаружение нескольких устройств не сводится к чтению одного адреса. Электрические
* уровни и длительности импульсов задаёт порт.
*/
/**
* @file onewire.h
* @brief Программная шина 1-Wire на выводе с открытым стоком.

View File

@@ -1,3 +1,7 @@
# Сборка библиотеки ds18b20_instance. Состав исходников и публичные include-пути задают
# подключение к проекту потребителя. Файл также собирает и регистрирует хостовые проверки;
# запускать их следует через CTest из каталога сборки.
cmake_minimum_required(VERSION 3.13)
project(ds18b20_instance C)
add_library(ds18b20_instance STATIC Src/ds18b20.c)

View File

@@ -1,3 +1,9 @@
/*
* Работа с термометрами DS18B20: поиск по ROM, запуск преобразования, чтение температуры и
* настройка scratchpad. ROM является адресом устройства на общей шине; результат чтения нельзя
* считать действительным до проверки статуса обмена и CRC.
*/
#ifndef PORTABLE_DS18B20_H
#define PORTABLE_DS18B20_H

View File

@@ -1,3 +1,9 @@
/*
* Конфигурация ds18b20. Макросы задают параметры сборки и ограничения, используемые
* исходниками этого модуля. Смысл и единицы каждого параметра определяются местом его
* использования; размеры буферов должны быть согласованы у всех потребителей заголовка.
*/
#ifndef PORTABLE_DS18B20_CONFIG_H
#define PORTABLE_DS18B20_CONFIG_H
#define DS18B20_DEFAULT_TIMEOUT_MS 750U

View File

@@ -1,3 +1,9 @@
/*
* Работа с термометрами DS18B20: поиск по ROM, запуск преобразования, чтение температуры и
* настройка scratchpad. ROM является адресом устройства на общей шине; результат чтения нельзя
* считать действительным до проверки статуса обмена и CRC.
*/
#include "ds18b20.h"
#include "ds18b20_config.h"
#include <string.h>

View File

@@ -1,3 +1,7 @@
# Сборка и запуск хостовых проверок экземплярного DS18B20. Скрипт готовит исполняемые тесты
# для проверки поиска ROM и задержек EEPROM без платы; ошибка компиляции или проверки должна
# завершить прогон неуспешно.
$ErrorActionPreference = "Stop"
$out = Join-Path $env:TEMP "test_ds18b20_copy_delay.exe"
$test = Join-Path $PSScriptRoot "test_ds18b20_copy_delay.c"

View File

@@ -1,3 +1,10 @@
/*
* Проверки ds18b20_copy_delay: фиксируют ожидаемое поведение на воспроизводимых входных
* данных.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
#include "ds18b20.h"
#include <assert.h>

View File

@@ -1,3 +1,10 @@
/*
* Проверки ds18b20_incremental_search: фиксируют ожидаемое поведение на воспроизводимых
* входных данных.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
/* Model real SEARCH ROM participation: each branch filters the active slaves.
* Fault injection tests transport recovery, not analog cable characteristics. */
#include "ds18b20.h"

View File

@@ -1,3 +1,9 @@
/*
* Конфигурация ds18b20 для порта stm32f1. Макросы задают параметры сборки и ограничения,
* используемые исходниками этого модуля. Это образец для проекта: значения выводов, размеров
* памяти и параметров устройства необходимо согласовать с целевой платой.
*/
/**
* @file onewire_config.f103.template.h
* @brief Шаблон привязки шины 1-Wire для STM32F103 (порт stm32f1).

View File

@@ -1,3 +1,9 @@
/*
* Аппаратные временные слоты 1-Wire на STM32F1: управление линией, чтение уровня и
* микросекундные задержки. Конфигурация выбирает GPIO и таймер; общий алгоритм поиска ROM
* остаётся в onewire.c.
*/
/**
* @file onewire_stm32f1.c
* @brief Порт шины 1-Wire на STM32F1: тайминги, вывод и задержки.

View File

@@ -1,3 +1,9 @@
/*
* Конфигурация ds18b20 для порта stm32f4. Макросы задают параметры сборки и ограничения,
* используемые исходниками этого модуля. Это образец для проекта: значения выводов, размеров
* памяти и параметров устройства необходимо согласовать с целевой платой.
*/
/**
* @file onewire_config.f407.template.h
* @brief Шаблон привязки шины 1-Wire для STM32F407VET6 (порт stm32f4).

View File

@@ -1,3 +1,9 @@
/*
* Аппаратные временные слоты 1-Wire на STM32F4 с открытым стоком. Порт использует
* CMSIS-регистры и параметры onewire_config.h; частота таймера должна соответствовать расчёту
* задержек при обмене с датчиками.
*/
/**
* @file onewire_stm32f4.c
* @brief Порт шины 1-Wire на STM32F4: тайминги, вывод и задержки.

View File

@@ -1,3 +1,9 @@
/*
* Конфигурация ds18b20 для порта stm32g4. Макросы задают параметры сборки и ограничения,
* используемые исходниками этого модуля. Это образец для проекта: значения выводов, размеров
* памяти и параметров устройства необходимо согласовать с целевой платой.
*/
/**
* @file onewire_config.g431.template.h
* @brief Шаблон привязки шины 1-Wire для STM32G431 (порт stm32g4).

View File

@@ -1,3 +1,9 @@
/*
* Конфигурация ds18b20 для порта stm32g4. Макросы задают параметры сборки и ограничения,
* используемые исходниками этого модуля. Это образец для проекта: значения выводов, размеров
* памяти и параметров устройства необходимо согласовать с целевой платой.
*/
/**
* @file onewire_config.g474.template.h
* @brief Шаблон привязки шины 1-Wire для STM32G474 (порт stm32g4).

View File

@@ -1,3 +1,9 @@
/*
* Аппаратные временные слоты 1-Wire для STM32G431/G474. GPIO и таймер задаются конфигурацией
* проекта; чтение уровня выполняется с линии, поэтому паразитное питание и подтяжка относятся
* к схеме платы.
*/
/**
* @file onewire_stm32g4.c
* @brief Порт шины 1-Wire на STM32G4: тайминги, вывод и задержки.

View File

@@ -1,3 +1,9 @@
/*
* Работа с термометрами DS18B20: поиск по ROM, запуск преобразования, чтение температуры и
* настройка scratchpad. ROM является адресом устройства на общей шине; результат чтения нельзя
* считать действительным до проверки статуса обмена и CRC.
*/
/** test
* @file ds18b20.c
* @brief Реализация драйвера DS18B20: поиск, чтение и запись scratchpad.

View File

@@ -1,3 +1,9 @@
/*
* Общие операции 1-Wire и обход дерева 64-битных ROM. Поиск разрешает коллизии побитно,
* поэтому обнаружение нескольких устройств не сводится к чтению одного адреса. Электрические
* уровни и длительности импульсов задаёт порт.
*/
/**
* @file onewire.c
* @brief Переносимая часть шины 1-Wire: побайтовый обмен, CRC8 и поиск ROM.

View File

@@ -1,3 +1,9 @@
/*
* Проверки fake_onewire: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
/**
* @file fake_onewire.c
* @brief Симулятор шины 1-Wire с виртуальными датчиками DS18B20.

View File

@@ -1,3 +1,9 @@
/*
* Проверки fake_onewire: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
/**
* @file fake_onewire.h
* @brief Модель шины 1-Wire с виртуальными датчиками для host-тестов.

View File

@@ -1,3 +1,19 @@
/*
* Проверки ds18b20: фиксируют ожидаемое поведение на воспроизводимых входных данных.
* Сценарии для навигации по файлу:
* test_crc8
* test_search_finds_all
* test_search_on_empty_bus
* test_search_single_device
* test_scan_filters_family
* test_read_all
* test_crc_error_does_not_stop_the_poll
* test_missing_device_is_reported
* Остальные сценарии продолжают эти проверки ниже в том же файле.
* Тестовые значения и подмены окружения относятся к проверке контракта; они не являются
* настройками рабочего устройства.
*/
/**
* Тесты драйвера DS18B20 и переносимой части 1-Wire на симуляторе шины.
*

View File

@@ -1,3 +1,9 @@
/*
* Доступ к EEPROM семейства 24Cxx через операции I2C порта. Запись разбивается на страницы:
* пересечение аппаратной границы одной транзакцией может завернуть адрес внутри страницы.
* После записи учитывается время внутреннего программирования.
*/
/**
* @file ft24c256.c
* @brief Постраничная запись, сплошное чтение и ожидание готовности FT24C256.

View File

@@ -1,3 +1,9 @@
/*
* Доступ к EEPROM семейства 24Cxx через операции I2C порта. Запись разбивается на страницы:
* пересечение аппаратной границы одной транзакцией может завернуть адрес внутри страницы.
* После записи учитывается время внутреннего программирования.
*/
/**
* @file ft24c256.h
* @brief Портируемый драйвер последовательной EEPROM FT24C256 и её семейства.

Some files were not shown because too many files have changed in this diff Show More