📄 user_generic_hid.c
字号:
/*********************************************************************
*
* Microchip USB C18 Firmware - Mouse Demo
*
*********************************************************************
* FileName: user_generic_hid.c
* Dependencies: See INCLUDES section below
* Processor: PIC18
* Compiler: C18 2.30.01+
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the Company for its PICmicro?Microcontroller is intended and
* supplied to you, the Company's customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AS IS CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Rawin Rojvanit 11/19/04 Original.
* Jan Axelson 3/4/05 Mouse application adapted for
* Generic HID application.
* 3/30/05 Minor bug fixes and enhancements.
********************************************************************/
/*
This application is a generic HID device (not a system keyboard or mouse)
that does the following:
Receives Output reports using interrupt OUT transfers and sends the report
data back to the host in Input reports using interrupt IN transfers.
Receives Output reports using control transfers (Set_Report request)
and sends the report data back to the host in Input reports using control
transfers (Get_Report requests.)
The application uses separate buffers for Output reports received via
interrupt transfers and Output reports received via control transfers use
separate buffers. The application uses separate buffers for Input reports
received via interrupt transfers and Input reports received via control
transfers.
Receives Feature reports using control transfers (Set_Report request)
and sends the report data back to the host in Feature reports using
control transfers (Get_Report requests.)
A single buffer holds received Feature reports and reports to be sent.
This example is adapted from Microchip's Mouse example.
This application and host applications to communicate with the device are available
from www.Lvr.com/hidpage.htm
*/
/** I N C L U D E S **********************************************************/
#include <p18cxxx.h>
#include <usart.h>
#include "system\typedefs.h"
#include "system\usb\usb.h"
#include "io_cfg.h" // I/O pin mapping
#include "user\user_generic_hid.h"
#include "mm36sb020.c"
/** V A R I A B L E S ********************************************************/
#pragma udata
// BOOL emulate_mode;
// rom signed char dir_table[]={-4,-4,-4, 0, 4, 4, 4, 0};
// byte movement_length;
// byte vector = 0;
byte number_of_bytes_read;
char transmit_buffer[EP0_BUFF_SIZE];
char receive_buffer[EP0_BUFF_SIZE];
char RealReceiveBuffer[64];
BOOL bLengthRsvd=FALSE;
byte dataPacket[dataPacketMAXSIZE];
byte pCount=0; // number of packets received
byte GCounter=0;
typedef union _DATA_PACKET
{
byte _byte[16]; //For Byte Access
unsigned long _dword[4];
} DATA_PACKET;
/** P R I V A T E P R O T O T Y P E S ***************************************/
void BlinkUSBStatus(void);
void ReportLoopback(void);
void HandleControlOutReport(void);
/** D E C L A R A T I O N S **************************************************/
#pragma code
void UserInit(void)
{
int i=0;
ClrWdt();
mInitAllLEDs();
// Flash
mm36sb020_OE_tris = 1;
initiate_mm36sb020 (); // 初始化必须放在整个程序开始的初始化函数中
for(i=0;i<64;i++) RealReceiveBuffer[i]=0xFF;
}//end UserInit
void UnknownPacket(void)
{
int count=0,i=0,j=0;
ClrWdt();
dataPacket[0]=4;
dataPacket[1]=3;
dataPacket[2]='U';
dataPacket[3]='n';
for(j=0;j<1024;j++)
{
for(i=0;i<HID_INPUT_REPORT_BYTES;i++)
dataPacket[i]=receive_buffer[i]+1;
for(count=0;count<dataPacket[0];count+=HID_INPUT_REPORT_BYTES-1)
{
for(i=0;i<HID_INPUT_REPORT_BYTES;i++)
transmit_buffer[i]=dataPacket[count+i];
while(mHIDTxIsBusy()) USBDriverService();
HIDTxReport(transmit_buffer, HID_INPUT_REPORT_BYTES);
}
}
}
void ReadBlackBox(void)
{
int count=0,PageAddress=0,PageOffset=0;
unsigned long FlashAddress=0,AddressCounter=0,counter16=0;
byte B4array[4],i=0;
DATA_PACKET FlashReadBuffer;
ClrWdt();
mm36sb020_OE_tris = 1;
while(!mm36sb020_OE) ; // 这里可能造成 死循环
mm36sb020_OE_lat = 0;
mm36sb020_OE_tris = 0; // 占用FLASH资源,向OE信号线写0,告诉其它控制器,我在占用.
mm36sb020_reset();
mm36sb020_read_nbytes(&AddressCounter,FlashReadBuffer._byte,16); //读的地址有可能出错,是否需要处理?
FlashAddress=FlashReadBuffer._dword[0]; //把从Flash读得的地址送到FlashAddress中
if (FlashAddress>0x40000) FlashAddress=0x3FFFF;
dataPacket[0]=0x12; // 每次向PC发送18个字节的数据,这里还可以提高效率,每次发送0x22个数据。
dataPacket[1]=READ_BLACKBOX;
AddressCounter=FlashAddress; //用AddressCounter来进行读取的地址计数。
// 从地址FlashAddress到0x3FFF0读取记录并发给PC,每条记录16字节.
while(AddressCounter<0x40000)
{
mm36sb020_read_nbytes(&AddressCounter,FlashReadBuffer._byte,16);
for(i=0;i<16;i++) dataPacket[2+i]=FlashReadBuffer._byte[i];
for(count=0;count<dataPacket[0];count+=HID_INPUT_REPORT_BYTES)
{
for(i=0;i<HID_INPUT_REPORT_BYTES;i++)
transmit_buffer[i]=dataPacket[count+i];
while(mHIDTxIsBusy()) USBDriverService();
HIDTxReport(transmit_buffer, HID_INPUT_REPORT_BYTES);
}
AddressCounter+=0x10;
ClrWdt();
}
AddressCounter=0x0080;
// 从地址0x00100到FlashAddress读取记录并发给PC,每条记录16字节
//如果遇到读的记录都是0xFF的话则退出.
while(AddressCounter<=FlashAddress)
{
mm36sb020_read_nbytes(&AddressCounter,FlashReadBuffer._byte,16);
if((FlashReadBuffer._byte[0]==0xFF) && (FlashReadBuffer._byte[15]==0xFF)) break;
for(i=0;i<16;i++)
dataPacket[2+i]=FlashReadBuffer._byte[i];
for(count=0;count<dataPacket[0];count+=HID_INPUT_REPORT_BYTES)
{
for(i=0;i<HID_INPUT_REPORT_BYTES;i++)
transmit_buffer[i]=dataPacket[count+i];
while(mHIDTxIsBusy()) USBDriverService();
HIDTxReport(transmit_buffer, HID_INPUT_REPORT_BYTES);
}
AddressCounter+=0x10;
ClrWdt();
}
for(i=0;i<16;i++) dataPacket[2+i]=0xFF;
for(count=0;count<dataPacket[0];count+=HID_INPUT_REPORT_BYTES)
{
for(i=0;i<HID_INPUT_REPORT_BYTES;i++)
transmit_buffer[i]=dataPacket[count+i];
while(mHIDTxIsBusy()) USBDriverService();
HIDTxReport(transmit_buffer, HID_INPUT_REPORT_BYTES);
}
//在PC端最后的结束的判断条件是最后的当前读取的记录==上一条读取的记录.
mm36sb020_test ();
initiate_mm36sb020 ();
mm36sb020_OE_tris = 1;// 释放FLASH芯片的OE占用信号,由于OE有上拉电阻,此时为1,其它主控CPU可以对其操作了
}
void InitBlackBox(void)
// 初始化黑匣子.
// 1)、把黑匣子数据都清空为0xFF.
// 2)、把0x00-0x03地址处写入0x3FFFF.
// 把当前日期和时间写入黑匣子的第0页第0x10开始的5个字节.
// 格式为: 00,年,月,日,时,分,秒.
// receive_buf[4] 到 receive_buf[9] 为 年,月,日,时,分,秒.
{
unsigned long i=0;
unsigned long FlashAddress=0;
DATA_PACKET FlashWriteBuffer;
int okFlag=TRUE,count=0;
ClrWdt();
mm36sb020_OE_tris = 1;
while(!mm36sb020_OE) ; // 这里可能造成 死循环
mm36sb020_OE_lat = 0;
mm36sb020_OE_tris = 0; // 占用FLASH资源,向OE信号线写0,告诉其它控制器,我在占用.
// initiate_mm36sb020();
mm36sb020_reset();
mm36sb020_erase(); // 清空Flash芯片
for(i=0;i<16;i++) FlashWriteBuffer._byte[i]=0xFF;
//FlashAddress=0x00010;
FlashAddress=(unsigned long)RealReceiveBuffer[0x14];
for(i=0;i<16;i++) FlashWriteBuffer._byte[i]=RealReceiveBuffer[4+i];
okFlag=mm36sb020_write_nbytes(&FlashAddress,FlashWriteBuffer._byte,16);
Nop();
Nop();
if(okFlag==TRUE)
{
dataPacket[0]=4;
dataPacket[1]=INIT_BLACKBOX;
dataPacket[2]=9;
dataPacket[3]=9;
}
else
{
dataPacket[0]=4;
dataPacket[1]=INIT_BLACKBOX;
dataPacket[2]=0;
dataPacket[3]=0;
}
for(count=0;count<dataPacket[0];count+=HID_INPUT_REPORT_BYTES)
{
for(i=0;i<HID_INPUT_REPORT_BYTES;i++)
transmit_buffer[i]=dataPacket[count+i];
while(mHIDTxIsBusy()) USBDriverService();
HIDTxReport(transmit_buffer, HID_INPUT_REPORT_BYTES);
}
mm36sb020_test ();
initiate_mm36sb020 ();
mm36sb020_OE_tris = 1;// 释放FLASH芯片的OE占用信号,由于OE有上拉电阻,此时为1,其它主控CPU可以对其操作了
}
/******************************************************************************
* Function: void ProcessIO(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: This function is a place holder for other user routines.
* It is a mixture of both USB and non-USB tasks.
*
* Note: None
*****************************************************************************/
void ProcessIO(void)
{
// Called repeatedly in main().
ClrWdt();
BlinkUSBStatus();
// User Application USB tasks
if((usb_device_state < CONFIGURED_STATE)||(UCONbits.SUSPND==1)) return;
ReportLoopback();
}//end ProcessIO
/******************************************************************************
* Function: void ReportLoopback(void)
*
* PreCondition: None
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Checks to see if an Output report has been received on
the Interrupt OUT endpoint. If yes, sends the report
data back as an Input report on the Interrupt IN endpoint.
Shows how to extract data from an Output report received
on an interrupt endpoint and how to provide data to be
sent in an Input report on an interrupt endpoint.
*
* Note: None
*****************************************************************************/
void ReportLoopback(void)
{
byte count=12,i=0;
ClrWdt();
number_of_bytes_read = HIDRxReport(receive_buffer, HID_OUTPUT_REPORT_BYTES);
if (number_of_bytes_read > 0)
{
{
for(i=0;i<HID_OUTPUT_REPORT_BYTES;i++)
RealReceiveBuffer[pCount++]=receive_buffer[i];
if(pCount>=RealReceiveBuffer[0]) // 判断已经从PC收到多少个字节, 可以在从PC收到固定多个字节后在做相应数据发送工作
{ bLengthRsvd=TRUE; pCount=0; }
}
if (bLengthRsvd==TRUE) // If received ID num then
{
switch(RealReceiveBuffer[2])
{
case READ_STATUS:
ReceiveControllerStatus();
break;
case READ_BLACKBOX:
ReadBlackBox();
break;
case INIT_BLACKBOX:
InitBlackBox();
break;
default:
UnknownPacket();
break;
}
bLengthRsvd=FALSE;
for(i=0;i<64;i++) RealReceiveBuffer[i]=0xFF;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -