Last active
July 7, 2022 10:44
-
-
Save mikklfr/b973f245ef83eca5f6f2 to your computer and use it in GitHub Desktop.
PIC18f26j50 CCS USB HID
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <18F26J50.h> | |
#fuses INTRC_PLL,PLL2,CPUDIV2 | |
#use delay(clock=6M) | |
// or clock=8M | |
#define USB_CONFIG_HID_TX_SIZE 60 | |
#define USB_CONFIG_HID_RX_SIZE 60 | |
#include <pic18_usb.h> | |
#include "my_usb_desc_hid.h" | |
#include <usb.c> | |
#include <STRING.H> | |
#include <stdio.h> | |
void usb_debug_task(void) | |
{ | |
int8 new_connected; | |
int8 new_enumerated; | |
new_connected=usb_attached(); | |
new_enumerated=usb_enumerated(); | |
} | |
char ledon[] = "AT LED ON"; | |
char ledoff[] = "AT LED OFF"; | |
char unknown[] = "Je connais pas"; | |
void main(void) | |
{ | |
char out_data[USB_CONFIG_HID_TX_SIZE]; | |
char in_data[USB_CONFIG_HID_RX_SIZE]; | |
setup_oscillator(OSC_PLL_ON); | |
usb_init_cs(); | |
char LED_ON = 1; | |
while (TRUE) | |
{ | |
if (LED_ON == 1) { | |
output_high(PIN_B7); | |
} else { | |
output_low(PIN_B7); | |
} | |
usb_task(); | |
usb_debug_task(); | |
if (usb_enumerated()) | |
{ | |
if (usb_kbhit(1)) | |
{ | |
usb_get_packet(1, in_data, USB_CONFIG_HID_RX_SIZE); | |
if (strstr(in_data, ledon) != 0) { | |
LED_ON = 1; | |
usb_put_packet(1, ledon, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE); | |
} | |
else if (strstr(in_data, ledoff) != 0) { | |
LED_ON = 0; | |
usb_put_packet(1, ledoff, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE); | |
} else { | |
usb_put_packet(1, unknown, USB_CONFIG_HID_TX_SIZE, USB_DTS_TOGGLE); | |
} | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/////////////////////////////////////////////////////////////////////////// | |
/// usb_desc_hid.h //// | |
//// //// | |
//// An example set of device / configuration descriptors for use with //// | |
//// CCS's HID Demo example (see ex_usb_hid.c) //// | |
//// //// | |
/////////////////////////////////////////////////////////////////////////// | |
//// //// | |
//// Version History: //// | |
//// //// | |
//// September 9th, 2010: //// | |
//// USB_CONFIG_HID_TX_SIZE and USB_CONFIG_HID_RX_SIZE were backwards //// | |
//// in HID report descriptor of usb_desc_hid.h //// | |
//// //// | |
//// March 5th, 2009: //// | |
//// Cleanup for Wizard. //// | |
//// PIC24 Initial release. //// | |
//// //// | |
//// June 20th, 2005: //// | |
//// PIC18Fxx5x initial release //// | |
//// //// | |
//// March 21st, 2005: //// | |
//// EP 0x01 and EP 0x81 now use USB_EP1_TX_SIZE and USB_EP1_RX_SIZE //// | |
//// to define max packet size, to make it easier for dynamically //// | |
//// changed code. //// | |
//// EP 0x01 and EP 0x81 will now use 1ms polling interval if using //// | |
//// a full speed device. //// | |
//// //// | |
//// May 4th, 2004: Optimization and cleanup. //// | |
//// Some definitions may have changed. //// | |
//// //// | |
//// May 6th, 2003: Fixed non-HID descriptors pointing to faulty //// | |
//// strings //// | |
//// //// | |
//// August 2nd, 2002: Initial Public Release //// | |
//// //// | |
//// //// | |
/////////////////////////////////////////////////////////////////////////// | |
//// (C) Copyright 1996,2005 Custom Computer Services //// | |
//// This source code may only be used by licensed users of the CCS //// | |
//// C compiler. This source code may only be distributed to other //// | |
//// licensed users of the CCS C compiler. No other use, //// | |
//// reproduction or distribution is permitted without written //// | |
//// permission. Derivative programs created using this software //// | |
//// in object code form are not restricted in any way. //// | |
/////////////////////////////////////////////////////////////////////////// | |
#IFNDEF __USB_DESCRIPTORS__ | |
#DEFINE __USB_DESCRIPTORS__ | |
#ifndef USB_CONFIG_PID | |
#define USB_CONFIG_PID 0x0020 | |
#endif | |
#ifndef USB_CONFIG_VID | |
#define USB_CONFIG_VID 0x0461 | |
#endif | |
#ifndef USB_CONFIG_BUS_POWER | |
//valid range is 0..500 | |
#define USB_CONFIG_BUS_POWER 100 //100mA | |
#endif | |
#ifndef USB_CONFIG_VERSION | |
//version number that is stored into descriptor, in bcd. | |
//range is 00.00 to 99.99 | |
#define USB_CONFIG_VERSION 0x0100 //01.00 | |
#endif | |
#ifndef USB_CONFIG_HID_TX_SIZE | |
//valid range is 0-255 | |
#define USB_CONFIG_HID_TX_SIZE 2 //compatible with hiddemo.exe | |
#endif | |
#ifndef USB_CONFIG_HID_RX_SIZE | |
//valid range is 0-255 | |
#define USB_CONFIG_HID_RX_SIZE 2 //compatible with hiddemo.exe | |
#endif | |
#ifndef USB_CONFIG_HID_TX_POLL | |
// for full speed devices, valid range is 1-255 | |
// for slow speed devices, valid range is 10-255 | |
#define USB_CONFIG_HID_TX_POLL 10 | |
#endif | |
#ifndef USB_CONFIG_HID_RX_POLL | |
// for full speed devices, valid range is 1-255 | |
// for slow speed devices, valid range is 10-255 | |
#define USB_CONFIG_HID_RX_POLL 10 | |
#endif | |
//Tells the CCS PIC USB firmware to include HID handling code. | |
#ifdef USB_HID_DEVICE | |
#undef USB_HID_DEVICE | |
#endif | |
#DEFINE USB_HID_DEVICE TRUE | |
//the following defines needed for the CCS USB PIC driver to enable the TX endpoint 1 | |
// and allocate buffer space on the peripheral | |
#ifdef USB_EP1_TX_ENABLE | |
#undef USB_EP1_TX_ENABLE | |
#endif | |
#define USB_EP1_TX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for IN bulk/interrupt transfers | |
#ifndef USB_EP1_TX_SIZE | |
#if (USB_CONFIG_HID_TX_SIZE >= 64) | |
// interrupt endpoint max packet size is 64. | |
#define USB_EP1_TX_SIZE 64 | |
#else | |
// by making EP packet size larger than message size, we can send message in one packet. | |
#define USB_EP1_TX_SIZE (USB_CONFIG_HID_TX_SIZE+1) | |
#endif | |
#endif | |
#ifdef USB_EP1_RX_ENABLE | |
#undef USB_EP1_RX_ENABLE | |
#endif | |
#define USB_EP1_RX_ENABLE USB_ENABLE_INTERRUPT //turn on EP1 for OUT bulk/interrupt transfers | |
#ifndef USB_EP1_RX_SIZE | |
#if (USB_CONFIG_HID_RX_SIZE >= 64) | |
// interrupt endpoint max packet size is 64. | |
#define USB_EP1_RX_SIZE 64 | |
#else | |
// by making EP packet size larger than message size, we can send message in one packet. | |
#define USB_EP1_RX_SIZE (USB_CONFIG_HID_RX_SIZE+1) | |
#endif | |
#endif | |
#include <usb.h> | |
////////////////////////////////////////////////////////////////// | |
/// | |
/// HID Report. Tells HID driver how to handle and deal with | |
/// received data. HID Reports can be extremely complex, | |
/// see HID specifcation for help on writing your own. | |
/// | |
/// CCS example uses a vendor specified usage, that sends and | |
/// receives 2 absolute bytes ranging from 0 to 0xFF. | |
/// | |
////////////////////////////////////////////////////////////////// | |
const char USB_CLASS_SPECIFIC_DESC[] = | |
{ | |
6, 0, 255, // Usage Page = Vendor Defined | |
9, 1, // Usage = IO device | |
0xa1, 1, // Collection = Application | |
0x19, 1, // Usage minimum | |
0x29, 8, // Usage maximum | |
0x15, 0x80, // Logical minimum (-128) | |
0x25, 0x7F, // Logical maximum (127) | |
0x75, 8, // Report size = 8 (bits) | |
0x95, USB_CONFIG_HID_TX_SIZE, // Report count = 16 bits (2 bytes) | |
0x81, 2, // Input (Data, Var, Abs) | |
0x19, 1, // Usage minimum | |
0x29, 8, // Usage maximum | |
0x75, 8, // Report size = 8 (bits) | |
0x95, USB_CONFIG_HID_RX_SIZE, // Report count = 16 bits (2 bytes) | |
0x91, 2, // Output (Data, Var, Abs) | |
0xc0 // End Collection | |
}; | |
//if a class has an extra descriptor not part of the config descriptor, | |
// this lookup table defines where to look for it in the const | |
// USB_CLASS_SPECIFIC_DESC[] array. | |
//first element is the config number (if your device has more than one config) | |
//second element is which interface number | |
//set element to 0xFFFF if this config/interface combo doesn't exist | |
const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP[USB_NUM_CONFIGURATIONS][1] = | |
{ | |
//config 1 | |
//interface 0 | |
0 | |
}; | |
//if a class has an extra descriptor not part of the config descriptor, | |
// this lookup table defines the size of that descriptor. | |
//first element is the config number (if your device has more than one config) | |
//second element is which interface number | |
//set element to 0xFFFF if this config/interface combo doesn't exist | |
const int16 USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[USB_NUM_CONFIGURATIONS][1] = | |
{ | |
//config 1 | |
//interface 0 | |
32 | |
}; | |
////////////////////////////////////////////////////////////////// | |
/// | |
/// start config descriptor | |
/// right now we only support one configuration descriptor. | |
/// the config, interface, class, and endpoint goes into this array. | |
/// | |
////////////////////////////////////////////////////////////////// | |
#DEFINE USB_TOTAL_CONFIG_LEN 41 //config+interface+class+endpoint+endpoint (2 endpoints) | |
const char USB_CONFIG_DESC[] = { | |
//IN ORDER TO COMPLY WITH WINDOWS HOSTS, THE ORDER OF THIS ARRAY MUST BE: | |
// config(s) | |
// interface(s) | |
// class(es) | |
// endpoint(s) | |
//config_descriptor for config index 1 | |
USB_DESC_CONFIG_LEN, //length of descriptor size ==1 | |
USB_DESC_CONFIG_TYPE, //constant CONFIGURATION (CONFIGURATION 0x02) ==2 | |
USB_TOTAL_CONFIG_LEN,0, //size of all data returned for this config ==3,4 | |
1, //number of interfaces this device supports ==5 | |
0x01, //identifier for this configuration. (IF we had more than one configurations) ==6 | |
0x00, //index of string descriptor for this configuration ==7 | |
// #if USB_CONFIG_BUS_POWER | |
0x80, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and bit7=1 ==8 | |
// #else | |
// 0xC0, //bit 6=1 if self powered, bit 5=1 if supports remote wakeup (we don't), bits 0-4 unused and bit7=1 ==8 | |
// #endif | |
USB_CONFIG_BUS_POWER/2, //maximum bus power required (maximum milliamperes/2) (0x32 = 100mA) | |
//interface descriptor 1 | |
USB_DESC_INTERFACE_LEN, //length of descriptor =10 | |
USB_DESC_INTERFACE_TYPE, //constant INTERFACE (INTERFACE 0x04) =11 | |
0x00, //number defining this interface (IF we had more than one interface) ==12 | |
0x00, //alternate setting ==13 | |
2, //number of endpoins, except 0 (pic167xx has 3, but we dont have to use all). ==14 | |
0x03, //class code, 03 = HID ==15 | |
0x00, //subclass code //boot ==16 | |
0x00, //protocol code ==17 | |
0x00, //index of string descriptor for interface ==18 | |
//class descriptor 1 (HID) | |
USB_DESC_CLASS_LEN, //length of descriptor ==19 | |
USB_DESC_CLASS_TYPE, //dscriptor type (0x21 == HID) ==20 | |
0x00,0x01, //hid class release number (1.0) ==21,22 | |
0x00, //localized country code (0 = none) ==23 | |
0x01, //number of hid class descrptors that follow (1) ==24 | |
0x22, //report descriptor type (0x22 == HID) ==25 | |
USB_CLASS_SPECIFIC_DESC_LOOKUP_SIZE[0][0], 0x00, //length of report descriptor ==26,27 | |
//endpoint descriptor | |
USB_DESC_ENDPOINT_LEN, //length of descriptor ==28 | |
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==29 | |
0x81, //endpoint number and direction (0x81 = EP1 IN) ==30 | |
USB_EP1_TX_ENABLE, //transfer type supported (0x03 is interrupt) ==31 | |
USB_EP1_TX_SIZE,0x00, //maximum packet size supported ==32,33 | |
USB_CONFIG_HID_TX_POLL, //polling interval, in ms. (cant be smaller than 10 for slow speed) ==34 | |
//endpoint descriptor | |
USB_DESC_ENDPOINT_LEN, //length of descriptor ==35 | |
USB_DESC_ENDPOINT_TYPE, //constant ENDPOINT (ENDPOINT 0x05) ==36 | |
0x01, //endpoint number and direction (0x01 = EP1 OUT) ==37 | |
USB_EP1_RX_ENABLE, //transfer type supported (0x03 is interrupt) ==38 | |
USB_EP1_RX_SIZE,0x00, //maximum packet size supported ==39,40 | |
USB_CONFIG_HID_RX_POLL //polling interval, in ms. (cant be smaller than 10 for slow speed) ==41 | |
}; | |
//****** BEGIN CONFIG DESCRIPTOR LOOKUP TABLES ******** | |
//since we can't make pointers to constants in certain pic16s, this is an offset table to find | |
// a specific descriptor in the above table. | |
//NOTE: DO TO A LIMITATION OF THE CCS CODE, ALL HID INTERFACES MUST START AT 0 AND BE SEQUENTIAL | |
// FOR EXAMPLE, IF YOU HAVE 2 HID INTERFACES THEY MUST BE INTERFACE 0 AND INTERFACE 1 | |
#define USB_NUM_HID_INTERFACES 1 | |
//the maximum number of interfaces seen on any config | |
//for example, if config 1 has 1 interface and config 2 has 2 interfaces you must define this as 2 | |
#define USB_MAX_NUM_INTERFACES 1 | |
//define how many interfaces there are per config. [0] is the first config, etc. | |
const char USB_NUM_INTERFACES[USB_NUM_CONFIGURATIONS]={1}; | |
//define where to find class descriptors | |
//first dimension is the config number | |
//second dimension specifies which interface | |
//last dimension specifies which class in this interface to get, but most will only have 1 class per interface | |
//if a class descriptor is not valid, set the value to 0xFFFF | |
const int16 USB_CLASS_DESCRIPTORS[USB_NUM_CONFIGURATIONS][1][1]= | |
{ | |
//config 1 | |
//interface 0 | |
//class 1 | |
18 | |
}; | |
#if (sizeof(USB_CONFIG_DESC) != USB_TOTAL_CONFIG_LEN) | |
#error USB_TOTAL_CONFIG_LEN not defined correctly | |
#endif | |
////////////////////////////////////////////////////////////////// | |
/// | |
/// start device descriptors | |
/// | |
////////////////////////////////////////////////////////////////// | |
const char USB_DEVICE_DESC[USB_DESC_DEVICE_LEN] ={ | |
//starts of with device configuration. only one possible | |
USB_DESC_DEVICE_LEN, //the length of this report ==1 | |
0x01, //the constant DEVICE (DEVICE 0x01) ==2 | |
0x10,0x01, //usb version in bcd ==3,4 | |
0x00, //class code ==5 | |
0x00, //subclass code ==6 | |
0x00, //protocol code ==7 | |
USB_MAX_EP0_PACKET_LENGTH, //max packet size for endpoint 0. (SLOW SPEED SPECIFIES 8) ==8 | |
USB_CONFIG_VID & 0xFF, ((USB_CONFIG_VID >> 8) & 0xFF), //vendor id ==9, 10 | |
USB_CONFIG_PID & 0xFF, ((USB_CONFIG_PID >> 8) & 0xFF), //product id, don't use 0xffff ==11, 12 | |
USB_CONFIG_VERSION & 0xFF, ((USB_CONFIG_VERSION >> 8) & 0xFF), //device release number ==13,14 | |
0x01, //index of string description of manufacturer. therefore we point to string_1 array (see below) ==15 | |
0x02, //index of string descriptor of the product ==16 | |
0x00, //index of string descriptor of serial number ==17 | |
USB_NUM_CONFIGURATIONS //number of possible configurations ==18 | |
}; | |
////////////////////////////////////////////////////////////////// | |
/// | |
/// start string descriptors | |
/// String 0 is a special language string, and must be defined. People in U.S.A. can leave this alone. | |
/// | |
/// You must define the length else get_next_string_character() will not see the string | |
/// Current code only supports 10 strings (0 thru 9) | |
/// | |
////////////////////////////////////////////////////////////////// | |
//the offset of the starting location of each string. offset[0] is the start of string 0, offset[1] is the start of string 1, etc. | |
char USB_STRING_DESC_OFFSET[]={0,4,12}; | |
// Here is where the "CCS" Manufacturer string and "CCS HID Demo" are stored. | |
// Strings are saved as unicode. | |
// These strings are mostly only displayed during the add hardware wizard. | |
// Once the operating system drivers have been installed it will usually display | |
// the name from the drivers .INF. | |
char const USB_STRING_DESC[]={ | |
//string 0 | |
4, //length of string index | |
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) | |
0x09,0x04, //Microsoft Defined for US-English | |
//string 1 | |
8, //length of string index | |
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) | |
'C',0, | |
'C',0, | |
'S',0, | |
//string 2 | |
26, //length of string index | |
USB_DESC_STRING_TYPE, //descriptor type 0x03 (STRING) | |
'R',0, | |
'E',0, | |
'G',0, | |
'U',0, | |
'L',0, | |
'S',0, | |
'M',0, | |
'O',0, | |
'K',0, | |
'E',0, | |
' ',0, | |
' ',0, | |
}; | |
#ENDIF |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment