changed bootloader back to using the minimal usb stack it came with because I have no idea how to get the bootloader code working with the full MLA HID USB stack

This commit is contained in:
2019-08-13 22:52:23 -04:00
parent 1ced4e1b78
commit a90344ef4c
19 changed files with 3823 additions and 510 deletions

View File

@@ -2,23 +2,6 @@
<configurationDescriptor version="65">
<logicalFolder name="root" displayName="root" projectFiles="true">
<logicalFolder name="f1" displayName="common_src" projectFiles="true">
<logicalFolder name="framework" displayName="framework" projectFiles="true">
<logicalFolder name="usb" displayName="usb" projectFiles="true">
<logicalFolder name="inc" displayName="inc" projectFiles="true">
<itemPath>../../common_src/framework/usb/inc/usb.h</itemPath>
<itemPath>../../common_src/framework/usb/inc/usb_ch9.h</itemPath>
<itemPath>../../common_src/framework/usb/inc/usb_common.h</itemPath>
<itemPath>../../common_src/framework/usb/inc/usb_device.h</itemPath>
<itemPath>../../common_src/framework/usb/inc/usb_device_hid.h</itemPath>
<itemPath>../../common_src/framework/usb/inc/usb_hal.h</itemPath>
<itemPath>../../common_src/framework/usb/inc/usb_hal_pic18.h</itemPath>
</logicalFolder>
<logicalFolder name="src" displayName="src" projectFiles="true">
<itemPath>../../common_src/framework/usb/src/usb_device.c</itemPath>
<itemPath>../../common_src/framework/usb/src/usb_device_hid.c</itemPath>
</logicalFolder>
</logicalFolder>
</logicalFolder>
<itemPath>../../common_src/system.c</itemPath>
<itemPath>../../common_src/memory.h</itemPath>
</logicalFolder>
@@ -27,16 +10,25 @@
projectFiles="true">
<itemPath>../src/usb_config.h</itemPath>
<itemPath>../src/bootloader.h</itemPath>
<itemPath>../src/typedefs.h</itemPath>
</logicalFolder>
<logicalFolder name="LinkerScript"
displayName="Linker Files"
projectFiles="true">
</logicalFolder>
<logicalFolder name="minimal_usb_driver"
displayName="minimal_usb_driver"
projectFiles="true">
<itemPath>../src/minimal_usb_driver/usb_device.c</itemPath>
<itemPath>../src/minimal_usb_driver/usb_device_hid.c</itemPath>
<itemPath>../src/minimal_usb_driver/usb.h</itemPath>
<itemPath>../src/minimal_usb_driver/usb_device.h</itemPath>
<itemPath>../src/minimal_usb_driver/usb_device_hid.h</itemPath>
</logicalFolder>
<logicalFolder name="SourceFiles"
displayName="Source Files"
projectFiles="true">
<itemPath>../src/usb_descriptors.c</itemPath>
<itemPath>../src/usb_events.c</itemPath>
<itemPath>../src/main.c</itemPath>
<itemPath>../src/bootloader.c</itemPath>
<itemPath>../src/VectorRemap.asm</itemPath>
@@ -100,7 +92,7 @@
<property key="define-macros" value=""/>
<property key="disable-optimizations" value="true"/>
<property key="extra-include-directories"
value="..\src;..\..\common_src\framework\usb\inc;..\..\common_src"/>
value="..\src;..\..\common_src;..\src\minimal_usb_driver"/>
<property key="favor-optimization-for" value="-speed,+space"/>
<property key="garbage-collect-data" value="true"/>
<property key="garbage-collect-functions" value="true"/>
@@ -139,7 +131,7 @@
<property key="calibrate-oscillator-value" value="0x3400"/>
<property key="clear-bss" value="true"/>
<property key="code-model-external" value="wordwrite"/>
<property key="code-model-rom" value="default,-2080-7FFF"/>
<property key="code-model-rom" value="default,-2000-7FFF"/>
<property key="create-html-files" value="false"/>
<property key="data-model-ram" value=""/>
<property key="data-model-size-of-double" value="32"/>

View File

@@ -20,14 +20,14 @@
;//High priority interrupt vector remapping
PSECT HiVector,class=CODE,delta=1,abs
org 0x08
goto 0x2088 ;Resides at 0x0008 (hardware high priority interrupt vector), and causes PC to jump to 0x2008 upon a high priority interrupt event
goto 0x2008 ;Resides at 0x0008 (hardware high priority interrupt vector), and causes PC to jump to 0x2008 upon a high priority interrupt event
;//Low priority interrupt vector remapping, as well as bootloader mode absolute
;//entry point (located at 0x001C).
PSECT LoVector,class=CODE,delta=1,abs
org 0x18
goto 0x2098 ;Resides at 0x0018 (hardware low priority interrupt vector), and causes PC to jump to 0x2018 upon a low priority interrupt event
goto 0x2018 ;Resides at 0x0018 (hardware low priority interrupt vector), and causes PC to jump to 0x2018 upon a low priority interrupt event
goto 0x30 ;Resides at 0x001C //Serves as absolute entry point from application program into the bootloader mode

View File

@@ -1,10 +1,7 @@
#include "bootloader.h"
#include <xc.h>
#include "usb.h"
#include "usb_device_hid.h"
#include "bootloader.h"
#undef uint24_t
#define uint24_t uint32_t
//The bootloader version, which the bootloader PC application can do extended query to get.
//Value provided is expected to be in the format of BOOTLOADER_VERSION_MAJOR.BOOTLOADER_VERSION_MINOR
@@ -145,8 +142,8 @@ typedef union
};
} PacketToFromPC;
PacketToFromPC PacketFromPC __at(0x42C);
PacketToFromPC PacketToPC __at(0x46C);
PacketToFromPC PacketFromPC;
PacketToFromPC PacketToPC;
unsigned char ProgrammingBuffer[ERASE_PAGE_SIZE];
unsigned char BootState;
unsigned int ErasePageTracker;
@@ -154,9 +151,6 @@ unsigned char BufferedDataIndex;
uint24_t ProgrammedPointer;
unsigned char ConfigsLockValue;
USB_VOLATILE USB_HANDLE txHandle;
USB_VOLATILE USB_HANDLE rxHandle;
void WriteFlashBlock(void);
void WriteConfigBits(void);
void WriteEEPROM(void);
@@ -173,10 +167,6 @@ void UserInit(void)
ProgrammedPointer = INVALID_ADDRESS;
BufferedDataIndex = 0;
ConfigsLockValue = 1;
USBEnableEndpoint(HID_EP, USB_IN_ENABLED|USB_OUT_ENABLED|USB_HANDSHAKE_ENABLED|USB_DISALLOW_SETUP);
rxHandle = HIDRxPacket(HID_EP, (uint8_t *)&PacketFromPC, USB_PACKET_SIZE);
txHandle = 0;
}
/******************************************************************************
@@ -218,12 +208,11 @@ void ProcessIO(void)
{
//We are currently in the IDLE state waiting for a command from the
//PC software on the USB host.
if(!HIDRxHandleBusy(rxHandle)) //Did we receive a command?
if(!mHIDRxIsBusy()) //Did we receive a command?
{
//We received a new command from the host. Copy the OUT packet from
//the host into a local buffer for processing.
rxHandle = HIDRxPacket(HID_EP, (uint8_t *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
//HIDRxReport((char *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
HIDRxReport((char *)&PacketFromPC, USB_PACKET_SIZE); //Also re-arms the OUT endpoint to be able to receive the next packet
BootState = NOT_IDLE; //Set flag letting state machine know it has a command that needs processing.
//Pre-initialize a response packet buffer (only used for some commands)
@@ -240,7 +229,7 @@ void ProcessIO(void)
case QUERY_DEVICE:
//Make sure the USB IN endpoint buffer is available, then load
//up a query response packet to send to the host.
if(!HIDTxHandleBusy(txHandle))
if(!mHIDTxIsBusy())
{
//Prepare a response packet, which lets the PC software know about the memory ranges of this device.
PacketToPC.Command = QUERY_DEVICE;
@@ -266,7 +255,7 @@ void ProcessIO(void)
//Init pad bytes to 0x00... Already done after we received the QUERY_DEVICE command (just after calling HIDRxReport()).
//Now send the packet to the USB host software, assuming the USB endpoint is available/ready to accept new data.
txHandle = HIDTxPacket(HID_EP, (uint8_t *)&PacketToPC, USB_PACKET_SIZE);
HIDTxReport((char *)&PacketToPC, USB_PACKET_SIZE);
BootState = IDLE;
}
break;
@@ -390,9 +379,9 @@ void ProcessIO(void)
//Assuming the USB IN (to host) buffer is available/ready, copy the
//data over so it can get sent to the USB host software.
if(!HIDTxHandleBusy(txHandle))
if(!mHIDTxIsBusy())
{
txHandle = HIDTxPacket(HID_EP, (uint8_t *)&PacketToPC, USB_PACKET_SIZE);
HIDTxReport((char *)&PacketToPC, USB_PACKET_SIZE);
BootState = IDLE;
}
break;
@@ -428,9 +417,9 @@ void ProcessIO(void)
PacketToPC.Config7HMask = 0xFF;
//Now actually command USB to send the packet to the host
if(!HIDTxHandleBusy(txHandle))
if(!mHIDTxIsBusy())
{
txHandle = HIDTxPacket(HID_EP, (uint8_t *)&PacketToPC, USB_PACKET_SIZE);
HIDTxReport((char *)&PacketToPC, USB_PACKET_SIZE);
BootState = IDLE; //Packet will be sent, go back to idle state ready for next command from host
}
break;

View File

@@ -38,9 +38,9 @@ void ProcessIO(void);
//#define REMAPPED_APPLICATION_LOW_ISR_VECTOR APP_FW_MEMORY_OFFSET + 0x18 //See VectorRemap.asm
#define BOOTLOADER_ABSOLUTE_ENTRY_ADDRESS BOOTLOADER_ENTRYPOINT //Execute a "goto 0x001C" inline assembly instruction, if you want to enter the bootloader mode from the application via software
#define APP_SIGNATURE_ADDRESS APP_FW_MEMORY_OFFSET + 0x06 //0x1C06 and 0x1C07 contains the "signature" WORD, indicating successful erase/program/verify operation
#define APP_SIGNATURE_VALUE 0x600D //leet "GOOD", implying that the erase/program was a success and the bootloader intentionally programmed the APP_SIGNATURE_ADDRESS with this value
#define APP_VERSION_ADDRESS APP_FW_MEMORY_OFFSET + 0x16 //0x1C16 and 0x1C17 should contain the application image firmware version number
//#define APP_SIGNATURE_ADDRESS APP_FW_MEMORY_OFFSET + 0x06 //0x1C06 and 0x1C07 contains the "signature" WORD, indicating successful erase/program/verify operation
//#define APP_SIGNATURE_VALUE 0x600D //leet "GOOD", implying that the erase/program was a success and the bootloader intentionally programmed the APP_SIGNATURE_ADDRESS with this value
//#define APP_VERSION_ADDRESS APP_FW_MEMORY_OFFSET + 0x16 //0x1C16 and 0x1C17 should contain the application image firmware version number
#endif /* BOOTLOADER_ */

View File

@@ -5,15 +5,18 @@
* Created on August 9, 2019, 6:14 PM
*/
#include <xc.h>
#include "usb.h"
#include "bootloader.h"
unsigned int uint_delay_counter;
/* Private prototypes */
void main(void);
void BootMain(void);
void InitializeSystem(void);
const unsigned int FlashSignatureWord __at(APP_SIGNATURE_ADDRESS) = APP_SIGNATURE_VALUE;
//const unsigned int FlashSignatureWord __at(APP_SIGNATURE_ADDRESS) = APP_SIGNATURE_VALUE;
void main(void)
{
@@ -24,7 +27,7 @@ void main(void)
// normal operation: verify the firmware signature is valid. if it isn't enter
// bootloader (fw update) mode so valid firmware can be flashed
//DoFlashSignatureCheck:
DoFlashSignatureCheck:
//Check if the application region flash signature is valid
if(*(const unsigned int*)APP_SIGNATURE_ADDRESS == APP_SIGNATURE_VALUE)
{
@@ -62,12 +65,8 @@ void BootMain(void) __at(0x30)
// any C initialized user variables (idata memory sections). Therefore, the above is all
// the initialization that is required.
// initialize the USB framework
USBDeviceInit();
USBDeviceAttach();
// initialize the bootloader
UserInit();
//Call other initialization code and (re)enable the USB module
InitializeSystem();
//Execute main loop
while(1)
@@ -81,3 +80,194 @@ void BootMain(void) __at(0x30)
//place see ProcessIO() function in the BootPIC[xxxx].c file.
}//end while
}
void InitializeSystem(void)
{
UserInit();
USBDeviceInit();
}
// ******************************************************************************************************
// ************** USB Callback Functions ****************************************************************
// ******************************************************************************************************
// The USB firmware stack will call the callback functions USBCBxxx() in response to certain USB related
// events. For example, if the host PC is powering down, it will stop sending out Start of Frame (SOF)
// packets to your device. In response to this, all USB devices are supposed to decrease their power
// consumption from the USB Vbus to <2.5mA* each. The USB module detects this condition (which according
// to the USB specifications is 3+ms of no bus activity/SOF packets) and then calls the USBCBSuspend()
// function. You should modify these callback functions to take appropriate actions for each of these
// conditions. For example, in the USBCBSuspend(), you may wish to add code that will decrease power
// consumption from Vbus to <2.5mA (such as by clock switching, turning off LEDs, putting the
// microcontroller to sleep, etc.). Then, in the USBCBWakeFromSuspend() function, you may then wish to
// add code that undoes the power saving things done in the USBCBSuspend() function.
//
// Note *: The "usb_20.pdf" specs indicate 500uA or 2.5mA, depending upon device classification. However,
// the USB-IF has officially issued an ECN (engineering change notice) changing this to 2.5mA for all
// devices. Make sure to re-download the latest specifications to get all of the newest ECNs.
/******************************************************************************
* Function: void USBCBWakeFromSuspend(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: The host may put USB peripheral devices in low power
* suspend mode (by "sending" 3+ms of idle). Once in suspend
* mode, the host may wake the device back up by sending non-
* idle state signalling.
*
* This call back is invoked when a wakeup from USB suspend
* is detected.
*
* Note: Before returning from this function, make sure that the
* oscillator settings are fully compatible with USB module
* operation.
* If using the two-speed startup feature, wakeup and execution
* will occur before the main oscillator + PLL has had a chance
* to start. Device will run from INTOSC (no PLL). However, the
* USB module cannot be clocked and receive correct USB data when
* it is not clocked with the correct frequency clock source.
* Therefore, when using two-speed startup, should execute software
* delay to prevent any other code from executing until the main
* oscillator is ready.
* The host will allow at least 10ms for USB "resume recovery", during
* which it will not try to communicate with the device.
*****************************************************************************/
void USBCBWakeFromSuspend(void)
{
//This code delays ~5ms @ 8MHz to execute (using C18 3.21 with full
//optimizations enabled), but takes much less time at 48MHz. This delay
//is to make sure the PLL is enabled and locked, in case two speed startup
//was enabled
DelayRoutine(0x300); //Device will switch clocks (if using two-speed startup) while executing this delay function
//Primary oscillator and PLL should be running by now.
//Do not return from this function until the oscillator is correctly configured and
//running in a USB compatible mode/frequency.
//Additional code for re-enabling I/O pins and increasing power draw from VBUS
//may be placed here (up to the maximum of 100mA [when unconfigured] or the
//amount specified in the configuration descriptor (when configured).
}
/******************************************************************************
* Function: void USBCBSuspend(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Call back that is invoked when a USB suspend is detected
*
* Note: None
*****************************************************************************/
void USBCBSuspend(void)
{
Sleep(); // Go to sleep, wake up when a USB activity event occurs
//If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
while((USBIF_FLAG == 0) && (RCONbits.TO == 0)) //If using the WDT, should go back to sleep if awoke by WDT instead of USBIF
{
Sleep(); //Entry into sleep clears WDT count, much like executing ClrWdt() instruction
}
//After the USB suspend event ends, you should re-configure your I/O pins
//for normal operation mode (which is allowed to consume more current).
//However, it is recommended to put this code in the USBCBWakeFromSuspend()
//function instead of here (so that this function will work with either
//sleeping or clock switching to a lower frequency).
}
/*******************************************************************
* Function: void USBCBInitEP(uint8_t ConfigurationIndex)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function is called when the device becomes
* initialized, which occurs after the host sends a
* SET_CONFIGURATION request. This
* callback function should initialize the endpoints
* for the device's usage according to the current
* configuration.
*
* Note: If the host ever "unconfigures" the device, it will
* set the configuration to '0'. In this case, this
* callback gets called with ConfigurationIndex == 0, where
* the firmware should disable all non-EP0 endpoints (until
* the next non-zero SET_CONFIGURATION request is received,
* which will cause this callback to execute again).
*******************************************************************/
void USBCBInitEP(uint8_t ConfigurationIndex)
{
//Check what configuration "index" the host has requested us to select.
//Configuration index 0 is special and represents that the device should be
//un-configured. However, when the host sets the configuration (with index
//matching the valid/implemented configuration from the configuration descriptor),
//the firmware should enable the application endpoints associated with that
//configuration, and (re)initialize all application state variables associated
//with the USB application endpoints operation.
if(ConfigurationIndex == 1) //This application only implements one configuration, with index == 1.
{
//The host sent us a non-zero set configuration index. In this
//case we should prepare the application endpoints to be ready
//to use, and to (re-)initialize any application variables associated
//with the endpoints.
HIDInitEP();
//(Re-)Initialize the application variables associated with the USB interface
UserInit(); // See BootPIC[xxxx].c. Initializes the bootloader firmware state machine variables.
}
//else the host set the configuration back to 0 (indicating unconfigured), or
//to some higher (non-implemented value). In either case, we don't need to
//do anything specifically, unless the application requires some kind of
//"safe shutdown" code to execute after the host has deconfigured the device.
}
/*******************************************************************
* Function: void USBCBCheckOtherReq(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function is called when the USB stack receives a
* new control transfer SETUP packet from the host. The
* USB stack handles normal USB "Chapter 9" requests internally,
* but some control transfer requests are class specific. In
* order to handle these class specific requests, you must call
* the class handler's firmware control transfer handler function.
* If implementing a composite device with multiple classes
* implemented, call each of the handlers in the below callback.
*
* Note: None
*******************************************************************/
void USBCBCheckOtherReq(void)
{
USBCheckHIDRequest();
}

View File

@@ -0,0 +1,55 @@
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
#ifndef USB_H
#define USB_H
/*
* usb.h provides a centralize way to include all files
* required by Microchip USB Firmware.
*
* The order of inclusion is important.
* Dependency conflicts are resolved by the correct ordering.
*/
#include "typedefs.h"
#include "usb_config.h"
#include "usb_device.h"
#if defined(USB_USE_HID) // See usb_config.h
#include "usb_device_hid.h"
#endif
//These callback functions belong in your main.c (or equivalent) file. The USB
//stack will call these callback functions in response to specific USB bus events,
//such as entry into USB suspend mode, exit from USB suspend mode, and upon
//receiving the "set configuration" control tranfer request, which marks the end
//of the USB enumeration sequence and the start of normal application run mode (and
//where application related variables and endpoints may need to get (re)-initialized.
void USBCBSuspend(void);
void USBCBWakeFromSuspend(void);
void USBCBInitEP(uint8_t ConfigurationIndex);
void USBCBCheckOtherReq(void);
//API renaming wrapper functions
#define HIDTxHandleBusy(a) {mHIDTxIsBusy()}
#define HIDRxHandleBusy(a) {mHIDRxIsBusy()}
#endif //USB_H

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,699 @@
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
#ifndef _USB_DEVICE_H
#define _USB_DEVICE_H
/** I N C L U D E S **********************************************************/
#include "usb.h"
//Hardware abstraction. The USBIF and USBIE bits reside in different registers
//on different USB microcontrollers.
#if defined(__18F45K50) || defined(__18F25K50) || defined(__18F24K50) || defined(__18LF45K50) || defined(__18LF25K50) || defined(__18LF24K50)
#define USBIF_FLAG PIR3bits.USBIF
#define USBIE_BIT PIE3bits.USBIE
#else
#define USBIF_FLAG PIR2bits.USBIF
#define USBIE_BIT PIE2bits.USBIE
#endif
/** D E F I N I T I O N S ****************************************************/
/******************************************************************************
* Standard Request Codes
* USB 2.0 Spec Ref Table 9-4
*****************************************************************************/
#define GET_STATUS 0
#define CLR_FEATURE 1
#define SET_FEATURE 3
#define SET_ADR 5
#define GET_DSC 6
#define SET_DSC 7
#define GET_CFG 8
#define SET_CFG 9
#define GET_INTF 10
#define SET_INTF 11
#define SYNCH_FRAME 12
/* Standard Feature Selectors */
#define DEVICE_REMOTE_WAKEUP 0x01
#define ENDPOINT_HALT 0x00
/* UCFG Initialization Parameters */
#define _PPBM0 0x00 // Pingpong Buffer Mode 0 - ping pong bufferring disabled
#define _PPBM1 0x01 // Pingpong Buffer Mode 1 - ping pong on EP0 OUT only
#define _PPBM2 0x02 // Pingpong Buffer Mode 2 - ping pong on all endpoints
#define _LS 0x00 // Use Low-Speed USB Mode
#define _FS 0x04 // Use Full-Speed USB Mode
#define _TRINT 0x00 // Use internal transceiver
#define _TREXT 0x08 // Use external transceiver
#define _PUEN 0x10 // Use internal pull-up resistor
#define _OEMON 0x40 // Use SIE output indicator
#define _UTEYE 0x80 // Use Eye-Pattern test
/* UEPn Initialization Parameters */
#define EP_CTRL 0x06 // Cfg Control pipe for this ep
#define EP_OUT 0x0C // Cfg OUT only pipe for this ep
#define EP_IN 0x0A // Cfg IN only pipe for this ep
#define EP_OUT_IN 0x0E // Cfg both OUT & IN pipes for this ep
#define HSHK_EN 0x10 // Enable handshake packet
// Handshake should be disable for isoch
/******************************************************************************
* USB - PICmicro Endpoint Definitions
* PICmicro EP Address Format: X:EP3:EP2:EP1:EP0:DIR:PPBI:X
* This is used when checking the value read from USTAT
*
* NOTE: These definitions are not used in the descriptors.
* EP addresses used in the descriptors have different format and
* are defined in: usb_device.h
*****************************************************************************/
#define OUT 0
#define IN 1
#define PIC_EP_NUM_MASK 0b01111000
#define PIC_EP_DIR_MASK 0b00000100
#define EP00_OUT ((0x00<<3)|(OUT<<2))
#define EP00_IN ((0x00<<3)|(IN<<2))
#define EP01_OUT ((0x01<<3)|(OUT<<2))
#define EP01_IN ((0x01<<3)|(IN<<2))
#define EP02_OUT ((0x02<<3)|(OUT<<2))
#define EP02_IN ((0x02<<3)|(IN<<2))
#define EP03_OUT ((0x03<<3)|(OUT<<2))
#define EP03_IN ((0x03<<3)|(IN<<2))
#define EP04_OUT ((0x04<<3)|(OUT<<2))
#define EP04_IN ((0x04<<3)|(IN<<2))
#define EP05_OUT ((0x05<<3)|(OUT<<2))
#define EP05_IN ((0x05<<3)|(IN<<2))
#define EP06_OUT ((0x06<<3)|(OUT<<2))
#define EP06_IN ((0x06<<3)|(IN<<2))
#define EP07_OUT ((0x07<<3)|(OUT<<2))
#define EP07_IN ((0x07<<3)|(IN<<2))
#define EP08_OUT ((0x08<<3)|(OUT<<2))
#define EP08_IN ((0x08<<3)|(IN<<2))
#define EP09_OUT ((0x09<<3)|(OUT<<2))
#define EP09_IN ((0x09<<3)|(IN<<2))
#define EP10_OUT ((0x0A<<3)|(OUT<<2))
#define EP10_IN ((0x0A<<3)|(IN<<2))
#define EP11_OUT ((0x0B<<3)|(OUT<<2))
#define EP11_IN ((0x0B<<3)|(IN<<2))
#define EP12_OUT ((0x0C<<3)|(OUT<<2))
#define EP12_IN ((0x0C<<3)|(IN<<2))
#define EP13_OUT ((0x0D<<3)|(OUT<<2))
#define EP13_IN ((0x0D<<3)|(IN<<2))
#define EP14_OUT ((0x0E<<3)|(OUT<<2))
#define EP14_IN ((0x0E<<3)|(IN<<2))
#define EP15_OUT ((0x0F<<3)|(OUT<<2))
#define EP15_IN ((0x0F<<3)|(IN<<2))
#define EP0_OUT_EVEN_BDT_INDEX 0
#define EP0_OUT_ODD_BDT_INDEX 1
/* Buffer Descriptor Status Register Initialization Parameters */
#define _BSTALL 0x04 //Buffer Stall enable
#define _DTSEN 0x08 //Data Toggle Synch enable
#define _INCDIS 0x10 //Address increment disable
#define _KEN 0x20 //SIE keeps buff descriptors enable
#define _DAT0 0x00 //DATA0 packet expected next
#define _DAT1 0x40 //DATA1 packet expected next
#define _DTSMASK 0x40 //DTS Mask
#define _USIE 0x80 //SIE owns buffer
#define _UCPU 0x00 //CPU owns buffer
/* USB Device States - To be used with [byte usb_device_state] */
#define DETACHED_STATE 0
#define ATTACHED_STATE 1
#define POWERED_STATE 2
#define DEFAULT_STATE 3
#define ADR_PENDING_STATE 4
#define ADDRESS_STATE 5
#define CONFIGURED_STATE 6
/* Memory Types for Control Transfer - used in USB_DEVICE_STATUS */
#define _RAM 0
#define _ROM 1
/* Descriptor Types */
#define DSC_DEV 0x01
#define DSC_CFG 0x02
#define DSC_STR 0x03
#define DSC_INTF 0x04
#define DSC_EP 0x05
/******************************************************************************
* USB Endpoint Definitions
* USB Standard EP Address Format: DIR:X:X:X:EP3:EP2:EP1:EP0
* This is used in the descriptors. See usb_descriptors.c
*
* NOTE: Do not use these values for checking against USTAT.
* To check against USTAT, use values defined in "usb_device.h"
*****************************************************************************/
#define _EP01_OUT 0x01
#define _EP01_IN 0x81
#define _EP02_OUT 0x02
#define _EP02_IN 0x82
#define _EP03_OUT 0x03
#define _EP03_IN 0x83
#define _EP04_OUT 0x04
#define _EP04_IN 0x84
#define _EP05_OUT 0x05
#define _EP05_IN 0x85
#define _EP06_OUT 0x06
#define _EP06_IN 0x86
#define _EP07_OUT 0x07
#define _EP07_IN 0x87
#define _EP08_OUT 0x08
#define _EP08_IN 0x88
#define _EP09_OUT 0x09
#define _EP09_IN 0x89
#define _EP10_OUT 0x0A
#define _EP10_IN 0x8A
#define _EP11_OUT 0x0B
#define _EP11_IN 0x8B
#define _EP12_OUT 0x0C
#define _EP12_IN 0x8C
#define _EP13_OUT 0x0D
#define _EP13_IN 0x8D
#define _EP14_OUT 0x0E
#define _EP14_IN 0x8E
#define _EP15_OUT 0x0F
#define _EP15_IN 0x8F
/* Configuration Attributes */
#define _DEFAULT 0x01<<7 //Default Value (Bit 7 is set)
#define _SELF 0x01<<6 //Self-powered (Supports if set)
#define _RWU 0x01<<5 //Remote Wakeup (Supports if set)
/* Endpoint Transfer Type */
#define _CTRL 0x00 //Control Transfer
#define _ISO 0x01 //Isochronous Transfer
#define _BULK 0x02 //Bulk Transfer
#define _INT 0x03 //Interrupt Transfer
/* Isochronous Endpoint Synchronization Type */
#define _NS 0x00<<2 //No Synchronization
#define _AS 0x01<<2 //Asynchronous
#define _AD 0x02<<2 //Adaptive
#define _SY 0x03<<2 //Synchronous
/* Isochronous Endpoint Usage Type */
#define _DE 0x00<<4 //Data endpoint
#define _FE 0x01<<4 //Feedback endpoint
#define _IE 0x02<<4 //Implicit feedback Data endpoint
/** T Y P E S ****************************************************************/
typedef union _USB_DEVICE_STATUS
{
uint8_t _byte;
struct
{
unsigned RemoteWakeup:1;// [0]Disabled [1]Enabled: See usb_device.c,usb9.c
unsigned ctrl_trf_mem:1;// [0]RAM [1]ROM
};
} USB_DEVICE_STATUS;
typedef union _BD_STAT
{
uint8_t _byte;
struct{
unsigned BC8:1;
unsigned BC9:1;
unsigned BSTALL:1; //Buffer Stall Enable
unsigned DTSEN:1; //Data Toggle Synch Enable
unsigned INCDIS:1; //Address Increment Disable
unsigned KEN:1; //BD Keep Enable
unsigned DTS:1; //Data Toggle Synch Value
unsigned UOWN:1; //USB Ownership
};
struct{
unsigned :2;
unsigned PID0:1;
unsigned PID1:1;
unsigned PID2:1;
unsigned PID3:1;
unsigned :2;
};
struct{
unsigned :2;
unsigned PID:4; //Packet Identifier
unsigned :2;
};
} BD_STAT; //Buffer Descriptor Status Register
typedef union _BDT
{
struct
{
BD_STAT Stat;
uint8_t Cnt;
uint8_t ADRL; //Buffer Address Low
uint8_t ADRH; //Buffer Address High
};
struct
{
unsigned :8;
unsigned :8;
uint8_t* ADR; //Buffer Address
};
} BDT; //Buffer Descriptor Table
/******************************************************************************
* CTRL_TRF_SETUP:
*
* Every setup packet has 8 bytes.
* However, the buffer size has to equal the EP0_BUFF_SIZE value specified
* in usb_config.h
* The value of EP0_BUFF_SIZE can be 8, 16, 32, or 64.
*
* First 8 bytes are defined to be directly addressable to improve speed
* and reduce code size.
* Bytes beyond the 8th byte have to be accessed using indirect addressing.
*****************************************************************************/
typedef union _CTRL_TRF_SETUP
{
/** Array for indirect addressing ****************************************/
struct
{
uint8_t _byte[EP0_BUFF_SIZE];
};
/** Standard Device Requests *********************************************/
struct
{
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
uint16_t wIndex;
uint16_t wLength;
};
struct
{
unsigned :8;
unsigned :8;
WORD_VAL W_Value;
WORD_VAL W_Index;
WORD_VAL W_Length;
};
struct
{
unsigned Recipient:5; //Device,Interface,Endpoint,Other
unsigned RequestType:2; //Standard,Class,Vendor,Reserved
unsigned DataDir:1; //Host-to-device,Device-to-host
unsigned :8;
uint8_t bFeature; //DEVICE_REMOTE_WAKEUP,ENDPOINT_HALT
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
uint8_t bDscIndex; //For Configuration and String DSC Only
uint8_t bDscType; //Device,Configuration,String
uint16_t wLangID; //Language ID
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
uint8_t bDevADR; //Device Address 0-127
uint8_t bDevADRH; //Must equal zero
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
uint8_t bCfgValue; //Configuration Value 0-255
uint8_t bCfgRSD; //Must equal zero (Reserved)
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
uint8_t bAltID; //Alternate Setting Value 0-255
uint8_t bAltID_H; //Must equal zero
uint8_t bIntfID; //Interface Number Value 0-255
uint8_t bIntfID_H; //Must equal zero
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
uint8_t bEPID; //Endpoint ID (Number & Direction)
uint8_t bEPID_H; //Must equal zero
unsigned :8;
unsigned :8;
};
struct
{
unsigned :8;
unsigned :8;
unsigned :8;
unsigned :8;
unsigned EPNum:4; //Endpoint Number 0-15
unsigned :3;
unsigned EPDir:1; //Endpoint Direction: 0-OUT, 1-IN
unsigned :8;
unsigned :8;
unsigned :8;
};
/** End: Standard Device Requests ****************************************/
} CTRL_TRF_SETUP;
/******************************************************************************
* CTRL_TRF_DATA:
*
* Buffer size has to equal the EP0_BUFF_SIZE value specified
* in usb_config.h
* The value of EP0_BUFF_SIZE can be 8, 16, 32, or 64.
*
* First 8 bytes are defined to be directly addressable to improve speed
* and reduce code size.
* Bytes beyond the 8th byte have to be accessed using indirect addressing.
*****************************************************************************/
typedef union _CTRL_TRF_DATA
{
/** Array for indirect addressing ****************************************/
struct
{
uint8_t _byte[EP0_BUFF_SIZE];
};
/** First 8-byte direct addressing ***************************************/
struct
{
uint8_t _byte0;
uint8_t _byte1;
uint8_t _byte2;
uint8_t _byte3;
uint8_t _byte4;
uint8_t _byte5;
uint8_t _byte6;
uint8_t _byte7;
};
struct
{
uint16_t _word0;
uint16_t _word1;
uint16_t _word2;
uint16_t _word3;
};
} CTRL_TRF_DATA;
/******************************************************************************
* USB Device Descriptor Structure
*****************************************************************************/
typedef struct _USB_DEV_DSC
{
uint8_t bLength; uint8_t bDscType; uint16_t bcdUSB;
uint8_t bDevCls; uint8_t bDevSubCls; uint8_t bDevProtocol;
uint8_t bMaxPktSize0; uint16_t idVendor; uint16_t idProduct;
uint16_t bcdDevice; uint8_t iMFR; uint8_t iProduct;
uint8_t iSerialNum; uint8_t bNumCfg;
} USB_DEV_DSC;
/******************************************************************************
* USB Configuration Descriptor Structure
*****************************************************************************/
typedef struct _USB_CFG_DSC
{
uint8_t bLength; uint8_t bDscType; uint16_t wTotalLength;
uint8_t bNumIntf; uint8_t bCfgValue; uint8_t iCfg;
uint8_t bmAttributes; uint8_t bMaxPower;
} USB_CFG_DSC;
/******************************************************************************
* USB Interface Descriptor Structure
*****************************************************************************/
typedef struct _USB_INTF_DSC
{
uint8_t bLength; uint8_t bDscType; uint8_t bIntfNum;
uint8_t bAltSetting; uint8_t bNumEPs; uint8_t bIntfCls;
uint8_t bIntfSubCls; uint8_t bIntfProtocol; uint8_t iIntf;
} USB_INTF_DSC;
/******************************************************************************
* USB Endpoint Descriptor Structure
*****************************************************************************/
typedef struct _USB_EP_DSC
{
uint8_t bLength; uint8_t bDscType; uint8_t bEPAdr;
uint8_t bmAttributes; uint16_t wMaxPktSize; uint8_t bInterval;
} USB_EP_DSC;
/******************************************************************************
* Macro: void mInitializeUSBDriver(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Configures the USB module, definition of UCFG_VAL can be
* found in usb_config.h
*
* This register determines: USB Speed, On-chip pull-up
* resistor selection, On-chip tranceiver selection, bus
* eye pattern generation mode, Ping-pong buffering mode
* selection.
*
* Note: None
*****************************************************************************/
#define mInitializeUSBDriver() {UCFG = UCFG_VAL; \
usb_device_state = DETACHED_STATE; \
USBProtocolResetHandler();}
/******************************************************************************
* Macro: void mDisableEP1to15(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This macro disables all endpoints except EP0.
* This macro should be called when the host sends a RESET
* signal or a SET_CONFIGURATION request.
*
* Note: None
*****************************************************************************/
//#if defined(__18F14K50) || defined(__18F13K50) || defined(__18LF14K50) || defined(__18LF13K50)
// #define mDisableEP1to15() ClearArray((uint8_t*)&UEP1,7);
//#else
// #define mDisableEP1to15() ClearArray((uint8_t*)&UEP1,15);
//#endif
//Using below instead to save code space. Dedicated bootloader project,
//will never use UEP3+, therefore no need to really mess with those registers
#define mDisableEP1to7() UEP1=0x00;UEP2=0x00;UEP3=0x00;\
UEP4=0x00;UEP5=0x00;UEP6=0x00;UEP7=0x00;
// UEP8=0x00;UEP9=0x00;UEP10=0x00;UEP11=0x00;\
// UEP12=0x00;UEP13=0x00;UEP14=0x00;UEP15=0x00;
/******************************************************************************
* Macro: void mUSBBufferReady(buffer_dsc)
*
* PreCondition: IN Endpoint: Buffer is loaded and ready to be sent.
* OUT Endpoint: Buffer is free to be written to by SIE.
*
* Input: byte buffer_dsc: Root name of the buffer descriptor group.
* i.e. ep0Bo, ep1Bi, ... Declared in usbmmap.c
* Names can be remapped for readability, see examples in
* usb_config.h (#define HID_BD_OUT ep1Bo)
*
* Output: None
*
* Side Effects: None
*
* Overview: This macro should be called each time after:
* 1. A non-EP0 IN endpoint buffer is populated with data.
* 2. A non-EP0 OUT endpoint buffer is read.
* This macro turns the buffer ownership to SIE for servicing.
* It also toggles the DTS bit for synchronization.
*
* Note: None
*****************************************************************************/
#define mUSBBufferReady(buffer_dsc) \
{ \
buffer_dsc.Stat._byte &= _DTSMASK; /* Save only DTS bit */ \
buffer_dsc.Stat.DTS = !buffer_dsc.Stat.DTS; /* Toggle DTS bit */ \
buffer_dsc.Stat._byte |= _DTSEN; /* Configure other settings */ \
buffer_dsc.Stat._byte |= _USIE; /* Turn ownership to SIE */ \
}
/** D E F I N I T I O N S ****************************************************/
/*
* MUID = Microchip USB Class ID
* Used to identify which of the USB classes owns the current
* session of control transfer over EP0
*/
#define MUID_NULL 0
#define MUID_USB9 1
#define MUID_HID 2
#define MUID_CDC 3
/* Control Transfer States */
#define WAIT_SETUP 0
#define CTRL_TRF_TX 1
#define CTRL_TRF_RX 2
/* Short Packet States - Used by Control Transfer Read - CTRL_TRF_TX */
#define SHORT_PKT_NOT_SENT 0
#define SHORT_PKT_PENDING 1
#define SHORT_PKT_SENT 2
/* USB PID: Token Types - See chapter 8 in the USB specification */
#define SETUP_TOKEN 0b00001101
#define OUT_TOKEN 0b00000001
#define IN_TOKEN 0b00001001
/* bmRequestType Definitions */
#define HOST_TO_DEV 0
#define DEV_TO_HOST 1
#define STANDARD 0x00
#define CLASS 0x01
#define VENDOR 0x02
#define RCPT_DEV 0
#define RCPT_INTF 1
#define RCPT_EP 2
#define RCPT_OTH 3
/** E X T E R N S ************************************************************/
extern uint8_t ctrl_trf_session_owner;
extern POINTER pSrc;
extern POINTER pDst;
extern WORD_VAL wCount;
extern uint8_t usb_device_state;
extern USB_DEVICE_STATUS usb_stat;
extern uint8_t usb_active_cfg;
extern uint8_t usb_alt_intf[MAX_NUM_INT];
extern volatile BDT ep0Bo; //Endpoint #0 BD Out
extern volatile BDT ep0Bi; //Endpoint #0 BD In
extern volatile BDT ep1Bo; //Endpoint #1 BD Out
extern volatile BDT ep1Bi; //Endpoint #1 BD In
extern volatile BDT ep2Bo; //Endpoint #2 BD Out
extern volatile BDT ep2Bi; //Endpoint #2 BD In
extern volatile BDT ep3Bo; //Endpoint #3 BD Out
extern volatile BDT ep3Bi; //Endpoint #3 BD In
extern volatile BDT ep4Bo; //Endpoint #4 BD Out
extern volatile BDT ep4Bi; //Endpoint #4 BD In
extern volatile BDT ep5Bo; //Endpoint #5 BD Out
extern volatile BDT ep5Bi; //Endpoint #5 BD In
extern volatile BDT ep6Bo; //Endpoint #6 BD Out
extern volatile BDT ep6Bi; //Endpoint #6 BD In
extern volatile BDT ep7Bo; //Endpoint #7 BD Out
extern volatile BDT ep7Bi; //Endpoint #7 BD In
extern volatile BDT ep8Bo; //Endpoint #8 BD Out
extern volatile BDT ep8Bi; //Endpoint #8 BD In
extern volatile BDT ep9Bo; //Endpoint #9 BD Out
extern volatile BDT ep9Bi; //Endpoint #9 BD In
extern volatile BDT ep10Bo; //Endpoint #10 BD Out
extern volatile BDT ep10Bi; //Endpoint #10 BD In
extern volatile BDT ep11Bo; //Endpoint #11 BD Out
extern volatile BDT ep11Bi; //Endpoint #11 BD In
extern volatile BDT ep12Bo; //Endpoint #12 BD Out
extern volatile BDT ep12Bi; //Endpoint #12 BD In
extern volatile BDT ep13Bo; //Endpoint #13 BD Out
extern volatile BDT ep13Bi; //Endpoint #13 BD In
extern volatile BDT ep14Bo; //Endpoint #14 BD Out
extern volatile BDT ep14Bi; //Endpoint #14 BD In
extern volatile BDT ep15Bo; //Endpoint #15 BD Out
extern volatile BDT ep15Bi; //Endpoint #15 BD In
extern CTRL_TRF_SETUP SetupPkt;
volatile extern CTRL_TRF_DATA CtrlTrfData;
#if defined(USB_USE_HID)
extern volatile unsigned char hid_report_out[HID_INT_OUT_EP_SIZE];
extern volatile unsigned char hid_report_in[HID_INT_IN_EP_SIZE];
#endif
extern ROM USB_DEV_DSC device_dsc;
extern ROM uint8_t CFG01[CONFIG_DESC_TOTAL_LEN];
extern ROM const unsigned char *ROM USB_CD_Ptr[];
extern ROM unsigned char* ROM USB_SD_Ptr[];
/** P U B L I C P R O T O T Y P E S *****************************************/
void USBDeviceInit(void);
void USBCheckBusStatus(void);
void USBSoftAttach(void);
void USBSoftDetach(void);
void USBDeviceTasks(void);
void USBDisableWithLongDelay(void);
void DelayRoutine(unsigned int DelayAmount);
void ClearWatchdog(void);
#define USBGetDeviceState() usb_device_state
#define USBIsDeviceSuspended() UCONbits.SUSPND
#endif //_USB_DEVICE_H

