appmain.c printf.c \
util.c \
string.c \
- usb.c \
usb_cdc.c \
cmd.c
for (;;)
{
- UsbPoll(FALSE);
- WDT_HIT();
+// UsbPoll(FALSE);
+ usb_poll();
+ WDT_HIT();
// Was our button held down or pressed?
int button_pressed = BUTTON_HELD(1000);
case CMD_SETUP_WRITE:
case CMD_FINISH_WRITE:
case CMD_HARDWARE_RESET: {
- USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
SpinDelay(1000);
SpinDelay(1000);
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
if(common_area.flags.bootrom_present) {
common_area.command = COMMON_AREA_COMMAND_ENTER_FLASH_MODE;
}
- USB_D_PLUS_PULLUP_OFF();
+ usb_disable();
AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST;
for(;;);
} break;
// Init USB device
usb_enable();
- UsbStart();
// UsbStart();
// The FPGA gets its clock from us from PCK0 output, so set that up.
void SimulateHitagTag(bool tag_mem_supplied, byte_t* data);
void ReaderHitag(hitag_function htf, hitag_data* htd);
+// cmd.h
+bool cmd_receive(UsbCommand* cmd);
+bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, byte_t* data, size_t len);
+
/// util.h
#endif
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- memcpy(ack.d.asBytes, dataoutbuf, 16);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// memcpy(ack.d.asBytes, dataoutbuf, 16);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// memcpy(ack.d.asBytes, dataoutbuf, 16 * 2);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
-\r
- SpinDelay(100);\r
+ cmd_send(CMD_ACK,isOK,0,0,dataoutbuf,32);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+// SpinDelay(100);\r
\r
- memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+// memcpy(ack.d.asBytes, dataoutbuf + 16 * 2, 16 * 2);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,dataoutbuf+32, 32);\r
+ LED_B_OFF();\r
\r
// Thats it...\r
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+ cmd_send(CMD_ACK,isOK,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ LED_B_OFF();\r
\r
\r
// Thats it...\r
nestedVector nvector[NES_MAX_INFO + 1][11];\r
int nvectorcount[NES_MAX_INFO + 1];\r
int ncount = 0;\r
- UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
struct Crypto1State mpcs = {0, 0};\r
struct Crypto1State *pcs;\r
pcs = &mpcs;\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
+// UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
+\r
for (i = 0; i < NES_MAX_INFO; i++) {\r
if (nvectorcount[i] > 10) continue;\r
\r
ncount = nvectorcount[i] - j;\r
if (ncount > 5) ncount = 5; \r
\r
- ack.arg[0] = 0; // isEOF = 0\r
- ack.arg[1] = ncount;\r
- ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
- memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+// ack.arg[0] = 0; // isEOF = 0\r
+// ack.arg[1] = ncount;\r
+// ack.arg[2] = targetBlockNo + (targetKeyType * 0x100);\r
+// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
\r
- memcpy(ack.d.asBytes, &cuid, 4);\r
+ byte_t buf[48];\r
+ memset(buf, 0x00, sizeof(buf));\r
+ memcpy(buf, &cuid, 4);\r
for (m = 0; m < ncount; m++) {\r
- memcpy(ack.d.asBytes + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
- memcpy(ack.d.asBytes + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
+ memcpy(buf + 8 + m * 8 + 0, &nvector[i][m + j].nt, 4);\r
+ memcpy(buf + 8 + m * 8 + 4, &nvector[i][m + j].ks1, 4);\r
}\r
\r
LED_B_ON();\r
- SpinDelay(100);\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+// SpinDelay(100);\r
+ cmd_send(CMD_ACK,0,ncount,targetBlockNo + (targetKeyType * 0x100),buf,48);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ LED_B_OFF();\r
}\r
}\r
\r
// finalize list\r
- ack.arg[0] = 1; // isEOF = 1\r
- ack.arg[1] = 0;\r
- ack.arg[2] = 0;\r
- memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
+// ack.arg[0] = 1; // isEOF = 1\r
+// ack.arg[1] = 0;\r
+// ack.arg[2] = 0;\r
+// memset(ack.d.asBytes, 0x00, sizeof(ack.d.asBytes));\r
\r
LED_B_ON();\r
- SpinDelay(300);\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- LED_B_OFF(); \r
+// SpinDelay(300);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,1,0,0,0,0);\r
+ LED_B_OFF();\r
\r
if (MF_DBGLEVEL >= 4) DbpString("NESTED FINISHED");\r
\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// if (isOK) memcpy(ack.d.asBytes, datain + i * 6, 6);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,datain + i * 6,6);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
// Thats it...\r
}\r
\r
void MifareEMemGet(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain){\r
- UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
+// UsbCommand ack = {CMD_ACK, {arg0, arg1, 0}};\r
\r
- emlGetMem(ack.d.asBytes, arg0, arg1); // data, block num, blocks count\r
+ byte_t buf[48];\r
+ emlGetMem(buf, arg0, arg1); // data, block num, blocks count\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,arg0,arg1,0,buf,48);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
}\r
\r
break;\r
}\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// if (isOK) memcpy(ack.d.asBytes, uid, 4);\r
\r
// add trace trailer\r
memset(uid, 0x44, 4);\r
LogTrace(uid, 4, 0, 0, TRUE);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,uid,4);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
if ((workFlags & 0x10) || (!isOK)) {\r
break;\r
}\r
\r
- UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
- if (isOK) memcpy(ack.d.asBytes, data, 18);\r
+// UsbCommand ack = {CMD_ACK, {isOK, 0, 0}};\r
+// if (isOK) memcpy(ack.d.asBytes, data, 18);\r
\r
// add trace trailer\r
memset(data, 0x44, 4);\r
LogTrace(data, 4, 0, 0, TRUE);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,isOK,0,0,data,18);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
if ((workFlags & 0x10) || (!isOK)) {\r
}\r
\r
int MfSniffEnd(void){\r
- UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
+// UsbCommand ack = {CMD_ACK, {0, 0, 0}};\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,0,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
return 0;\r
\r
while (pckLen > 0) {\r
pckSize = MIN(32, pckLen);\r
- UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};\r
- memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);\r
+// UsbCommand ack = {CMD_ACK, {1, pckSize, pckNum}};\r
+// memcpy(ack.d.asBytes, trace + traceLen - pckLen, pckSize);\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
- SpinDelay(20);\r
+ cmd_send(CMD_ACK,1,pckSize,pckNum,trace + traceLen - pckLen,pckSize);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+// SpinDelay(20);\r
LED_B_OFF();\r
\r
pckLen -= pckSize;\r
pckNum++;\r
}\r
\r
- UsbCommand ack = {CMD_ACK, {2, 0, 0}};\r
+// UsbCommand ack = {CMD_ACK, {2, 0, 0}};\r
\r
LED_B_ON();\r
- UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
+ cmd_send(CMD_ACK,2,0,0,0,0);\r
+// UsbSendPacket((uint8_t *)&ack, sizeof(UsbCommand));\r
LED_B_OFF();\r
\r
traceLen = 0;\r
*/\r
\r
#include "usb_cdc.h"\r
+#include "util.h"\r
\r
#define MIN(a, b) (((a) < (b)) ? (a) : (b))\r
#define MAX(a, b) (((a) > (b)) ? (a) : (b))\r
byte_t btConnection = 0;\r
byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;\r
\r
+//*----------------------------------------------------------------------------\r
+//* \fn AT91F_USB_Disable\r
+//* \brief This function deactivates the USB device\r
+//*----------------------------------------------------------------------------\r
+void usb_disable() {\r
+ // Disconnect and reconnect USB controller for 100ms\r
+ AT91C_BASE_PIOA->PIO_ODR = AT91C_PIO_PA24;\r
+ SpinDelay(100);\r
+ \r
+ // Clear all lingering interrupts\r
+ if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {\r
+ pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;\r
+ }\r
+}\r
+\r
//*----------------------------------------------------------------------------\r
//* \fn AT91F_USB_Enable\r
//* \brief This function Activates the USB device\r
//*----------------------------------------------------------------------------\r
-void usb_enable()\r
-{\r
+void usb_enable() {\r
// Set the PLL USB Divider\r
AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ;\r
\r
\r
// Clear for set the Pul up resistor\r
AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA16;\r
+ \r
+ // Disconnect and USB device\r
+ usb_disable();\r
+ \r
+ // Wait for a short while\r
+ SpinDelay(100);\r
+\r
+ // Reconnect USB reconnect\r
+ AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA24;\r
+ AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA24;\r
}\r
\r
//*----------------------------------------------------------------------------\r
//* \fn AT91F_UDP_IsConfigured\r
//* \brief Test if the device is configured and handle enumeration\r
//*----------------------------------------------------------------------------\r
-bool usb_check()\r
-{\r
+bool usb_check() {\r
AT91_REG isr = pUdp->UDP_ISR;\r
\r
if (isr & AT91C_UDP_ENDBUSRES) {\r
//* \fn AT91F_UDP_Read\r
//* \brief Read available data from Endpoint OUT\r
//*----------------------------------------------------------------------------\r
-uint32_t usb_read(byte_t* data, size_t len)\r
-{\r
+uint32_t usb_read(byte_t* data, size_t len) {\r
byte_t bank = btReceiveBank;\r
uint32_t packetSize, nbBytesRcv = 0;\r
uint32_t time_out = 0;\r
//* \fn AT91F_CDC_Write\r
//* \brief Send through endpoint 2\r
//*----------------------------------------------------------------------------\r
-uint32_t usb_write(const byte_t* data, const size_t len)\r
-{\r
+uint32_t usb_write(const byte_t* data, const size_t len) {\r
size_t length = len;\r
uint32_t cpt = 0;\r
\r
unsigned int csrTab[100];\r
unsigned char csrIdx = 0;\r
\r
-static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length)\r
-{\r
+static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) {\r
uint32_t cpt = 0;\r
AT91_REG csr;\r
\r
//* \fn AT91F_USB_SendZlp\r
//* \brief Send zero length packet through the control endpoint\r
//*----------------------------------------------------------------------------\r
-void AT91F_USB_SendZlp(AT91PS_UDP pUdp)\r
-{\r
+void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {\r
pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;\r
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) );\r
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP);\r
//* \fn AT91F_USB_SendStall\r
//* \brief Stall the control endpoint\r
//*----------------------------------------------------------------------------\r
-void AT91F_USB_SendStall(AT91PS_UDP pUdp)\r
-{\r
+void AT91F_USB_SendStall(AT91PS_UDP pUdp) {\r
pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;\r
while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) );\r
pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);\r
//* \fn AT91F_CDC_Enumerate\r
//* \brief This function is a callback invoked when a SETUP packet is received\r
//*----------------------------------------------------------------------------\r
-void AT91F_CDC_Enumerate()\r
-{\r
+void AT91F_CDC_Enumerate() {\r
byte_t bmRequestType, bRequest;\r
uint16_t wValue, wIndex, wLength, wStatus;\r
\r
\r
#include <common.h>\r
\r
+void usb_disable();\r
void usb_enable();\r
bool usb_check();\r
bool usb_poll();\r
# DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code
ARMSRC =
-THUMBSRC = usb.c bootrom.c
+THUMBSRC = usb_hid.c bootrom.c
ASMSRC = ram-reset.s flash-reset.s
## There is a strange bug with the linker: Sometimes it will not emit the glue to call
//-----------------------------------------------------------------------------
#include <proxmark3.h>
+#include "usb_hid.h"
struct common_area common_area __attribute__((section(".commonarea")));
unsigned int start_addr, end_addr, bootrom_unlocked;
--- /dev/null
+//-----------------------------------------------------------------------------
+// Jonathan Westhues, split Aug 14 2005
+//
+// This code is licensed to you under the terms of the GNU GPL, version 2 or,
+// at your option, any later version. See the LICENSE.txt file for the text of
+// the license.
+//-----------------------------------------------------------------------------
+// The common USB driver used for both the bootloader and the application.
+//-----------------------------------------------------------------------------
+
+#include "proxmark3.h"
+#include "usb_hid.h"
+
+#define min(a, b) (((a) > (b)) ? (b) : (a))
+
+#define USB_REPORT_PACKET_SIZE 64
+
+typedef struct PACKED {
+ uint8_t bmRequestType;
+ uint8_t bRequest;
+ uint16_t wValue;
+ uint16_t wIndex;
+ uint16_t wLength;
+} UsbSetupData;
+
+#define USB_REQUEST_GET_STATUS 0
+#define USB_REQUEST_CLEAR_FEATURE 1
+#define USB_REQUEST_SET_FEATURE 3
+#define USB_REQUEST_SET_ADDRESS 5
+#define USB_REQUEST_GET_DESCRIPTOR 6
+#define USB_REQUEST_SET_DESCRIPTOR 7
+#define USB_REQUEST_GET_CONFIGURATION 8
+#define USB_REQUEST_SET_CONFIGURATION 9
+#define USB_REQUEST_GET_INTERFACE 10
+#define USB_REQUEST_SET_INTERFACE 11
+#define USB_REQUEST_SYNC_FRAME 12
+
+#define USB_DESCRIPTOR_TYPE_DEVICE 1
+#define USB_DESCRIPTOR_TYPE_CONFIGURATION 2
+#define USB_DESCRIPTOR_TYPE_STRING 3
+#define USB_DESCRIPTOR_TYPE_INTERFACE 4
+#define USB_DESCRIPTOR_TYPE_ENDPOINT 5
+#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 6
+#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONF 7
+#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 8
+#define USB_DESCRIPTOR_TYPE_HID 0x21
+#define USB_DESCRIPTOR_TYPE_HID_REPORT 0x22
+
+#define USB_DEVICE_CLASS_HID 0x03
+
+static const uint8_t HidReportDescriptor[] = {
+ 0x06,0xA0,0xFF, // Usage Page (vendor defined) FFA0
+ 0x09,0x01, // Usage (vendor defined)
+ 0xA1,0x01, // Collection (Application)
+ 0x09,0x02, // Usage (vendor defined)
+ 0xA1,0x00, // Collection (Physical)
+ 0x06,0xA1,0xFF, // Usage Page (vendor defined)
+
+ //The,input report
+ 0x09,0x03, // usage - vendor defined
+ 0x09,0x04, // usage - vendor defined
+ 0x15,0x80, // Logical Minimum (-128)
+ 0x25,0x7F, // Logical Maximum (127)
+ 0x35,0x00, // Physical Minimum (0)
+ 0x45,0xFF, // Physical Maximum (255)
+ 0x75,0x08, // Report Size (8) (bits)
+ 0x95,0x40, // Report Count (64) (fields)
+ 0x81,0x02, // Input (Data,Variable,Absolute)
+
+ //The,output report
+ 0x09,0x05, // usage - vendor defined
+ 0x09,0x06, // usage - vendor defined
+ 0x15,0x80, // Logical Minimum (-128)
+ 0x25,0x7F, // Logical Maximum (127)
+ 0x35,0x00, // Physical Minimum (0)
+ 0x45,0xFF, // Physical Maximum (255)
+ 0x75,0x08, // Report Size (8) (bits)
+ 0x95,0x40, // Report Count (64) (fields)
+ 0x91,0x02, // Output (Data,Variable,Absolute)
+
+ 0xC0, // End Collection
+
+ 0xC0, // End Collection
+};
+
+static const uint8_t DeviceDescriptor[] = {
+ 0x12, // Descriptor length (18 bytes)
+ 0x01, // Descriptor type (Device)
+ 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
+ 0x00, // Class code (0)
+ 0x00, // Subclass code (0)
+ 0x00, // Protocol (No specific protocol)
+ 0x08, // Maximum packet size for Endpoint 0 (8 bytes)
+ 0xc4,0x9a, // Vendor ID (random numbers)
+ 0x8f,0x4b, // Product ID (random numbers)
+ 0x01,0x00, // Device release number (0001)
+ 0x01, // Manufacturer string descriptor index
+ 0x02, // Product string descriptor index
+ 0x03, // Serial Number string descriptor index
+ 0x01, // Number of possible configurations (1)
+};
+
+static const uint8_t ConfigurationDescriptor[] = {
+ 0x09, // Descriptor length (9 bytes)
+ 0x02, // Descriptor type (Configuration)
+ 0x29,0x00, // Total data length (41 bytes)
+ 0x01, // Interface supported (1)
+ 0x01, // Configuration value (1)
+ 0x00, // Index of string descriptor (None)
+ 0x80, // Configuration (Bus powered)
+ 250, // Maximum power consumption (500mA)
+
+ //interface
+ 0x09, // Descriptor length (9 bytes)
+ 0x04, // Descriptor type (Interface)
+ 0x00, // Number of interface (0)
+ 0x00, // Alternate setting (0)
+ 0x02, // Number of interface endpoint (2)
+ 0x03, // Class code (HID)
+ 0x00, // Subclass code ()
+ 0x00, // Protocol code ()
+ 0x00, // Index of string()
+
+ // class
+ 0x09, // Descriptor length (9 bytes)
+ 0x21, // Descriptor type (HID)
+ 0x00,0x01, // HID class release number (1.00)
+ 0x00, // Localized country code (None)
+ 0x01, // # of HID class dscrptr to follow (1)
+ 0x22, // Report descriptor type (HID)
+ // Total length of report descriptor
+ sizeof(HidReportDescriptor),0x00,
+
+ // endpoint 1
+ 0x07, // Descriptor length (7 bytes)
+ 0x05, // Descriptor type (Endpoint)
+ 0x01, // Encoded address (Respond to OUT)
+ 0x03, // Endpoint attribute (Interrupt transfer)
+ 0x08,0x00, // Maximum packet size (8 bytes)
+ 0x01, // Polling interval (1 ms)
+
+ // endpoint 2
+ 0x07, // Descriptor length (7 bytes)
+ 0x05, // Descriptor type (Endpoint)
+ 0x82, // Encoded address (Respond to IN)
+ 0x03, // Endpoint attribute (Interrupt transfer)
+ 0x08,0x00, // Maximum packet size (8 bytes)
+ 0x01, // Polling interval (1 ms)
+};
+
+static const uint8_t StringDescriptor0[] = {
+ 0x04, // Length
+ 0x03, // Type is string
+ 0x09, // English
+ 0x04, // US
+};
+
+static const uint8_t StringDescriptor1[] = {
+ 24, // Length
+ 0x03, // Type is string
+ 'J', 0x00,
+ '.', 0x00,
+ ' ', 0x00,
+ 'W', 0x00,
+ 'e', 0x00,
+ 's', 0x00,
+ 't', 0x00,
+ 'h', 0x00,
+ 'u', 0x00,
+ 'e', 0x00,
+ 's', 0x00,
+};
+
+static const uint8_t StringDescriptor2[] = {
+ 54, // Length
+ 0x03, // Type is string
+ 'P', 0x00,
+ 'r', 0x00,
+ 'o', 0x00,
+ 'x', 0x00,
+ 'M', 0x00,
+ 'a', 0x00,
+ 'r', 0x00,
+ 'k', 0x00,
+ '-', 0x00,
+ '3', 0x00,
+ ' ', 0x00,
+ 'R', 0x00,
+ 'F', 0x00,
+ 'I', 0x00,
+ 'D', 0x00,
+ ' ', 0x00,
+ 'I', 0x00,
+ 'n', 0x00,
+ 's', 0x00,
+ 't', 0x00,
+ 'r', 0x00,
+ 'u', 0x00,
+ 'm', 0x00,
+ 'e', 0x00,
+ 'n', 0x00,
+ 't', 0x00,
+};
+
+// Serial Number
+// TODO: Pick yours! Don't forget to modify the length, if needed.
+static const uint8_t StringDescriptor3[] = {
+ 18, // Length
+ 0x03, // Type is string
+ 'C', 0x00,
+ 'h', 0x00,
+ 'a', 0x00,
+ 'n', 0x00,
+ 'g', 0x00,
+ 'e', 0x00,
+ 'M', 0x00,
+ 'e', 0x00,
+};
+
+static const uint8_t * const StringDescriptors[] = {
+ StringDescriptor0,
+ StringDescriptor1,
+ StringDescriptor2,
+ StringDescriptor3,
+};
+
+
+static uint8_t UsbBuffer[64];
+static int UsbSoFarCount;
+
+static uint8_t CurrentConfiguration;
+
+static void UsbSendEp0(const uint8_t *data, int len)
+{
+ int thisTime, i;
+
+ do {
+ thisTime = min(len, 8);
+ len -= thisTime;
+
+ for(i = 0; i < thisTime; i++) {
+ AT91C_BASE_UDP->UDP_FDR[0] = *data;
+ data++;
+ }
+
+ if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
+ AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
+ while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
+ ;
+ }
+
+ AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
+
+ do {
+ if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) {
+ // This means that the host is trying to write to us, so
+ // abandon our write to them.
+ AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
+ return;
+ }
+ } while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP));
+ } while(len > 0);
+
+ if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
+ AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
+ while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
+ ;
+ }
+}
+
+static void UsbSendZeroLength(void)
+{
+ AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
+
+ while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP))
+ ;
+
+ AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
+
+ while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
+ ;
+}
+
+static void UsbSendStall(void)
+{
+ AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
+
+ while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT))
+ ;
+
+ AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_STALLSENT;
+
+ while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT)
+ ;
+}
+
+static void HandleRxdSetupData(void)
+{
+ int i;
+ UsbSetupData usd;
+
+ for(i = 0; i < sizeof(usd); i++) {
+ ((uint8_t *)&usd)[i] = AT91C_BASE_UDP->UDP_FDR[0];
+ }
+
+ if(usd.bmRequestType & 0x80) {
+ AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_DIR;
+ while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_DIR))
+ ;
+ }
+
+ AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
+ while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)
+ ;
+
+ switch(usd.bRequest) {
+ case USB_REQUEST_GET_DESCRIPTOR:
+ if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_DEVICE) {
+ UsbSendEp0((uint8_t *)&DeviceDescriptor,
+ min(sizeof(DeviceDescriptor), usd.wLength));
+ } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION) {
+ UsbSendEp0((uint8_t *)&ConfigurationDescriptor,
+ min(sizeof(ConfigurationDescriptor), usd.wLength));
+ } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_STRING) {
+ const uint8_t *s = StringDescriptors[usd.wValue & 0xff];
+ UsbSendEp0(s, min(s[0], usd.wLength));
+ } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT) {
+ UsbSendEp0((uint8_t *)&HidReportDescriptor,
+ min(sizeof(HidReportDescriptor), usd.wLength));
+ } else {
+ *((uint32_t *)0x00200000) = usd.wValue;
+ }
+ break;
+
+ case USB_REQUEST_SET_ADDRESS:
+ UsbSendZeroLength();
+ AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN | usd.wValue ;
+ if(usd.wValue != 0) {
+ AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
+ } else {
+ AT91C_BASE_UDP->UDP_GLBSTATE = 0;
+ }
+ break;
+
+ case USB_REQUEST_GET_CONFIGURATION:
+ UsbSendEp0(&CurrentConfiguration, sizeof(CurrentConfiguration));
+ break;
+
+ case USB_REQUEST_GET_STATUS: {
+ if(usd.bmRequestType & 0x80) {
+ uint16_t w = 0;
+ UsbSendEp0((uint8_t *)&w, sizeof(w));
+ }
+ break;
+ }
+ case USB_REQUEST_SET_CONFIGURATION:
+ CurrentConfiguration = usd.wValue;
+ if(CurrentConfiguration) {
+ AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
+ AT91C_BASE_UDP->UDP_CSR[1] = AT91C_UDP_EPEDS |
+ AT91C_UDP_EPTYPE_INT_OUT;
+ AT91C_BASE_UDP->UDP_CSR[2] = AT91C_UDP_EPEDS |
+ AT91C_UDP_EPTYPE_INT_IN;
+ } else {
+ AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
+ AT91C_BASE_UDP->UDP_CSR[1] = 0;
+ AT91C_BASE_UDP->UDP_CSR[2] = 0;
+ }
+ UsbSendZeroLength();
+ break;
+
+ case USB_REQUEST_GET_INTERFACE: {
+ uint8_t b = 0;
+ UsbSendEp0(&b, sizeof(b));
+ break;
+ }
+
+ case USB_REQUEST_SET_INTERFACE:
+ UsbSendZeroLength();
+ break;
+
+ case USB_REQUEST_CLEAR_FEATURE:
+ case USB_REQUEST_SET_FEATURE:
+ UsbSendStall();
+ break;
+ case USB_REQUEST_SET_DESCRIPTOR:
+ case USB_REQUEST_SYNC_FRAME:
+ default:
+ break;
+ }
+}
+
+void UsbSendPacket(uint8_t *packet, int len)
+{
+ int i, thisTime;
+
+ while(len > 0) {
+ thisTime = min(len, 8);
+
+ for(i = 0; i < thisTime; i++) {
+ AT91C_BASE_UDP->UDP_FDR[2] = packet[i];
+ }
+ AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
+
+ while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)) {
+ WDT_HIT();
+ }
+
+ AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
+
+ while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) {
+ WDT_HIT();
+ }
+
+ len -= thisTime;
+ packet += thisTime;
+ }
+}
+
+static void HandleRxdData(void)
+{
+ int i, len;
+
+ if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
+ len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
+
+ for(i = 0; i < len; i++) {
+ UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
+ UsbSoFarCount++;
+ }
+
+ AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
+ while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
+ WDT_HIT();
+ }
+
+ if(UsbSoFarCount >= 64) {
+ UsbPacketReceived(UsbBuffer, UsbSoFarCount);
+ UsbSoFarCount = 0;
+ }
+ }
+
+ if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
+ len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
+
+ for(i = 0; i < len; i++) {
+ UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
+ UsbSoFarCount++;
+ }
+
+ AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
+ while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
+ WDT_HIT();
+ }
+
+ if(UsbSoFarCount >= 64) {
+ UsbPacketReceived(UsbBuffer, UsbSoFarCount);
+ UsbSoFarCount = 0;
+ }
+ }
+
+ WDT_HIT();
+}
+
+void UsbStart(void)
+{
+ volatile int i;
+
+ UsbSoFarCount = 0;
+
+ USB_D_PLUS_PULLUP_OFF();
+
+ for(i = 0; i < 1000000; i++)
+ ;
+
+ USB_D_PLUS_PULLUP_ON();
+
+ if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
+ AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
+ }
+}
+
+int UsbConnected()
+{
+ if (AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+int UsbPoll(int blinkLeds)
+{
+ int ret = FALSE;
+
+ if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
+ AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
+
+ // following a reset we should be ready to receive a setup packet
+ AT91C_BASE_UDP->UDP_RSTEP = 0xf;
+ AT91C_BASE_UDP->UDP_RSTEP = 0;
+
+ AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;
+
+ AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;
+
+ CurrentConfiguration = 0;
+
+ ret = TRUE;
+ }
+
+ if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(0)) {
+ if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) {
+ HandleRxdSetupData();
+ ret = TRUE;
+ }
+ }
+
+ if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(1)) {
+ HandleRxdData();
+ ret = TRUE;
+ }
+
+ return ret;
+}
--- /dev/null
+#ifndef _USB_HID_H_\r
+#define _USB_HID_H_\r
+\r
+#include <common.h>\r
+#include <proxmark3.h>\r
+\r
+//--------------------------------\r
+// USB defines\r
+\r
+#define USB_D_PLUS_PULLUP_ON() { \\r
+HIGH(GPIO_USB_PU); \\r
+AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; \\r
+}\r
+#define USB_D_PLUS_PULLUP_OFF() AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU\r
+\r
+//--------------------------------\r
+// USB declarations\r
+\r
+void UsbSendPacket(uint8_t *packet, int len);\r
+int UsbConnected();\r
+int UsbPoll(int blinkLeds);\r
+void UsbStart(void);\r
+\r
+// This function is provided by the apps/bootrom, and called from UsbPoll\r
+// if data are available.\r
+void UsbPacketReceived(uint8_t *packet, int len);\r
+\r
+#endif // _USB_HID_H_\r
+\r
+++ /dev/null
-//-----------------------------------------------------------------------------
-// Jonathan Westhues, split Aug 14 2005
-//
-// This code is licensed to you under the terms of the GNU GPL, version 2 or,
-// at your option, any later version. See the LICENSE.txt file for the text of
-// the license.
-//-----------------------------------------------------------------------------
-// The common USB driver used for both the bootloader and the application.
-//-----------------------------------------------------------------------------
-
-#include "proxmark3.h"
-
-#define min(a, b) (((a) > (b)) ? (b) : (a))
-
-#define USB_REPORT_PACKET_SIZE 64
-
-typedef struct PACKED {
- uint8_t bmRequestType;
- uint8_t bRequest;
- uint16_t wValue;
- uint16_t wIndex;
- uint16_t wLength;
-} UsbSetupData;
-
-#define USB_REQUEST_GET_STATUS 0
-#define USB_REQUEST_CLEAR_FEATURE 1
-#define USB_REQUEST_SET_FEATURE 3
-#define USB_REQUEST_SET_ADDRESS 5
-#define USB_REQUEST_GET_DESCRIPTOR 6
-#define USB_REQUEST_SET_DESCRIPTOR 7
-#define USB_REQUEST_GET_CONFIGURATION 8
-#define USB_REQUEST_SET_CONFIGURATION 9
-#define USB_REQUEST_GET_INTERFACE 10
-#define USB_REQUEST_SET_INTERFACE 11
-#define USB_REQUEST_SYNC_FRAME 12
-
-#define USB_DESCRIPTOR_TYPE_DEVICE 1
-#define USB_DESCRIPTOR_TYPE_CONFIGURATION 2
-#define USB_DESCRIPTOR_TYPE_STRING 3
-#define USB_DESCRIPTOR_TYPE_INTERFACE 4
-#define USB_DESCRIPTOR_TYPE_ENDPOINT 5
-#define USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER 6
-#define USB_DESCRIPTOR_TYPE_OTHER_SPEED_CONF 7
-#define USB_DESCRIPTOR_TYPE_INTERFACE_POWER 8
-#define USB_DESCRIPTOR_TYPE_HID 0x21
-#define USB_DESCRIPTOR_TYPE_HID_REPORT 0x22
-
-#define USB_DEVICE_CLASS_HID 0x03
-
-static const uint8_t HidReportDescriptor[] = {
- 0x06,0xA0,0xFF, // Usage Page (vendor defined) FFA0
- 0x09,0x01, // Usage (vendor defined)
- 0xA1,0x01, // Collection (Application)
- 0x09,0x02, // Usage (vendor defined)
- 0xA1,0x00, // Collection (Physical)
- 0x06,0xA1,0xFF, // Usage Page (vendor defined)
-
- //The,input report
- 0x09,0x03, // usage - vendor defined
- 0x09,0x04, // usage - vendor defined
- 0x15,0x80, // Logical Minimum (-128)
- 0x25,0x7F, // Logical Maximum (127)
- 0x35,0x00, // Physical Minimum (0)
- 0x45,0xFF, // Physical Maximum (255)
- 0x75,0x08, // Report Size (8) (bits)
- 0x95,0x40, // Report Count (64) (fields)
- 0x81,0x02, // Input (Data,Variable,Absolute)
-
- //The,output report
- 0x09,0x05, // usage - vendor defined
- 0x09,0x06, // usage - vendor defined
- 0x15,0x80, // Logical Minimum (-128)
- 0x25,0x7F, // Logical Maximum (127)
- 0x35,0x00, // Physical Minimum (0)
- 0x45,0xFF, // Physical Maximum (255)
- 0x75,0x08, // Report Size (8) (bits)
- 0x95,0x40, // Report Count (64) (fields)
- 0x91,0x02, // Output (Data,Variable,Absolute)
-
- 0xC0, // End Collection
-
- 0xC0, // End Collection
-};
-
-static const uint8_t DeviceDescriptor[] = {
- 0x12, // Descriptor length (18 bytes)
- 0x01, // Descriptor type (Device)
- 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10)
- 0x00, // Class code (0)
- 0x00, // Subclass code (0)
- 0x00, // Protocol (No specific protocol)
- 0x08, // Maximum packet size for Endpoint 0 (8 bytes)
- 0xc4,0x9a, // Vendor ID (random numbers)
- 0x8f,0x4b, // Product ID (random numbers)
- 0x01,0x00, // Device release number (0001)
- 0x01, // Manufacturer string descriptor index
- 0x02, // Product string descriptor index
- 0x03, // Serial Number string descriptor index
- 0x01, // Number of possible configurations (1)
-};
-
-static const uint8_t ConfigurationDescriptor[] = {
- 0x09, // Descriptor length (9 bytes)
- 0x02, // Descriptor type (Configuration)
- 0x29,0x00, // Total data length (41 bytes)
- 0x01, // Interface supported (1)
- 0x01, // Configuration value (1)
- 0x00, // Index of string descriptor (None)
- 0x80, // Configuration (Bus powered)
- 250, // Maximum power consumption (500mA)
-
- //interface
- 0x09, // Descriptor length (9 bytes)
- 0x04, // Descriptor type (Interface)
- 0x00, // Number of interface (0)
- 0x00, // Alternate setting (0)
- 0x02, // Number of interface endpoint (2)
- 0x03, // Class code (HID)
- 0x00, // Subclass code ()
- 0x00, // Protocol code ()
- 0x00, // Index of string()
-
- // class
- 0x09, // Descriptor length (9 bytes)
- 0x21, // Descriptor type (HID)
- 0x00,0x01, // HID class release number (1.00)
- 0x00, // Localized country code (None)
- 0x01, // # of HID class dscrptr to follow (1)
- 0x22, // Report descriptor type (HID)
- // Total length of report descriptor
- sizeof(HidReportDescriptor),0x00,
-
- // endpoint 1
- 0x07, // Descriptor length (7 bytes)
- 0x05, // Descriptor type (Endpoint)
- 0x01, // Encoded address (Respond to OUT)
- 0x03, // Endpoint attribute (Interrupt transfer)
- 0x08,0x00, // Maximum packet size (8 bytes)
- 0x01, // Polling interval (1 ms)
-
- // endpoint 2
- 0x07, // Descriptor length (7 bytes)
- 0x05, // Descriptor type (Endpoint)
- 0x82, // Encoded address (Respond to IN)
- 0x03, // Endpoint attribute (Interrupt transfer)
- 0x08,0x00, // Maximum packet size (8 bytes)
- 0x01, // Polling interval (1 ms)
-};
-
-static const uint8_t StringDescriptor0[] = {
- 0x04, // Length
- 0x03, // Type is string
- 0x09, // English
- 0x04, // US
-};
-
-static const uint8_t StringDescriptor1[] = {
- 24, // Length
- 0x03, // Type is string
- 'J', 0x00,
- '.', 0x00,
- ' ', 0x00,
- 'W', 0x00,
- 'e', 0x00,
- 's', 0x00,
- 't', 0x00,
- 'h', 0x00,
- 'u', 0x00,
- 'e', 0x00,
- 's', 0x00,
-};
-
-static const uint8_t StringDescriptor2[] = {
- 54, // Length
- 0x03, // Type is string
- 'P', 0x00,
- 'r', 0x00,
- 'o', 0x00,
- 'x', 0x00,
- 'M', 0x00,
- 'a', 0x00,
- 'r', 0x00,
- 'k', 0x00,
- '-', 0x00,
- '3', 0x00,
- ' ', 0x00,
- 'R', 0x00,
- 'F', 0x00,
- 'I', 0x00,
- 'D', 0x00,
- ' ', 0x00,
- 'I', 0x00,
- 'n', 0x00,
- 's', 0x00,
- 't', 0x00,
- 'r', 0x00,
- 'u', 0x00,
- 'm', 0x00,
- 'e', 0x00,
- 'n', 0x00,
- 't', 0x00,
-};
-
-// Serial Number
-// TODO: Pick yours! Don't forget to modify the length, if needed.
-static const uint8_t StringDescriptor3[] = {
- 18, // Length
- 0x03, // Type is string
- 'C', 0x00,
- 'h', 0x00,
- 'a', 0x00,
- 'n', 0x00,
- 'g', 0x00,
- 'e', 0x00,
- 'M', 0x00,
- 'e', 0x00,
-};
-
-static const uint8_t * const StringDescriptors[] = {
- StringDescriptor0,
- StringDescriptor1,
- StringDescriptor2,
- StringDescriptor3,
-};
-
-
-static uint8_t UsbBuffer[64];
-static int UsbSoFarCount;
-
-static uint8_t CurrentConfiguration;
-
-static void UsbSendEp0(const uint8_t *data, int len)
-{
- int thisTime, i;
-
- do {
- thisTime = min(len, 8);
- len -= thisTime;
-
- for(i = 0; i < thisTime; i++) {
- AT91C_BASE_UDP->UDP_FDR[0] = *data;
- data++;
- }
-
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
- ;
- }
-
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
-
- do {
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) {
- // This means that the host is trying to write to us, so
- // abandon our write to them.
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RX_DATA_BK0;
- return;
- }
- } while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP));
- } while(len > 0);
-
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP) {
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
- ;
- }
-}
-
-static void UsbSendZeroLength(void)
-{
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY;
-
- while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP))
- ;
-
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_TXCOMP;
-
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_TXCOMP)
- ;
-}
-
-static void UsbSendStall(void)
-{
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_FORCESTALL;
-
- while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT))
- ;
-
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_STALLSENT;
-
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_STALLSENT)
- ;
-}
-
-static void HandleRxdSetupData(void)
-{
- int i;
- UsbSetupData usd;
-
- for(i = 0; i < sizeof(usd); i++) {
- ((uint8_t *)&usd)[i] = AT91C_BASE_UDP->UDP_FDR[0];
- }
-
- if(usd.bmRequestType & 0x80) {
- AT91C_BASE_UDP->UDP_CSR[0] |= AT91C_UDP_DIR;
- while(!(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_DIR))
- ;
- }
-
- AT91C_BASE_UDP->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP;
- while(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP)
- ;
-
- switch(usd.bRequest) {
- case USB_REQUEST_GET_DESCRIPTOR:
- if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_DEVICE) {
- UsbSendEp0((uint8_t *)&DeviceDescriptor,
- min(sizeof(DeviceDescriptor), usd.wLength));
- } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_CONFIGURATION) {
- UsbSendEp0((uint8_t *)&ConfigurationDescriptor,
- min(sizeof(ConfigurationDescriptor), usd.wLength));
- } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_STRING) {
- const uint8_t *s = StringDescriptors[usd.wValue & 0xff];
- UsbSendEp0(s, min(s[0], usd.wLength));
- } else if((usd.wValue >> 8) == USB_DESCRIPTOR_TYPE_HID_REPORT) {
- UsbSendEp0((uint8_t *)&HidReportDescriptor,
- min(sizeof(HidReportDescriptor), usd.wLength));
- } else {
- *((uint32_t *)0x00200000) = usd.wValue;
- }
- break;
-
- case USB_REQUEST_SET_ADDRESS:
- UsbSendZeroLength();
- AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN | usd.wValue ;
- if(usd.wValue != 0) {
- AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
- } else {
- AT91C_BASE_UDP->UDP_GLBSTATE = 0;
- }
- break;
-
- case USB_REQUEST_GET_CONFIGURATION:
- UsbSendEp0(&CurrentConfiguration, sizeof(CurrentConfiguration));
- break;
-
- case USB_REQUEST_GET_STATUS: {
- if(usd.bmRequestType & 0x80) {
- uint16_t w = 0;
- UsbSendEp0((uint8_t *)&w, sizeof(w));
- }
- break;
- }
- case USB_REQUEST_SET_CONFIGURATION:
- CurrentConfiguration = usd.wValue;
- if(CurrentConfiguration) {
- AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_CONFG;
- AT91C_BASE_UDP->UDP_CSR[1] = AT91C_UDP_EPEDS |
- AT91C_UDP_EPTYPE_INT_OUT;
- AT91C_BASE_UDP->UDP_CSR[2] = AT91C_UDP_EPEDS |
- AT91C_UDP_EPTYPE_INT_IN;
- } else {
- AT91C_BASE_UDP->UDP_GLBSTATE = AT91C_UDP_FADDEN;
- AT91C_BASE_UDP->UDP_CSR[1] = 0;
- AT91C_BASE_UDP->UDP_CSR[2] = 0;
- }
- UsbSendZeroLength();
- break;
-
- case USB_REQUEST_GET_INTERFACE: {
- uint8_t b = 0;
- UsbSendEp0(&b, sizeof(b));
- break;
- }
-
- case USB_REQUEST_SET_INTERFACE:
- UsbSendZeroLength();
- break;
-
- case USB_REQUEST_CLEAR_FEATURE:
- case USB_REQUEST_SET_FEATURE:
- UsbSendStall();
- break;
- case USB_REQUEST_SET_DESCRIPTOR:
- case USB_REQUEST_SYNC_FRAME:
- default:
- break;
- }
-}
-
-void UsbSendPacket(uint8_t *packet, int len)
-{
- int i, thisTime;
-
- while(len > 0) {
- thisTime = min(len, 8);
-
- for(i = 0; i < thisTime; i++) {
- AT91C_BASE_UDP->UDP_FDR[2] = packet[i];
- }
- AT91C_BASE_UDP->UDP_CSR[2] |= AT91C_UDP_TXPKTRDY;
-
- while(!(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP)) {
- WDT_HIT();
- }
-
- AT91C_BASE_UDP->UDP_CSR[2] &= ~AT91C_UDP_TXCOMP;
-
- while(AT91C_BASE_UDP->UDP_CSR[2] & AT91C_UDP_TXCOMP) {
- WDT_HIT();
- }
-
- len -= thisTime;
- packet += thisTime;
- }
-}
-
-static void HandleRxdData(void)
-{
- int i, len;
-
- if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
- len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
-
- for(i = 0; i < len; i++) {
- UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
- UsbSoFarCount++;
- }
-
- AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK0;
- while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK0) {
- WDT_HIT();
- }
-
- if(UsbSoFarCount >= 64) {
- UsbPacketReceived(UsbBuffer, UsbSoFarCount);
- UsbSoFarCount = 0;
- }
- }
-
- if(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
- len = UDP_CSR_BYTES_RECEIVED(AT91C_BASE_UDP->UDP_CSR[1]);
-
- for(i = 0; i < len; i++) {
- UsbBuffer[UsbSoFarCount] = AT91C_BASE_UDP->UDP_FDR[1];
- UsbSoFarCount++;
- }
-
- AT91C_BASE_UDP->UDP_CSR[1] &= ~AT91C_UDP_RX_DATA_BK1;
- while(AT91C_BASE_UDP->UDP_CSR[1] & AT91C_UDP_RX_DATA_BK1) {
- WDT_HIT();
- }
-
- if(UsbSoFarCount >= 64) {
- UsbPacketReceived(UsbBuffer, UsbSoFarCount);
- UsbSoFarCount = 0;
- }
- }
-
- WDT_HIT();
-}
-
-void UsbStart(void)
-{
- volatile int i;
-
- UsbSoFarCount = 0;
-
- USB_D_PLUS_PULLUP_OFF();
-
- for(i = 0; i < 1000000; i++)
- ;
-
- USB_D_PLUS_PULLUP_ON();
-
- if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
- AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
- }
-}
-
-int UsbConnected()
-{
- if (AT91C_BASE_UDP->UDP_GLBSTATE & AT91C_UDP_CONFG)
- return TRUE;
- else
- return FALSE;
-}
-
-int UsbPoll(int blinkLeds)
-{
- int ret = FALSE;
-
- if(AT91C_BASE_UDP->UDP_ISR & AT91C_UDP_ENDBUSRES) {
- AT91C_BASE_UDP->UDP_ICR = AT91C_UDP_ENDBUSRES;
-
- // following a reset we should be ready to receive a setup packet
- AT91C_BASE_UDP->UDP_RSTEP = 0xf;
- AT91C_BASE_UDP->UDP_RSTEP = 0;
-
- AT91C_BASE_UDP->UDP_FADDR = AT91C_UDP_FEN;
-
- AT91C_BASE_UDP->UDP_CSR[0] = AT91C_UDP_EPTYPE_CTRL | AT91C_UDP_EPEDS;
-
- CurrentConfiguration = 0;
-
- ret = TRUE;
- }
-
- if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(0)) {
- if(AT91C_BASE_UDP->UDP_CSR[0] & AT91C_UDP_RXSETUP) {
- HandleRxdSetupData();
- ret = TRUE;
- }
- }
-
- if(AT91C_BASE_UDP->UDP_ISR & UDP_INTERRUPT_ENDPOINT(1)) {
- HandleRxdData();
- ret = TRUE;
- }
-
- return ret;
-}
//#define PACKED __attribute__((__packed__))
-#define USB_D_PLUS_PULLUP_ON() { \
- HIGH(GPIO_USB_PU); \
- AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; \
- }
-#define USB_D_PLUS_PULLUP_OFF() AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU
-
#define LED_A_ON() HIGH(GPIO_LED_A)
#define LED_A_OFF() LOW(GPIO_LED_A)
#define LED_A_INV() INVBIT(GPIO_LED_A)
#define RELAY_ON() HIGH(GPIO_RELAY)
#define RELAY_OFF() LOW(GPIO_RELAY)
#define BUTTON_PRESS() !(AT91C_BASE_PIOA->PIO_PDSR & GPIO_BUTTON)
-//--------------------------------
-// USB declarations
-
-void UsbSendPacket(uint8_t *packet, int len);
-int UsbConnected();
-int UsbPoll(int blinkLeds);
-void UsbStart(void);
-
-// This function is provided by the apps/bootrom, and called from UsbPoll
-// if data are available.
-void UsbPacketReceived(uint8_t *packet, int len);
#define VERSION_INFORMATION_MAGIC 0x56334d50
struct version_information {