2022-02-09 05:39:39 +01:00
|
|
|
|
// Copyright 2021 IOsetting <iosetting(at)outlook.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.
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* USB Keyboard Demo
|
|
|
|
|
*
|
|
|
|
|
* P0: 8 bits for 4x4 Key matrix
|
|
|
|
|
* P6.0: NumLock
|
|
|
|
|
* P6.1: CapsLock
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "fw_hal.h"
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
|
|
#define KeyIO P0
|
|
|
|
|
|
|
|
|
|
__BIT B_1ms; // 1ms flag
|
|
|
|
|
__BIT KeyChangeTemp;
|
|
|
|
|
__BIT KeyChangeFlag;
|
|
|
|
|
uint16_t cnt50ms;
|
|
|
|
|
uint16_t KeyCode; // code of key pressed
|
|
|
|
|
uint16_t OldKeyCode; // for key status changing check
|
|
|
|
|
uint16_t NewKeyCode; // new key status
|
|
|
|
|
uint16_t KeyHoldTime;
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t DEVICEDESC[18];
|
|
|
|
|
__CODE uint8_t CONFIGDESC[41];
|
|
|
|
|
__CODE uint8_t HIDREPORTDESC[63];
|
|
|
|
|
__CODE uint8_t LANGIDDESC[4];
|
|
|
|
|
__CODE uint8_t MANUFACTDESC[8];
|
|
|
|
|
__CODE uint8_t PRODUCTDESC[30];
|
|
|
|
|
__CODE uint8_t KeyMap[16];
|
|
|
|
|
__XDATA uint8_t HidFreature[64];
|
|
|
|
|
__XDATA uint8_t HidInput[64];
|
|
|
|
|
__XDATA uint8_t HidOutput[64];
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_Request_t usb_request;
|
|
|
|
|
USB_EP0_Stage_t usb_ep0_stage;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
|
|
|
|
|
void USB_Init(void);
|
|
|
|
|
void KeyScan(void);
|
|
|
|
|
void SendKeyStatus(void);
|
|
|
|
|
|
|
|
|
|
void main()
|
|
|
|
|
{
|
|
|
|
|
uint8_t i;
|
|
|
|
|
|
|
|
|
|
GPIO_P1_SetMode(GPIO_Pin_All, GPIO_Mode_InOut_QBD);
|
2022-02-09 07:49:48 +01:00
|
|
|
|
GPIO_P3_SetMode(GPIO_Pin_0 | GPIO_Pin_1, GPIO_Mode_Input_HIP);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
GPIO_P6_SetMode(GPIO_Pin_All, GPIO_Mode_Output_PP);
|
|
|
|
|
|
|
|
|
|
USB_Init();
|
|
|
|
|
|
|
|
|
|
TIM_Timer0_Config(HAL_State_ON, TIM_TimerMode_16BitAuto, 1000);
|
|
|
|
|
EXTI_Timer0_SetIntState(HAL_State_ON);
|
|
|
|
|
EXTI_Timer0_SetIntPriority(EXTI_IntPriority_High);
|
|
|
|
|
TIM_Timer0_SetRunState(HAL_State_ON);
|
|
|
|
|
EXTI_Global_SetIntState(HAL_State_ON);
|
|
|
|
|
|
2022-02-09 07:49:48 +01:00
|
|
|
|
for (i = 0; i < 8; i++)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
HidInput[i] = 0;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (B_1ms) // every 1 ms
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
B_1ms = 0;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (++cnt50ms >= 50) // scan every 50 ms
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
cnt50ms = 0;
|
|
|
|
|
KeyScan();
|
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (KeyChangeFlag) // if key status changed
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
KeyChangeFlag = 0;
|
|
|
|
|
SendKeyStatus();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void USB_Init()
|
|
|
|
|
{
|
|
|
|
|
SYS_EnableOscillator48M();
|
|
|
|
|
USB_SetClockSource(USB_ClockSource_6M);
|
|
|
|
|
USB_SetEnabled(HAL_State_ON);
|
|
|
|
|
USB_SetDpDmPullUp(HAL_State_ON);
|
|
|
|
|
EXTI_USB_SetIntPriority(EXTI_IntPriority_Highest);
|
|
|
|
|
|
|
|
|
|
USB_WriteReg(FADDR, 0x00);
|
|
|
|
|
USB_WriteReg(POWER, 0x08);
|
|
|
|
|
USB_WriteReg(INTRIN1E, 0x3f);
|
|
|
|
|
USB_WriteReg(INTROUT1E, 0x3f);
|
|
|
|
|
USB_WriteReg(INTRUSBE, 0x00);
|
|
|
|
|
USB_WriteReg(POWER, 0x01);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
|
|
|
|
|
EXTI_USB_SetIntState(HAL_State_ON);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INTERRUPT(USB_Routine, EXTI_VectUSB)
|
|
|
|
|
{
|
|
|
|
|
uint8_t intrusb;
|
|
|
|
|
uint8_t intrin;
|
|
|
|
|
uint8_t introut;
|
|
|
|
|
uint8_t csr;
|
|
|
|
|
uint8_t cnt;
|
2022-02-09 07:10:27 +01:00
|
|
|
|
uint16_t len = 0;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
intrusb = USB_ReadReg(INTRUSB);
|
|
|
|
|
intrin = USB_ReadReg(INTRIN1);
|
|
|
|
|
introut = USB_ReadReg(INTROUT1);
|
|
|
|
|
if (intrusb & RSTIF)
|
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_SelectEndPoint(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
USB_WriteReg(INCSR1, INCLRDT);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_SelectEndPoint(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
USB_WriteReg(OUTCSR1, OUTCLRDT);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
if (intrin & EP0IF)
|
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_SelectEndPoint(0);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
csr = USB_ReadReg(CSR0);
|
|
|
|
|
if (csr & STSTL)
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(CSR0, csr & ~STSTL);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
if (csr & SUEND)
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(CSR0, csr | SSUEND);
|
|
|
|
|
}
|
2022-02-09 07:59:29 +01:00
|
|
|
|
switch (usb_ep0_stage.bStage)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
case USB_CtrlState_Idle:
|
|
|
|
|
if (csr & OPRDY)
|
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_SettingUp;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
USB_ReadFIFO(FIFO0, (uint8_t *)&usb_request);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
((uint8_t *)&usb_ep0_stage.wResidue)[0] = usb_request.wLength.bb.bh;
|
|
|
|
|
((uint8_t *)&usb_ep0_stage.wResidue)[1] = usb_request.wLength.bb.bl;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
switch (usb_request.bmRequestType & REQUEST_TYPE_MASK)
|
|
|
|
|
{
|
|
|
|
|
case USB_RequestType_Standard:
|
2022-02-09 07:49:48 +01:00
|
|
|
|
switch (usb_request.bRequest)
|
|
|
|
|
{
|
|
|
|
|
case USB_StdReq_SetAddress:
|
|
|
|
|
USB_WriteReg(FADDR, usb_request.wValue.bb.bl);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case USB_StdReq_SetConfiguration:
|
|
|
|
|
USB_SelectEndPoint(1);
|
|
|
|
|
USB_WriteReg(INCSR2, INMODEIN);
|
|
|
|
|
USB_WriteReg(INMAXP, 8);
|
|
|
|
|
USB_SelectEndPoint(1);
|
|
|
|
|
USB_WriteReg(INCSR2, INMODEOUT);
|
|
|
|
|
USB_WriteReg(OUTMAXP, 8);
|
|
|
|
|
USB_SelectEndPoint(0);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case USB_StdReq_GetDescriptor:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_DataIn;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
switch (usb_request.wValue.bb.bh)
|
|
|
|
|
{
|
|
|
|
|
case USB_DescriptorType_Device:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = (uint8_t *)DEVICEDESC;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
len = sizeof(DEVICEDESC);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case USB_DescriptorType_Configuration:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = (uint8_t *)CONFIGDESC;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
len = sizeof(CONFIGDESC);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case USB_DescriptorType_String:
|
|
|
|
|
switch (usb_request.wValue.bb.bl)
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = (uint8_t *)LANGIDDESC;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
len = sizeof(LANGIDDESC);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 1:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = (uint8_t *)MANUFACTDESC;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
len = sizeof(MANUFACTDESC);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case 2:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = (uint8_t *)PRODUCTDESC;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
len = sizeof(PRODUCTDESC);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Stalled;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case USB_DescriptorType_Report:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = (uint8_t *)HIDREPORTDESC;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
len = sizeof(HIDREPORTDESC);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Stalled;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-02-09 07:59:29 +01:00
|
|
|
|
if (len < usb_ep0_stage.wResidue)
|
2022-02-09 07:49:48 +01:00
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.wResidue = len;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Stalled;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-02-09 05:39:39 +01:00
|
|
|
|
break;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_RequestType_Class:
|
|
|
|
|
switch (usb_request.bRequest)
|
|
|
|
|
{
|
|
|
|
|
case USB_HidReq_GetReport:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = HidFreature;
|
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_DataIn;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
break;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_HidReq_SetReport:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.pData = HidFreature;
|
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_DataOut;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
break;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_HidReq_SetIdle:
|
|
|
|
|
break;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 07:10:27 +01:00
|
|
|
|
// case USB_HidReq_GetIdle:
|
|
|
|
|
// case USB_HidReq_GetProtocol:
|
|
|
|
|
// case USB_HidReq_SetProtocol:
|
2022-02-09 05:39:39 +01:00
|
|
|
|
default:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Stalled;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
default:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Stalled;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 07:59:29 +01:00
|
|
|
|
switch (usb_ep0_stage.bStage)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
case USB_CtrlState_DataIn:
|
|
|
|
|
USB_WriteReg(CSR0, SOPRDY);
|
|
|
|
|
goto L_Ep0SendData;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_CtrlState_DataOut:
|
|
|
|
|
USB_WriteReg(CSR0, SOPRDY);
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_CtrlState_SettingUp:
|
|
|
|
|
USB_WriteReg(CSR0, SOPRDY | DATEND);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_CtrlState_Stalled:
|
|
|
|
|
USB_WriteReg(CSR0, SOPRDY | SDSTL);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case USB_CtrlState_DataIn:
|
|
|
|
|
if (!(csr & IPRDY))
|
|
|
|
|
{
|
|
|
|
|
L_Ep0SendData:
|
2022-02-09 07:59:29 +01:00
|
|
|
|
cnt = usb_ep0_stage.wResidue > 64 ? 64 : usb_ep0_stage.wResidue;
|
|
|
|
|
USB_WriteFIFO(FIFO0, usb_ep0_stage.pData, cnt);
|
|
|
|
|
usb_ep0_stage.wResidue -= cnt;
|
|
|
|
|
usb_ep0_stage.pData += cnt;
|
|
|
|
|
if (usb_ep0_stage.wResidue == 0)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(CSR0, IPRDY | DATEND);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(CSR0, IPRDY);
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
case USB_CtrlState_DataOut:
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (csr & OPRDY)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
cnt = USB_ReadFIFO(FIFO0, usb_ep0_stage.pData);
|
|
|
|
|
usb_ep0_stage.wResidue -= cnt;
|
|
|
|
|
usb_ep0_stage.pData += cnt;
|
|
|
|
|
if (usb_ep0_stage.wResidue == 0)
|
2022-02-09 07:49:48 +01:00
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(CSR0, SOPRDY | DATEND);
|
2022-02-09 07:59:29 +01:00
|
|
|
|
usb_ep0_stage.bStage = USB_CtrlState_Idle;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(CSR0, SOPRDY);
|
|
|
|
|
}
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
break;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (intrin & EP1INIF)
|
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_SelectEndPoint(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
csr = USB_ReadReg(INCSR1);
|
|
|
|
|
if (csr & INSTSTL)
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(INCSR1, INCLRDT);
|
|
|
|
|
}
|
|
|
|
|
if (csr & INUNDRUN)
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(INCSR1, 0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (introut & EP1OUTIF)
|
|
|
|
|
{
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_SelectEndPoint(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
csr = USB_ReadReg(OUTCSR1);
|
|
|
|
|
if (csr & OUTSTSTL)
|
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(OUTCSR1, OUTCLRDT);
|
|
|
|
|
}
|
|
|
|
|
if (csr & OUTOPRDY)
|
|
|
|
|
{
|
|
|
|
|
USB_ReadFIFO(FIFO1, HidOutput);
|
|
|
|
|
USB_WriteReg(OUTCSR1, 0);
|
|
|
|
|
|
|
|
|
|
P6 = ~HidOutput[0]; // update LED status
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint8_t KeyCount(uint16_t dat)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i;
|
|
|
|
|
|
|
|
|
|
i = 0;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
while (dat)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (dat & 0x8000) i++;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
dat <<= 1;
|
|
|
|
|
}
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//HidInput first byte for special keys,second byte is reserved,the reset 6 bytes for normal keys
|
|
|
|
|
void SendKeyStatus(void)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i,n;
|
|
|
|
|
|
|
|
|
|
if(KeyCode) // if key pressed
|
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
// allow 3 keys pressed simultaneously
|
2022-02-09 05:39:39 +01:00
|
|
|
|
if(KeyCount(KeyCode) > 3)
|
|
|
|
|
{
|
|
|
|
|
return; // too many keys
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
n = 2;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
for (i = 0; i < 16; i++)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (i == 1)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (KeyCode & (1 << i)) // left Ctrl
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
HidInput[0] |= 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
HidInput[0] &= ~1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
else if (i == 2)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (KeyCode & (1 << i)) // left alt
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
HidInput[0] |= 1 << 2;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
HidInput[0] &= ~(1 << 2);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (KeyCode & (1 << i))
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
HidInput[n++] = KeyMap[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
for(; n<8; n++)
|
|
|
|
|
{
|
|
|
|
|
HidInput[n]=0; // fill 0 to the rest
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else // if no key pressed, return 0
|
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
for (i = 0; i < 8; i++)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
2022-02-09 07:49:48 +01:00
|
|
|
|
HidInput[i] = 0;
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// return 8 bytes data
|
2022-02-09 07:59:29 +01:00
|
|
|
|
USB_SelectEndPoint(1);
|
2022-02-09 07:49:48 +01:00
|
|
|
|
for (i = 0; i < 8; i++)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
USB_WriteReg(FIFO1, HidInput[i]);
|
|
|
|
|
}
|
|
|
|
|
USB_WriteReg(INCSR1, INIPRDY);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
INTERRUPT(Timer0_Routine, EXTI_VectTimer0)
|
|
|
|
|
{
|
|
|
|
|
B_1ms = 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*****************************************************
|
|
|
|
|
Key Matrix Scan
|
|
|
|
|
|
|
|
|
|
Y P04 P05 P06 P07
|
|
|
|
|
| | | |
|
|
|
|
|
X | | | |
|
|
|
|
|
P00 ---- K00 ---- K01 ---- K02 ---- K03 ----
|
|
|
|
|
| | | |
|
|
|
|
|
P01 ---- K04 ---- K05 ---- K06 ---- K07 ----
|
|
|
|
|
| | | |
|
|
|
|
|
P02 ---- K08 ---- K09 ---- K10 ---- K11 ----
|
|
|
|
|
| | | |
|
|
|
|
|
P03 ---- K12 ---- K13 ---- K14 ---- K15 ----
|
|
|
|
|
| | | |
|
|
|
|
|
******************************************************/
|
|
|
|
|
|
|
|
|
|
void KeyScan(void)
|
|
|
|
|
{
|
|
|
|
|
uint8_t temp;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
KeyIO = 0x0F;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
SYS_DelayUs(1);
|
|
|
|
|
if ((KeyIO & 0x0F) == 0x0F) // no key pressed
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
NewKeyCode = 0;
|
|
|
|
|
}
|
2022-02-09 07:49:48 +01:00
|
|
|
|
else // start scan
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
// scan first line
|
2022-02-09 07:10:27 +01:00
|
|
|
|
KeyIO = (uint8_t)~0x10;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
SYS_DelayUs(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
// save 4 keys status
|
|
|
|
|
temp = KeyIO & 0x0F;
|
|
|
|
|
|
|
|
|
|
// second line
|
2022-02-09 07:10:27 +01:00
|
|
|
|
KeyIO = (uint8_t)~0x20;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
SYS_DelayUs(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
temp |= KeyIO << 4;
|
|
|
|
|
|
|
|
|
|
// save current key status
|
|
|
|
|
NewKeyCode = (~temp) & 0xFF;
|
|
|
|
|
|
2022-02-09 07:49:48 +01:00
|
|
|
|
// third line
|
2022-02-09 07:10:27 +01:00
|
|
|
|
KeyIO = (uint8_t)~0x40;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
SYS_DelayUs(1);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
temp = KeyIO & 0x0F;
|
|
|
|
|
|
2022-02-09 07:49:48 +01:00
|
|
|
|
// 4th line
|
2022-02-09 07:10:27 +01:00
|
|
|
|
KeyIO = (uint8_t)~0x80;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
SYS_DelayUs(1);
|
|
|
|
|
temp |= KeyIO << 4;
|
|
|
|
|
|
2022-02-09 05:39:39 +01:00
|
|
|
|
// save all 16 keys' status in 2 bytes, 1 indicates key pressed
|
2022-02-09 07:49:48 +01:00
|
|
|
|
NewKeyCode |= (((uint16_t)~temp) << 8);
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (NewKeyCode != OldKeyCode)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
KeyHoldTime = 0;
|
|
|
|
|
OldKeyCode = NewKeyCode;
|
|
|
|
|
KeyChangeTemp = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
KeyHoldTime++;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (KeyHoldTime >= 1)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
KeyHoldTime = 1;
|
|
|
|
|
KeyCode = OldKeyCode;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
if (KeyChangeTemp)
|
2022-02-09 05:39:39 +01:00
|
|
|
|
{
|
|
|
|
|
KeyChangeTemp = 0;
|
2022-02-09 07:49:48 +01:00
|
|
|
|
KeyChangeFlag = 1; // Set send flag
|
2022-02-09 05:39:39 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t DEVICEDESC[18] =
|
|
|
|
|
{
|
|
|
|
|
0x12, //bLength(18);
|
|
|
|
|
0x01, //bDescriptorType(Device);
|
|
|
|
|
0x00,0x02, //bcdUSB(2.00);
|
|
|
|
|
0x00, //bDeviceClass(0);
|
|
|
|
|
0x00, //bDeviceSubClass0);
|
|
|
|
|
0x00, //bDeviceProtocol(0);
|
|
|
|
|
0x40, //bMaxPacketSize0(64);
|
|
|
|
|
0x54,0x53, //idVendor(5354);
|
|
|
|
|
0x80,0x44, //idProduct(4480);
|
|
|
|
|
0x00,0x01, //bcdDevice(1.00);
|
|
|
|
|
0x01, //iManufacturer(1);
|
|
|
|
|
0x02, //iProduct(2);
|
|
|
|
|
0x03, //iSerialNumber(3);
|
|
|
|
|
0x01, //bNumConfigurations(1);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t CONFIGDESC[41] =
|
|
|
|
|
{
|
|
|
|
|
0x09, //bLength(9);
|
|
|
|
|
0x02, //bDescriptorType(Configuration);
|
|
|
|
|
0x29,0x00, //wTotalLength(41);
|
|
|
|
|
0x01, //bNumInterfaces(1);
|
|
|
|
|
0x01, //bConfigurationValue(1);
|
|
|
|
|
0x00, //iConfiguration(0);
|
|
|
|
|
0xa0, //bmAttributes(BUSPower);
|
|
|
|
|
0xc8, //MaxPower(400mA);
|
|
|
|
|
|
|
|
|
|
0x09, //bLength(9);
|
|
|
|
|
0x04, //bDescriptorType(Interface);
|
|
|
|
|
0x00, //bInterfaceNumber(0);
|
|
|
|
|
0x00, //bAlternateSetting(0);
|
|
|
|
|
0x02, //bNumEndpoints(2);
|
|
|
|
|
0x03, //bInterfaceClass(HID);
|
|
|
|
|
0x01, //bInterfaceSubClass(1);
|
|
|
|
|
0x01, //bInterfaceProtocol(1);
|
|
|
|
|
0x00, //iInterface(0);
|
|
|
|
|
|
|
|
|
|
0x09, //bLength(9);
|
|
|
|
|
0x21, //bDescriptorType(HID);
|
|
|
|
|
0x01,0x10, //bcdHID(1.01);
|
|
|
|
|
0x00, //bCountryCode(0);
|
|
|
|
|
0x01, //bNumDescriptors(1);
|
|
|
|
|
0x22, //bDescriptorType(HID Report);
|
|
|
|
|
0x3f,0x00, //wDescriptorLength(63);
|
|
|
|
|
0x07, //bLength(7);
|
|
|
|
|
0x05, //bDescriptorType(Endpoint);
|
|
|
|
|
0x81, //bEndpointAddress(EndPoint1 as IN);
|
|
|
|
|
0x03, //bmAttributes(Interrupt);
|
|
|
|
|
0x40,0x00, //wMaxPacketSize(64);
|
|
|
|
|
0x0a, //bInterval(10ms);
|
|
|
|
|
0x07, //bLength(7);
|
|
|
|
|
0x05, //bDescriptorType(Endpoint);
|
|
|
|
|
0x01, //bEndpointAddress(EndPoint1 as OUT);
|
|
|
|
|
0x03, //bmAttributes(Interrupt);
|
|
|
|
|
0x40,0x00, //wMaxPacketSize(64);
|
|
|
|
|
0x0a, //bInterval(10ms);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t HIDREPORTDESC[63] =
|
|
|
|
|
{
|
|
|
|
|
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
|
|
|
|
|
0x09, 0x06, // USAGE (Keyboard)
|
|
|
|
|
0xa1, 0x01, // COLLECTION (Application)
|
|
|
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
|
|
|
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
|
|
|
|
|
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
|
|
|
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
|
|
|
0x25, 0x01, // LOGICAL_MAXIMUM (1)
|
|
|
|
|
0x75, 0x01, // REPORT_SIZE (1)
|
|
|
|
|
0x95, 0x08, // REPORT_COUNT (8)
|
|
|
|
|
0x81, 0x02, // INPUT (Data,Var,Abs)
|
|
|
|
|
0x95, 0x01, // REPORT_COUNT (1)
|
|
|
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
|
|
|
0x81, 0x03, // INPUT (Cnst,Var,Abs)
|
|
|
|
|
0x95, 0x05, // REPORT_COUNT (5)
|
|
|
|
|
0x75, 0x01, // REPORT_SIZE (1)
|
|
|
|
|
0x05, 0x08, // USAGE_PAGE (LEDs)
|
|
|
|
|
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
|
|
|
|
|
0x29, 0x05, // USAGE_MAXIMUM (Kana)
|
|
|
|
|
0x91, 0x02, // OUTPUT (Data,Var,Abs)
|
|
|
|
|
0x95, 0x01, // REPORT_COUNT (1)
|
|
|
|
|
0x75, 0x03, // REPORT_SIZE (3)
|
|
|
|
|
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
|
|
|
|
|
0x95, 0x06, // REPORT_COUNT (6)
|
|
|
|
|
0x75, 0x08, // REPORT_SIZE (8)
|
|
|
|
|
0x15, 0x00, // LOGICAL_MINIMUM (0)
|
|
|
|
|
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
|
|
|
|
|
0x05, 0x07, // USAGE_PAGE (Keyboard)
|
|
|
|
|
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
|
|
|
|
|
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
|
|
|
|
|
0x81, 0x00, // INPUT (Data,Ary,Abs)
|
|
|
|
|
0xc0 // END_COLLECTION
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t LANGIDDESC[4] =
|
|
|
|
|
{
|
|
|
|
|
0x04,0x03,
|
|
|
|
|
0x09,0x04,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t MANUFACTDESC[8] =
|
|
|
|
|
{
|
|
|
|
|
0x08,0x03,
|
|
|
|
|
'S',0,
|
|
|
|
|
'T',0,
|
|
|
|
|
'C',0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t PRODUCTDESC[30] =
|
|
|
|
|
{
|
|
|
|
|
0x1e,0x03,
|
|
|
|
|
'S',0,
|
|
|
|
|
'T',0,
|
|
|
|
|
'C',0,
|
|
|
|
|
' ',0,
|
|
|
|
|
'U',0,
|
|
|
|
|
'S',0,
|
|
|
|
|
'B',0,
|
|
|
|
|
' ',0,
|
|
|
|
|
'D',0,
|
|
|
|
|
'e',0,
|
|
|
|
|
'v',0,
|
|
|
|
|
'i',0,
|
|
|
|
|
'c',0,
|
|
|
|
|
'e',0,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
__CODE uint8_t KeyMap[16] = {
|
|
|
|
|
0x53, //0: Num Lock
|
|
|
|
|
0xFF, //1: NULL - Left Ctrl
|
|
|
|
|
0xFF, //2: NULL - Left ALT
|
|
|
|
|
0x2A, //3: BackSpace
|
|
|
|
|
|
|
|
|
|
0x5F, //4: 7
|
|
|
|
|
0x60, //5: 8
|
|
|
|
|
0x61, //6: 9
|
|
|
|
|
0x62, //7: 0
|
|
|
|
|
|
|
|
|
|
0x5C, //8: 4
|
|
|
|
|
0x5D, //9: 5
|
|
|
|
|
0x5E, //A: 6
|
|
|
|
|
0x63, //B: DEL
|
|
|
|
|
|
|
|
|
|
0x59, //C: 1
|
|
|
|
|
0x5A, //D: 2
|
|
|
|
|
0x5B, //E: 3
|
|
|
|
|
0x58, //F: Return
|
|
|
|
|
};
|