физику usb я знаю, раньше успешно сделал функцию на tms5509a
но не могу понять что от меня хочет lpc2368
(среда crossworks)
почему-то весь процесс затыкается после установки адреса (SET_ADDRESS)
(1) я принял SETUP c get descriptor (DEVICE_DESCRIPTOR)
(2) отослал IN c 18 байтами дескриптора
(3) получил пустой OUT
(4) принял SETUP с set address
(5) отослал пустой IN
(6) в прерывании по успешной высылке IN устанавливаю адрес
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
и на этом все заканчивается
точнее при некоторых условиях через десяток секунд ПК опять спрашивает DEVICE_DESCRIPTOR, но процесс дальше не идет
куда копать не понимаю
событие reset не приходит
по идее у меня какая-то чехарда или недоделка в stall/unstall, но перепробовав кучу вариантов не смог найти работоспособного
посмотрите пожалуйста код
может что-то не так делаю
ниже конспективно код с комментариями
пока обрабочиков прерываний нет, только поллинг
В StartUsb инициализация :
Код
void StartUsb(void)
{
rUSBClkCtrl=(1<<1)|(1<<4);
while(1) if ((rUSBClkSt)==((1<<1)|(1<<4))) break;
rUSBReEp = 0;
rUSBReEp |= (1<<0); // realize EP0
rUSBEpInd = 0; // control OUT
rUSBMaxPSize = 64;
while(1) if (((rUSBDevIntSt)&(1<<8))==(1<<8)) break;
rUSBDevIntClr = (1<<8); // EP_RLZED
rUSBReEp |= (1<<1); // realize EP1
rUSBEpInd = 1; // control IN
rUSBMaxPSize = 64;
while(1) if (((rUSBDevIntSt)&(1<<8))==(1<<8)) break;
rUSBDevIntClr = (1<<8); // EP_RLZED
rUSBEpIntPri = 0x00000000;
rUSBDevIntEn = (1<<USBDEVINT_TxENDPKT)|
(1<<USBDEVINT_RxENDPKT)|
(1<<USBDEVINT_DEV_STAT)|
(1<<USBDEVINT_EP_SLOW)|
(1<<USBDEVINT_ERR_INT);
rUSBDevIntClr = 0xFFFFFFFF;
rUSBEpIntEn = (1<<0)|(1<<1);
rUSBEpIntClr = 0xFFFFFFFF;
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,0+0x80);
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,0+0x80);
w0 = UsbReadCommandWord(USB_SIE_COMMAND_ReadTestRegister);
if (w0 != 0xa50f) while(1);
}
{
rUSBClkCtrl=(1<<1)|(1<<4);
while(1) if ((rUSBClkSt)==((1<<1)|(1<<4))) break;
rUSBReEp = 0;
rUSBReEp |= (1<<0); // realize EP0
rUSBEpInd = 0; // control OUT
rUSBMaxPSize = 64;
while(1) if (((rUSBDevIntSt)&(1<<8))==(1<<8)) break;
rUSBDevIntClr = (1<<8); // EP_RLZED
rUSBReEp |= (1<<1); // realize EP1
rUSBEpInd = 1; // control IN
rUSBMaxPSize = 64;
while(1) if (((rUSBDevIntSt)&(1<<8))==(1<<8)) break;
rUSBDevIntClr = (1<<8); // EP_RLZED
rUSBEpIntPri = 0x00000000;
rUSBDevIntEn = (1<<USBDEVINT_TxENDPKT)|
(1<<USBDEVINT_RxENDPKT)|
(1<<USBDEVINT_DEV_STAT)|
(1<<USBDEVINT_EP_SLOW)|
(1<<USBDEVINT_ERR_INT);
rUSBDevIntClr = 0xFFFFFFFF;
rUSBEpIntEn = (1<<0)|(1<<1);
rUSBEpIntClr = 0xFFFFFFFF;
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,0+0x80);
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,0+0x80);
w0 = UsbReadCommandWord(USB_SIE_COMMAND_ReadTestRegister);
if (w0 != 0xa50f) while(1);
}
В основном теле опрашиваются события, ошибки, прерывания от точек:
Код
// check error interrupt
if ( (UsbDevIntStatus&(1<<USBDEVINT_ERR_INT)) != 0 )
{
UsbErrorCode = UsbReadCommandByte( USB_SIE_COMMAND_GetErrorCode );
UsbErrorStatus = UsbReadCommandByte( USB_SIE_COMMAND_ReadErrorStatus );
UsbErrorCounter++;
rUSBDevIntClr = (1<<USBDEVINT_ERR_INT); // ERR_INT
}
// check status change event
if ( (UsbDevIntStatus&(1<<USBDEVINT_DEV_STAT)) != 0 )
{
UsbDeviceStatus = UsbReadCommandByte( USB_SIE_COMMAND_GetDeviceStatus );
if ((UsbDeviceStatus&(1<<3))!=0)
if ((UsbDeviceStatus&(1<<2))!=0) {/**/};
if ((UsbDeviceStatus&(1<<4))!=0) { /**/};
rUSBDevIntClr = (1<<USBDEVINT_DEV_STAT);
}
// endpoint interrupt
if ( (UsbDevIntStatus&(1<<USBDEVINT_EP_SLOW)) != 0 )
{
UsbEpIntStatus = rUSBEpIntSt;
if ( (UsbEpIntStatus&(1<<0))!=0 ) UsbType1ProcessEp0Rx();
if ( (UsbEpIntStatus&(1<<1))!=0 ) UsbType1ProcessEp0Tx();
rUSBDevIntClr = (1<<USBDEVINT_EP_SLOW);
}
if ( (UsbDevIntStatus&(1<<USBDEVINT_ERR_INT)) != 0 )
{
UsbErrorCode = UsbReadCommandByte( USB_SIE_COMMAND_GetErrorCode );
UsbErrorStatus = UsbReadCommandByte( USB_SIE_COMMAND_ReadErrorStatus );
UsbErrorCounter++;
rUSBDevIntClr = (1<<USBDEVINT_ERR_INT); // ERR_INT
}
// check status change event
if ( (UsbDevIntStatus&(1<<USBDEVINT_DEV_STAT)) != 0 )
{
UsbDeviceStatus = UsbReadCommandByte( USB_SIE_COMMAND_GetDeviceStatus );
if ((UsbDeviceStatus&(1<<3))!=0)
if ((UsbDeviceStatus&(1<<2))!=0) {/**/};
if ((UsbDeviceStatus&(1<<4))!=0) { /**/};
rUSBDevIntClr = (1<<USBDEVINT_DEV_STAT);
}
// endpoint interrupt
if ( (UsbDevIntStatus&(1<<USBDEVINT_EP_SLOW)) != 0 )
{
UsbEpIntStatus = rUSBEpIntSt;
if ( (UsbEpIntStatus&(1<<0))!=0 ) UsbType1ProcessEp0Rx();
if ( (UsbEpIntStatus&(1<<1))!=0 ) UsbType1ProcessEp0Tx();
rUSBDevIntClr = (1<<USBDEVINT_EP_SLOW);
}
Обработчик OUT ep0:
Код
void UsbType1ProcessEp0Rx(void)
{
UsbCounterEp0Rx++;
rUSBCtrl = (1<<0)|(0<<2); // RD_EN, LOG_ENDPOINT=0
UsbRxPacketLength = UsbReadRxPacketLength();
UsbReadPacket((WORD)UsbRxPacketLength);
rUSBDevIntClr = (1<<USBDEVINT_RxENDPKT); // RxENDPKT
rUSBCtrl = 0;
UsbClearBufferResult = UsbReadCommandByte(USB_SIE_COMMAND_ClearBuffer);
UsbSelectEndpoint0 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint0);
rUSBEpIntClr = (1<<0);
if ( (UsbSelectEndpoint0&(1<<2)) != 0 ) // setup packet
{
UsbCounterEp0Setup++;
UsbSetupMaxLength = *(WORD*)(&(UsbRxPacket[6]));
switch(*(WORD*)(&(UsbRxPacket[0])) & 0xFF80)
{
//-------------------------------------------------------------
case 0x0680: // get descriptor
switch(*(WORD*)(&(UsbRxPacket[2])) & 0xFF00)
{
//-------------------------------------------------------------
case USB_DEVICE_DESCRIPTOR_TYPE:
UsbCounterEp0Setup1++;
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbType1DeviceDescriptor,18);
rUSBCtrl = 0;
UsbWriteCommand(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
//-------------------------------------------------------------
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
rUSBCtrl = (1<<1)|(0<<2);
if (UsbSetupMaxLength>=32)
UsbSendPacket(_UsbType1ConfigurationDescriptor,32);
else
UsbSendPacket(_UsbType1ConfigurationDescriptor,UsbSetupMaxLength);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
//-------------------------------------------------------------
case USB_STRING_DESCRIPTOR_TYPE:
switch(*(WORD*)(&(UsbRxPacket[2])) & 0x00FF)
{
case 0:
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbLanguage,4);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
case 1:
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbStringManufacturer,50);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
case 2:
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbStringProduct,50);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
default:
UsbStallEp0Rx();
UsbStallEp0Tx();
break;
}
break;
//-------------------------------------------------------------
default:
UsbStallEp0Rx();
UsbStallEp0Tx();
break;
//-------------------------------------------------------------
}
break;
//-------------------------------------------------------------
case 0x0500: // set address
UsbCounterEp0Setup2++;
// UsbUnstallEp0Rx();
UsbUnstallEp0Tx();
UsbDeviceAddress = 0x7F & (*(WORD*)(&(UsbRxPacket[2])));
rUSBCtrl = (1<<1)|(0<<2);
rUSBTxPLen = 0;
rUSBCtrl = 0;
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
UsbWriteCommand(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
break;
//-------------------------------------------------------------
case 0x0900: // set configuration
UsbUnstallEp0Tx();
rUSBCtrl = (1<<1)|(0<<2);
rUSBTxPLen = 0;
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
UsbConfigured = 1;
break;
//-------------------------------------------------------------
default:
UsbStallEp0Rx();
UsbStallEp0Tx();
break;
//-------------------------------------------------------------
}
}
else // data OUT packet
{
UsbCounterEp0Data++;
}
}
{
UsbCounterEp0Rx++;
rUSBCtrl = (1<<0)|(0<<2); // RD_EN, LOG_ENDPOINT=0
UsbRxPacketLength = UsbReadRxPacketLength();
UsbReadPacket((WORD)UsbRxPacketLength);
rUSBDevIntClr = (1<<USBDEVINT_RxENDPKT); // RxENDPKT
rUSBCtrl = 0;
UsbClearBufferResult = UsbReadCommandByte(USB_SIE_COMMAND_ClearBuffer);
UsbSelectEndpoint0 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint0);
rUSBEpIntClr = (1<<0);
if ( (UsbSelectEndpoint0&(1<<2)) != 0 ) // setup packet
{
UsbCounterEp0Setup++;
UsbSetupMaxLength = *(WORD*)(&(UsbRxPacket[6]));
switch(*(WORD*)(&(UsbRxPacket[0])) & 0xFF80)
{
//-------------------------------------------------------------
case 0x0680: // get descriptor
switch(*(WORD*)(&(UsbRxPacket[2])) & 0xFF00)
{
//-------------------------------------------------------------
case USB_DEVICE_DESCRIPTOR_TYPE:
UsbCounterEp0Setup1++;
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbType1DeviceDescriptor,18);
rUSBCtrl = 0;
UsbWriteCommand(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
//-------------------------------------------------------------
case USB_CONFIGURATION_DESCRIPTOR_TYPE:
rUSBCtrl = (1<<1)|(0<<2);
if (UsbSetupMaxLength>=32)
UsbSendPacket(_UsbType1ConfigurationDescriptor,32);
else
UsbSendPacket(_UsbType1ConfigurationDescriptor,UsbSetupMaxLength);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
//-------------------------------------------------------------
case USB_STRING_DESCRIPTOR_TYPE:
switch(*(WORD*)(&(UsbRxPacket[2])) & 0x00FF)
{
case 0:
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbLanguage,4);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
case 1:
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbStringManufacturer,50);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
case 2:
rUSBCtrl = (1<<1)|(0<<2);
UsbSendPacket(_UsbStringProduct,50);
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
break;
default:
UsbStallEp0Rx();
UsbStallEp0Tx();
break;
}
break;
//-------------------------------------------------------------
default:
UsbStallEp0Rx();
UsbStallEp0Tx();
break;
//-------------------------------------------------------------
}
break;
//-------------------------------------------------------------
case 0x0500: // set address
UsbCounterEp0Setup2++;
// UsbUnstallEp0Rx();
UsbUnstallEp0Tx();
UsbDeviceAddress = 0x7F & (*(WORD*)(&(UsbRxPacket[2])));
rUSBCtrl = (1<<1)|(0<<2);
rUSBTxPLen = 0;
rUSBCtrl = 0;
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
UsbWriteCommand(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
break;
//-------------------------------------------------------------
case 0x0900: // set configuration
UsbUnstallEp0Tx();
rUSBCtrl = (1<<1)|(0<<2);
rUSBTxPLen = 0;
rUSBCtrl = 0;
UsbSelectEndpoint1 = UsbReadCommandByte(USB_SIE_COMMAND_SelectEndpoint1);
UsbWriteCommand(USB_SIE_COMMAND_ValidateBuffer);
rUSBDevIntClr = (1<<USBDEVINT_TxENDPKT);
UsbConfigured = 1;
break;
//-------------------------------------------------------------
default:
UsbStallEp0Rx();
UsbStallEp0Tx();
break;
//-------------------------------------------------------------
}
}
else // data OUT packet
{
UsbCounterEp0Data++;
}
}
Обработчик IN ep0:
Код
void UsbType1ProcessEp0Tx(void)
{
UsbCounterEp0Tx++;
rUSBEpIntClr = (1<<1);
if (UsbDeviceAddress!=0)
{
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
UsbDeviceAddress = 0;
}
if (UsbConfigured!=0)
{
while(1);
UsbConfigured=0;
UsbStatus = USB_STATUS_TYPE1_CONFIGURED;
UsbWriteCommandByte(USB_SIE_COMMAND_ConfigureDevice,1);
/*... */
}
}
{
UsbCounterEp0Tx++;
rUSBEpIntClr = (1<<1);
if (UsbDeviceAddress!=0)
{
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
UsbWriteCommandByte(USB_SIE_COMMAND_SetAddress,UsbDeviceAddress+(1<<7));
UsbDeviceAddress = 0;
}
if (UsbConfigured!=0)
{
while(1);
UsbConfigured=0;
UsbStatus = USB_STATUS_TYPE1_CONFIGURED;
UsbWriteCommandByte(USB_SIE_COMMAND_ConfigureDevice,1);
/*... */
}
}
На всякий случай вспомогательные вещи:
Код
void UsbStallEp0Rx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint0,1);}
void UsbUnstallEp0Rx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint0,0);}
void UsbStallEp0Tx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint1,1);}
void UsbUnstallEp0Tx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint1,0);}
BYTE __attribute__ ((aligned (4))) _UsbType1DeviceDescriptor[18] = {
0x12, //;BYTE bLength : 8;
0x01, //;BYTE bDescriptorType : 8;
0x00,0x02, //;WORD bcdUSB : 16;
0x00, //;BYTE bDeviceClass : 8;
0x00, //;BYTE bDeviceSubclass : 8;
0x00, //;BYTE bDeviceProtocol : 8;
64, //;BYTE bMaxPacketSize : 8;
0x34,0x12, //;WORD idVendor : 16;
0x78,0x56, //;WORD idProduct : 16;
0x00,0x00, //;WORD bcdDevice : 16;
1, //;BYTE iManufacturer : 8;
2, //;BYTE iProduct : 8;
0, //;BYTE iSerialNumber : 8;
1, //;BYTE iNumConfigurations : 8;
};
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint0,1);}
void UsbUnstallEp0Rx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint0,0);}
void UsbStallEp0Tx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint1,1);}
void UsbUnstallEp0Tx(void){
UsbWriteCommandByte(USB_SIE_COMMAND_SetEndpointStatusEndpoint1,0);}
BYTE __attribute__ ((aligned (4))) _UsbType1DeviceDescriptor[18] = {
0x12, //;BYTE bLength : 8;
0x01, //;BYTE bDescriptorType : 8;
0x00,0x02, //;WORD bcdUSB : 16;
0x00, //;BYTE bDeviceClass : 8;
0x00, //;BYTE bDeviceSubclass : 8;
0x00, //;BYTE bDeviceProtocol : 8;
64, //;BYTE bMaxPacketSize : 8;
0x34,0x12, //;WORD idVendor : 16;
0x78,0x56, //;WORD idProduct : 16;
0x00,0x00, //;WORD bcdDevice : 16;
1, //;BYTE iManufacturer : 8;
2, //;BYTE iProduct : 8;
0, //;BYTE iSerialNumber : 8;
1, //;BYTE iNumConfigurations : 8;
};