Невозможно прочитать значение из Mc Device с помощью функции WinUsb_ReadPipe в VC++ 2013
Я застрял с проблемой, связанной с функцией winusbReadpipe. Я использую Pic18f4550 Mc(компилятор XC8) и VC ++ 2013 (MFC).
Я просто пытаюсь читать и писать на / с устройства / хоста. Пример программы, предоставленной Microchip, работает нормально, и я могу отправлять данные на все конечные точки 01, 02, 03 в устройстве с хоста.
Однако я не могу прочитать какие-либо отзывы от устройства к хосту. Я читаю и пишу данные в двух отдельных потоках. Моя идея состоит в том, чтобы просто прочитать отзыв о нажатой кнопке на Моей демонстрационной доске или хотя бы команду echo back. Кажется, он просто входит один раз в функцию чтения, а затем останавливается. Не уверен насчет этого.
Я пытался искать через Интернет и реализовал все предложения, приведенные на разных форумах, но до настоящего времени безуспешно. хуже всего то, что я пытаюсь опубликовать свой запрос на форуме Microchip, но не могу зарегистрироваться, он всегда говорит, что администратор утвердит мой идентификатор, но пока ничего не произошло.
Ниже мой код как со стороны устройства, так и со стороны хоста. Пожалуйста скажите мне, если что-то еще требуется от моей стороны.
Я жду вашей поддержки в этом.
Спасибо,
Рахул
Код VC++:
Читать код темы
UINT CUsbHighSpeedDlg::ReadThread()
{
while (true)
{
if (AttachedState == TRUE) //Do not try to use the read/write handles unless the USB device is attached and ready
{
m_DebugVal7.SetWindowTextW(TEXT("INSIDE read //pipe"));
WinUsb_ReadPipe(MyWinUSBInterfaceHandle, 0x81, &INBuffer[0], 64, &BytesRead, NULL);
if (INBuffer[0] = 0x81)
{
m_DebugVal5.SetWindowTextW(TEXT("button true"));
}
if ((INBuffer[0] = 0x81) && (INBuffer[1] = 0x00))
{
PushbuttonPressed = TRUE;
m_DebugVal5.SetWindowTextW(TEXT("button true"));
}
if ((INBuffer[0] = 0x81) && (INBuffer[1] = 0x01))
{
PushbuttonPressed = FALSE;
m_DebugVal6.SetWindowTextW(TEXT("button False"));
}
}
} return 0;
}
Заголовочные файлы, объявленные в VC++ для использования функции чтения / записи.
//WinUsb_Initialize() needs to be called before the application can begin sending/receiving data with the USB device.
[DllImport("Winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_Initialize", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_Initialize(
_In_ HANDLE DeviceHandle,
_Out_ PWINUSB_INTERFACE_HANDLE InterfaceHandle
);
//WinUsb_WritePipe() is the basic function used to write data to the USB device (sends data to OUT endpoints on the device)
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_WritePipe", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_WritePipe(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
_In_ UCHAR PipeID,
_In_ PUCHAR Buffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG LengthTransferred,
_In_opt_ LPOVERLAPPED Overlapped
);
//WinUsb_ReadPipe() is the basic function used to read data from the USB device (polls for and obtains data from
//IN endpoints on the device)
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_ReadPipe", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_ReadPipe(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
_In_ UCHAR PipeID,
_Out_ PUCHAR Buffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG LengthTransferred,
_In_opt_ LPOVERLAPPED Overlapped
);
//WinUsb_SetPipePolicy() can be used to configure the behavior of the WinUSB use of the specified endpoint
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_SetPipePolicy", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_SetPipePolicy(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
_In_ UCHAR PipeID,
_In_ ULONG PolicyType,
_In_ ULONG ValueLength,
_In_ PVOID Value
);
//WinUsb_Free() is used to free up resources/close the handle that was returned when calling WinUsb_Initialize()
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_Free", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_Free(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle
);
//WinUsb_FlushPipe() is used to discard any data that may be "cached in a pipe".
[DllImport("winusb.dll", CharSet = CharSet::Seeifdef, EntryPoint = "WinUsb_Free", CallingConvention = CallingConvention::Winapi)]
BOOL __stdcall WinUsb_FlushPipe(
_In_ WINUSB_INTERFACE_HANDLE InterfaceHandle,
_In_ UCHAR PipeID
);
Код микроконтроллера
Раздел объявления переменных
#elif defined(__XC8) && defined(FIXED_ADDRESS_MEMORY)
USB_VOLATILE uint8_t EP1OUTEvenBuffer[64] @ EP1_EVEN_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP1OUTOddBuffer[64] @ EP1_ODD_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP2OUTEvenBuffer[64] @ EP2_EVEN_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP2OUTOddBuffer[64] @ EP2_ODD_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP3OUTEvenBuffer[64] @ EP3_EVEN_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP3OUTOddBuffer[64] @ EP3_ODD_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP1INEvenBuffer[64] @ EP1IN_EVEN_DATA_BUFFER_ADDRESS;
USB_VOLATILE uint8_t EP1INOddBuffer[64] @ EP1IN_ODD_DATA_BUFFER_ADDRESS;
#else
#define FIXED_ADDRESS_MEMORY
#define EP1_EVEN_DATA_BUFFER_ADDRESS 0x480
#define EP1_ODD_DATA_BUFFER_ADDRESS 0x4C0
#define EP2_EVEN_DATA_BUFFER_ADDRESS 0x500
#define EP2_ODD_DATA_BUFFER_ADDRESS 0x540
#define EP3_EVEN_DATA_BUFFER_ADDRESS 0x580
#define EP3_ODD_DATA_BUFFER_ADDRESS 0x5C0
#define EP1IN_EVEN_DATA_BUFFER_ADDRESS 0x600 // NEW MEMORY ADDRESS DECLARED
#define EP1IN_ODD_DATA_BUFFER_ADDRESS 0x640// NEW MEMORY ADDRESS DECLARED
#endif //FIXED_MEMORY_ADDRESS
дескриптор
/* Device Descriptor */
const USB_DEVICE_DESCRIPTOR device_dsc=
{
0x12, // Size of this descriptor in bytes
USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
0x0200, // USB Spec Release Number in BCD format
0x00, // Class Code
0x00, // Subclass code
0x00, // Protocol code
USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
0x04D8, // Vendor ID: 0x04D8 is Microchip's Vendor ID
0x0052, // Product ID: 0x0052
0x0000, // Device release number in BCD format
0x01, // Manufacturer string index
0x02, // Product string index
0x00, // Device serial number string index
0x01 // Number of possible configurations
};
/* Configuration 1 Descriptor */
const uint8_t configDescriptor1[]={
/* Configuration Descriptor */
0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
0x2E,0x00, // Total length of data for this cfg
1, // Number of interfaces in this cfg
1, // Index value of this configuration
0, // Configuration string index
_DEFAULT | _SELF, // Attributes, see usb_device.h
50, // Max power consumption (2X mA)
/* Interface Descriptor */
0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
0, // Interface Number
0, // Alternate Setting Number
4, // Number of endpoints in this intf
0xFF, // Class code
0xFF, // Subclass code
0xFF, // Protocol code
0, // Interface string index
/* Endpoint Descriptor */
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_OUT, //EndpointAddress
_BULK, //Attributes
64,0x00, //size
1, //Interval
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP02_OUT, //EndpointAddress
_BULK, //Attributes
64,0x00, //size
1, //Interval
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP03_OUT, //EndpointAddress
_BULK, //Attributes
64,0x00, //size
1, //Interval
0x07, /*sizeof(USB_EP_DSC)*/// New Endpoint for Sending Data To Host
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_IN, //EndpointAddress// VALUE MODIFED FOR SENDING DATA
_BULK, //Attributes
64,0x00, //size
1 //Interval
};
Инициализация USB для массовой передачи
void APP_DeviceVendorThroughputTestInitialize()
{
EP1OUTEvenHandle = NULL;
EP2OUTEvenHandle = NULL;
EP3OUTEvenHandle = NULL;
EP1INEvenHandle = NULL;
EP1OUTOddHandle = NULL;
EP2OUTOddHandle = NULL;
EP3OUTOddHandle = NULL;
EP1INOddHandle = NULL;
//Now that we are configured, enable the endpoints for use in the demo
// and start the initial transfers
USBEnableEndpoint(_EP01_OUT,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
USBEnableEndpoint(2,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
USBEnableEndpoint(4,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
USBEnableEndpoint(_EP01_IN,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
//Prepare the OUT endpoints to receive the first packets from the host.
EP1OUTEvenHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTEvenBuffer,64); //First 64-bytes of data sent to EP1 OUT will arrive in the even buffer.
EP1OUTOddHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTOddBuffer,64); //Second 64-bytes of data sent to EP1 OUT will arrive in the odd buffer.
EP1OUTEvenNeedsServicingNext = true; //Used to keep track of which buffer will contain the next sequential data packet.
EP2OUTEvenHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTEvenBuffer,64);
EP2OUTOddHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTOddBuffer,64);
EP2OUTEvenNeedsServicingNext = true; //Used to keep track of which buffer will contain the next sequential data packet.
EP3OUTEvenHandle = USBTransferOnePacket(4, OUT_FROM_HOST,(uint8_t*)&EP3OUTEvenBuffer,64);
EP3OUTOddHandle = USBTransferOnePacket(4, OUT_FROM_HOST,(uint8_t*)&EP3OUTOddBuffer,64);
EP3OUTEvenNeedsServicingNext = true; //Used to keep track of which buffer will contain the next sequential data packet.
EP1INEvenHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64); //First 64-bytes of data RECIVE to EP3 IN will arrive in the even buffer.
// EP1INOddHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INOddBuffer,64); //Second 64-bytes of data RECIVE to EP3 IN will arrive in the odd buffer.
// EP1INEvenNeedsServicingNext = true;
}
Код для передачи данных, Примечание: _EP01_Out =0x01 & _EP01_IN =0x81
if(EP1OUTEvenNeedsServicingNext == true) //Check which buffer (even/odd) the next set of data is going to arrive in
{
if(!USBHandleBusy(EP1OUTEvenHandle)) //Check if the endpoint has received any data from the host.
{
PORTDbits.RD1=1;
PORTDbits.RD2=0;
switch(EP1OUTEvenBuffer[0]) //Data arrived, check what kind of command might be in the packet of data.
{
case 0x81: //Get push button state command from PC application.
EP1INEvenBuffer[0] = 0x81;
EP1INEvenHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64);
break;
case 0x82: //Toggle LED(s) command from PC application.
LATDbits.LD3=0;
break;
case 0x80: //Toggle LED(s) command from PC application.
LATDbits.LD3=1;
break;
EP1OUTEvenHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTEvenBuffer,64);
EP1OUTEvenNeedsServicingNext = false;
}
}
else //else EP1OUTOdd needs servicing next
{
if(!USBHandleBusy(EP1OUTOddHandle)) //Check if the endpoint has received any data from the host.
{
PORTDbits.RD1=0;
PORTDbits.RD2=1;
switch(EP1OUTOddBuffer[0]) //Data arrived, check what kind of command might be in the packet of data.
{
case 0x81:
EP1INEvenBuffer[0] = 0x81;
EP1INEvenHandle = USBTransferOnePacket(_EP01_IN, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64);
break;
case 0x82: //Toggle LED(s) command from PC application.
LATDbits.LD3=0;
break;
case 0x80: //Toggle LED(s) command from PC application.
LATDbits.LD3=1;
break;
}
EP1OUTOddHandle = USBTransferOnePacket(_EP01_OUT, OUT_FROM_HOST,(uint8_t*)&EP1OUTOddBuffer,64);
EP1OUTEvenNeedsServicingNext = true;
}
}
Конец кода
1 ответ
Я решаю проблему неработающей функции чтения канала winusb.
выполнив много ударов и проб, я сделал следующие изменения и смог успешно прочитать обратную связь потенциометра и нажатой кнопки.
фиксированный адрес памяти
#define EP1_EVEN_DATA_BUFFER_ADDRESS 0x480
#define EP1_ODD_DATA_BUFFER_ADDRESS 0x4C0
#define EP2_EVEN_DATA_BUFFER_ADDRESS 0x500
#define EP2_ODD_DATA_BUFFER_ADDRESS 0x540
#define EP3_EVEN_DATA_BUFFER_ADDRESS 0x580
#define EP3_ODD_DATA_BUFFER_ADDRESS 0x5C0
#define EP1IN_EVEN_DATA_BUFFER_ADDRESS 0x600 // NEW MEMORY ADDRESS DECLARED
#define EP1IN_ODD_DATA_BUFFER_ADDRESS 0x640// NEW MEMORY ADDRESS DECLARED
#endif //FIXED_MEMORY_ADDRESS
установка адреса конечной точки также как 1
//Now that we are configured, enable the endpoints for use in the demo
// and start the initial transfers
USBEnableEndpoint(1,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
USBEnableEndpoint(2,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
USBEnableEndpoint(3,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
// USBEnableEndpoint(1,USB_OUT_ENABLED|USB_IN_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
//Prepare the OUT endpoints to receive the first packets from the host.
EP1OUTEvenHandle = USBTransferOnePacket(1, OUT_FROM_HOST,(uint8_t*)&EP1OUTEvenBuffer,64); //First 64-bytes of data sent to EP1 OUT will arrive in the even buffer.
EP1OUTOddHandle = USBTransferOnePacket(1, OUT_FROM_HOST,(uint8_t*)&EP1OUTOddBuffer,64); //Second 64-bytes of data sent to EP1 OUT will arrive in the odd buffer.
EP1OUTEvenNeedsServicingNext = true; //Used to keep track of which buffer will contain the next sequential data packet.
EP2OUTEvenHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTEvenBuffer,64);
EP2OUTOddHandle = USBTransferOnePacket(2, OUT_FROM_HOST,(uint8_t*)&EP2OUTOddBuffer,64);
EP2OUTEvenNeedsServicingNext = true; //Used to keep track of which buffer will contain the next sequential data packet.
EP3OUTEvenHandle = USBTransferOnePacket(3, OUT_FROM_HOST,(uint8_t*)&EP3OUTEvenBuffer,64);
EP3OUTOddHandle = USBTransferOnePacket(3, OUT_FROM_HOST,(uint8_t*)&EP3OUTOddBuffer,64);
EP3OUTEvenNeedsServicingNext = true; //Used to keep track of which buffer will contain the next sequential data packet.
EP1INEvenHandle = USBTransferOnePacket(1, IN_TO_HOST,(uint8_t*)&EP1INEvenBuffer,64); //First 64-bytes of data RECIVE to EP3 IN will arrive in the even buffer.
EP1INOddHandle = USBTransferOnePacket(1, IN_TO_HOST,(uint8_t*)&EP1INOddBuffer,64); //Second 64-bytes of data RECIVE to EP3 IN will arrive in the odd buffer.
EP1INEvenNeedsServicingNext = true;
USB DESCRIPTOR
/* Device Descriptor */
const USB_DEVICE_DESCRIPTOR device_dsc=
{
0x12, // Size of this descriptor in bytes
USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
0x0200, // USB Spec Release Number in BCD format
0x00, // Class Code
0x00, // Subclass code
0x00, // Protocol code
USB_EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
0x04D8, // Vendor ID: 0x04D8 is Microchip's Vendor ID
0x0052, // Product ID: 0x0052
0x0000, // Device release number in BCD format
0x01, // Manufacturer string index
0x02, // Product string index
0x00, // Device serial number string index
0x01 // Number of possible configurations
};
/* Configuration 1 Descriptor */
const uint8_t configDescriptor1[]={
/* Configuration Descriptor */
0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
0x2E,0x00, // Total length of data for this cfg
1, // Number of interfaces in this cfg
1, // Index value of this configuration
0, // Configuration string index
_DEFAULT | _SELF, // Attributes, see usb_device.h
50, // Max power consumption (2X mA)
/* Interface Descriptor */
0x09,//sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_INTERFACE, // INTERFACE descriptor type
0, // Interface Number
0, // Alternate Setting Number
4, // Number of endpoints in this intf
0xFF, // Class code
0xFF, // Subclass code
0xFF, // Protocol code
0, // Interface string index
/* Endpoint Descriptor */
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_OUT, //EndpointAddress
_BULK, //Attributes
64,0x00, //size
1, //Interval
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP02_OUT, //EndpointAddress
_BULK, //Attributes
64,0x00, //size
1, //Interval
0x07, /*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP03_OUT, //EndpointAddress
_BULK, //Attributes
64,0x00, //size
1, //Interval
0x07, /*sizeof(USB_EP_DSC)*/// New Endpoint for Sending Data To Host
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_IN, //EndpointAddress// VALUE MODIFED FOR SENDING DATA
_BULK, //Attributes
64,0x00, //size
0 //Interval
};
ТАК ОСНОВНО ПРОБЛЕМА ПОЛУЧИЛА РЕШЕНИЕ, ПОТОМУ ЧТО Я ИСПОЛЬЗУЮ 1 В КАЧЕСТВЕ АДРЕСНОГО АДРЕСА ДЛЯ ОБОИХ ВХОДОВ И ВЫХОДОВ
ОДНАКО ЭТО ОЗНАЧАЕТ, ЧТО МОЯ КОММУНИКАЦИЯ ДВУСТОРОННЯЯ, И Я ХОЧУ, ЧТОБЫ ЭТО БЫЛО НАПРАВЛЕНО. ТАК, ЧТО Я МОГУ ДОБИТЬСЯ ВЫСШЕГО BADWIDTH.
Я ДОЛЖЕН УЗНАТЬ, КАК СВЯЗАТЬСЯ С ИСПОЛЬЗОВАНИЕМ 1 ВНЕ КОНЕЧНОЙ ТОЧКИ И 81 В АДРЕСЕ КОНЕЧНОЙ ТОЧКИ.
СЧАСТЛИВОЕ ПРОГРАММИРОВАНИЕ!!