View File

@@ -0,0 +1,302 @@
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
/** I N C L U D E S **********************************************************/
#include "usb.h"
#ifdef USB_USE_HID
/** V A R I A B L E S ********************************************************/
#ifndef __XC8__
#pragma udata
#endif
uint8_t idle_rate;
uint8_t active_protocol; // [0] Boot Protocol [1] Report Protocol
uint8_t hid_rpt_rx_len;
/** P R I V A T E P R O T O T Y P E S ***************************************/
void HIDGetReportHandler(void);
void HIDSetReportHandler(void);
/** D E C L A R A T I O N S **************************************************/
#ifndef __XC8__
#pragma code
#endif
/** C L A S S S P E C I F I C R E Q ****************************************/
/******************************************************************************
* Function: void USBCheckHIDRequest(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This routine checks the setup data packet to see if it
* knows how to handle it
*
* Note: None
*****************************************************************************/
void USBCheckHIDRequest(void)
{
if(SetupPkt.Recipient != RCPT_INTF) return;
if(SetupPkt.bIntfID != HID_INTF_ID) return;
/*
* There are two standard requests that hid.c may support.
* 1. GET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
* 2. SET_DSC(DSC_HID,DSC_RPT,DSC_PHY);
*/
if(SetupPkt.bRequest == GET_DSC)
{
switch(SetupPkt.bDscType)
{
case DSC_HID:
ctrl_trf_session_owner = MUID_HID;
pSrc.bRom = &CFG01[18]; //18 is a magic number (offset from start of configuration descriptor, to the start of the HID descriptor)
wCount.Val = sizeof(USB_HID_DSC);
break;
case DSC_RPT:
ctrl_trf_session_owner = MUID_HID;
mUSBGetHIDRptDscAdr(pSrc.bRom); // See usb_config.h
mUSBGetHIDRptDscSize(wCount.Val); // See usb_config.h
break;
case DSC_PHY:
// ctrl_trf_session_owner = MUID_HID;
break;
}//end switch(SetupPkt.bDscType)
usb_stat.ctrl_trf_mem = _ROM;
}//end if(SetupPkt.bRequest == GET_DSC)
if(SetupPkt.RequestType != CLASS) return;
switch(SetupPkt.bRequest)
{
case GET_REPORT:
HIDGetReportHandler();
break;
case SET_REPORT:
HIDSetReportHandler();
break;
case GET_IDLE:
ctrl_trf_session_owner = MUID_HID;
pSrc.bRam = (uint8_t*)&idle_rate; // Set source
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
wCount.v[0] = 1; // Set data count
break;
case SET_IDLE:
ctrl_trf_session_owner = MUID_HID;
//idle_rate = MSB(SetupPkt.W_Value);
idle_rate = SetupPkt.W_Value.v[1];
break;
case GET_PROTOCOL:
ctrl_trf_session_owner = MUID_HID;
pSrc.bRam = (uint8_t*)&active_protocol;// Set source
usb_stat.ctrl_trf_mem = _RAM; // Set memory type
wCount.v[0] = 1; // Set data count
break;
case SET_PROTOCOL:
ctrl_trf_session_owner = MUID_HID;
//active_protocol = LSB(SetupPkt.W_Value);
active_protocol = SetupPkt.W_Value.v[0];
break;
}//end switch(SetupPkt.bRequest)
}//end USBCheckHIDRequest
void HIDGetReportHandler(void)
{
// ctrl_trf_session_owner = MUID_HID;
}//end HIDGetReportHandler
void HIDSetReportHandler(void)
{
// ctrl_trf_session_owner = MUID_HID;
// pDst.bRam = (byte*)&hid_report_out;
}//end HIDSetReportHandler
/** U S E R A P I ***********************************************************/
/******************************************************************************
* Function: void HIDInitEP(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: HIDInitEP initializes HID endpoints, buffer descriptors,
* internal state-machine, and variables.
* It should be called after the USB host has sent out a
* SET_CONFIGURATION request.
* See USBStdSetCfgHandler() in usb9.c for examples.
*
* Note: None
*****************************************************************************/
void HIDInitEP(void)
{
hid_rpt_rx_len =0;
HID_UEP = EP_OUT_IN|HSHK_EN; // Enable 2 data pipes
//Arm the OUT interrupt endpoint so the host can send the first packet of data.
HID_BD_OUT.Cnt = sizeof(hid_report_out); // Set buffer size
HID_BD_OUT.ADR = (uint8_t*)&hid_report_out; // Set buffer address
HID_BD_OUT.Stat._byte = _DAT0|_DTSEN; // Set status
HID_BD_OUT.Stat._byte |= _USIE;
/*
* Do not have to init Cnt of IN pipes here.
* Reason: Number of bytes to send to the host
* varies from one transaction to
* another. Cnt should equal the exact
* number of bytes to transmit for
* a given IN transaction.
* This number of bytes will only
* be known right before the data is
* sent.
*/
HID_BD_IN.ADR = (uint8_t*)&hid_report_in; // Set buffer address
HID_BD_IN.Stat._byte = _UCPU|_DAT1; // Set status
}//end HIDInitEP
/******************************************************************************
* Function: void HIDTxReport(char *buffer, byte len)
*
* PreCondition: mHIDTxIsBusy() must return false.
*
* Value of 'len' must be equal to or smaller than
* HID_INT_IN_EP_SIZE
* For an interrupt endpoint, the largest buffer size is
* 64 bytes.
*
* Input: buffer : Pointer to the starting location of data bytes
* len : Number of bytes to be transferred
*
* Output: None
*
* Side Effects: None
*
* Overview: Use this macro to transfer data located in data memory.
*
* Remember: mHIDTxIsBusy() must return false before user
* can call this function.
* Unexpected behavior will occur if this function is called
* when mHIDTxIsBusy() == 0
*
* Typical Usage:
* if(!mHIDTxIsBusy())
* HIDTxReport(buffer, 3);
*
* Note: None
*****************************************************************************/
void HIDTxReport(char *buffer, uint8_t len)
{
uint8_t i;
/*
* Value of len should be equal to or smaller than HID_INT_IN_EP_SIZE.
* This check forces the value of len to meet the precondition.
*/
if(len > HID_INT_IN_EP_SIZE)
len = HID_INT_IN_EP_SIZE;
/*
* Copy data from user's buffer to a USB module accessible RAM packet buffer
*/
for (i = 0; i < len; i++)
hid_report_in[i] = buffer[i];
HID_BD_IN.Cnt = len;
mUSBBufferReady(HID_BD_IN);
}//end HIDTxReport
/******************************************************************************
* Function: byte HIDRxReport(char *buffer, byte len)
*
* PreCondition: Value of input argument 'len' should be smaller than the
* maximum endpoint size responsible for receiving report
* data from USB host for HID class.
* Input argument 'buffer' should point to a buffer area that
* is bigger or equal to the size specified by 'len'.
*
* Input: buffer : Pointer to where received bytes are to be stored
* len : The number of bytes expected.
*
* Output: The number of bytes copied to buffer.
*
* Side Effects: Publicly accessible variable hid_rpt_rx_len is updated
* with the number of bytes copied to buffer.
* Once HIDRxReport is called, subsequent retrieval of
* hid_rpt_rx_len can be done by calling macro
* mHIDGetRptRxLength().
*
* Overview: HIDRxReport copies a string of bytes received through
* USB HID OUT endpoint to a user's specified location.
* It is a non-blocking function. It does not wait
* for data if there is no data available. Instead it returns
* '0' to notify the caller that there is no data available.
*
* Note: If the actual number of bytes received is larger than the
* number of bytes expected (len), only the expected number
* of bytes specified will be copied to buffer.
* If the actual number of bytes received is smaller than the
* number of bytes expected (len), only the actual number
* of bytes received will be copied to buffer.
*****************************************************************************/
uint8_t HIDRxReport(char *buffer, uint8_t len)
{
hid_rpt_rx_len = 0;
if(!mHIDRxIsBusy())
{
/*
* Adjust the expected number of bytes to equal
* the actual number of bytes received.
*/
if(len > HID_BD_OUT.Cnt)
len = HID_BD_OUT.Cnt;
/*
* Copy data from dual-ram buffer to user's buffer
*/
for(hid_rpt_rx_len = 0; hid_rpt_rx_len < len; hid_rpt_rx_len++)
buffer[hid_rpt_rx_len] = hid_report_out[hid_rpt_rx_len];
/*
* Prepare dual-ram buffer for next OUT transaction
*/
HID_BD_OUT.Cnt = sizeof(hid_report_out);
mUSBBufferReady(HID_BD_OUT);
}//end if
return hid_rpt_rx_len;
}//end HIDRxReport
#endif //def USB_USE_HID
/** EOF hid.c ***************************************************************/

View File

@@ -0,0 +1,163 @@
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
#ifndef HID_H
#define HID_H
/** I N C L U D E S **********************************************************/
#include "typedefs.h"
/** D E F I N I T I O N S ****************************************************/
/* Class-Specific Requests */
#define GET_REPORT 0x01
#define GET_IDLE 0x02
#define GET_PROTOCOL 0x03
#define SET_REPORT 0x09
#define SET_IDLE 0x0A
#define SET_PROTOCOL 0x0B
/* Class Descriptor Types */
#define DSC_HID 0x21
#define DSC_RPT 0x22
#define DSC_PHY 0x23
/* Protocol Selection */
#define BOOT_PROTOCOL 0x00
#define RPT_PROTOCOL 0x01
/* HID Interface Class Code */
#define HID_INTF 0x03
/* HID Interface Class SubClass Codes */
#define BOOT_INTF_SUBCLASS 0x01
/* HID Interface Class Protocol Codes */
#define HID_PROTOCOL_NONE 0x00
#define HID_PROTOCOL_KEYBOAD 0x01
#define HID_PROTOCOL_MOUSE 0x02
/******************************************************************************
* Macro: (bit) mHIDRxIsBusy(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This macro is used to check if HID OUT endpoint is
* busy (owned by SIE) or not.
* Typical Usage: if(mHIDRxIsBusy())
*
* Note: None
*****************************************************************************/
#define mHIDRxIsBusy() HID_BD_OUT.Stat.UOWN
/******************************************************************************
* Macro: (bit) mHIDTxIsBusy(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This macro is used to check if HID IN endpoint is
* busy (owned by SIE) or not.
* Typical Usage: if(mHIDTxIsBusy())
*
* Note: None
*****************************************************************************/
#define mHIDTxIsBusy() HID_BD_IN.Stat.UOWN
/******************************************************************************
* Macro: uint8_t mHIDGetRptRxLength(void)
*
* PreCondition: None
*
* Input: None
*
* Output: mHIDGetRptRxLength returns hid_rpt_rx_len
*
* Side Effects: None
*
* Overview: mHIDGetRptRxLength is used to retrieve the number of bytes
* copied to user's buffer by the most recent call to
* HIDRxReport function.
*
* Note: None
*****************************************************************************/
#define mHIDGetRptRxLength() hid_rpt_rx_len
/* HID macros */
#define mUSBGetHIDDscAdr(ptr) \
{ \
if(usb_active_cfg == 1) \
ptr = (ROM uint8_t*)&cfg01.hid_i00a00; \
}
#define mUSBGetHIDRptDscAdr(ptr) \
{ \
if(usb_active_cfg == 1) \
ptr = (ROM uint8_t*)&hid_rpt01; \
}
#define mUSBGetHIDRptDscSize(count) \
{ \
if(usb_active_cfg == 1) \
count = sizeof(hid_rpt01); \
}
/** S T R U C T U R E S ******************************************************/
typedef struct _USB_HID_DSC_HEADER
{
uint8_t bDscType;
uint16_t wDscLength;
} USB_HID_DSC_HEADER;
typedef struct _USB_HID_DSC
{
uint8_t bLength; uint8_t bDscType; uint16_t bcdHID;
uint8_t bCountryCode; uint8_t bNumDsc;
USB_HID_DSC_HEADER hid_dsc_header[HID_NUM_OF_DSC];
/*
* HID_NUM_OF_DSC is defined in autofiles\usb_config.h
*/
} USB_HID_DSC;
/** E X T E R N S ************************************************************/
extern uint8_t hid_rpt_rx_len;
extern ROM uint8_t hid_rpt01[HID_RPT01_SIZE];
/** P U B L I C P R O T O T Y P E S *****************************************/
void HIDInitEP(void);
void USBCheckHIDRequest(void);
void HIDTxReport(char *buffer, uint8_t len);
uint8_t HIDRxReport(char *buffer, uint8_t len);
#endif //HID_H

425
bootloader/src/typedefs.h Normal file
View File

@@ -0,0 +1,425 @@
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
#ifndef __CUSTOMIZED_TYPE_DEFS_H_
#define __CUSTOMIZED_TYPE_DEFS_H_
#include <xc.h>
#define ROM const
#define rom
#include <stdint.h>
#include <stdbool.h>
#ifndef Nop()
#define Nop() {asm("NOP");}
#endif
#ifndef ClrWdt()
#define ClrWdt() {asm("CLRWDT");}
#endif
#ifndef Reset()
#define Reset() {asm("RESET");}
#endif
#ifndef Sleep()
#define Sleep() {asm("SLEEP");}
#endif
#define __EXTENSION
#if !defined(__PACKED)
#define __PACKED
#endif
/* get compiler defined type definitions (NULL, size_t, etc) */
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define PUBLIC /* Function attributes */
#define PROTECTED
#define PRIVATE static
/* INT is processor specific in length may vary in size */
typedef signed int INT;
typedef signed char INT8;
typedef signed short int INT16;
typedef signed long int INT32;
/* UINT is processor specific in length may vary in size */
typedef unsigned int UINT;
typedef unsigned char UINT8;
typedef unsigned short int UINT16;
typedef unsigned long int UINT32; /* other name for 32-bit integer */
typedef union
{
UINT8 Val;
struct
{
__EXTENSION UINT8 b0:1;
__EXTENSION UINT8 b1:1;
__EXTENSION UINT8 b2:1;
__EXTENSION UINT8 b3:1;
__EXTENSION UINT8 b4:1;
__EXTENSION UINT8 b5:1;
__EXTENSION UINT8 b6:1;
__EXTENSION UINT8 b7:1;
} bits;
} UINT8_VAL, UINT8_BITS;
typedef union
{
UINT16 Val;
UINT8 v[2] __PACKED;
struct __PACKED
{
UINT8 LB;
UINT8 HB;
} byte;
struct __PACKED
{
__EXTENSION UINT8 b0:1;
__EXTENSION UINT8 b1:1;
__EXTENSION UINT8 b2:1;
__EXTENSION UINT8 b3:1;
__EXTENSION UINT8 b4:1;
__EXTENSION UINT8 b5:1;
__EXTENSION UINT8 b6:1;
__EXTENSION UINT8 b7:1;
__EXTENSION UINT8 b8:1;
__EXTENSION UINT8 b9:1;
__EXTENSION UINT8 b10:1;
__EXTENSION UINT8 b11:1;
__EXTENSION UINT8 b12:1;
__EXTENSION UINT8 b13:1;
__EXTENSION UINT8 b14:1;
__EXTENSION UINT8 b15:1;
} bits;
} UINT16_VAL, UINT16_BITS;
typedef union
{
UINT32 Val;
UINT16 w[2] __PACKED;
UINT8 v[4] __PACKED;
struct __PACKED
{
UINT16 LW;
UINT16 HW;
} word;
struct __PACKED
{
UINT8 LB;
UINT8 HB;
UINT8 UB;
UINT8 MB;
} byte;
struct __PACKED
{
UINT16_VAL low;
UINT16_VAL high;
}wordUnion;
struct __PACKED
{
__EXTENSION UINT8 b0:1;
__EXTENSION UINT8 b1:1;
__EXTENSION UINT8 b2:1;
__EXTENSION UINT8 b3:1;
__EXTENSION UINT8 b4:1;
__EXTENSION UINT8 b5:1;
__EXTENSION UINT8 b6:1;
__EXTENSION UINT8 b7:1;
__EXTENSION UINT8 b8:1;
__EXTENSION UINT8 b9:1;
__EXTENSION UINT8 b10:1;
__EXTENSION UINT8 b11:1;
__EXTENSION UINT8 b12:1;
__EXTENSION UINT8 b13:1;
__EXTENSION UINT8 b14:1;
__EXTENSION UINT8 b15:1;
__EXTENSION UINT8 b16:1;
__EXTENSION UINT8 b17:1;
__EXTENSION UINT8 b18:1;
__EXTENSION UINT8 b19:1;
__EXTENSION UINT8 b20:1;
__EXTENSION UINT8 b21:1;
__EXTENSION UINT8 b22:1;
__EXTENSION UINT8 b23:1;
__EXTENSION UINT8 b24:1;
__EXTENSION UINT8 b25:1;
__EXTENSION UINT8 b26:1;
__EXTENSION UINT8 b27:1;
__EXTENSION UINT8 b28:1;
__EXTENSION UINT8 b29:1;
__EXTENSION UINT8 b30:1;
__EXTENSION UINT8 b31:1;
} bits;
} UINT32_VAL;
/***********************************************************************************/
/* Alternate definitions */
typedef void VOID;
typedef char CHAR8;
typedef unsigned char UCHAR8;
typedef unsigned char BYTE; /* 8-bit unsigned */
typedef unsigned short int WORD; /* 16-bit unsigned */
typedef unsigned long DWORD; /* 32-bit unsigned */
//typedef unsigned long long QWORD; /* 64-bit unsigned */
typedef signed char CHAR; /* 8-bit signed */
typedef signed short int SHORT; /* 16-bit signed */
typedef signed long LONG; /* 32-bit signed */
//typedef signed long long LONGLONG; /* 64-bit signed */
typedef union
{
BYTE Val;
struct __PACKED
{
__EXTENSION BYTE b0:1;
__EXTENSION BYTE b1:1;
__EXTENSION BYTE b2:1;
__EXTENSION BYTE b3:1;
__EXTENSION BYTE b4:1;
__EXTENSION BYTE b5:1;
__EXTENSION BYTE b6:1;
__EXTENSION BYTE b7:1;
} bits;
} BYTE_VAL, BYTE_BITS;
typedef union
{
WORD Val;
BYTE v[2] __PACKED;
struct __PACKED
{
BYTE LB;
BYTE HB;
} byte;
struct __PACKED
{
__EXTENSION BYTE b0:1;
__EXTENSION BYTE b1:1;
__EXTENSION BYTE b2:1;
__EXTENSION BYTE b3:1;
__EXTENSION BYTE b4:1;
__EXTENSION BYTE b5:1;
__EXTENSION BYTE b6:1;
__EXTENSION BYTE b7:1;
__EXTENSION BYTE b8:1;
__EXTENSION BYTE b9:1;
__EXTENSION BYTE b10:1;
__EXTENSION BYTE b11:1;
__EXTENSION BYTE b12:1;
__EXTENSION BYTE b13:1;
__EXTENSION BYTE b14:1;
__EXTENSION BYTE b15:1;
} bits;
} WORD_VAL, WORD_BITS;
typedef union
{
DWORD Val;
WORD w[2] __PACKED;
BYTE v[4] __PACKED;
struct __PACKED
{
WORD LW;
WORD HW;
} word;
struct __PACKED
{
BYTE LB;
BYTE HB;
BYTE UB;
BYTE MB;
} byte;
struct __PACKED
{
WORD_VAL low;
WORD_VAL high;
}wordUnion;
struct __PACKED
{
__EXTENSION BYTE b0:1;
__EXTENSION BYTE b1:1;
__EXTENSION BYTE b2:1;
__EXTENSION BYTE b3:1;
__EXTENSION BYTE b4:1;
__EXTENSION BYTE b5:1;
__EXTENSION BYTE b6:1;
__EXTENSION BYTE b7:1;
__EXTENSION BYTE b8:1;
__EXTENSION BYTE b9:1;
__EXTENSION BYTE b10:1;
__EXTENSION BYTE b11:1;
__EXTENSION BYTE b12:1;
__EXTENSION BYTE b13:1;
__EXTENSION BYTE b14:1;
__EXTENSION BYTE b15:1;
__EXTENSION BYTE b16:1;
__EXTENSION BYTE b17:1;
__EXTENSION BYTE b18:1;
__EXTENSION BYTE b19:1;
__EXTENSION BYTE b20:1;
__EXTENSION BYTE b21:1;
__EXTENSION BYTE b22:1;
__EXTENSION BYTE b23:1;
__EXTENSION BYTE b24:1;
__EXTENSION BYTE b25:1;
__EXTENSION BYTE b26:1;
__EXTENSION BYTE b27:1;
__EXTENSION BYTE b28:1;
__EXTENSION BYTE b29:1;
__EXTENSION BYTE b30:1;
__EXTENSION BYTE b31:1;
} bits;
} DWORD_VAL;
/* MPLAB C Compiler for PIC18 does not support 64-bit integers */
/*typedef union
{
QWORD Val;
DWORD d[2] __PACKED;
WORD w[4] __PACKED;
BYTE v[8] __PACKED;
struct __PACKED
{
DWORD LD;
DWORD HD;
} dword;
struct __PACKED
{
WORD LW;
WORD HW;
WORD UW;
WORD MW;
} word;
struct __PACKED
{
__EXTENSION BYTE b0:1;
__EXTENSION BYTE b1:1;
__EXTENSION BYTE b2:1;
__EXTENSION BYTE b3:1;
__EXTENSION BYTE b4:1;
__EXTENSION BYTE b5:1;
__EXTENSION BYTE b6:1;
__EXTENSION BYTE b7:1;
__EXTENSION BYTE b8:1;
__EXTENSION BYTE b9:1;
__EXTENSION BYTE b10:1;
__EXTENSION BYTE b11:1;
__EXTENSION BYTE b12:1;
__EXTENSION BYTE b13:1;
__EXTENSION BYTE b14:1;
__EXTENSION BYTE b15:1;
__EXTENSION BYTE b16:1;
__EXTENSION BYTE b17:1;
__EXTENSION BYTE b18:1;
__EXTENSION BYTE b19:1;
__EXTENSION BYTE b20:1;
__EXTENSION BYTE b21:1;
__EXTENSION BYTE b22:1;
__EXTENSION BYTE b23:1;
__EXTENSION BYTE b24:1;
__EXTENSION BYTE b25:1;
__EXTENSION BYTE b26:1;
__EXTENSION BYTE b27:1;
__EXTENSION BYTE b28:1;
__EXTENSION BYTE b29:1;
__EXTENSION BYTE b30:1;
__EXTENSION BYTE b31:1;
__EXTENSION BYTE b32:1;
__EXTENSION BYTE b33:1;
__EXTENSION BYTE b34:1;
__EXTENSION BYTE b35:1;
__EXTENSION BYTE b36:1;
__EXTENSION BYTE b37:1;
__EXTENSION BYTE b38:1;
__EXTENSION BYTE b39:1;
__EXTENSION BYTE b40:1;
__EXTENSION BYTE b41:1;
__EXTENSION BYTE b42:1;
__EXTENSION BYTE b43:1;
__EXTENSION BYTE b44:1;
__EXTENSION BYTE b45:1;
__EXTENSION BYTE b46:1;
__EXTENSION BYTE b47:1;
__EXTENSION BYTE b48:1;
__EXTENSION BYTE b49:1;
__EXTENSION BYTE b50:1;
__EXTENSION BYTE b51:1;
__EXTENSION BYTE b52:1;
__EXTENSION BYTE b53:1;
__EXTENSION BYTE b54:1;
__EXTENSION BYTE b55:1;
__EXTENSION BYTE b56:1;
__EXTENSION BYTE b57:1;
__EXTENSION BYTE b58:1;
__EXTENSION BYTE b59:1;
__EXTENSION BYTE b60:1;
__EXTENSION BYTE b61:1;
__EXTENSION BYTE b62:1;
__EXTENSION BYTE b63:1;
} bits;
} QWORD_VAL;
*/
#undef __EXTENSION
#ifndef uint24_t
#define uint24_t uint32_t
#endif
typedef void(*pFunc)(void);
typedef union _POINTER
{
struct
{
BYTE bLow;
BYTE bHigh;
//BYTE bUpper;
};
uint16_t _word; // bLow & bHigh
//pFunc _pFunc; // Usage: ptr.pFunc(); Init: ptr.pFunc = &<Function>;
BYTE* bRam; // Ram byte pointer: 2 bytes pointer pointing
// to 1 byte of data
uint16_t* wRam; // Ram word poitner: 2 bytes poitner pointing
// to 2 bytes of data
ROM BYTE* bRom; // Size depends on compiler setting
ROM WORD* wRom;
//ROM near BYTE* nbRom; // Near = 2 bytes pointer
//ROM near uint16_t* nwRom;
//ROM far BYTE* fbRom; // Far = 3 bytes pointer
//ROM far uint16_t* fwRom;
} POINTER;
#endif /* __CUSTOMIZED_TYPE_DEFS_H_ */

