mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-09-20 15:26:13 +08:00
chg: usb_cdc, it should be similar to official pm3. lets
This commit is contained in:
parent
1f0a1edfbe
commit
3b665be5fc
|
@ -84,11 +84,11 @@ static void Fatal(void) {
|
|||
}
|
||||
|
||||
void UsbPacketReceived(uint8_t *packet, int len) {
|
||||
int i, dont_ack=0;
|
||||
int i, dont_ack = 0;
|
||||
UsbCommand* c = (UsbCommand *)packet;
|
||||
volatile uint32_t *p;
|
||||
|
||||
if ( len != sizeof(UsbCommand)) Fatal();
|
||||
//if ( len != sizeof(UsbCommand)) Fatal();
|
||||
|
||||
uint32_t arg0 = (uint32_t)c->arg[0];
|
||||
|
||||
|
|
127
common/usb_cdc.c
127
common/usb_cdc.c
|
@ -99,6 +99,38 @@ AT91SAM7S256 USB Device Port
|
|||
#define MS_WCID_GET_DESCRIPTOR 0xC0
|
||||
#define MS_WCID_GET_FEATURE_DESCRIPTOR 0xC1
|
||||
|
||||
/* USB standard request code */
|
||||
#define STD_GET_STATUS_ZERO 0x0080
|
||||
#define STD_GET_STATUS_INTERFACE 0x0081
|
||||
#define STD_GET_STATUS_ENDPOINT 0x0082
|
||||
|
||||
#define STD_CLEAR_FEATURE_ZERO 0x0100
|
||||
#define STD_CLEAR_FEATURE_INTERFACE 0x0101
|
||||
#define STD_CLEAR_FEATURE_ENDPOINT 0x0102
|
||||
|
||||
#define STD_SET_FEATURE_ZERO 0x0300
|
||||
#define STD_SET_FEATURE_INTERFACE 0x0301
|
||||
#define STD_SET_FEATURE_ENDPOINT 0x0302
|
||||
|
||||
#define STD_SET_ADDRESS 0x0500
|
||||
#define STD_GET_DESCRIPTOR 0x0680
|
||||
#define STD_SET_DESCRIPTOR 0x0700
|
||||
#define STD_GET_CONFIGURATION 0x0880
|
||||
#define STD_SET_CONFIGURATION 0x0900
|
||||
#define STD_GET_INTERFACE 0x0A81
|
||||
#define STD_SET_INTERFACE 0x0B01
|
||||
#define STD_SYNCH_FRAME 0x0C82
|
||||
|
||||
/* CDC Class Specific Request Code */
|
||||
#define GET_LINE_CODING 0x21A1
|
||||
#define SET_LINE_CODING 0x2021
|
||||
#define SET_CONTROL_LINE_STATE 0x2221
|
||||
|
||||
AT91PS_UDP pUdp = AT91C_BASE_UDP;
|
||||
uint8_t btConfiguration = 0;
|
||||
uint8_t btConnection = 0;
|
||||
uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
|
||||
|
||||
static const char devDescriptor[] = {
|
||||
/* Device descriptor */
|
||||
0x12, // Length
|
||||
|
@ -127,7 +159,7 @@ static const char cfgDescriptor[] = {
|
|||
2, // Number of Interfaces
|
||||
1, // Index value of this Configuration (used in SetConfiguration from Host)
|
||||
0, // Configuration string index
|
||||
_DEFAULT, // Attributes 0xA0
|
||||
0xC0, // Attributes 0xA0
|
||||
0xFA, // Max Power consumption
|
||||
|
||||
// IAD to associate the one CDC interface
|
||||
|
@ -370,6 +402,7 @@ const char* getStringDescriptor(uint8_t idx) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
// Bitmap for all status bits in CSR which must be written as 1 to cause no effect
|
||||
#define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \
|
||||
|AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \
|
||||
|
@ -395,33 +428,6 @@ const char* getStringDescriptor(uint8_t idx) {
|
|||
while ( ( pUdp->UDP_CSR[(endpoint)] & (flags)) != (flags)) {}; \
|
||||
} \
|
||||
|
||||
|
||||
/* USB standard request code */
|
||||
#define STD_GET_STATUS_ZERO 0x0080
|
||||
#define STD_GET_STATUS_INTERFACE 0x0081
|
||||
#define STD_GET_STATUS_ENDPOINT 0x0082
|
||||
|
||||
#define STD_CLEAR_FEATURE_ZERO 0x0100
|
||||
#define STD_CLEAR_FEATURE_INTERFACE 0x0101
|
||||
#define STD_CLEAR_FEATURE_ENDPOINT 0x0102
|
||||
|
||||
#define STD_SET_FEATURE_ZERO 0x0300
|
||||
#define STD_SET_FEATURE_INTERFACE 0x0301
|
||||
#define STD_SET_FEATURE_ENDPOINT 0x0302
|
||||
|
||||
#define STD_SET_ADDRESS 0x0500
|
||||
#define STD_GET_DESCRIPTOR 0x0680
|
||||
#define STD_SET_DESCRIPTOR 0x0700
|
||||
#define STD_GET_CONFIGURATION 0x0880
|
||||
#define STD_SET_CONFIGURATION 0x0900
|
||||
#define STD_GET_INTERFACE 0x0A81
|
||||
#define STD_SET_INTERFACE 0x0B01
|
||||
#define STD_SYNCH_FRAME 0x0C82
|
||||
|
||||
/* CDC Class Specific Request Code */
|
||||
#define GET_LINE_CODING 0x21A1
|
||||
#define SET_LINE_CODING 0x2021
|
||||
#define SET_CONTROL_LINE_STATE 0x2221
|
||||
|
||||
typedef struct {
|
||||
uint32_t BitRate;
|
||||
|
@ -436,11 +442,6 @@ AT91S_CDC_LINE_CODING line = {
|
|||
0, // None Parity
|
||||
8}; // 8 Data bits
|
||||
|
||||
AT91PS_UDP pUdp = AT91C_BASE_UDP;
|
||||
uint8_t btConfiguration = 0;
|
||||
uint8_t btConnection = 0;
|
||||
uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
|
||||
|
||||
static void SpinDelay(int ms) {
|
||||
int us = ms * 1000;
|
||||
int ticks = (48 * us) >> 10;
|
||||
|
@ -490,6 +491,9 @@ void usb_enable() {
|
|||
// Enables the 48MHz USB clock UDPCK and System Peripheral USB Clock
|
||||
AT91C_BASE_PMC->PMC_SCER = AT91C_PMC_UDP;
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_UDP);
|
||||
|
||||
AT91C_BASE_UDP->UDP_FADDR = 0;
|
||||
AT91C_BASE_UDP->UDP_GLBSTATE = 0;
|
||||
|
||||
// Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO
|
||||
// Set in PIO mode and Configure in Output
|
||||
|
@ -567,19 +571,18 @@ bool usb_check() {
|
|||
pUdp->UDP_FADDR = AT91C_UDP_FEN;
|
||||
// Configure endpoint 0 (enable control endpoint)
|
||||
pUdp->UDP_CSR[AT91C_EP_CONTROL] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL);
|
||||
// clear it
|
||||
pUdp->UDP_ICR |= AT91C_UDP_ENDBUSRES;
|
||||
}
|
||||
else if (isr & AT91C_UDP_EPINT0) {
|
||||
pUdp->UDP_ICR = AT91C_UDP_EPINT0;
|
||||
AT91F_CDC_Enumerate();
|
||||
//pUdp->UDP_ICR |= AT91C_UDP_EPINT0;
|
||||
}
|
||||
}
|
||||
/*
|
||||
else if (isr & AT91C_UDP_EPINT3 ) {
|
||||
pUdp->UDP_ICR = AT91C_UDP_EPINT3;
|
||||
AT91F_CDC_Enumerate();
|
||||
pUdp->UDP_ICR |= AT91C_UDP_EPINT3;
|
||||
//pUdp->UDP_ICR |= AT91C_UDP_EPINT3;
|
||||
}
|
||||
*/
|
||||
return (btConfiguration) ? true : false;
|
||||
}
|
||||
|
||||
|
@ -599,7 +602,7 @@ bool usb_poll() {
|
|||
bool usb_poll_validate_length() {
|
||||
if (!usb_check()) return false;
|
||||
if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;
|
||||
return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;
|
||||
return ((pUdp->UDP_CSR[AT91C_EP_OUT] & AT91C_UDP_RXBYTECNT) >> 16) > 0;
|
||||
}
|
||||
|
||||
//*----------------------------------------------------------------------------
|
||||
|
@ -608,6 +611,8 @@ bool usb_poll_validate_length() {
|
|||
//*----------------------------------------------------------------------------
|
||||
uint32_t usb_read(byte_t* data, size_t len) {
|
||||
|
||||
if ( len == 0 ) return 0;
|
||||
|
||||
uint8_t bank = btReceiveBank;
|
||||
uint32_t packetSize, nbBytesRcv = 0;
|
||||
uint32_t time_out = 0;
|
||||
|
@ -616,11 +621,14 @@ uint32_t usb_read(byte_t* data, size_t len) {
|
|||
if (!usb_check()) break;
|
||||
|
||||
if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
|
||||
packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
|
||||
|
||||
packetSize = (pUdp->UDP_CSR[AT91C_EP_OUT] & AT91C_UDP_RXBYTECNT) >> 16;
|
||||
packetSize = MIN( packetSize, len);
|
||||
len -= packetSize;
|
||||
while (packetSize--)
|
||||
data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
|
||||
|
||||
// flip bank
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank)
|
||||
|
||||
if (bank == AT91C_UDP_RX_DATA_BK0)
|
||||
|
@ -643,19 +651,23 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
|
|||
|
||||
if (!len) return 0;
|
||||
if (!usb_check()) return 0;
|
||||
|
||||
// can we write?
|
||||
if ( (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXPKTRDY) != 0 ) return 0;
|
||||
|
||||
size_t length = len;
|
||||
uint32_t cpt = 0;
|
||||
|
||||
|
||||
// send first chunk
|
||||
cpt = MIN(length, AT91C_EP_IN_SIZE);
|
||||
length -= cpt;
|
||||
while (cpt--) {
|
||||
pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
|
||||
}
|
||||
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY)
|
||||
|
||||
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
|
||||
|
||||
while (length) {
|
||||
// Send next chunk
|
||||
cpt = MIN(length, AT91C_EP_IN_SIZE);
|
||||
|
@ -664,13 +676,15 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
|
|||
pUdp->UDP_FDR[AT91C_EP_IN] = *data++;
|
||||
}
|
||||
|
||||
// Wait for the first bank to be sent
|
||||
// Wait for previous chunk to be sent
|
||||
// (iceman) when is the bankswapping done?
|
||||
while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) {
|
||||
if (!usb_check()) return length;
|
||||
}
|
||||
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP)
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY)
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
|
||||
|
||||
}
|
||||
|
||||
// Wait for the end of transfer
|
||||
|
@ -703,7 +717,7 @@ void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {
|
|||
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP)
|
||||
}
|
||||
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY)
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
|
||||
|
||||
do {
|
||||
csr = pUdp->UDP_CSR[AT91C_EP_CONTROL];
|
||||
|
@ -766,7 +780,7 @@ void AT91F_CDC_Enumerate() {
|
|||
wLength |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);
|
||||
|
||||
if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR)
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);
|
||||
}
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP)
|
||||
|
||||
|
@ -813,10 +827,17 @@ void AT91F_CDC_Enumerate() {
|
|||
case STD_SET_CONFIGURATION:
|
||||
btConfiguration = wValue;
|
||||
AT91F_USB_SendZlp(pUdp);
|
||||
pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
|
||||
pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_CONFG : AT91C_UDP_FADDEN;
|
||||
|
||||
// make sure we are not stalled
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT , AT91C_UDP_FORCESTALL);
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_IN , AT91C_UDP_FORCESTALL);
|
||||
UDP_CLEAR_EP_FLAGS(AT91C_EP_NOTIFY, AT91C_UDP_FORCESTALL);
|
||||
|
||||
// enable endpoints
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_OUT, (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0 );
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_IN, (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0 );
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_NOTIFY, (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0 );
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_NOTIFY, (wValue) ? AT91C_UDP_EPTYPE_INT_IN : 0 );
|
||||
// pUdp->UDP_CSR[AT91C_EP_OUT] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) : 0;
|
||||
// pUdp->UDP_CSR[AT91C_EP_IN] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) : 0;
|
||||
// pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0;
|
||||
|
@ -870,15 +891,15 @@ void AT91F_CDC_Enumerate() {
|
|||
case STD_CLEAR_FEATURE_ENDPOINT:
|
||||
wIndex &= 0x0F;
|
||||
if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {
|
||||
if (wIndex == 1) {
|
||||
if (wIndex == AT91C_EP_OUT) {
|
||||
//pUdp->UDP_CSR[AT91C_EP_OUT] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT);
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_OUT, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT) );
|
||||
}
|
||||
else if (wIndex == 2) {
|
||||
else if (wIndex == AT91C_EP_IN) {
|
||||
//pUdp->UDP_CSR[AT91C_EP_IN] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN);
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_IN, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_IN) );
|
||||
}
|
||||
else if (wIndex == 3) {
|
||||
else if (wIndex == AT91C_EP_NOTIFY) {
|
||||
//pUdp->UDP_CSR[AT91C_EP_NOTIFY] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN);
|
||||
UDP_SET_EP_FLAGS(AT91C_EP_NOTIFY, (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue