FIX: at91sam7s256 has some limits on endpoints maxpacket sizes. Took me sometime to find it.

This commit is contained in:
iceman1001 2017-10-11 10:15:41 +02:00
parent f788ef51d1
commit c9f37223ce

View file

@ -34,14 +34,24 @@
#include "usb_cdc.h" #include "usb_cdc.h"
/*
AT91SAM7S256 USB Device Port
Embedded 328-byte dual-port RAM for endpoints
Four endpoints
Endpoint 0: 8 bytes
Endpoint 1 and 2: 64 bytes ping-pong
Endpoint 3: 64 bytes
Ping-pong Mode (two memory banks) for bulk endpoints
*/
#define AT91C_EP_CONTROL 0 #define AT91C_EP_CONTROL 0
#define AT91C_EP_CONTROL_SIZE 0x40 #define AT91C_EP_CONTROL_SIZE 0x08
#define AT91C_EP_IN 2 #define AT91C_EP_IN 2
#define AT91C_EP_IN_SIZE 0x200 #define AT91C_EP_IN_SIZE 0x40
#define AT91C_EP_OUT 1 #define AT91C_EP_OUT 1
#define AT91C_EP_OUT_SIZE 0x200 #define AT91C_EP_OUT_SIZE 0x40
// Section: USB Descriptors // Section: USB Descriptors
#define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor. #define USB_DESCRIPTOR_DEVICE 0x01 // bDescriptorType for a Device Descriptor.
@ -83,8 +93,8 @@
#define MS_VENDOR_CODE 0x1C #define MS_VENDOR_CODE 0x1C
#define MS_EXTENDED_COMPAT_ID 0x04 #define MS_EXTENDED_COMPAT_ID 0x04
#define MS_EXTENDED_PROPERTIES 0x05 #define MS_EXTENDED_PROPERTIES 0x05
#define MS_WCID_GET_DESCRIPTOR ((MS_VENDOR_CODE << 8) | 0xC0) #define MS_WCID_GET_DESCRIPTOR 0xC0
#define MS_WCID_GET_FEATURE_DESCRIPTOR ((MS_VENDOR_CODE << 8 )| 0xC1) #define MS_WCID_GET_FEATURE_DESCRIPTOR 0xC1
static const char devDescriptor[] = { static const char devDescriptor[] = {
/* Device descriptor */ /* Device descriptor */
@ -94,7 +104,7 @@ static const char devDescriptor[] = {
0x02, // Device Class: CDC class code 0x02, // Device Class: CDC class code
0x02, // Device Subclass: CDC class sub code ACM [ice 0x02 = win10 virtual comport :) ] 0x02, // Device Subclass: CDC class sub code ACM [ice 0x02 = win10 virtual comport :) ]
0x00, // Device Protocol: CDC Device protocol 0x00, // Device Protocol: CDC Device protocol
0x40, // MaxPacket Size0 (ice 0x40, rflder 0x40, pm3, 0x08 AT91C_EP_CONTROL_SIZE, // MaxPacketSize0
0xc4,0x9a, // Vendor ID [0x9ac4 = J. Westhues] 0xc4,0x9a, // Vendor ID [0x9ac4 = J. Westhues]
0x8f,0x4b, // Product ID [0x4b8f = Proxmark-3 RFID Instrument] 0x8f,0x4b, // Product ID [0x4b8f = Proxmark-3 RFID Instrument]
0x01,0x00, // Device release number (0001) 0x01,0x00, // Device release number (0001)
@ -113,7 +123,7 @@ static const char cfgDescriptor[] = {
0x02, // Number of Interfaces 0x02, // Number of Interfaces
0x01, // Index value of this Configuration 0x01, // Index value of this Configuration
0x00, // Configuration string index 0x00, // Configuration string index
_DEFAULT | _SELF, // Attributes 0xA0 _DEFAULT, // Attributes 0xA0
0xFA, // Max Power consumption 0xFA, // Max Power consumption
/* Communication Class Interface Descriptor Requirement */ /* Communication Class Interface Descriptor Requirement */
@ -137,7 +147,7 @@ static const char cfgDescriptor[] = {
0x04, // Function Length 0x04, // Function Length
0x24, // Descriptor Type: CS_INTERFACE 0x24, // Descriptor Type: CS_INTERFACE
0x02, // Descriptor Subtype: ACM Func Desc 0x02, // Descriptor Subtype: ACM Func Desc
0x0F, // Capabilities (rfidler 0x04, pm3 0x02, zero should also work ) 0x02, // Capabilities (rfidler 0x04, pm3 0x02, zero should also work )
/* Union Functional Descriptor */ /* Union Functional Descriptor */
0x05, // Function Length 0x05, // Function Length
@ -150,7 +160,7 @@ static const char cfgDescriptor[] = {
0x05, // Function Length 0x05, // Function Length
0x24, // Descriptor Type: CS_INTERFACE 0x24, // Descriptor Type: CS_INTERFACE
0x01, // Descriptor Subtype: Call Management Func Desc 0x01, // Descriptor Subtype: Call Management Func Desc
0x03, // Capabilities: D1 + D0 (ice 0x03, pm3 0x00, rfidler 0x00) 0x00, // Capabilities: D1 + D0 (ice 0x03, pm3 0x00, rfidler 0x00)
0x01, // Data Interface: Data Class Interface 1 0x01, // Data Interface: Data Class Interface 1
/* Endpoint descriptor */ /* Endpoint descriptor */
@ -158,8 +168,8 @@ static const char cfgDescriptor[] = {
USB_DESCRIPTOR_ENDPOINT, // Descriptor Type USB_DESCRIPTOR_ENDPOINT, // Descriptor Type
_EP03_IN, // EndpointAddress, Endpoint 03-IN _EP03_IN, // EndpointAddress, Endpoint 03-IN
_INTERRUPT, // Attributes _INTERRUPT, // Attributes
0x00, 0x02, // MaxPacket Size (ice 0x200, pm3 0x08) 0x40, 0x00, // MaxPacket Size (ice 0x200, pm3 0x08)
0xff, // Interval polling (rfidler 0x02, pm3 0xff) 0x02, // Interval polling (rfidler 0x02, pm3 0xff)
/* Data Class Interface Descriptor Requirement */ /* Data Class Interface Descriptor Requirement */
0x09, // Length 0x09, // Length
@ -177,7 +187,7 @@ static const char cfgDescriptor[] = {
USB_DESCRIPTOR_ENDPOINT, // Descriptor Type USB_DESCRIPTOR_ENDPOINT, // Descriptor Type
_EP01_OUT, // Endpoint Address, Endpoint 01-OUT _EP01_OUT, // Endpoint Address, Endpoint 01-OUT
_BULK, // Attributes BULK _BULK, // Attributes BULK
0x00, 0x02, // MaxPacket Size 0x40, 0x00, // MaxPacket Size
0x00, // Interval 0x00, // Interval
/* Endpoint descriptor */ /* Endpoint descriptor */
@ -185,7 +195,7 @@ static const char cfgDescriptor[] = {
USB_DESCRIPTOR_ENDPOINT, // DescriptorType USB_DESCRIPTOR_ENDPOINT, // DescriptorType
_EP02_IN, // Endpoint Address, Endpoint 02-IN _EP02_IN, // Endpoint Address, Endpoint 02-IN
_BULK, // Attributes BULK _BULK, // Attributes BULK
0x00, 0x02, // MaxPacket Size 0x40, 0x00, // MaxPacket Size
0x00 // Interval 0x00 // Interval
}; };
@ -417,8 +427,8 @@ AT91S_CDC_LINE_CODING line = {
8}; // 8 Data bits 8}; // 8 Data bits
AT91PS_UDP pUdp = AT91C_BASE_UDP; AT91PS_UDP pUdp = AT91C_BASE_UDP;
byte_t btConfiguration = 0; uint16_t btConfiguration = 0;
byte_t btConnection = 0; uint16_t btConnection = 0;
byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
@ -528,6 +538,8 @@ bool usb_check() {
} }
*/ */
WDT_HIT();
// interrupt status register // interrupt status register
AT91_REG isr = pUdp->UDP_ISR; AT91_REG isr = pUdp->UDP_ISR;
@ -539,9 +551,8 @@ bool usb_check() {
pUdp->UDP_RSTEP = 0; pUdp->UDP_RSTEP = 0;
// Enable the function // Enable the function
pUdp->UDP_FADDR = AT91C_UDP_FEN; pUdp->UDP_FADDR = AT91C_UDP_FEN;
// Configure endpoint 0 // Configure endpoint 0 (enable control endpoint)
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL)); UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL));
//pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
// clear it // clear it
pUdp->UDP_ICR |= AT91C_UDP_ENDBUSRES; pUdp->UDP_ICR |= AT91C_UDP_ENDBUSRES;
} }
@ -655,10 +666,9 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
uint32_t cpt = 0; uint32_t cpt = 0;
AT91_REG csr;
do { do {
cpt = MIN(length, 0x40); cpt = MIN(length, 8);
length -= cpt; length -= cpt;
while (cpt--) while (cpt--)
@ -672,16 +682,13 @@ void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY) UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY)
do { do {
csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];
// Data IN stage has been stopped by a status OUT // Data IN stage has been stopped by a status OUT
if (csr & AT91C_UDP_RX_DATA_BK0) { if ( pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) {
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0) UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0)
return; return;
} }
} while ( !(csr & AT91C_UDP_TXCOMP) ); } while ( !( pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) );
} while (length); } while (length);
@ -706,6 +713,7 @@ void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
void AT91F_USB_SendStall(AT91PS_UDP pUdp) { void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL); UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);
while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR) );
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR));
} }
@ -734,26 +742,26 @@ void AT91F_CDC_Enumerate() {
} }
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP) UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP)
// if ( bRequest == MS_VENDOR_CODE) { if ( bRequest == MS_VENDOR_CODE) {
// if ( bmRequestType == MS_WCID_GET_DESCRIPTOR ) { // C0 if ( bmRequestType == MS_WCID_GET_DESCRIPTOR ) { // C0
// if ( wIndex == MS_EXTENDED_COMPAT_ID ) { // 4 if ( wIndex == MS_EXTENDED_COMPAT_ID ) { // 4
// AT91F_USB_SendData(pUdp, CompatIDFeatureDescriptor, MIN(sizeof(CompatIDFeatureDescriptor), wLength)); AT91F_USB_SendData(pUdp, CompatIDFeatureDescriptor, MIN(sizeof(CompatIDFeatureDescriptor), wLength));
// } else { } else {
// AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
// } }
// return; return;
// } }
// if ( bmRequestType == MS_WCID_GET_FEATURE_DESCRIPTOR ) { //C1 if ( bmRequestType == MS_WCID_GET_FEATURE_DESCRIPTOR ) { //C1
// if ( wIndex == MS_EXTENDED_PROPERTIES ) { // 5 if ( wIndex == MS_EXTENDED_PROPERTIES ) { // 5
// AT91F_USB_SendData(pUdp, (char *)&OSPropertyDescriptor, MIN(sizeof(OSPropertyDescriptor), wLength)); AT91F_USB_SendData(pUdp, (char *)&OSPropertyDescriptor, MIN(sizeof(OSPropertyDescriptor), wLength));
// AT91F_USB_SendData(pUdp, OSprop, MIN(sizeof(OSprop), wLength)); AT91F_USB_SendData(pUdp, OSprop, MIN(sizeof(OSprop), wLength));
// } else { } else {
// AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
// } }
// return; return;
// } }
// } }
// Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
switch ((bRequest << 8) | bmRequestType) { switch ((bRequest << 8) | bmRequestType) {
case STD_GET_DESCRIPTOR: case STD_GET_DESCRIPTOR:
@ -782,9 +790,13 @@ void AT91F_CDC_Enumerate() {
btConfiguration = wValue; btConfiguration = wValue;
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);
pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN; pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0; UDP_SET_EP_FLAGS(1, (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0 );
pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0; UDP_SET_EP_FLAGS(2, (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0 );
UDP_SET_EP_FLAGS(3, (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0 );
// pUdp->UDP_CSR[1] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
// pUdp->UDP_CSR[2] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
// pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
break; break;
case STD_GET_CONFIGURATION: case STD_GET_CONFIGURATION:
AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration)); AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
@ -835,12 +847,18 @@ void AT91F_CDC_Enumerate() {
case STD_CLEAR_FEATURE_ENDPOINT: case STD_CLEAR_FEATURE_ENDPOINT:
wIndex &= 0x0F; wIndex &= 0x0F;
if ((wValue == 0) && wIndex && (wIndex <= 3)) { if ((wValue == 0) && wIndex && (wIndex <= 3)) {
if (wIndex == 1) if (wIndex == 1) {
pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT); //pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
else if (wIndex == 2) UDP_SET_EP_FLAGS(1, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) );
pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN); }
else if (wIndex == 3) else if (wIndex == 2) {
pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN); //pUdp->UDP_CSR[2] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
UDP_SET_EP_FLAGS(2, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) );
}
else if (wIndex == 3) {
//pUdp->UDP_CSR[3] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN);
UDP_SET_EP_FLAGS(3, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_ISO_IN) );
}
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);
} else { } else {
AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
@ -849,6 +867,7 @@ void AT91F_CDC_Enumerate() {
// handle CDC class requests // handle CDC class requests
case SET_LINE_CODING: case SET_LINE_CODING:
// ignor SET_LINE_CODING...
while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) ); while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) );
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);