View File

@@ -1,180 +1,89 @@
/*************************************************************************
* Copyright (C) 2019 by Justin Byers
*
* This file is part of clubdance_v2.
*
* clubdance_v2 is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* clubdance_v2 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with clubdance_v2. If not, see <https://www.gnu.org/licenses/>.
*************************************************************************/
/**
* @file usb_config.h
* @author Justin Byers
* @date 6 Aug 2019
* @brief Configuration of the MLA USB framework.
*
* Descriptor specific type definitions are defined in: usbd.h
*/
/*******************************************************************************
Copyright 2016 Microchip Technology Inc. (www.microchip.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
To request to license the code under the MLA license (www.microchip.com/mla_license),
please contact mla_licensing@microchip.com
*******************************************************************************/
#ifndef USBCFG_H
#define USBCFG_H
#include <usb_ch9.h>
//----------------------------------------------------------------------------------------------------------
//User configurable options
//----------------------------------------------------------------------------------------------------------
/** DEFINITIONS ****************************************************/
#define USB_EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
// Using larger options take more SRAM, but
// does not provide much advantage in most types
// of applications. Exceptions to this, are applications
// that use EP0 IN or OUT for sending large amounts of
// application related data.
//When defined/enabled, this option allows the boot up code to check an I/O pin
//(as defined by the sw2() macro in HardwareProfile.h), and if logic low, execution
//stays within the bootloader, allowing the user to update the firmware. If this
//option is not enabled, then the only method of entering the bootloader will
//be from the application firmware project, by executing a goto 0x001C operation.
//Enabling the I/O pin to enter the bootloader is recommended, since it is more
//robust/recoverable (compared to software only entry into the bootloader), in
//the event of a failed erase/program/verify operation, or an otherwise corrupted
//application firmware image is loaded.
#define ENABLE_IO_PIN_CHECK_BOOTLOADER_ENTRY //Uncomment if you wish to enable I/O pin entry method into bootloader mode
//Make sure proper sw2() macro definition is provided in HardwareProfile.h
#define USB_MAX_NUM_INT 1 //Set this number to match the maximum interface number used in the descriptors for this firmware project
#define USB_MAX_EP_NUMBER 1 //Set this number to match the maximum endpoint number used in the descriptors for this firmware project
//Device descriptor - if these two definitions are not defined then
// a const USB_DEVICE_DESCRIPTOR variable by the exact name of device_dsc
// must exist.
#define USB_USER_DEVICE_DESCRIPTOR &device_dsc
#define USB_USER_DEVICE_DESCRIPTOR_INCLUDE extern const USB_DEVICE_DESCRIPTOR device_dsc
//Configuration descriptors - if these two definitions do not exist then
// a const BYTE *const variable named exactly USB_CD_Ptr[] must exist.
#define USB_USER_CONFIG_DESCRIPTOR USB_CD_Ptr
#define USB_USER_CONFIG_DESCRIPTOR_INCLUDE extern const uint8_t *const USB_CD_Ptr[]
//Option to allow blinking of LED to show USB bus status. May be optionally
//commented out to save code space (and/or if there are no LEDs available on
//the actual target application board). If this option is uncommented, you must
//provide the proper LED pin definitions in the HardwareProfile.h file.
#define ENABLE_USB_LED_BLINK_STATUS
//------------------------------------------------------------------------------
//Select an endpoint ping-pong bufferring mode. Some microcontrollers only
//support certain modes. For most applications, it is recommended to use either
//the USB_PING_PONG__FULL_PING_PONG or USB_PING_PONG__EP0_OUT_ONLY options.
//The other settings are supported on some devices, but they are not
//recommended, as they offer inferior control transfer timing performance.
//See inline code comments in usb_device.c for additional details.
//Enabling ping pong bufferring on an endpoint generally increases firmware
//overhead somewhat, but when both buffers are used simultaneously in the
//firmware, can offer better sustained bandwidth, especially for OUT endpoints.
//------------------------------------------------------
//#define USB_PING_PONG_MODE USB_PING_PONG__NO_PING_PONG //Not recommended
//#define USB_PING_PONG_MODE USB_PING_PONG__FULL_PING_PONG //A good all around setting
#define USB_PING_PONG_MODE USB_PING_PONG__EP0_OUT_ONLY //Another good setting
//#define USB_PING_PONG_MODE USB_PING_PONG__ALL_BUT_EP0 //Not recommended
//------------------------------------------------------------------------------
//USB VBUS sensing and USB Bus/Self power sensing options.
//---------------------------------------------------------
//#define USE_SELF_POWER_SENSE_IO //Leave commented if device is bus powered only (or self powered only, uncomment for some types of dual powered devices)
//#define USE_USB_BUS_SENSE_IO //If the device is self powered, this needs to uncommented if making a fully compliant USB design
//------------------------------------------------------------------------------
//Select a USB stack operating mode. In the USB_INTERRUPT mode, the USB stack
//main task handler gets called only when necessary as an interrupt handler.
//This can potentially minimize CPU utilization, but adds context saving
//and restoring overhead associated with interrupts, which can potentially
//decrease performance.
//When the USB_POLLING mode is selected, the USB stack main task handler
//(ex: USBDeviceTasks()) must be called periodically by the application firmware
//at a minimum rate as described in the inline code comments in usb_device.c.
//------------------------------------------------------
#define USB_POLLING
//#define USB_INTERRUPT
//------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------------
//Other semi-configurable settings that tell the USB stack how to operate (but usually don't need changing)
//----------------------------------------------------------------------------------------------------------
#define MAX_EP_NUMBER 1 // EP0 and EP1 are the only EPs used in this application
#define MAX_NUM_INT 1 // For tracking Alternate Setting - make sure this matches the number of interfaces implemented in the device
#define EP0_BUFF_SIZE 8 // Valid Options: 8, 16, 32, or 64 bytes.
// There is little advantage in using
// more than 8 bytes on EP0 IN/OUT in most cases.
#define USB_MAX_NUM_CONFIG_DSC 1 // Number of configurations that this firmware implements
//#define ENABLE_CONTROL_TRANSFERS_WITH_OUT_DATA_STAGE //Commented out to save code size, since this bootloader firmware doesn't use OUT control transfers with data stage
#define CONFIG_DESC_TOTAL_LEN 41 //Make sure this matches the size of your configuration descriptor + all subordinate
//descriptors returned by the get descriptor(configuration) request
/* Parameter definitions are defined in usb_device.h */
#define USB_PULLUP_OPTION USB_PULLUP_ENABLE
//#define USB_PULLUP_OPTION USB_PULLUP_DISABLED
#define MODE_PP _PPBM1 //This code is only written to support _PPBM1 mode only (ping pong on EP0 OUT buffer only). Do not change.
#define UCFG_VAL _PUEN|_TRINT|_FS|MODE_PP
#define USB_TRANSCEIVER_OPTION USB_INTERNAL_TRANSCEIVER
//External Transceiver support is not available on all product families. Please
// refer to the product family datasheet for more information if this feature
// is available on the target processor.
//#define USB_TRANSCEIVER_OPTION USB_EXTERNAL_TRANSCEIVER
#define USB_SPEED_OPTION USB_FULL_SPEED
//#define USB_SPEED_OPTION USB_LOW_SPEED //(this mode is only supported on some microcontrollers)
//------------------------------------------------------------------------------------------------------------------
//Option to enable auto-arming of the status stage of control transfers, if no
//"progress" has been made for the USB_STATUS_STAGE_TIMEOUT value.
//If progress is made (any successful transactions completing on EP0 IN or OUT)
//the timeout counter gets reset to the USB_STATUS_STAGE_TIMEOUT value.
//
//During normal control transfer processing, the USB stack or the application
//firmware will call USBCtrlEPAllowStatusStage() as soon as the firmware is finished
//processing the control transfer. Therefore, the status stage completes as
//quickly as is physically possible. The USB_ENABLE_STATUS_STAGE_TIMEOUTS
//feature, and the USB_STATUS_STAGE_TIMEOUT value are only relevant, when:
//1. The application uses the USBDeferStatusStage() API function, but never calls
// USBCtrlEPAllowStatusStage(). Or:
//2. The application uses host to device (OUT) control transfers with data stage,
// and some abnormal error occurs, where the host might try to abort the control
// transfer, before it has sent all of the data it claimed it was going to send.
//
//If the application firmware never uses the USBDeferStatusStage() API function,
//and it never uses host to device control transfers with data stage, then
//it is not required to enable the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature.
#define USB_ENABLE_STATUS_STAGE_TIMEOUTS //Comment this out to disable this feature.
//Section 9.2.6 of the USB 2.0 specifications indicate that:
//1. Control transfers with no data stage: Status stage must complete within
// 50ms of the start of the control transfer.
//2. Control transfers with (IN) data stage: Status stage must complete within
// 50ms of sending the last IN data packet in fullfilment of the data stage.
//3. Control transfers with (OUT) data stage: No specific status stage timing
// requirement. However, the total time of the entire control transfer (ex:
// including the OUT data stage and IN status stage) must not exceed 5 seconds.
//
//Therefore, if the USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is used, it is suggested
//to set the USB_STATUS_STAGE_TIMEOUT value to timeout in less than 50ms. If the
//USB_ENABLE_STATUS_STAGE_TIMEOUTS feature is not enabled, then the USB_STATUS_STAGE_TIMEOUT
//parameter is not relevant.
#define USB_STATUS_STAGE_TIMEOUT (uint8_t)45 //Approximate timeout in milliseconds, except when
//USB_POLLING mode is used, and USBDeviceTasks() is called at < 1kHz
//In this special case, the timeout becomes approximately:
//Timeout(in milliseconds) = ((1000 * (USB_STATUS_STAGE_TIMEOUT - 1)) / (USBDeviceTasks() polling frequency in Hz))
//------------------------------------------------------------------------------------------------------------------
#define USB_SUPPORT_DEVICE
#define USB_NUM_STRING_DESCRIPTORS 3 //Set this number to match the total number of string descriptors that are implemented in the usb_descriptors.c file
/*******************************************************************
* Event disable options
* Enable a definition to suppress a specific event. By default
* all events are sent.
*******************************************************************/
//#define USB_DISABLE_SUSPEND_HANDLER
//#define USB_DISABLE_WAKEUP_FROM_SUSPEND_HANDLER
//#define USB_DISABLE_SOF_HANDLER
//#define USB_DISABLE_TRANSFER_TERMINATED_HANDLER
//#define USB_DISABLE_ERROR_HANDLER
//#define USB_DISABLE_NONSTANDARD_EP0_REQUEST_HANDLER
//#define USB_DISABLE_SET_DESCRIPTOR_HANDLER
//#define USB_DISABLE_SET_CONFIGURATION_HANDLER
//#define USB_DISABLE_TRANSFER_COMPLETE_HANDLER
/** DEVICE CLASS USAGE *********************************************/
//Device class and endpoint definitions
#define USB_USE_HID
/** ENDPOINTS ALLOCATION *******************************************/
/* HID */
#define HID_INTF_ID 0x00
#define HID_UEP UEP1
#define HID_BD_OUT ep1Bo
#define HID_INT_OUT_EP_SIZE 64
#define HID_BD_IN ep1Bi
#define HID_INT_IN_EP_SIZE 64
#define HID_NUM_OF_DSC 1
#define HID_RPT01_SIZE 29
#define HID_NUM_OF_DSC 1 //Just the Report descriptor (no physical descriptor present)
#define HID_RPT01_SIZE 29 //Make sure this matches the size of your HID report descriptor
#define HID_EP 1
#define HID_IN_EP HID_EP
#define HID_OUT_EP HID_EP
/** DEFINITIONS ****************************************************/
#endif //USBCFG_H

