Reystlin 0 3 января, 2023 Опубликовано 3 января, 2023 (изменено) · Жалоба Доброго времени суток пытаюсь понять как работать с Custom HID на основе статьи https://microtechnics.ru/stm32cube-usb-custom-hid-sozdanie-deskriptorov-ustrojstva/?ysclid=lcfzgdcyrl345227162 в контроллере сделал вот так Spoiler __ALIGN_BEGIN static uint8_t CUSTOM_HID_ReportDesc_FS[USBD_CUSTOM_HID_REPORT_DESC_SIZE] __ALIGN_END = { /* USER CODE BEGIN 0 */ 0x06, 0x00, 0xff, // USAGE_PAGE (Generic Desktop) 0x09, 0x01, // USAGE (Vendor Usage 1) // System Parameters 0xa1, 0x01, // COLLECTION (Application) 0x85, 0x01, // REPORT_ID (1) 0x09, 0x01, // USAGE (Vendor Usage 1) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 4, // REPORT_COUNT (4) 0xb1, 0x82, // FEATURE (Data,Var,Abs,Vol) 0x85, 0x01, // REPORT_ID (1) 0x09, 0x01, // USAGE (Vendor Usage 1) 0x91, 0x82, // OUTPUT (Data,Var,Abs,Vol) 0x85, 0x02, // REPORT_ID (2) 0x09, 0x02, // USAGE (Vendor Usage 2) 0x75, 0x08, // REPORT_SIZE (8) 0x95, 4, // REPORT_COUNT (4) 0x81, 0x82, // INPUT (Data,Var,Abs,Vol) /* USER CODE END 0 */ 0xC0 /* END_COLLECTION */ }; static int8_t CUSTOM_HID_OutEvent_FS(uint8_t event_idx, uint8_t state) { /* USER CODE BEGIN 6 */ USBD_CUSTOM_HID_HandleTypeDef *hhid = (USBD_CUSTOM_HID_HandleTypeDef*)hUsbDeviceFS.pClassData; for (uint8_t i = 0; i < 4; i++) { dataToReceive[i] = hhid->Report_buf[i]; } if(dataToReceive[0]==0x01) HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); return (USBD_OK); /* USER CODE END 6 */ } В мейне: /* USER CODE BEGIN 2 */ dataToSend[0] = 'S'; dataToSend[1] = 'n'; dataToSend[2] = 'd'; dataToSend[3] = '\0'; /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ HAL_Delay(1000); USBD_CUSTOM_HID_SendReport(&hUsbDeviceFS, dataToSend, 4); /* USER CODE BEGIN 3 */ } Проблемы с тем на базе какой библиотеки на компе код удобней делать. в исходной статье применяли libusb но почему-то не смог найти той версии, по которой делали статью. по другим статьям тоже ничего не вышло Смотрел WinUSB там вообще не понятно как этим пользоваться взял HIDAPI на ней по примерам получилось увидеть мою плату но не получается отправить и получить данные Spoiler #include <iostream> #include <windows.h> #include <winusb.h> #include <usb.h> #include "hidapi.h" void print_device(struct hid_device_info* cur_dev) { printf("Device Found\n type: %04hx %04hx\n path: %s\n serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number); printf("\n"); printf(" Manufacturer: %ls\n", cur_dev->manufacturer_string); printf(" Product: %ls\n", cur_dev->product_string); printf(" Release: %hx\n", cur_dev->release_number); printf(" Interface: %d\n", cur_dev->interface_number); printf(" Usage (page): 0x%hx (0x%hx)\n", cur_dev->usage, cur_dev->usage_page); printf(" Bus type: %d\n", cur_dev->bus_type); printf("\n"); } void print_devices(struct hid_device_info* cur_dev) { while (cur_dev) { print_device(cur_dev); cur_dev = cur_dev->next; } } int main(int argc, char* argv[]) { (void)argc; (void)argv; int res; unsigned char buf[256]; #define MAX_STR 255 wchar_t wstr[MAX_STR]; hid_device* handle; int i; // struct hid_device_info* devs; if (hid_init()) return -1; // devs = hid_enumerate(0x0, 0x0); // print_devices(devs); // hid_free_enumeration(devs); // Set up the command buffer. memset(buf, 0x00, sizeof(buf)); buf[0] = 0x01; buf[1] = 0x81; // Open the device using the VID, PID, // and optionally the Serial number. ////handle = hid_open(0x4d8, 0x3f, L"12345"); handle = hid_open(0x0485, 0x5752, NULL); if (!handle) { printf("unable to open device\n"); hid_exit(); return 1; } // Read the Manufacturer String wstr[0] = 0x0000; res = hid_get_manufacturer_string(handle, wstr, MAX_STR); if (res < 0) printf("Unable to read manufacturer string\n"); printf("Manufacturer String: %ls\n", wstr); // Read the Product String wstr[0] = 0x0000; res = hid_get_product_string(handle, wstr, MAX_STR); if (res < 0) printf("Unable to read product string\n"); printf("Product String: %ls\n", wstr); // Read the Serial Number String wstr[0] = 0x0000; res = hid_get_serial_number_string(handle, wstr, MAX_STR); if (res < 0) printf("Unable to read serial number string\n"); printf("Serial Number String: (%d) %ls", wstr[0], wstr); printf("\n"); struct hid_device_info* info = hid_get_device_info(handle); if (info == NULL) { printf("Unable to get device info\n"); } else { print_devices(info); } /* // Read Indexed String 1 wstr[0] = 0x0000; res = hid_get_indexed_string(handle, 1, wstr, MAX_STR); if (res < 0) printf("Unable to read indexed string 1\n"); printf("Indexed String 1: %ls\n", wstr); */ // Set the hid_read() function to be non-blocking. hid_set_nonblocking(handle, 1); struct { uint8_t reportID; uint8_t data[4]; } report; report.reportID = 0x01; report.data[0] = 0x01; res = hid_write(handle, (const unsigned char*)&report, sizeof(report)); if (res < 0) { printf("Unable to write(report): %ls\n", hid_error(handle)); } res = hid_send_feature_report(handle, (const unsigned char*)&report, sizeof(report)); if (res < 0) { printf("((Unable to send a feature report)).\n"); } buf[0] = 0x81; res = hid_get_feature_report(handle, buf, 5); if (res < 0) { printf("Unable to get a feature report: %ls\n", hid_error(handle)); } else { // Print out the returned buffer. printf("Feature Report\n "); for (i = 0; i < res; i++) printf("%02x ", (unsigned int)buf[i]); printf("\n"); } memset(buf, 0, sizeof(buf)); // Send a Feature Report to the device buf[0] = 0x01; buf[1] = 0x01; buf[2] = 0x01; buf[3] = 0x01; buf[4] = 0x01; res = hid_send_feature_report(handle, buf, 4); if (res < 0) { printf("Unable to send a feature report.\n"); } memset(buf, 0, sizeof(buf)); // Toggle LED (cmd 0x80). The first byte is the report number (0x1). buf[0] = 0x01; buf[1] = 0x01; buf[2] = 0x01; res = hid_write(handle, buf, 4); if (res < 0) { printf("Unable to write(): %ls\n", hid_error(handle)); } memset(buf, 0, sizeof(buf)); // Request state (cmd 0x81). The first byte is the report number (0x1). buf[0] = 0x01; buf[1] = 0x81; hid_write(handle, buf, 4); if (res < 0) { printf("Unable to write()/2: %ls\n", hid_error(handle)); } // Read requested state. hid_read() has been set to be // non-blocking by the call to hid_set_nonblocking() above. // This loop demonstrates the non-blocking nature of hid_read(). res = 0; i = 0; while (res == 0) { res = hid_read(handle, buf, 4); if (res == 0) { printf("waiting...\n"); } if (res < 0) { printf("Unable to read(): %ls\n", hid_error(handle)); break; } i++; if (i >= 10) { /* 10 tries by 500 ms - 5 seconds of waiting*/ printf("read() timeout\n"); break; } Sleep(500); } if (res > 0) { printf("Data read:\n "); // Print out the returned buffer. for (i = 0; i < res; i++) printf("%02x ", (unsigned int)buf[i]); printf("\n"); } hid_close(handle); /* Free static HIDAPI objects. */ hid_exit(); #ifdef _WIN32 system("pause"); #endif return 0; } Кто какие библиотеки использует? Может у кого есть рабочий пример для стороны контроллера и компа? Изменено 3 января, 2023 пользователем haker_fox Длинный код нужно прятать под спойлер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 5 3 января, 2023 Опубликовано 3 января, 2023 (изменено) · Жалоба Вот функции записи и чтения данных HID-устройства из моего проекта. В программе используется HID API с отслеживанием событий подключения и отключения устройств. Spoiler int CCDevWritePacket(hid_device *hiddev, unsigned char *buff, int len) { unsigned char repbuf[CCREP_SIZE+1]; int wr = 0, writed = 0, bwrited = 0;; while (len > 0) { wr = len; if (wr > CCREP_SIZE-2) wr = CCREP_SIZE-2; repbuf[0] = CCREP_ID; repbuf[1] = wr; memcpy(repbuf+2, buff+bwrited, wr); if ((writed = hid_write(hiddev, repbuf, CCREP_SIZE+1)) < wr) { return 1; } len -= wr; bwrited += wr; } return 0; } // ----------------------------------------------------------------------------------- int CCDevReadPacket(hid_device *hiddev, unsigned char *buff) { unsigned char repbuf[CCREP_SIZE+1]; GFPACKET *pack = (GFPACKET*)buff; DWORD rd = 0, readed = 0; BOOL fullpacket = false; while (1) { if ((rd = hid_read_timeout(hiddev, repbuf, CCREP_SIZE+1, 1000)) < CCREP_SIZE) { return 1; } if (repbuf[0] == CCREP_ID) { memcpy(buff+readed, repbuf+2, repbuf[1]); readed += repbuf[1]; if (readed > 7) { if (readed == pack->dlen + 8) { unsigned short crc = 0; unsigned short *pcrc = (unsigned short*)(buff+6+pack->dlen); for (DWORD i = 0; i < readed-2; i++) crc += buff[i]; if (pack->header == PID_HEADER && crc == *pcrc) fullpacket = true; break; } } if (readed > 1100) break; } } if (fullpacket) return 0; return 1; } // ----------------------------------------------------------------------------------- Изменено 3 января, 2023 пользователем haker_fox Длинный код нужно прятать под спойлер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 60 3 января, 2023 Опубликовано 3 января, 2023 · Жалоба Модератор: длинный код прячем под спойлер. Это кнопка с глазом на панели редактора. Потом самим же удобнее читать тему, не пролистывая километровые простыни кода. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AndyBig 5 3 января, 2023 Опубликовано 3 января, 2023 · Жалоба Прошу прощения, учту на будущее 🙂 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться