I'm attempting to communicate over the onboard CAN bus on a fusion 7 with a mx795F512L and the 3.3V CANSPI Click board in position D on a Flip&Click (f&c).
An issue has come up when trying to build for the f&c. Taking the 3.3V CAN SPI and f&c USB examples and combining them then modifying for the f&c P32MZ2048EFH100 @ 80 Mhz so that it simply outputs a letter or a number to the HID terminal if it detects CAN communication.
I have tried both making a USBdsc.c file and using the one from the f&c USB example. In the case of just using the sample USBdsc.c file the code below compiles but 'USB HID Library' does not show up in the list in HID terminal. The original f&c USB sample compiles and functions correctly.
It almost appears as if the v4 PIC32 C compiler HID Terminal is building a more up to date descriptor yet the USB library is looking for a different or perhaps a previous version. I have searched in the forum and on Libstock but so far haven't found anything.
Attempting to build and use a new descriptor file gives these errors:
0 360 Unresolved extern 'hidInit0' __Lib_USB_MZ_HS.c
0 360 Unresolved extern 'stringDescriptors' __Lib_USB_MZ_HS.c
Lastly, not being too familiar with PPS the settings in the code for mikrobus D on the Flip&Click may be incorrect. I took a stab at it reading the data sheet and there's a great chance it's wrong. Probably among the many things awry with my code.
Any help is appreciated, thanks much.
-Colin
Here is the code for the newly created USBdsc.c file, it is quite different from the sample:
Code: Select all
const unsigned int USB_VENDOR_ID = 0x2DBC;
const unsigned int USB_PRODUCT_ID = 0x0001;
const char USB_SELF_POWER = 0x80; // Self powered 0xC0, 0x80 bus powered
const char USB_MAX_POWER = 50; // Bus power required in units of 2 mA
const char HID_INPUT_REPORT_BYTES = 64;
const char HID_OUTPUT_REPORT_BYTES = 64;
const char USB_TRANSFER_TYPE = 0x03; //0x03 Interrupt
const char EP_IN_INTERVAL = 1;
const char EP_OUT_INTERVAL = 1;
const char USB_INTERRUPT = 1;
const char USB_HID_EP = 1;
const char USB_HID_RPT_SIZE = 33;
/* Device Descriptor */
const struct {
char bLength; // bLength - Descriptor size in bytes (12h)
char bDescriptorType; // bDescriptorType - The constant DEVICE (01h)
unsigned int bcdUSB; // bcdUSB - USB specification release number (BCD)
char bDeviceClass; // bDeviceClass - Class Code
char bDeviceSubClass; // bDeviceSubClass - Subclass code
char bDeviceProtocol; // bDeviceProtocol - Protocol code
char bMaxPacketSize0; // bMaxPacketSize0 - Maximum packet size for endpoint 0
unsigned int idVendor; // idVendor - Vendor ID
unsigned int idProduct; // idProduct - Product ID
unsigned int bcdDevice; // bcdDevice - Device release number (BCD)
char iManufacturer; // iManufacturer - Index of string descriptor for the manufacturer
char iProduct; // iProduct - Index of string descriptor for the product.
char iSerialNumber; // iSerialNumber - Index of string descriptor for the serial number.
char bNumConfigurations; // bNumConfigurations - Number of possible configurations
} device_dsc = {
0x12, // bLength
0x01, // bDescriptorType
0x0200, // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
8, // bMaxPacketSize0
USB_VENDOR_ID, // idVendor
USB_PRODUCT_ID, // idProduct
0x0001, // bcdDevice
0x01, // iManufacturer
0x02, // iProduct
0x00, // iSerialNumber
0x01 // bNumConfigurations
};
/* Configuration 1 Descriptor */
const char configDescriptor1[]= {
// Configuration Descriptor
0x09, // bLength - Descriptor size in bytes
0x02, // bDescriptorType - The constant CONFIGURATION (02h)
0x29,0x00, // wTotalLength - The number of bytes in the configuration descriptor and all of its subordinate descriptors
1, // bNumInterfaces - Number of interfaces in the configuration
1, // bConfigurationValue - Identifier for Set Configuration and Get Configuration requests
0, // iConfiguration - Index of string descriptor for the configuration
USB_SELF_POWER, // bmAttributes - Self/bus power and remote wakeup settings
USB_MAX_POWER, // bMaxPower - Bus power required in units of 2 mA
// Interface Descriptor
0x09, // bLength - Descriptor size in bytes (09h)
0x04, // bDescriptorType - The constant Interface (04h)
0, // bInterfaceNumber - Number identifying this interface
0, // bAlternateSetting - A number that identifies a descriptor with alternate settings for this bInterfaceNumber.
2, // bNumEndpoint - Number of endpoints supported not counting endpoint zero
0x03, // bInterfaceClass - Class code
0, // bInterfaceSubclass - Subclass code
0, // bInterfaceProtocol - Protocol code
0, // iInterface - Interface string index
// HID Class-Specific Descriptor
0x09, // bLength - Descriptor size in bytes.
0x21, // bDescriptorType - This descriptor's type: 21h to indicate the HID class.
0x01,0x01, // bcdHID - HID specification release number (BCD).
0x00, // bCountryCode - Numeric expression identifying the country for localized hardware (BCD) or 00h.
1, // bNumDescriptors - Number of subordinate report and physical descriptors.
0x22, // bDescriptorType - The type of a class-specific descriptor that follows
USB_HID_RPT_SIZE,0x00, // wDescriptorLength - Total length of the descriptor identified above.
// Endpoint Descriptor
0x07, // bLength - Descriptor size in bytes (07h)
0x05, // bDescriptorType - The constant Endpoint (05h)
USB_HID_EP | 0x80, // bEndpointAddress - Endpoint number and direction
USB_TRANSFER_TYPE, // bmAttributes - Transfer type and supplementary information
0x40,0x00, // wMaxPacketSize - Maximum packet size supported
EP_IN_INTERVAL, // bInterval - Service interval or NAK rate
// Endpoint Descriptor
0x07, // bLength - Descriptor size in bytes (07h)
0x05, // bDescriptorType - The constant Endpoint (05h)
USB_HID_EP, // bEndpointAddress - Endpoint number and direction
USB_TRANSFER_TYPE, // bmAttributes - Transfer type and supplementary information
0x40,0x00, // wMaxPacketSize - Maximum packet size supported
EP_OUT_INTERVAL // bInterval - Service interval or NAK rate
};
const struct {
char report[USB_HID_RPT_SIZE];
}hid_rpt_desc =
{
{0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
0x09, 0x01, // Usage (Vendor Usage 1)
0xA1, 0x01, // Collection (Application)
// Input report
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum
0x15, 0x00, // Logical Minimum (data bytes in the report may have minimum value = 0x00)
0x26, 0xFF, 0x00, // Logical Maximum (data bytes in the report may have maximum value = 0x00FF = unsigned 255)
0x75, 0x08, // Report Size: 8-bit field size
0x95, HID_INPUT_REPORT_BYTES,// Report Count
0x81, 0x02, // Input (Data, Array, Abs)
// Output report
0x19, 0x01, // Usage Minimum
0x29, 0x40, // Usage Maximum
0x75, 0x08, // Report Size: 8-bit field size
0x95, HID_OUTPUT_REPORT_BYTES,// Report Count
0x91, 0x02, // Output (Data, Array, Abs)
0xC0} // End Collection
};
//Language code string descriptor
const struct {
char bLength;
char bDscType;
unsigned int string[1];
} strd1 = {
4,
0x03,
{0x0409}
};
//Manufacturer string descriptor
const struct{
char bLength;
char bDscType;
unsigned int string[4];
}strd2={
10, //sizeof this descriptor string
0x03,
{'t','e','s','t'}
};
//Product string descriptor
const struct{
char bLength;
char bDscType;
unsigned int string[4];
}strd3={
10, //sizeof this descriptor string
0x03,
{'t','e','s','t'}
};
//Array of configuration descriptors
const char* USB_config_dsc_ptr[1];
//Array of string descriptors
const char* USB_string_dsc_ptr[3];
void USB_Init_Desc(){
USB_config_dsc_ptr[0] = &configDescriptor1;
USB_string_dsc_ptr[0] = (const char*)&strd1;
USB_string_dsc_ptr[1] = (const char*)&strd2;
USB_string_dsc_ptr[2] = (const char*)&strd3;
}
Code: Select all
// snipped from Can_Spi_2st (CAN Network demonstration with mikroE's CAN SPI Click 3,3V)
#include <stdint.h>
#include "resources.h"
/**************************************************************************************************
* Global variables
**************************************************************************************************/
uint8_t cnt;
uint8_t kk;
uint8_t readbuff[64];
uint8_t writebuff[64];
unsigned char Can_Init_Flags, Can_Send_Flags, Can_Rcv_Flags; // can flags
unsigned char Rx_Data_Len; // received data length in bytes
char RxTx_Data[8]; // can rx/tx data buffer
char Msg_Rcvd; // reception flag
const long ID_1st = 12111, ID_2nd = 3; // node IDs
long Rx_ID;
/**************************************************************************************************
* Port read variables
**************************************************************************************************/
char port_rd;
char port_rd_temp;
char i;
char old_message = 0xFF;
sbit LEDA at LATA6_bit;
sbit LEDA_Dir at TRISA6_bit;
void main() {
Unlock_IOLOCK();
PPS_Mapping_NoLock( _RPD3, _OUTPUT, _SDO1 );
PPS_Mapping_NoLock( _RPD2, _INPUT, _SDI1 );
Lock_IOLOCK();
HID_Enable(readbuff, writebuff);
//AD1PCFG = 0xFFFF; // Configure AN pins as digital I/O
ANSELA = 1;
ANSELE = 1;
ANSELD = 1;
JTAGEN_bit = 0; // Disable JTAG
CanSpi_CS_Direction = 0;
CanSpi_CS = 1;
Can_Init_Flags = 0; //
Can_Send_Flags = 0; // clear flags
Can_Rcv_Flags = 0; //
Can_Send_Flags = _CANSPI_TX_PRIORITY_0 & // form value to be used
_CANSPI_TX_XTD_FRAME & // with CANSPIWrite
_CANSPI_TX_NO_RTR_FRAME;
Can_Init_Flags = _CANSPI_CONFIG_SAMPLE_THRICE & // form value to be used
_CANSPI_CONFIG_PHSEG2_PRG_ON & // with CANSPIInit
_CANSPI_CONFIG_XTD_MSG &
_CANSPI_CONFIG_DBL_BUFFER_ON &
_CANSPI_CONFIG_VALID_XTD_MSG &
_CANSPI_CONFIG_LINE_FILTER_OFF;
// Initialize SPI1 module
SPI1_Init_Advanced(_SPI_MASTER, _SPI_8_BIT, 80, _SPI_SS_DISABLE, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_HIGH, _SPI_ACTIVE_2_IDLE);
// Focs = 10MHz, SJW = 1, PHSEG1 = 3, PHSEG2 = 3, PROPSEG = 1, -> N = 1+3+3+1, N = 8
// Desired Baud rate Fbaud = 125kb/s
// BRP = Fosc/(2*N*Fbaud) = 5
CANSPIInitialize(1,5,3,3,1,Can_Init_Flags); // initialize external CANSPI module
CANSPISetOperationMode(_CANSPI_MODE_CONFIG,0xFF); // set CONFIGURATION mode
CANSPISetMask(_CANSPI_MASK_B1,-1,_CANSPI_CONFIG_XTD_MSG); // set all mask1 bits to ones
CANSPISetMask(_CANSPI_MASK_B2,-1,_CANSPI_CONFIG_XTD_MSG); // set all mask2 bits to ones
CANSPISetFilter(_CANSPI_FILTER_B2_F3,ID_1st,_CANSPI_CONFIG_XTD_MSG); // set id of filter B2_F3 to 1st node ID
CANSPISetOperationMode(_CANSPI_MODE_NORMAL,0xFF); // set NORMAL mode
while(1) // endless loop
{
//LATA6_bit =~ PORTAbits.RA6;
//Delay_ms(100);
////////////////////////////////////////////////////
USB_Polling_Proc(); // Call this routine periodically
kk = HID_Read(); // not really used for this test
Msg_Rcvd = CANSPIRead(&Rx_ID , RxTx_Data , &Rx_Data_Len, &Can_Rcv_Flags); // receive message
if ((Rx_ID == ID_1st) && Msg_Rcvd) { // if message received check id
if (RxTx_Data[0] != old_message){ // id correct, output data at PORTD
old_message = RxTx_Data[0];
HID_Write("a", 64); // HID_Write(7, 64); //send a character to HID as confirmation
//LATA6_bit =~ PORTAbits.RA6; // toggle LEDA
}
}
}
}