View File

@@ -17,142 +17,159 @@ To request to license the code under the MLA license (www.microchip.com/mla_lice
please contact mla_licensing@microchip.com
*******************************************************************************/
/********************************************************************
-usb_descriptors.c-
-------------------------------------------------------------------
Filling in the descriptor values in the usb_descriptors.c file:
-------------------------------------------------------------------
[Device Descriptors]
The device descriptor is defined as a USB_DEVICE_DESCRIPTOR type.
This type is defined in usb_ch9.h Each entry into this structure
needs to be the correct length for the data type of the entry.
[Configuration Descriptors]
The configuration descriptor was changed in v2.x from a structure
to a uint8_t array. Given that the configuration is now a byte array
each byte of multi-byte fields must be listed individually. This
means that for fields like the total size of the configuration where
the field is a 16-bit value "64,0," is the correct entry for a
configuration that is only 64 bytes long and not "64," which is one
too few bytes.
The configuration attribute must always have the _DEFAULT
definition at the minimum. Additional options can be ORed
to the _DEFAULT attribute. Available options are _SELF and _RWU.
These definitions are defined in the usb_device.h file. The
_SELF tells the USB host that this device is self-powered. The
_RWU tells the USB host that this device supports Remote Wakeup.
[Endpoint Descriptors]
Like the configuration descriptor, the endpoint descriptors were
changed in v2.x of the stack from a structure to a uint8_t array. As
endpoint descriptors also has a field that are multi-byte entities,
please be sure to specify both bytes of the field. For example, for
the endpoint size an endpoint that is 64 bytes needs to have the size
defined as "64,0," instead of "64,"
Take the following example:
// Endpoint Descriptor //
0x07, //the size of this descriptor //
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP02_IN, //EndpointAddress
_INT, //Attributes
0x08,0x00, //size (note: 2 bytes)
0x02, //Interval
The first two parameters are self-explanatory. They specify the
length of this endpoint descriptor (7) and the descriptor type.
The next parameter identifies the endpoint, the definitions are
defined in usb_device.h and has the following naming
convention:
_EP<##>_<dir>
where ## is the endpoint number and dir is the direction of
transfer. The dir has the value of either 'OUT' or 'IN'.
The next parameter identifies the type of the endpoint. Available
options are _BULK, _INT, _ISO, and _CTRL. The _CTRL is not
typically used because the default control transfer endpoint is
not defined in the USB descriptors. When _ISO option is used,
addition options can be ORed to _ISO. Example:
_ISO|_AD|_FE
This describes the endpoint as an isochronous pipe with adaptive
and feedback attributes. See usb_device.h and the USB
specification for details. The next parameter defines the size of
the endpoint. The last parameter in the polling interval.
-------------------------------------------------------------------
Adding a USB String
-------------------------------------------------------------------
A string descriptor array should have the following format:
rom struct{byte bLength;byte bDscType;word string[size];}sdxxx={
sizeof(sdxxx),DSC_STR,<text>};
The above structure provides a means for the C compiler to
calculate the length of string descriptor sdxxx, where xxx is the
index number. The first two bytes of the descriptor are descriptor
length and type. The rest <text> are string texts which must be
in the unicode format. The unicode format is achieved by declaring
each character as a word type. The whole text string is declared
as a word array with the number of characters equals to <size>.
<size> has to be manually counted and entered into the array
declaration. Let's study this through an example:
if the string is "USB" , then the string descriptor should be:
(Using index 02)
rom struct{byte bLength;byte bDscType;word string[3];}sd002={
sizeof(sd002),DSC_STR,'U','S','B'};
A USB project may have multiple strings and the firmware supports
the management of multiple strings through a look-up table.
The look-up table is defined as:
rom const unsigned char *rom USB_SD_Ptr[]={&sd000,&sd001,&sd002};
The above declaration has 3 strings, sd000, sd001, and sd002.
Strings can be removed or added. sd000 is a specialized string
descriptor. It defines the language code, usually this is
US English (0x0409). The index of the string must match the index
position of the USB_SD_Ptr array, &sd000 must be in position
USB_SD_Ptr[0], &sd001 must be in position USB_SD_Ptr[1] and so on.
The look-up table USB_SD_Ptr is used by the get string handler
function.
-------------------------------------------------------------------
The look-up table scheme also applies to the configuration
descriptor. A USB device may have multiple configuration
descriptors, i.e. CFG01, CFG02, etc. To add a configuration
descriptor, user must implement a structure similar to CFG01.
The next step is to add the configuration descriptor name, i.e.
cfg01, cfg02,.., to the look-up table USB_CD_Ptr. USB_CD_Ptr[0]
is a dummy place holder since configuration 0 is the un-configured
state according to the definition in the USB specification.
********************************************************************/
/*********************************************************************
* Descriptor specific type definitions are defined in:
* usb_device.h
* -usb_descriptors.c-
* This file contains the USB descriptor information. It is used
* in conjunction with the usb_descriptors.h file. When a descriptor is added
* or removed from the main configuration descriptor, i.e. CFG01,
* the user must also change the descriptor structure defined in
* the usb_descriptors.h file. The structure is used to calculate the
* descriptor size, i.e. sizeof(CFG01).
*
* A typical configuration descriptor consists of:
* At least one configuration descriptor (USB_CFG_DSC)
* One or more interface descriptors (USB_INTF_DSC)
* One or more endpoint descriptors (USB_EP_DSC)
*
* Naming Convention:
* To resolve ambiguity, the naming convention are as followed:
* - USB_CFG_DSC type should be named cdxx, where xx is the
* configuration number. This number should match the actual
* index value of this configuration.
* - USB_INTF_DSC type should be named i<yy>a<zz>, where yy is the
* interface number and zz is the alternate interface number.
* - USB_EP_DSC type should be named ep<##><d>_i<yy>a<zz>, where
* ## is the endpoint number and d is the direction of transfer.
* The interface name should also be listed as a suffix to identify
* which interface does the endpoint belong to.
*
* Example:
* If a device has one configuration, two interfaces; interface 0
* has two endpoints (in and out), and interface 1 has one endpoint(in).
* Then the CFG01 structure in the usb_descriptors.h should be:
*
* #define CFG01 ROM struct \
* { USB_CFG_DSC cd01; \
* USB_INTF_DSC i00a00; \
* USB_EP_DSC ep01o_i00a00; \
* USB_EP_DSC ep01i_i00a00; \
* USB_INTF_DSC i01a00; \
* USB_EP_DSC ep02i_i01a00; \
* } cfg01
*
* Note the hierarchy of the descriptors above, it follows the USB
* specification requirement. All endpoints belonging to an interface
* should be listed immediately after that interface.
*
* -------------------------------------------------------------------
* Filling in the descriptor values in the usb_descriptors.c file:
* -------------------------------------------------------------------
* Most items should be self-explanatory, however, a few will be
* explained for clarification.
*
* [Configuration Descriptor(USB_CFG_DSC)]
* The configuration attribute must always have the _DEFAULT
* definition at the minimum. Additional options can be ORed
* to the _DEFAULT attribute. Available options are _SELF and _RWU.
* These definitions are defined in the usb_device.h file. The
* _SELF tells the USB host that this device is self-powered. The
* _RWU tells the USB host that this device supports Remote Wakeup.
*
* [Endpoint Descriptor(USB_EP_DSC)]
* Assume the following example:
* sizeof(USB_EP_DSC),DSC_EP,_EP01_OUT,_BULK,64,0x00
*
* The first two parameters are self-explanatory. They specify the
* length of this endpoint descriptor (7) and the descriptor type.
* The next parameter identifies the endpoint, the definitions are
* defined in usb_device.h and has the following naming
* convention:
* _EP<##>_<dir>
* where ## is the endpoint number and dir is the direction of
* transfer. The dir has the value of either 'OUT' or 'IN'.
* The next parameter identifies the type of the endpoint. Available
* options are _BULK, _INT, _ISO, and _CTRL. The _CTRL is not
* typically used because the default control transfer endpoint is
* not defined in the USB descriptors. When _ISO option is used,
* addition options can be ORed to _ISO. Example:
* _ISO|_AD|_FE
* This describes the endpoint as an isochronous pipe with adaptive
* and feedback attributes. See usb_device.h and the USB
* specification for details. The next parameter defines the size of
* the endpoint. The last parameter in the polling interval.
*
* -------------------------------------------------------------------
* Adding a USB String
* -------------------------------------------------------------------
* A string descriptor array should have the following format:
*
* ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[size];}sdxxx={
* sizeof(sdxxx),DSC_STR,<text>};
*
* The above structure provides a means for the C compiler to
* calculate the length of string descriptor sdxxx, where xxx is the
* index number. The first two bytes of the descriptor are descriptor
* length and type. The rest <text> are string texts which must be
* in the unicode format. The unicode format is achieved by declaring
* each character as a word type. The whole text string is declared
* as a word array with the number of characters equals to <size>.
* <size> has to be manually counted and entered into the array
* declaration. Let's study this through an example:
* if the string is "USB" , then the string descriptor should be:
* (Using index 02)
* ROM struct{byte bLength;uint8_t bDscType;uint16_t string[3];}sd002={
* sizeof(sd002),DSC_STR,'U','S','B'};
*
* A USB project may have multiple strings and the firmware supports
* the management of multiple strings through a look-up table.
* The look-up table is defined as:
* ROM const unsigned char *ROM USB_SD_Ptr[]={&sd000,&sd001,&sd002};
*
* The above declaration has 3 strings, sd000, sd001, and sd002.
* Strings can be removed or added. sd000 is a specialized string
* descriptor. It defines the language code, usually this is
* US English (0x0409). The index of the string must match the index
* position of the USB_SD_Ptr array, &sd000 must be in position
* USB_SD_Ptr[0], &sd001 must be in position USB_SD_Ptr[1] and so on.
* The look-up table USB_SD_Ptr is used by the get string handler
* function in usb9.c.
*
* -------------------------------------------------------------------
*
* The look-up table scheme also applies to the configuration
* descriptor. A USB device may have multiple configuration
* descriptors, i.e. CFG01, CFG02, etc. To add a configuration
* descriptor, user must implement a structure similar to CFG01.
* The next step is to add the configuration descriptor name, i.e.
* cfg01, cfg02,.., to the look-up table USB_CD_Ptr. USB_CD_Ptr[0]
* is a dummy place holder since configuration 0 is the un-configured
* state according to the definition in the USB specification.
*
* Configuration options are defined in:
* usb_config.h
********************************************************************/
/** INCLUDES *******************************************************/
/** I N C L U D E S *************************************************/
#include "usb.h"
#include "usb_device_hid.h"
/** C O N S T A N T S ************************************************/
#ifndef __XC8__
#pragma romdata
#endif
/* Device Descriptor */
const USB_DEVICE_DESCRIPTOR device_dsc=
ROM USB_DEV_DSC device_dsc=
{
0x12, // Size of this descriptor in bytes
USB_DESCRIPTOR_DEVICE, // DEVICE descriptor type
sizeof(USB_DEV_DSC), // Size of this descriptor in bytes
DSC_DEV, // 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, see usb_config.h
0x003C, // Product ID, see usb_config.h
EP0_BUFF_SIZE, // Max packet size for EP0, see usb_config.h
0x04D8, // Vendor ID: Microchip
0x003C, // Product ID: HID Bootloader
0x0101, // Device release number in BCD format
0x01, // Manufacturer string index
0x02, // Product string index
@@ -160,13 +177,13 @@ const USB_DEVICE_DESCRIPTOR device_dsc=
0x01 // Number of possible configurations
};
/* Configuration 1 Descriptor */
const uint8_t configDescriptor1[]={
/* Configuration 1 Descriptors */
ROM uint8_t CFG01[CONFIG_DESC_TOTAL_LEN]={
/* Configuration Descriptor */
0x09,//sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
USB_DESCRIPTOR_CONFIGURATION, // CONFIGURATION descriptor type
0x29, // Total length of data for this cfg - LSB
0x00, // Total length of data for this cfg - MSB
sizeof(USB_CFG_DSC), // Size of this descriptor in bytes
DSC_CFG, // CONFIGURATION descriptor type
(uint8_t)CONFIG_DESC_TOTAL_LEN, // Total length of data for this cfg - LSB
(uint8_t)(CONFIG_DESC_TOTAL_LEN>>8), // Total length of data for this cfg - MSB
1, // Number of interfaces in this cfg
1, // Index value of this configuration
0, // Configuration string index
@@ -174,78 +191,65 @@ const uint8_t configDescriptor1[]={
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
sizeof(USB_INTF_DSC), // Size of this descriptor in bytes
DSC_INTF, // INTERFACE descriptor type
0, // Interface Number
0, // Alternate Setting Number
2, // Number of endpoints in this intf
HID_INTF, // Class code
0, // Subclass code
0, // Protocol code
0, // Subclass code, no subclass
0, // Protocol code, no protocol
0, // Interface string index
/* HID Class-Specific Descriptor */
0x09,//sizeof(USB_HID_DSC)+3, // Size of this descriptor in bytes RRoj hack
sizeof(USB_HID_DSC), // Size of this descriptor in bytes
DSC_HID, // HID descriptor type
0x11, // HID Spec Release Number in BCD format (0x0111 = v1.11) - LSB
0x01, // HID Spec Release Number in BCD format (0x0111 = v1.11) - MSB
0x00, // Country Code (0x00 for Not supported)
HID_NUM_OF_DSC, // Number of class descriptors, see usbcfg.h
HID_NUM_OF_DSC, // Number of class descriptors, see usb_config.h
DSC_RPT, // Report descriptor type
DESC_CONFIG_WORD(HID_RPT01_SIZE), //sizeof(hid_rpt01), // Size of the report descriptor
(uint8_t)HID_RPT01_SIZE, // Size of the report descriptor - LSB
(uint8_t)((uint16_t)HID_RPT01_SIZE >> 8), // Size of the report descriptor - MSB
/* Endpoint Descriptor */
0x07,/*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_IN, //EndpointAddress
_INTERRUPT, //Attributes
DESC_CONFIG_WORD(HID_INT_IN_EP_SIZE), //size
0x01, //Interval
sizeof(USB_EP_DSC), //Endpoint descriptor size
DSC_EP, //Type of descriptor (endpoint)
_EP01_IN, //Endpoint number + direction
_INT, //Endpoint transfer type implemented
HID_INT_IN_EP_SIZE, //LSB - endpoint size
0x00, //MSB - endpoint size
0x01, //bInterval
/* Endpoint Descriptor */
0x07,/*sizeof(USB_EP_DSC)*/
USB_DESCRIPTOR_ENDPOINT, //Endpoint Descriptor
_EP01_OUT, //EndpointAddress
_INTERRUPT, //Attributes
DESC_CONFIG_WORD(HID_INT_OUT_EP_SIZE), //size
0x01, //Interval
sizeof(USB_EP_DSC), //Endpoint descriptor size
DSC_EP, //Type of descriptor (endpoint)
_EP01_OUT, //Endpoint number + direction
_INT, //Endpoint transfer type implemented
HID_INT_OUT_EP_SIZE, //LSB - endpoint size
0x00, //MSB - endpoint size
0x01 //bInterval
};
ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[1];}sd000={
sizeof(sd000),DSC_STR,0x0409};
//Language code string descriptor
const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[1];}sd000={
sizeof(sd000),USB_DESCRIPTOR_STRING,{0x0409
}};
ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd001={
sizeof(sd001),DSC_STR,
'M','i','c','r','o','c','h','i','p',' ',
'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.'};
//Manufacturer string descriptor
const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[25];}sd001={
sizeof(sd001),USB_DESCRIPTOR_STRING,
{'M','i','c','r','o','c','h','i','p',' ',
'T','e','c','h','n','o','l','o','g','y',' ','I','n','c','.'
}};
ROM struct{uint8_t bLength;uint8_t bDscType;uint16_t string[18];}sd002={
sizeof(sd002),DSC_STR,
'H','I','D',' ','U','S','B',' ','B','o','o',
't','l','o','a','d','e','r'};
//Product string descriptor
const struct{uint8_t bLength;uint8_t bDscType;uint16_t string[18];}sd002={
sizeof(sd002),USB_DESCRIPTOR_STRING,
{'H','I','D',' ','U','S','B',' ','B','o','o',
't','l','o','a','d','e','r'
}};
//Array of configuration descriptors
const uint8_t *const USB_CD_Ptr[]=
ROM uint8_t hid_rpt01[HID_RPT01_SIZE]=
// First byte in each row is the "item". First byte's two least significant
// bits are the number of data bytes that follow, but encoded (0=0, 1=1, 2=2, 3=4 bytes).
// bSize should match number of bytes that follow, or REPORT descriptor parser won't work. The bytes
// that follow in each item line are data bytes
{
(const uint8_t *const)&configDescriptor1
};
//Array of string descriptors
const uint8_t *const USB_SD_Ptr[]=
{
(const uint8_t *const)&sd000,
(const uint8_t *const)&sd001,
(const uint8_t *const)&sd002
};
const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={{
0x06, 0x00, 0xFF, // Usage Page = 0xFF00 (Vendor Defined Page 1)
0x09, 0x01, // Usage (Vendor Usage 1)
0xA1, 0x01, // Collection (Application)
@@ -260,7 +264,19 @@ const struct{uint8_t report[HID_RPT01_SIZE];}hid_rpt01={{
0x29, 0x40, // Usage Maximum //64 output usages total (0x01 to 0x40)
0x91, 0x00, // Output (Data, Array, Abs): Instantiates output packet fields. Uses same report size and count as "Input" fields, since nothing new/different was specified to the parser since the "Input" item.
0xC0 // End Collection
}
};
/** EOF usb_descriptors.c ***************************************************/
ROM unsigned char* ROM USB_SD_Ptr[]=
{
(ROM const unsigned char *ROM)&sd000,
(ROM const unsigned char *ROM)&sd001,
(ROM const unsigned char *ROM)&sd002
};
#ifndef __XC8__
#pragma code
#endif
/** EOF usb_descriptors.c ****************************************************/

View File

@@ -1,85 +0,0 @@
#include "usb.h"
#include "usb_device_hid.h"
#include "bootloader.h"
/*******************************************************************
* Function: bool USER_USB_CALLBACK_EVENT_HANDLER(
* USB_EVENT event, void *pdata, uint16_t size)
*
* PreCondition: None
*
* Input: USB_EVENT event - the type of event
* void *pdata - pointer to the event data
* uint16_t size - size of the event data
*
* Output: None
*
* Side Effects: None
*
* Overview: This function is called from the USB stack to
* notify a user application that a USB event
* occured. This callback is in interrupt context
* when the USB_INTERRUPT option is selected.
*
* Note: None
*******************************************************************/
bool USER_USB_CALLBACK_EVENT_HANDLER(USB_EVENT event, void *pdata, uint16_t size)
{
switch( (int) event )
{
case EVENT_TRANSFER:
break;
case EVENT_SOF:
break;
case EVENT_SUSPEND:
//Call the hardware platform specific handler for suspend events for
//possible further action (like optionally going reconfiguring the application
//for lower power states and going to sleep during the suspend event). This
//would normally be done in USB compliant bus powered applications, although
//no further processing is needed for purely self powered applications that
//don't consume power from the host.
//asm("SLEEP"); // sleep right now, execution starts on next line when woken up
// we have been woken up. if the watchdog was the cause go back to sleep
//while ((PIR2bits.USBIF == 0) && (RCONbits.TO == 0))
//{
// asm("SLEEP");
//}
break;
case EVENT_RESUME:
// restore any hardware states (i.e. IO pin config) that were changed on suspend
break;
case EVENT_CONFIGURED:
// When the device is configured, we should (re)initialize our state variables
UserInit();
break;
case EVENT_SET_DESCRIPTOR:
break;
case EVENT_EP0_REQUEST:
/* We have received a non-standard USB request. The HID driver
* needs to check to see if the request was for it. */
USBCheckHIDRequest();
break;
case EVENT_BUS_ERROR:
break;
case EVENT_TRANSFER_TERMINATED:
break;
default:
break;
}
return true;
}
/*******************************************************************************
End of File
*/

View File

@@ -334,7 +334,7 @@ typedef union __USTAT
#define USBHALGetLastDirection(stat) stat.direction
#define USBHALGetLastPingPong(stat) stat.ping_pong
/*
typedef union _POINTER
{
struct
@@ -359,7 +359,7 @@ typedef union _POINTER
//rom far byte* fbRom; // Far = 3 bytes pointer
//rom far word* fwRom;
} POINTER;
*/
// *****************************************************************************
// *****************************************************************************
// Section: Interface Routines

View File

@@ -27,11 +27,15 @@
#ifndef MEMORY_
#define MEMORY_
#define APP_FW_MEMORY_OFFSET 0x2080
#define APP_FW_MEMORY_OFFSET 0x2000
#define BOOTLOADER_ENTRYPOINT 0x001C
#define APP_FW_VERSION_ADDRESS (APP_FW_MEMORY_OFFSET + 0x0016)
#define APP_FW_VERSION_ADDRESS (APP_FW_MEMORY_OFFSET + 0x16)
#define APP_SIGNATURE_ADDRESS (APP_FW_MEMORY_OFFSET + 0x06) //0x1C06 and 0x1C07 contains the "signature" WORD, indicating successful erase/program/verify operation
#define APP_SIGNATURE_VALUE 0x600D //leet "GOOD", implying that the erase/program was a success and the bootloader intentionally programmed the APP_SIGNATURE_ADDRESS with this value
#define APP_VERSION_ADDRESS APP_FW_VERSION_ADDRESS //0x1C16 and 0x1C17 should contain the application image firmware version number
#endif /* MEMORY_ */

View File

@@ -95,16 +95,46 @@
<makeCustomizationNormalizeHexFile>false</makeCustomizationNormalizeHexFile>
</makeCustomizationType>
<item path="../../common_src/framework/usb/src/usb_device_hid.c"
ex="true"
ex="false"
overriding="false">
<HI-TECH-COMP>
</HI-TECH-COMP>
<HI-TECH-LINK>
</HI-TECH-LINK>
<XC8-config-global>
</XC8-config-global>
</item>
<item path="../src/dancepad.c" ex="true" overriding="false">
<item path="../src/dancepad.c" ex="false" overriding="false">
<HI-TECH-COMP>
</HI-TECH-COMP>
<HI-TECH-LINK>
</HI-TECH-LINK>
<XC8-config-global>
</XC8-config-global>
</item>
<item path="../src/interrupts.c" ex="true" overriding="false">
<item path="../src/interrupts.c" ex="false" overriding="false">
<HI-TECH-COMP>
</HI-TECH-COMP>
<HI-TECH-LINK>
</HI-TECH-LINK>
<XC8-config-global>
</XC8-config-global>
</item>
<item path="../src/padhal.c" ex="true" overriding="false">
<item path="../src/padhal.c" ex="false" overriding="false">
<HI-TECH-COMP>
</HI-TECH-COMP>
<HI-TECH-LINK>
</HI-TECH-LINK>
<XC8-config-global>
</XC8-config-global>
</item>
<item path="../src/usb_events.c" ex="true" overriding="false">
<item path="../src/usb_events.c" ex="false" overriding="false">
<HI-TECH-COMP>
</HI-TECH-COMP>
<HI-TECH-LINK>
</HI-TECH-LINK>
<XC8-config-global>
</XC8-config-global>
</item>
<HI-TECH-COMP>
<property key="additional-warnings" value="true"/>
@@ -142,7 +172,7 @@
</HI-TECH-COMP>
<HI-TECH-LINK>
<property key="additional-options-checksum" value=""/>
<property key="additional-options-code-offset" value="2080"/>
<property key="additional-options-code-offset" value="0x2000"/>
<property key="additional-options-command-line" value=""/>
<property key="additional-options-errata" value=""/>
<property key="additional-options-extend-address" value="false"/>
@@ -153,7 +183,7 @@
<property key="calibrate-oscillator-value" value="0x3400"/>
<property key="clear-bss" value="true"/>
<property key="code-model-external" value="wordwrite"/>
<property key="code-model-rom" value="default,-0-207F,-2086-2087,-2096-2097"/>
<property key="code-model-rom" value="default,-0-1FFF,-2006-2007,-2016-2017"/>
<property key="create-html-files" value="false"/>
<property key="data-model-ram" value=""/>
<property key="data-model-size-of-double" value="32"/>
@@ -264,7 +294,6 @@
<archiverTool>
</archiverTool>
<loading>
<loadableFile>../../bootloader/clubdance_v2_bootloader.X/dist/default/production/clubdance_v2_bootloader.X.production.hex</loadableFile>
<useAlternateLoadableFile>false</useAlternateLoadableFile>
<parseOnProdLoad>false</parseOnProdLoad>
<alternateLoadableFile></alternateLoadableFile>

View File

@@ -24,33 +24,33 @@
*/
#pragma warning disable 1510
//#include "usb.h"
//#include "padhal.h"
//#include "dancepad.h"
#include "usb.h"
#include "padhal.h"
#include "dancepad.h"
#include "memory.h"
//#ifdef LINK_FOR_BOOTLOADER
#ifdef LINK_FOR_BOOTLOADER
// only define this if building fw to be used with the bootloader
const unsigned int VersionWord __at(APP_FW_VERSION_ADDRESS) = 0x0100;
//#endif
const uint16_t VersionWord __at(0x2016) = 0x0100;
#endif
void main(void)
{
// initialize sensor HAL & the dancepad driver
/*PADHAL_Initialize();
PADHAL_Initialize();
DANCEPAD_Initialize();
// initialize the USB framework
USBDeviceInit();
USBDeviceAttach();*/
USBDeviceAttach();
while(1)
{
// do nothing if: not connected to USB host, or the host put us in suspend state
//if((USBGetDeviceState() < CONFIGURED_STATE) | USBIsDeviceSuspended())
// continue;
if((USBGetDeviceState() < CONFIGURED_STATE) | USBIsDeviceSuspended())
continue;
// run application specific tasks
//DANCEPAD_Tasks();
DANCEPAD_Tasks();
}
}

View File

@@ -80,8 +80,8 @@
//(ex: USBDeviceTasks()) must be called periodically by the application firmware
//at a minimum rate as described in the inline code comments in usb_device.c.
//------------------------------------------------------
#define USB_POLLING
//#define USB_INTERRUPT
//#define USB_POLLING
#define USB_INTERRUPT
//------------------------------------------------------------------------------
/* Parameter definitions are defined in usb_device.h */