Гудвин, волшебник (24.04.2012 19:59, просмотров: 172) ответил Гудвин на В общем так: Надоело биться с ветряными мельницами. "Прямой" драйвер HID в RL ARM. Там все пучком - есть правильная функция "usbd_hid_get_report_trigger(0, buf, len)". И прерывание постоянно не щелкает - только когда передаются данные. Цена
Жаба заставила-таки добить гада ;) Душа радОВАеЦЦа: "Program Size: Code=904 RO-data=424 RW-data=16 ZI-data=536". Все пучком - прерывание не дергается, данные шлются только по приказу "партии и правительства"... Вот чо добавил (код ~150 байт):
/****************************************************************************
* $Id:: demo.c 7214 2011-04-27 00:50:19Z usb00423 $
* Project: NXP LPC13xx USB HID ROM version example
*
* Description:
* This file contains USB HID test modules, main entry, to test ROM based
* USB HID APIs.
*
****************************************************************************
* Software that is described herein is for illustrative purposes only
* which provides customers with programming information regarding the
* products. This software is supplied "AS IS" without any warranties.
* NXP Semiconductors assumes no responsibility or liability for the
* use of the software, conveys no license or title under any patent,
* copyright, or mask work right to the product. NXP Semiconductors
* reserves the right to make changes in the software without
* notification. NXP Semiconductors also make no representation or
* warranty that such application will be suitable for the specified
* use without further testing or modification.
****************************************************************************/
#include "lpc13xx.h" /* LPC13xx definitions */
#include "type.h"
#include "usb.h"
#include "usbdesc.h"
//#include "gpio.h"
//#include "timer16.h"
#include "demo.h"
#include "rom_drivers.h"
extern volatile uint32_t timer16_0_counter;
uint8_t InReport; /* HID Input Report */
/* Bit0 : Buttons */
/* Bit1..7: Reserved */
uint8_t OutReport; /* HID Out Report */
#define LED_PORT 2
#define LED_BIT 0 /* Bit0..7: LEDs */
#define USB_VENDOR_ID 0x1FC9
#define USB_PROD_ID 0x0003
#define USB_DEVICE 0x0100
USB_DEV_INFO DeviceInfo;
HID_DEVICE_INFO HidDevInfo;
ROM ** rom = (ROM **)0x1fff1ff8;
#define EN_TIMER32_1 (1<<10)
#define EN_IOCON (1<<16)
#define EN_USBREG (1<<14)
#define CCEMTY_INT (0x1<<10)
#define CMD_SEL_EP(x) (0x00000500 | ((x) << 16))
#define CTRL_WR_EN 0x00000002
#define CMD_VALID_BUF 0x00FA0500
#define CMD_SEL_EP_CLRI(x) (0x00400500 | ((x) << 16))
/*
* Get Endpoint Physical Address
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* Return Value: Endpoint Physical Address
*/
uint32_t EPAdr (uint32_t EPNum) {
uint32_t val;
val = (EPNum & 0x0F) << 1;
if (EPNum & 0x80) {
val += 1;
}
return (val);
}
/*
* Write Command to Endpoint
* Parameters: cmd: Command
* val: Data
* Return Value: None
*/
void WrCmdEP (uint32_t EPNum, uint32_t cmd) {
LPC_USB->DevIntClr = CCEMTY_INT;
LPC_USB->CmdCode = CMD_SEL_EP(EPAdr(EPNum));
while ((LPC_USB->DevIntSt & CCEMTY_INT) == 0);
LPC_USB->DevIntClr = CCEMTY_INT;
LPC_USB->CmdCode = cmd;
while ((LPC_USB->DevIntSt & CCEMTY_INT) == 0);
}
/*
* Write Command
* Parameters: cmd: Command
* Return Value: None
*/
void WrCmd (uint32_t cmd) {
LPC_USB->DevIntClr = CCEMTY_INT;
LPC_USB->CmdCode = cmd;
while ((LPC_USB->DevIntSt & CCEMTY_INT) == 0);
}
/*
* Write USB Device Endpoint Data
* Parameters: EPNum: Endpoint Number
* EPNum.0..3: Address
* EPNum.7: Dir
* pData: Pointer to Data Buffer
* cnt: Number of bytes to write
* Return Value: Number of bytes written
*/
// эта байда сейчас и служит для отсылки данных
uint32_t USBD_WriteEP (uint32_t EPNum, uint8_t *pData, uint32_t cnt) {
uint32_t n;
LPC_USB->Ctrl = ((EPNum & 0x0F) << 2) | CTRL_WR_EN;
for (n = 0; n < 3; n++) __nop(); /* 3 clock cycles to fetch
the packet length from RAM. */
LPC_USB->TxPLen = cnt;
for (n = 0; n < (cnt + 3) / 4; n++) {
LPC_USB->TxData = *((__packed uint32_t *)pData);
pData += 4;
}
LPC_USB->Ctrl = 0;
WrCmdEP(EPNum, CMD_VALID_BUF);
return (cnt);
}
USB_IRQHandler(void)
{
#define INT_IN_EP 0x10 // это бит прерывания Input Report
uint32_t disr;
disr = LPC_USB->DevIntSt;
/* Device Interrupt Status */
if (disr & INT_IN_EP) // пришлепнем гада в зародыше
{
LPC_USB->DevIntClr = disr & INT_IN_EP; // сбросим прерывание
WrCmd(CMD_SEL_EP_CLRI(INT_IN_EP>>1));
}
else (*rom)->pUSBD->isr();
}
/*
* Get HID Input Report -> InReport
*/
// эта байда больше никогда не вызывается
void GetInReport (uint8_t src[], uint32_t length) {
return;
}
/*
* Set HID Output Report <- OutReport
*/
void SetOutReport (uint8_t dst[], uint32_t length) {
USBD_WriteEP (0x81, dst, length); // пришем прямо в EP (в данном случае возвращаем обратно, что приняли)
return;
}
/* Main Program */
int main (void)
{
uint32_t n;
//SCB->VTOR = 0x00; vector table
HidDevInfo.idVendor = USB_VENDOR_ID;
HidDevInfo.idProduct = USB_PROD_ID;
HidDevInfo.bcdDevice = USB_DEVICE;
HidDevInfo.StrDescPtr = (uint32_t)&USB_StringDescriptor[0];
HidDevInfo.InReportCount = 64;
HidDevInfo.OutReportCount = 64;
HidDevInfo.SampleInterval = 0x1;
HidDevInfo.InReport = GetInReport;
HidDevInfo.OutReport = SetOutReport;
DeviceInfo.DevType = USB_DEVICE_CLASS_HUMAN_INTERFACE;
DeviceInfo.DevDetailPtr = (uint32_t)&HidDevInfo;
/* Enable Timer32_1, IOCON, and USB blocks (for USB ROM driver) */
LPC_SYSCON->SYSAHBCLKCTRL |= (EN_TIMER32_1 | EN_IOCON | EN_USBREG);
(*rom)->pUSBD->init_clk_pins(); /* Use pll and pin init function in rom */
/* insert a delay between clk init and usb init */
for (n = 0; n < 75; n++) {
}
(*rom)->pUSBD->init(&DeviceInfo); /* USB Initialization */
(*rom)->pUSBD->connect(TRUE); /* USB Connect */
while (1) /* Loop forever */
{
}
}