From: roel@libnfc.org Date: Thu, 28 Feb 2013 15:11:52 +0000 (+0000) Subject: Finally, rewrote bootrom and flasher program, much faster now X-Git-Tag: v1.0.0~130^2~14 X-Git-Url: http://git.zerfleddert.de/cgi-bin/gitweb.cgi/proxmark3-svn/commitdiff_plain/28fdb04fd8d62e46c36f959b373d662f1a146448 Finally, rewrote bootrom and flasher program, much faster now --- diff --git a/armsrc/Makefile b/armsrc/Makefile index 47d56a2e..2e5350bb 100644 --- a/armsrc/Makefile +++ b/armsrc/Makefile @@ -10,7 +10,7 @@ APP_INCLUDES = apps.h #remove one of the following defines and comment out the relevant line #in the next section to remove that particular feature from compilation -APP_CFLAGS = -O2 -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG +APP_CFLAGS = -DWITH_LF -DWITH_ISO15693 -DWITH_ISO14443a -DWITH_ISO14443b -DWITH_ICLASS -DWITH_LEGICRF -DWITH_HITAG #-DWITH_LCD #SRC_LCD = fonts.c LCD.c diff --git a/armsrc/appmain.c b/armsrc/appmain.c index bdd04757..2bd8caea 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -955,7 +955,7 @@ void __attribute__((noreturn)) AppMain(void) LED_B_OFF(); LED_A_OFF(); - // Init USB device + // Init USB device` usb_enable(); // UsbStart(); diff --git a/armsrc/cmd.c b/armsrc/cmd.c deleted file mode 100644 index ff5c4f81..00000000 --- a/armsrc/cmd.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Proxmark send and receive commands - * - * Copyright (c) 2012, Roel Verdult - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @file cmd.c - * @brief - */ - -#include "cmd.h" -#include "string.h" -#include "util.h" -#include "proxmark3.h" - -//static UsbCommand txcmd; - -bool cmd_receive(UsbCommand* cmd) { - - // Check if there is a usb packet available - if (!usb_poll()) return false; - - // Try to retrieve the available command frame - size_t rxlen = usb_read((byte_t*)cmd,sizeof(UsbCommand)); - - // Check if the transfer was complete - if (rxlen != sizeof(UsbCommand)) return false; - - // Received command successfully - return true; -} - -bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) { - UsbCommand txcmd; - - // Compose the outgoing command frame - txcmd.cmd = cmd; - txcmd.arg[0] = arg0; - txcmd.arg[1] = arg1; - txcmd.arg[2] = arg2; - - // Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE - if (data && len) { - memcpy(txcmd.d.asBytes,(byte_t*)data,MIN(len,USB_CMD_DATA_SIZE)); - } - - // Send frame and make sure all bytes are transmitted - if (usb_write((byte_t*)&txcmd,sizeof(UsbCommand)) != 0) return false; - - return true; -} - - diff --git a/armsrc/cmd.h b/armsrc/cmd.h deleted file mode 100644 index b330a219..00000000 --- a/armsrc/cmd.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Proxmark send and receive commands - * - * Copyright (c) 2010, Roel Verdult - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * @file cmd.h - * @brief - */ - -#ifndef _PROXMARK_CMD_H_ -#define _PROXMARK_CMD_H_ - -#include -#include -#include "usb_cdc.h" - -bool cmd_receive(UsbCommand* cmd); -bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len); - -#endif // _PROXMARK_CMD_H_ - diff --git a/armsrc/usb_cdc.c b/armsrc/usb_cdc.c deleted file mode 100644 index fa1f849e..00000000 --- a/armsrc/usb_cdc.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - * at91sam7s USB CDC device implementation - * - * Copyright (c) 2012, Roel Verdult - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * based on the "Basic USB Example" from ATMEL (doc6123.pdf) - * - * @file usb_cdc.c - * @brief - */ - -#include "usb_cdc.h" -#include "util.h" -#include "config_gpio.h" - -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) -#define AT91C_EP_IN_SIZE 0x40 -#define AT91C_EP_OUT 1 -#define AT91C_EP_OUT_SIZE 0x40 -#define AT91C_EP_IN 2 - -const char devDescriptor[] = { - /* Device descriptor */ - 0x12, // bLength - 0x01, // bDescriptorType - 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10) - 0x02, // bDeviceClass: CDC class code - 0x00, // bDeviceSubclass: CDC class sub code - 0x00, // bDeviceProtocol: CDC Device protocol - 0x08, // bMaxPacketSize0 - 0x2d,0x2d, // Vendor ID (--) - 0x4d,0x50, // Product ID (PM), transmitted in reverse - 0x01,0x00, // Device release number (0001) - 0x01, // iManufacturer // 0x01 - 0x00, // iProduct - 0x00, // SerialNumber - 0x01 // bNumConfigs -}; - -const char cfgDescriptor[] = { - /* ============== CONFIGURATION 1 =========== */ - /* Configuration 1 descriptor */ - 0x09, // CbLength - 0x02, // CbDescriptorType - 0x43, // CwTotalLength 2 EP + Control - 0x00, - 0x02, // CbNumInterfaces - 0x01, // CbConfigurationValue - 0x00, // CiConfiguration - 0xC0, // CbmAttributes 0xA0 - 0x00, // CMaxPower - - /* Communication Class Interface Descriptor Requirement */ - 0x09, // bLength - 0x04, // bDescriptorType - 0x00, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x01, // bNumEndpoints - 0x02, // bInterfaceClass - 0x02, // bInterfaceSubclass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - /* Header Functional Descriptor */ - 0x05, // bFunction Length - 0x24, // bDescriptor type: CS_INTERFACE - 0x00, // bDescriptor subtype: Header Func Desc - 0x10, // bcdCDC:1.1 - 0x01, - - /* ACM Functional Descriptor */ - 0x04, // bFunctionLength - 0x24, // bDescriptor Type: CS_INTERFACE - 0x02, // bDescriptor Subtype: ACM Func Desc - 0x00, // bmCapabilities - - /* Union Functional Descriptor */ - 0x05, // bFunctionLength - 0x24, // bDescriptorType: CS_INTERFACE - 0x06, // bDescriptor Subtype: Union Func Desc - 0x00, // bMasterInterface: Communication Class Interface - 0x01, // bSlaveInterface0: Data Class Interface - - /* Call Management Functional Descriptor */ - 0x05, // bFunctionLength - 0x24, // bDescriptor Type: CS_INTERFACE - 0x01, // bDescriptor Subtype: Call Management Func Desc - 0x00, // bmCapabilities: D1 + D0 - 0x01, // bDataInterface: Data Class Interface 1 - - /* Endpoint 1 descriptor */ - 0x07, // bLength - 0x05, // bDescriptorType - 0x83, // bEndpointAddress, Endpoint 03 - IN - 0x03, // bmAttributes INT - 0x08, // wMaxPacketSize - 0x00, - 0xFF, // bInterval - - /* Data Class Interface Descriptor Requirement */ - 0x09, // bLength - 0x04, // bDescriptorType - 0x01, // bInterfaceNumber - 0x00, // bAlternateSetting - 0x02, // bNumEndpoints - 0x0A, // bInterfaceClass - 0x00, // bInterfaceSubclass - 0x00, // bInterfaceProtocol - 0x00, // iInterface - - /* First alternate setting */ - /* Endpoint 1 descriptor */ - 0x07, // bLength - 0x05, // bDescriptorType - 0x01, // bEndpointAddress, Endpoint 01 - OUT - 0x02, // bmAttributes BULK - AT91C_EP_OUT_SIZE, // wMaxPacketSize - 0x00, - 0x00, // bInterval - - /* Endpoint 2 descriptor */ - 0x07, // bLength - 0x05, // bDescriptorType - 0x82, // bEndpointAddress, Endpoint 02 - IN - 0x02, // bmAttributes BULK - AT91C_EP_IN_SIZE, // wMaxPacketSize - 0x00, - 0x00 // bInterval -}; - -const char strDescriptor[] = { - 26, // Length - 0x03, // Type is string - 'p', 0x00, - 'r', 0x00, - 'o', 0x00, - 'x', 0x00, - 'm', 0x00, - 'a', 0x00, - 'r', 0x00, - 'k', 0x00, - '.', 0x00, - 'o', 0x00, - 'r', 0x00, - 'g', 0x00, -}; - - -/* 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 { - unsigned int dwDTERRate; - char bCharFormat; - char bParityType; - char bDataBits; -} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING; - -AT91S_CDC_LINE_CODING line = { - 115200, // baudrate - 0, // 1 Stop Bit - 0, // None Parity - 8}; // 8 Data bits - -void AT91F_CDC_Enumerate(); - -AT91PS_UDP pUdp = AT91C_BASE_UDP; -byte_t btConfiguration = 0; -byte_t btConnection = 0; -byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; - -//*---------------------------------------------------------------------------- -//* \fn usb_disable -//* \brief This function deactivates the USB device -//*---------------------------------------------------------------------------- -void usb_disable() { - // Disconnect the USB device - AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU; - SpinDelay(100); - - // Clear all lingering interrupts - if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) { - pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES; - } -} - -//*---------------------------------------------------------------------------- -//* \fn usb_enable -//* \brief This function Activates the USB device -//*---------------------------------------------------------------------------- -void usb_enable() { - // Set the PLL USB Divider - AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ; - - // Specific Chip USB Initialisation - // 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); - - // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO - // Set in PIO mode and Configure in Output - AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode - AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output - - // Clear for set the Pullup resistor - AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU; - - // Disconnect and reconnect USB controller for 100ms - usb_disable(); - - // Wait for a short while - SpinDelay(100); - - // Reconnect USB reconnect - AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU; - AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; -} - -//*---------------------------------------------------------------------------- -//* \fn usb_check -//* \brief Test if the device is configured and handle enumeration -//*---------------------------------------------------------------------------- -bool usb_check() { - AT91_REG isr = pUdp->UDP_ISR; - - if (isr & AT91C_UDP_ENDBUSRES) { - pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES; - // reset all endpoints - pUdp->UDP_RSTEP = (unsigned int)-1; - pUdp->UDP_RSTEP = 0; - // Enable the function - pUdp->UDP_FADDR = AT91C_UDP_FEN; - // Configure endpoint 0 - pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL); - } - else if (isr & AT91C_UDP_EPINT0) { - pUdp->UDP_ICR = AT91C_UDP_EPINT0; - AT91F_CDC_Enumerate(); - } - return (btConfiguration) ? true : false; -} - - -bool usb_poll() -{ - if (!usb_check()) return false; - return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank); -} - -//*---------------------------------------------------------------------------- -//* \fn usb_read -//* \brief Read available data from Endpoint OUT -//*---------------------------------------------------------------------------- -uint32_t usb_read(byte_t* data, size_t len) { - byte_t bank = btReceiveBank; - uint32_t packetSize, nbBytesRcv = 0; - uint32_t time_out = 0; - - while (len) - { - if (!usb_check()) break; - - if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) { - packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len); - len -= packetSize; - while(packetSize--) - data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT]; - pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank); - if (bank == AT91C_UDP_RX_DATA_BK0) - { - bank = AT91C_UDP_RX_DATA_BK1; - } else { - bank = AT91C_UDP_RX_DATA_BK0; - } - } - if (time_out++ == 0x1fff) break; - } - - btReceiveBank = bank; - return nbBytesRcv; -} - -//*---------------------------------------------------------------------------- -//* \fn usb_write -//* \brief Send through endpoint 2 -//*---------------------------------------------------------------------------- -uint32_t usb_write(const byte_t* data, const size_t len) { - size_t length = len; - uint32_t cpt = 0; - - if (!length) return 0; - if (!usb_check()) return 0; - - // Send the first packet - cpt = MIN(length, AT91C_EP_IN_SIZE-1); - length -= cpt; - while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++; - pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; - - while (length) { - // Fill the second bank - cpt = MIN(length, AT91C_EP_IN_SIZE-1); - length -= cpt; - while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++; - // Wait for the the first bank to be sent - while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) { - if (!usb_check()) return length; - } - pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); - pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; - } - - // Wait for the end of transfer - while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) { - if (!usb_check()) return length; - } - - pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); - - return length; -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_USB_SendData -//* \brief Send Data through the control endpoint -//*---------------------------------------------------------------------------- -unsigned int csrTab[100]; -unsigned char csrIdx = 0; - -static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { - uint32_t cpt = 0; - AT91_REG csr; - - do { - cpt = MIN(length, 8); - length -= cpt; - - while (cpt--) - pUdp->UDP_FDR[0] = *pData++; - - if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) { - pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP); - } - - pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; - do { - csr = pUdp->UDP_CSR[0]; - - // Data IN stage has been stopped by a status OUT - if (csr & AT91C_UDP_RX_DATA_BK0) { - pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0); - return; - } - } while ( !(csr & AT91C_UDP_TXCOMP) ); - - } while (length); - - if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) { - pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP); - } -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_USB_SendZlp -//* \brief Send zero length packet through the control endpoint -//*---------------------------------------------------------------------------- -void AT91F_USB_SendZlp(AT91PS_UDP pUdp) { - pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; - while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ); - pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP); - while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP); -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_USB_SendStall -//* \brief Stall the control endpoint -//*---------------------------------------------------------------------------- -void AT91F_USB_SendStall(AT91PS_UDP pUdp) { - pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL; - while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) ); - pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR); - while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); -} - -//*---------------------------------------------------------------------------- -//* \fn AT91F_CDC_Enumerate -//* \brief This function is a callback invoked when a SETUP packet is received -//*---------------------------------------------------------------------------- -void AT91F_CDC_Enumerate() { - byte_t bmRequestType, bRequest; - uint16_t wValue, wIndex, wLength, wStatus; - - if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) ) - return; - - bmRequestType = pUdp->UDP_FDR[0]; - bRequest = pUdp->UDP_FDR[0]; - wValue = (pUdp->UDP_FDR[0] & 0xFF); - wValue |= (pUdp->UDP_FDR[0] << 8); - wIndex = (pUdp->UDP_FDR[0] & 0xFF); - wIndex |= (pUdp->UDP_FDR[0] << 8); - wLength = (pUdp->UDP_FDR[0] & 0xFF); - wLength |= (pUdp->UDP_FDR[0] << 8); - - if (bmRequestType & 0x80) { - pUdp->UDP_CSR[0] |= AT91C_UDP_DIR; - while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) ); - } - pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP; - while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) ); - - // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 - switch ((bRequest << 8) | bmRequestType) { - case STD_GET_DESCRIPTOR: - if (wValue == 0x100) // Return Device Descriptor - AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength)); - else if (wValue == 0x200) // Return Configuration Descriptor - AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength)); - else if ((wValue & 0x300) == 0x300) // Return String Descriptor - AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength)); - else - AT91F_USB_SendStall(pUdp); - break; - case STD_SET_ADDRESS: - AT91F_USB_SendZlp(pUdp); - pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue); - pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0; - break; - case STD_SET_CONFIGURATION: - btConfiguration = wValue; - AT91F_USB_SendZlp(pUdp); - 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; - pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0; - break; - case STD_GET_CONFIGURATION: - AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration)); - break; - case STD_GET_STATUS_ZERO: - wStatus = 0; - AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); - break; - case STD_GET_STATUS_INTERFACE: - wStatus = 0; - AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); - break; - case STD_GET_STATUS_ENDPOINT: - wStatus = 0; - wIndex &= 0x0F; - if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) { - wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; - AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); - } - else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) { - wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; - AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); - } - else - AT91F_USB_SendStall(pUdp); - break; - case STD_SET_FEATURE_ZERO: - AT91F_USB_SendStall(pUdp); - break; - case STD_SET_FEATURE_INTERFACE: - AT91F_USB_SendZlp(pUdp); - break; - case STD_SET_FEATURE_ENDPOINT: - wIndex &= 0x0F; - if ((wValue == 0) && wIndex && (wIndex <= 3)) { - pUdp->UDP_CSR[wIndex] = 0; - AT91F_USB_SendZlp(pUdp); - } - else - AT91F_USB_SendStall(pUdp); - break; - case STD_CLEAR_FEATURE_ZERO: - AT91F_USB_SendStall(pUdp); - break; - case STD_CLEAR_FEATURE_INTERFACE: - AT91F_USB_SendZlp(pUdp); - break; - case STD_CLEAR_FEATURE_ENDPOINT: - wIndex &= 0x0F; - if ((wValue == 0) && wIndex && (wIndex <= 3)) { - if (wIndex == 1) - pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT); - else if (wIndex == 2) - pUdp->UDP_CSR[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); - AT91F_USB_SendZlp(pUdp); - } - else - AT91F_USB_SendStall(pUdp); - break; - - // handle CDC class requests - case SET_LINE_CODING: - while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) ); - pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0); - AT91F_USB_SendZlp(pUdp); - break; - case GET_LINE_CODING: - AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength)); - break; - case SET_CONTROL_LINE_STATE: - btConnection = wValue; - AT91F_USB_SendZlp(pUdp); - break; - default: - AT91F_USB_SendStall(pUdp); - break; - } -} diff --git a/armsrc/usb_cdc.h b/armsrc/usb_cdc.h deleted file mode 100644 index d7b9c2e5..00000000 --- a/armsrc/usb_cdc.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * at91sam7s USB CDC device implementation - * - * Copyright (c) 2012, Roel Verdult - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holders nor the - * names of its contributors may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * based on the "Basic USB Example" from ATMEL (doc6123.pdf) - * - * @file usb_cdc.c - * @brief - */ - -#ifndef _USB_CDC_H_ -#define _USB_CDC_H_ - -#include - -void usb_disable(); -void usb_enable(); -bool usb_check(); -bool usb_poll(); -uint32_t usb_read(byte_t* data, size_t len); -uint32_t usb_write(const byte_t* data, const size_t len); - -#endif // _USB_CDC_H_ - diff --git a/armsrc/util.h b/armsrc/util.h index b68c511c..d2a85ba0 100644 --- a/armsrc/util.h +++ b/armsrc/util.h @@ -15,10 +15,7 @@ #include #define RAMFUNC __attribute((long_call, section(".ramfunc"))) - #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff ) -#define MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) #define LED_RED 1 #define LED_ORANGE 2 diff --git a/bootrom/Makefile b/bootrom/Makefile index e2dc0dbd..92373995 100644 --- a/bootrom/Makefile +++ b/bootrom/Makefile @@ -8,15 +8,15 @@ # DO NOT use thumb mode in the phase 1 bootloader since that generates a section with glue code ARMSRC = -THUMBSRC = usb_hid.c bootrom.c +THUMBSRC = cmd.c usb_cdc.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 ## BootROM from ARM mode. The symbol is emitted, but the section will be filled with ## zeroes. As a temporary workaround, do not use thumb for the phase 2 bootloader ## -- Henryk Plötz 2009-09-01 -ARMSRC := $(ARMSRC) $(THUMBSRC) -THUMBSRC := +# ARMSRC := $(ARMSRC) $(THUMBSRC) +# THUMBSRC := # stdint.h provided locally until GCC 4.5 becomes C99 compliant APP_CFLAGS = -I. diff --git a/bootrom/bootrom.c b/bootrom/bootrom.c index fc1c8a2c..afb49c3c 100644 --- a/bootrom/bootrom.c +++ b/bootrom/bootrom.c @@ -7,7 +7,17 @@ //----------------------------------------------------------------------------- #include -#include "usb_hid.h" +#include "usb_cdc.h" +#include "cmd.h" +//#include "usb_hid.h" + +void DbpString(char *str) { + byte_t len = 0; + while (str[len] != 0x00) { + len++; + } + cmd_send(CMD_DEBUG_PRINT_STRING,len,0,0,(byte_t*)str,len); +} struct common_area common_area __attribute__((section(".commonarea"))); unsigned int start_addr, end_addr, bootrom_unlocked; @@ -76,110 +86,130 @@ static void ConfigClocks(void) static void Fatal(void) { - for(;;); + LED_D_OFF(); + LED_C_OFF(); + LED_B_OFF(); + LED_A_OFF(); + for(;;); } -void UsbPacketReceived(uint8_t *packet, int len) -{ - int i, dont_ack=0; - UsbCommand *c = (UsbCommand *)packet; - volatile uint32_t *p; - - if(len != sizeof(*c)) { - Fatal(); - } - - switch(c->cmd) { - case CMD_DEVICE_INFO: - dont_ack = 1; - c->cmd = CMD_DEVICE_INFO; - c->arg[0] = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | - DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH; - if(common_area.flags.osimage_present) c->arg[0] |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT; - UsbSendPacket(packet, len); - break; - - case CMD_SETUP_WRITE: - /* The temporary write buffer of the embedded flash controller is mapped to the - * whole memory region, only the last 8 bits are decoded. - */ - p = (volatile uint32_t *)&_flash_start; - for(i = 0; i < 12; i++) { - p[i+c->arg[0]] = c->d.asDwords[i]; - } - break; - - case CMD_FINISH_WRITE: - p = (volatile uint32_t *)&_flash_start; - for(i = 0; i < 4; i++) { - p[i+60] = c->d.asDwords[i]; - } - - /* Check that the address that we are supposed to write to is within our allowed region */ - if( ((c->arg[0]+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (c->arg[0] < start_addr) ) { - /* Disallow write */ - dont_ack = 1; - c->cmd = CMD_NACK; - UsbSendPacket(packet, len); - } else { - /* Translate address to flash page and do flash, update here for the 512k part */ - AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY | - MC_FLASH_COMMAND_PAGEN((c->arg[0]-(int)&_flash_start)/AT91C_IFLASH_PAGE_SIZE) | - AT91C_MC_FCMD_START_PROG; - } - - uint32_t sr; - - while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY)) - ; - if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) { - dont_ack = 1; - c->cmd = CMD_NACK; - UsbSendPacket(packet, len); - } - break; - - case CMD_HARDWARE_RESET: - USB_D_PLUS_PULLUP_OFF(); - AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; - break; - - case CMD_START_FLASH: - if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1; - else bootrom_unlocked = 0; - { - int prot_start = (int)&_bootrom_start; - int prot_end = (int)&_bootrom_end; - int allow_start = (int)&_flash_start; - int allow_end = (int)&_flash_end; - int cmd_start = c->arg[0]; - int cmd_end = c->arg[1]; - - /* Only allow command if the bootrom is unlocked, or the parameters are outside of the protected - * bootrom area. In any case they must be within the flash area. - */ - if( (bootrom_unlocked || ((cmd_start >= prot_end) || (cmd_end < prot_start))) - && (cmd_start >= allow_start) && (cmd_end <= allow_end) ) { - start_addr = cmd_start; - end_addr = cmd_end; - } else { - start_addr = end_addr = 0; - dont_ack = 1; - c->cmd = CMD_NACK; - UsbSendPacket(packet, len); - } - } - break; - - default: - Fatal(); - break; - } - - if(!dont_ack) { - c->cmd = CMD_ACK; - UsbSendPacket(packet, len); - } +void UsbPacketReceived(uint8_t *packet, int len) { + int i, dont_ack=0; + UsbCommand* c = (UsbCommand *)packet; + volatile uint32_t *p; + + if(len != sizeof(UsbCommand)) { + Fatal(); + } + + uint32_t arg0 = (uint32_t)c->arg[0]; + + switch(c->cmd) { + case CMD_DEVICE_INFO: { + dont_ack = 1; +// c->cmd = CMD_DEVICE_INFO; + arg0 = DEVICE_INFO_FLAG_BOOTROM_PRESENT | DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM | + DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH; + if(common_area.flags.osimage_present) { + arg0 |= DEVICE_INFO_FLAG_OSIMAGE_PRESENT; + } +// UsbSendPacket(packet, len); + cmd_send(CMD_DEVICE_INFO,arg0,1,2,0,0); + } break; + + case CMD_SETUP_WRITE: { + /* The temporary write buffer of the embedded flash controller is mapped to the + * whole memory region, only the last 8 bits are decoded. + */ + p = (volatile uint32_t *)&_flash_start; + for(i = 0; i < 12; i++) { + p[i+arg0] = c->d.asDwords[i]; + } + } break; + + case CMD_FINISH_WRITE: { + uint32_t* flash_mem = (uint32_t*)(&_flash_start); +// p = (volatile uint32_t *)&_flash_start; + for (size_t j=0; j<2; j++) { + for(i = 0+(64*j); i < 64+(64*j); i++) { + //p[i+60] = c->d.asDwords[i]; + flash_mem[i] = c->d.asDwords[i]; + } + + uint32_t flash_address = arg0 + (0x100*j); + + /* Check that the address that we are supposed to write to is within our allowed region */ + if( ((flash_address+AT91C_IFLASH_PAGE_SIZE-1) >= end_addr) || (flash_address < start_addr) ) { + /* Disallow write */ + dont_ack = 1; + // c->cmd = CMD_NACK; + // UsbSendPacket(packet, len); + cmd_send(CMD_NACK,0,0,0,0,0); + } else { + uint32_t page_n = (flash_address - ((uint32_t)flash_mem)) / AT91C_IFLASH_PAGE_SIZE; + /* Translate address to flash page and do flash, update here for the 512k part */ + AT91C_BASE_EFC0->EFC_FCR = MC_FLASH_COMMAND_KEY | + MC_FLASH_COMMAND_PAGEN(page_n) | + AT91C_MC_FCMD_START_PROG; + // arg0 = (address - ((uint32_t)flash_s)); + } + + // Wait until flashing of page finishes + uint32_t sr; + while(!((sr = AT91C_BASE_EFC0->EFC_FSR) & AT91C_MC_FRDY)); + if(sr & (AT91C_MC_LOCKE | AT91C_MC_PROGE)) { + dont_ack = 1; + // c->cmd = CMD_NACK; + cmd_send(CMD_NACK,0,0,0,0,0); + // UsbSendPacket(packet, len); + } + } + } break; + + case CMD_HARDWARE_RESET: { +// USB_D_PLUS_PULLUP_OFF(); + usb_disable(); + AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; + } break; + + case CMD_START_FLASH: { + if(c->arg[2] == START_FLASH_MAGIC) bootrom_unlocked = 1; + else bootrom_unlocked = 0; + { + int prot_start = (int)&_bootrom_start; + int prot_end = (int)&_bootrom_end; + int allow_start = (int)&_flash_start; + int allow_end = (int)&_flash_end; + int cmd_start = c->arg[0]; + int cmd_end = c->arg[1]; + + /* Only allow command if the bootrom is unlocked, or the parameters are outside of the protected + * bootrom area. In any case they must be within the flash area. + */ + if( (bootrom_unlocked || ((cmd_start >= prot_end) || (cmd_end < prot_start))) + && (cmd_start >= allow_start) && (cmd_end <= allow_end) ) { + start_addr = cmd_start; + end_addr = cmd_end; + } else { + start_addr = end_addr = 0; + dont_ack = 1; +// c->cmd = CMD_NACK; +// UsbSendPacket(packet, len); + cmd_send(CMD_NACK,0,0,0,0,0); + } + } + } break; + + default: { + Fatal(); + } break; + } + + if(!dont_ack) { +// c->cmd = CMD_ACK; +// UsbSendPacket(packet, len); + cmd_send(CMD_ACK,arg0,0,0,0,0); + } } static void flash_mode(int externally_entered) @@ -187,16 +217,34 @@ static void flash_mode(int externally_entered) start_addr = 0; end_addr = 0; bootrom_unlocked = 0; + byte_t rx[sizeof(UsbCommand)]; + size_t rx_len; + + usb_enable(); + for (volatile size_t i=0; i<0x100000; i++); + LED_D_ON(); + LED_C_ON(); + LED_B_ON(); + LED_A_ON(); - UsbStart(); +// UsbStart(); for(;;) { WDT_HIT(); - UsbPoll(TRUE); + if (usb_poll()) { + rx_len = usb_read(rx,sizeof(UsbCommand)); + if (rx_len) { +// DbpString("starting to flash"); + UsbPacketReceived(rx,rx_len); + } + } + +// UsbPoll(TRUE); if(!externally_entered && !BUTTON_PRESS()) { /* Perform a reset to leave flash mode */ - USB_D_PLUS_PULLUP_OFF(); +// USB_D_PLUS_PULLUP_OFF(); + usb_disable(); LED_B_ON(); AT91C_BASE_RSTC->RSTC_RCR = RST_CONTROL_KEY | AT91C_RSTC_PROCRST; for(;;); @@ -208,7 +256,7 @@ static void flash_mode(int externally_entered) } } -extern char _osimage_entry; +extern uint32_t _osimage_entry; void BootROM(void) { //------------ @@ -252,7 +300,8 @@ void BootROM(void) GPIO_LED_C | GPIO_LED_D; - USB_D_PLUS_PULLUP_OFF(); +// USB_D_PLUS_PULLUP_OFF(); + usb_disable(); LED_D_OFF(); LED_C_ON(); LED_B_OFF(); @@ -297,7 +346,7 @@ void BootROM(void) flash_mode(1); } else if(BUTTON_PRESS()) { flash_mode(0); - } else if(*(uint32_t*)&_osimage_entry == 0xffffffffU) { + } else if(_osimage_entry == 0xffffffffU) { flash_mode(1); } else { // jump to Flash address of the osimage entry point (LSBit set for thumb mode) diff --git a/bootrom/stdint.h b/bootrom/stdint.h deleted file mode 100644 index 78a0b051..00000000 --- a/bootrom/stdint.h +++ /dev/null @@ -1,27 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2010 Hector Martin "marcan" -// -// 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. -//----------------------------------------------------------------------------- -// Replacement stdint.h because GCC doesn't come with it yet (C99) -//----------------------------------------------------------------------------- - -#ifndef __STDINT_H -#define __STDINT_H - -typedef signed char int8_t; -typedef short int int16_t; -typedef int int32_t; -typedef long long int int64_t; - -typedef unsigned char uint8_t; -typedef unsigned short int uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long long int uint64_t; - -typedef int intptr_t; -typedef unsigned int uintptr_t; - -#endif /* __STDINT_H */ diff --git a/bootrom/usb_hid.c b/bootrom/usb_hid.c deleted file mode 100644 index 189b4092..00000000 --- a/bootrom/usb_hid.c +++ /dev/null @@ -1,524 +0,0 @@ -//----------------------------------------------------------------------------- -// 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; -} diff --git a/bootrom/usb_hid.h b/bootrom/usb_hid.h deleted file mode 100644 index bbc6cec9..00000000 --- a/bootrom/usb_hid.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef _USB_HID_H_ -#define _USB_HID_H_ - -#include -#include - -//-------------------------------- -// USB defines - -#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 - -//-------------------------------- -// 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); - -#endif // _USB_HID_H_ - diff --git a/client/Makefile b/client/Makefile index 364070e8..4ab1b806 100644 --- a/client/Makefile +++ b/client/Makefile @@ -14,7 +14,7 @@ OBJDIR = obj LDLIBS = -L/opt/local/lib -L/usr/local/lib -lusb -lreadline -lpthread LDFLAGS = $(COMMON_FLAGS) -CFLAGS = -std=gnu99 -I. -I../include -I../common -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS) -g -O3 +CFLAGS = -std=c99 -I. -I../include -I../common -I/opt/local/include -Wall -Wno-unused-function $(COMMON_FLAGS) -g -O4 ifneq (,$(findstring MINGW,$(platform))) CXXFLAGS = -I$(QTDIR)/include -I$(QTDIR)/include/QtCore -I$(QTDIR)/include/QtGui @@ -30,7 +30,7 @@ CXXFLAGS = -I/Library/Frameworks/QtGui.framework/Versions/Current/Headers -I/Lib QTLDLIBS = -framework QtGui -framework QtCore MOC = moc else -CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O3 +CXXFLAGS = $(shell pkg-config --cflags QtCore QtGui 2>/dev/null) -Wall -O4 QTLDLIBS = $(shell pkg-config --libs QtCore QtGui 2>/dev/null) MOC = $(shell pkg-config --variable=moc_location QtCore) endif @@ -67,14 +67,15 @@ CMDSRCS = \ cmdhfmf.c \ cmdhw.c \ cmdlf.c \ - cmdlfem4x.c \ cmdlfhid.c \ + cmdlfem4x.c \ cmdlfhitag.c \ cmdlfti.c \ cmdparser.c \ cmdmain.c \ uart.c + CMDOBJS = $(CMDSRCS:%.c=$(OBJDIR)/%.o) RM = rm -f @@ -87,16 +88,16 @@ all-static: LDLIBS:=-static $(LDLIBS) all-static: snooper cli flasher proxmark3: LDLIBS+=$(QTLDLIBS) -proxmark3: $(OBJDIR)/proxmark3.o $(CMDOBJS) $(OBJDIR)/proxusb.o $(QTGUI) +proxmark3: $(OBJDIR)/proxmark3.o $(CMDOBJS) $(OBJDIR)/uart.o $(QTGUI) $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@ -snooper: $(OBJDIR)/snooper.o $(CMDOBJS) $(OBJDIR)/proxusb.o $(OBJDIR)/guidummy.o +snooper: $(OBJDIR)/snooper.o $(CMDOBJS) $(OBJDIR)/uart.o $(OBJDIR)/guidummy.o $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@ -cli: $(OBJDIR)/cli.o $(CMDOBJS) $(OBJDIR)/proxusb.o $(OBJDIR)/guidummy.o +cli: $(OBJDIR)/cli.o $(CMDOBJS) $(OBJDIR)/uart.o $(OBJDIR)/guidummy.o $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@ -flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/proxusb.o +flasher: $(OBJDIR)/flash.o $(OBJDIR)/flasher.o $(OBJDIR)/uart.o $(CXX) $(CXXFLAGS) $^ $(LDLIBS) -o $@ $(OBJDIR)/%.o: %.c diff --git a/client/cmddata.c b/client/cmddata.c index 1c58c69b..6c2c7841 100644 --- a/client/cmddata.c +++ b/client/cmddata.c @@ -12,7 +12,7 @@ #include #include #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "ui.h" diff --git a/client/cmdhf.c b/client/cmdhf.c index cfbd9e16..d955fc83 100644 --- a/client/cmdhf.c +++ b/client/cmdhf.c @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "graph.h" #include "ui.h" diff --git a/client/cmdhf14a.c b/client/cmdhf14a.c index 79273040..ad89fe96 100644 --- a/client/cmdhf14a.c +++ b/client/cmdhf14a.c @@ -16,7 +16,7 @@ #include "util.h" #include "iso14443crc.h" #include "data.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" @@ -169,7 +169,6 @@ int CmdHF14AReader(const char *Cmd) WaitForResponse(CMD_ACK,&resp); iso14a_card_select_t *card = (iso14a_card_select_t *)resp.d.asBytes; - uint8_t * uid = card->uid; if(resp.arg[0] == 0) { PrintAndLog("iso14443a card select failed"); diff --git a/client/cmdhf14b.c b/client/cmdhf14b.c index 9b2fa753..f1238d22 100644 --- a/client/cmdhf14b.c +++ b/client/cmdhf14b.c @@ -14,7 +14,7 @@ #include #include #include "iso14443crc.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "graph.h" diff --git a/client/cmdhf15.c b/client/cmdhf15.c index e1e5e02a..ec898755 100644 --- a/client/cmdhf15.c +++ b/client/cmdhf15.c @@ -26,7 +26,7 @@ #include #include #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "graph.h" diff --git a/client/cmdhfepa.c b/client/cmdhfepa.c index 41f801e7..d9413cf3 100644 --- a/client/cmdhfepa.c +++ b/client/cmdhfepa.c @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- #include "util.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" diff --git a/client/cmdhficlass.c b/client/cmdhficlass.c index 944ec498..f807e972 100644 --- a/client/cmdhficlass.c +++ b/client/cmdhficlass.c @@ -14,7 +14,7 @@ #include #include "iso14443crc.h" // Can also be used for iClass, using 0xE012 as CRC-type #include "data.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" diff --git a/client/cmdhflegic.c b/client/cmdhflegic.c index 7a268e92..26a2c724 100644 --- a/client/cmdhflegic.c +++ b/client/cmdhflegic.c @@ -10,7 +10,7 @@ #include #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "ui.h" @@ -324,7 +324,7 @@ int CmdLegicRfSim(const char *Cmd) c.arg[0] = 6; c.arg[1] = 3; c.arg[2] = 0; - sscanf(Cmd, " %i %i %i", &c.arg[0], &c.arg[1], &c.arg[2]); + sscanf(Cmd, " %lli %lli %lli", &c.arg[0], &c.arg[1], &c.arg[2]); SendCommand(&c); return 0; } @@ -332,7 +332,7 @@ int CmdLegicRfSim(const char *Cmd) int CmdLegicRfWrite(const char *Cmd) { UsbCommand c={CMD_WRITER_LEGIC_RF}; - int res = sscanf(Cmd, " 0x%x 0x%x", &c.arg[0], &c.arg[1]); + int res = sscanf(Cmd, " 0x%llx 0x%llx", &c.arg[0], &c.arg[1]); if(res != 2) { PrintAndLog("Please specify the offset and length as two hex strings"); return -1; @@ -344,7 +344,7 @@ int CmdLegicRfWrite(const char *Cmd) int CmdLegicRfFill(const char *Cmd) { UsbCommand cmd ={CMD_WRITER_LEGIC_RF}; - int res = sscanf(Cmd, " 0x%x 0x%x 0x%x", &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]); + int res = sscanf(Cmd, " 0x%llx 0x%llx 0x%llx", &cmd.arg[0], &cmd.arg[1], &cmd.arg[2]); if(res != 3) { PrintAndLog("Please specify the offset, length and value as two hex strings"); return -1; diff --git a/client/cmdhfmf.h b/client/cmdhfmf.h index d7ee5a4b..65b789bf 100644 --- a/client/cmdhfmf.h +++ b/client/cmdhfmf.h @@ -18,7 +18,7 @@ #include "proxmark3.h" #include "iso14443crc.h" #include "data.h" -#include "proxusb.h" +//#include "proxusb.h" #include "ui.h" #include "cmdparser.h" #include "common.h" diff --git a/client/cmdhw.c b/client/cmdhw.c index 991cd532..cdeb48b8 100644 --- a/client/cmdhw.c +++ b/client/cmdhw.c @@ -13,7 +13,7 @@ #include #include #include "ui.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "cmdparser.h" #include "cmdhw.h" diff --git a/client/cmdlf.c b/client/cmdlf.c index 98a6c1f0..00f10088 100644 --- a/client/cmdlf.c +++ b/client/cmdlf.c @@ -12,7 +12,7 @@ #include #include #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "graph.h" @@ -36,7 +36,7 @@ int CmdLFCommandRead(const char *Cmd) dummy[0]= ' '; UsbCommand c = {CMD_MOD_THEN_ACQUIRE_RAW_ADC_SAMPLES_125K}; - sscanf(Cmd, "%i %i %i %s %s", &c.arg[0], &c.arg[1], &c.arg[2], (char *) &c.d.asBytes,(char *) &dummy+1); + sscanf(Cmd, "%lli %lli %lli %s %s", &c.arg[0], &c.arg[1], &c.arg[2], (char *) &c.d.asBytes,(char *) &dummy+1); // in case they specified 'h' strcpy((char *)&c.d.asBytes + strlen((char *)c.d.asBytes), dummy); SendCommand(&c); diff --git a/client/cmdlfem4x.c b/client/cmdlfem4x.c index 83ed673b..efbd4c48 100644 --- a/client/cmdlfem4x.c +++ b/client/cmdlfem4x.c @@ -11,7 +11,7 @@ #include #include #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "ui.h" #include "graph.h" diff --git a/client/cmdlfhid.c b/client/cmdlfhid.c index 93c351f1..d13856f4 100644 --- a/client/cmdlfhid.c +++ b/client/cmdlfhid.c @@ -9,7 +9,7 @@ //----------------------------------------------------------------------------- #include -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "ui.h" #include "graph.h" diff --git a/client/cmdlfhitag.c b/client/cmdlfhitag.c index 1ee88401..c648f6a5 100644 --- a/client/cmdlfhitag.c +++ b/client/cmdlfhitag.c @@ -12,7 +12,7 @@ #include #include #include "data.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "ui.h" #include "cmdparser.h" diff --git a/client/cmdlfti.c b/client/cmdlfti.c index 4e8b1150..5a88f579 100644 --- a/client/cmdlfti.c +++ b/client/cmdlfti.c @@ -11,7 +11,7 @@ #include #include #include "crc16.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "data.h" #include "ui.h" @@ -274,7 +274,7 @@ int CmdTIWrite(const char *Cmd) UsbCommand c = {CMD_WRITE_TI_TYPE}; int res = 0; - res = sscanf(Cmd, "0x%x 0x%x 0x%x ", &c.arg[0], &c.arg[1], &c.arg[2]); + res = sscanf(Cmd, "0x%llx 0x%llx 0x%llx ", &c.arg[0], &c.arg[1], &c.arg[2]); if (res == 2) c.arg[2]=0; if (res < 2) PrintAndLog("Please specify the data as two hex strings, optionally the CRC as a third"); diff --git a/client/data.c b/client/data.c index b6639867..51134d48 100644 --- a/client/data.c +++ b/client/data.c @@ -12,7 +12,7 @@ #include #include "data.h" #include "ui.h" -#include "proxusb.h" +//#include "proxusb.h" #include "proxmark3.h" #include "cmdmain.h" diff --git a/client/flash.c b/client/flash.c index 8fe874e5..4d091126 100644 --- a/client/flash.c +++ b/client/flash.c @@ -12,10 +12,16 @@ #include #include #include "sleep.h" -#include "proxusb.h" +//#include "proxusb.h" #include "flash.h" #include "elf.h" #include "proxendian.h" +#include "usb_cmd.h" + +void SendCommand(UsbCommand* txcmd); +void ReceiveCommand(UsbCommand* rxcmd); +void CloseProxmark(); +int OpenProxmark(size_t i); // FIXME: what the fuckity fuck unsigned int current_command = CMD_UNKNOWN; @@ -26,7 +32,7 @@ unsigned int current_command = CMD_UNKNOWN; #define BOOTLOADER_SIZE 0x2000 #define BOOTLOADER_END (FLASH_START + BOOTLOADER_SIZE) -#define BLOCK_SIZE 0x100 +#define BLOCK_SIZE 0x200 static const uint8_t elf_ident[] = { 0x7f, 'E', 'L', 'F', @@ -267,11 +273,11 @@ fail: // Get the state of the proxmark, backwards compatible static int get_proxmark_state(uint32_t *state) { - HidCommand c; + UsbCommand c; c.cmd = CMD_DEVICE_INFO; - SendCommand_(&c); - - HidCommand resp; +// SendCommand_(&c); + SendCommand(&c); + UsbCommand resp; ReceiveCommand(&resp); // Three outcomes: @@ -290,7 +296,7 @@ static int get_proxmark_state(uint32_t *state) *state = resp.arg[0]; break; default: - fprintf(stderr, "Error: Couldn't get proxmark state, bad response type: 0x%04x\n", resp.cmd); + fprintf(stderr, "Error: Couldn't get proxmark state, bad response type: 0x%04llx\n", resp.cmd); return -1; break; } @@ -313,7 +319,7 @@ static int enter_bootloader(void) if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) { fprintf(stderr,"Entering bootloader...\n"); - HidCommand c; + UsbCommand c; memset(&c, 0, sizeof (c)); if ((state & DEVICE_INFO_FLAG_BOOTROM_PRESENT) @@ -322,12 +328,12 @@ static int enter_bootloader(void) // New style handover: Send CMD_START_FLASH, which will reset the board // and enter the bootrom on the next boot. c.cmd = CMD_START_FLASH; - SendCommand_(&c); + SendCommand(&c); fprintf(stderr,"(Press and release the button only to abort)\n"); } else { // Old style handover: Ask the user to press the button, then reset the board c.cmd = CMD_HARDWARE_RESET; - SendCommand_(&c); + SendCommand(&c); fprintf(stderr,"Press and hold down button NOW if your bootloader requires it.\n"); } fprintf(stderr,"Waiting for Proxmark to reappear on USB..."); @@ -349,10 +355,10 @@ static int enter_bootloader(void) static int wait_for_ack(void) { - HidCommand ack; + UsbCommand ack; ReceiveCommand(&ack); if (ack.cmd != CMD_ACK) { - printf("Error: Unexpected reply 0x%04x (expected ACK)\n", ack.cmd); + printf("Error: Unexpected reply 0x%04llx (expected ACK)\n", ack.cmd); return -1; } return 0; @@ -372,7 +378,7 @@ int flash_start_flashing(int enable_bl_writes) if (state & DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH) { // This command is stupid. Why the heck does it care which area we're // flashing, as long as it's not the bootloader area? The mind boggles. - HidCommand c = {CMD_START_FLASH}; + UsbCommand c = {CMD_START_FLASH}; if (enable_bl_writes) { c.arg[0] = FLASH_START; @@ -383,7 +389,8 @@ int flash_start_flashing(int enable_bl_writes) c.arg[1] = FLASH_END; c.arg[2] = 0; } - SendCommand_(&c); + SendCommand(&c); +// SendCommand_(&c); return wait_for_ack(); } else { fprintf(stderr, "Note: Your bootloader does not understand the new START_FLASH command\n"); @@ -399,21 +406,26 @@ static int write_block(uint32_t address, uint8_t *data, uint32_t length) memset(block_buf, 0xFF, BLOCK_SIZE); memcpy(block_buf, data, length); - - HidCommand c = {CMD_SETUP_WRITE}; + UsbCommand c; +/* + c.cmd = {CMD_SETUP_WRITE}; for (int i = 0; i < 240; i += 48) { memcpy(c.d.asBytes, block_buf + i, 48); c.arg[0] = i / 4; - SendCommand_(&c); - if (wait_for_ack() < 0) + SendCommand(&c); +// SendCommand_(&c); + if (wait_for_ack() < 0) { return -1; + } } - +*/ c.cmd = CMD_FINISH_WRITE; c.arg[0] = address; - memcpy(c.d.asBytes, block_buf+240, 16); - SendCommand_(&c); - return wait_for_ack(); +// memcpy(c.d.asBytes, block_buf+240, 16); +// SendCommand_(&c); + memcpy(c.d.asBytes, block_buf, length); + SendCommand(&c); + return wait_for_ack(); } // Write a file's segments to Flash @@ -472,7 +484,8 @@ void flash_free(flash_file_t *ctx) // just reset the unit int flash_stop_flashing(void) { - HidCommand c = {CMD_HARDWARE_RESET}; - SendCommand_(&c); - return 0; + UsbCommand c = {CMD_HARDWARE_RESET}; +// SendCommand_(&c); + SendCommand(&c); + return 0; } diff --git a/client/flasher.c b/client/flasher.c index 85aae049..2e8bd2ed 100644 --- a/client/flasher.c +++ b/client/flasher.c @@ -10,12 +10,71 @@ #include #include #include "sleep.h" -#include "proxusb.h" +//#include "proxusb.h" #include "flash.h" +#include "uart.h" +#include "usb_cmd.h" + +static serial_port sp; +static char* serial_port_name; + +void cmd_debug(UsbCommand* UC) { + // Debug + printf("UsbCommand length[len=%zd]\n",sizeof(UsbCommand)); + printf(" cmd[len=%zd]: %016llx\n",sizeof(UC->cmd),UC->cmd); + printf(" arg0[len=%zd]: %016llx\n",sizeof(UC->arg[0]),UC->arg[0]); + printf(" arg1[len=%zd]: %016llx\n",sizeof(UC->arg[1]),UC->arg[1]); + printf(" arg2[len=%zd]: %016llx\n",sizeof(UC->arg[2]),UC->arg[2]); + printf(" data[len=%zd]: ",sizeof(UC->d.asBytes)); + for (size_t i=0; i<16; i++) { + printf("%02x",UC->d.asBytes[i]); + } + printf("...\n"); +} + +void SendCommand(UsbCommand* txcmd) { +// printf("send: "); +// cmd_debug(txcmd); + if (!uart_send(sp,(byte_t*)txcmd,sizeof(UsbCommand))) { + printf("Sending bytes to proxmark failed\n"); + exit(1); + } +} + +void ReceiveCommand(UsbCommand* rxcmd) { + byte_t* prxcmd = (byte_t*)rxcmd; + byte_t* prx = prxcmd; + size_t rxlen; + while (true) { + rxlen = sizeof(UsbCommand) - (prx-prxcmd); + if (uart_receive(sp,prx,&rxlen)) { +// printf("received [%zd] bytes\n",rxlen); + prx += rxlen; + if ((prx-prxcmd) >= sizeof(UsbCommand)) { +// printf("received: "); +// cmd_debug(rxcmd); + return; + } + } + } +} + +void CloseProxmark() { + // Clean up the port + uart_close(sp); +} + +int OpenProxmark(size_t i) { + sp = uart_open(serial_port_name); + if (sp == INVALID_SERIAL_PORT) { + return 0; + } + return 1; +} static void usage(char *argv0) { - fprintf(stderr, "Usage: %s [-b] image.elf [image.elf...]\n\n", argv0); + fprintf(stderr, "Usage: %s [-b] image.elf [image.elf...]\n\n", argv0); fprintf(stderr, "\t-b\tEnable flashing of bootloader area (DANGEROUS)\n\n"); fprintf(stderr, "Example: %s path/to/osimage.elf path/to/fpgaimage.elf\n", argv0); } @@ -31,12 +90,12 @@ int main(int argc, char **argv) memset(files, 0, sizeof(files)); - if (argc < 2) { + if (argc < 3) { usage(argv[0]); return -1; } - for (int i = 1; i < argc; i++) { + for (int i = 2; i < argc; i++) { if (argv[i][0] == '-') { if (!strcmp(argv[i], "-b")) { can_write_bl = 1; @@ -55,11 +114,9 @@ int main(int argc, char **argv) } } - usb_init(); - + serial_port_name = argv[1]; fprintf(stderr, "Waiting for Proxmark to appear on USB..."); while (!OpenProxmark(0)) { - sleep(1); fprintf(stderr, "."); } fprintf(stderr, " Found.\n"); diff --git a/client/mifarehost.c b/client/mifarehost.c index 825e06d8..14674b16 100644 --- a/client/mifarehost.c +++ b/client/mifarehost.c @@ -15,7 +15,6 @@ #include "proxmark3.h" // MIFARE - int compar_int(const void * a, const void * b) { return (*(uint64_t*)b - *(uint64_t*)a); } diff --git a/client/mifarehost.h b/client/mifarehost.h index a264002f..9e026a55 100644 --- a/client/mifarehost.h +++ b/client/mifarehost.h @@ -15,7 +15,7 @@ #include "cmdmain.h" #include "ui.h" #include "data.h" -#include "proxusb.h" +//#include "proxusb.h" #include "util.h" #include "nonce2key/nonce2key.h" #include "nonce2key/crapto1.h" diff --git a/client/proxusb.c b/client/proxusb.c deleted file mode 100644 index 2f152ace..00000000 --- a/client/proxusb.c +++ /dev/null @@ -1,222 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2009 Michael Gernoth -// Copyright (C) 2010 iZsh -// -// 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. -//----------------------------------------------------------------------------- -// USB utilities -//----------------------------------------------------------------------------- - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "sleep.h" -#include "proxusb.h" -#include "proxmark3.h" -#include "usb_cmd.h" - -// It seems to be missing for mingw -#ifndef ETIMEDOUT -#define ETIMEDOUT 116 -#endif - -usb_dev_handle *devh = NULL; -static unsigned int claimed_iface = 0; -unsigned char return_on_error = 0; -unsigned char error_occured = 0; -extern unsigned int current_command; - -void SendCommand_(HidCommand *c) -{ - int ret; - -#if 0 - printf("Sending %d bytes\n", sizeof(HidCommand)); -#endif - current_command = c->cmd; - ret = usb_bulk_write(devh, 0x01, (char*)c, sizeof(HidCommand), 1000); - if (ret<0) { - error_occured = 1; - if (return_on_error) - return; - - fprintf(stderr, "write failed: %s!\nTrying to reopen device...\n", - usb_strerror()); - - if (devh) { - usb_close(devh); - devh = NULL; - } - while(!OpenProxmark(0)) { sleep(1); } - printf(PROXPROMPT); - fflush(NULL); - - return; - } -} - -bool ReceiveCommandPoll(HidCommand *c) -{ - int ret; - - memset(c, 0, sizeof (HidCommand)); - ret = usb_bulk_read(devh, 0x82, (char*)c, sizeof(HidCommand), 500); - if (ret<0) { - if (ret != -ETIMEDOUT) { - error_occured = 1; - if (return_on_error) - return false; - - fprintf(stderr, "read failed: %s(%d)!\nTrying to reopen device...\n", - usb_strerror(), ret); - - if (devh) { - usb_close(devh); - devh = NULL; - } - while(!OpenProxmark(0)) { sleep(1); } - printf(PROXPROMPT); - fflush(NULL); - - return false; - } - } else { - if (ret && (ret < sizeof(HidCommand))) { - fprintf(stderr, "Read only %d instead of requested %d bytes!\n", - ret, (int)sizeof(HidCommand)); - } - } - - return ret > 0; -} - -void ReceiveCommand(HidCommand *c) -{ -// printf("%s()\n", __FUNCTION__); - int retval = 0; - do { - retval = ReceiveCommandPoll(c); - if (retval != 1) printf("ReceiveCommandPoll returned %d\n", retval); - } while(retval<0); -// printf("recv %x\n", c->cmd); -} - -usb_dev_handle* findProxmark(int verbose, unsigned int *iface) -{ - struct usb_bus *busses, *bus; - usb_dev_handle *handle = NULL; - struct prox_unit units[50]; - int iUnit = 0; - - usb_find_busses(); - usb_find_devices(); - - busses = usb_get_busses(); - - for (bus = busses; bus; bus = bus->next) { - struct usb_device *dev; - - for (dev = bus->devices; dev; dev = dev->next) { - struct usb_device_descriptor *desc = &(dev->descriptor); - - if ((desc->idProduct == 0x4b8f) && (desc->idVendor == 0x9ac4)) { - handle = usb_open(dev); - if (!handle) { - if (verbose) - fprintf(stderr, "open fabiled: %s!\n", usb_strerror()); - //return NULL; - continue; - } - *iface = dev->config[0].interface[0].altsetting[0].bInterfaceNumber; - - struct prox_unit unit = {handle, {0}}; - usb_get_string_simple(handle, desc->iSerialNumber, unit.serial_number, sizeof(unit.serial_number)); - units[iUnit++] = unit; - - //return handle; - } - } - } - - if (iUnit > 0) { - int iSelection = 0; - - fprintf(stdout, "\nConnected units:\n"); - - for (int i = 0; i < iUnit; i++) { - struct usb_device * dev = usb_device(units[i].handle); - fprintf(stdout, "\t%d. SN: %s [%s/%s]\n", i+1, units[i].serial_number, dev->bus->dirname, dev->filename); - } - if (iUnit > 1) { - while (iSelection < 1 || iSelection > iUnit) { - fprintf(stdout, "Which unit do you want to connect to? "); - fscanf(stdin, "%d", &iSelection); - } - } - else - iSelection = 1; - iSelection --; - - for (int i = 0; i < iUnit; i++) { - if (iSelection == i) continue; - usb_close(units[i].handle); - units[i].handle = NULL; - } - - return units[iSelection].handle; - } - - return NULL; -} - -usb_dev_handle* OpenProxmark(int verbose) -{ - int ret; - usb_dev_handle *handle = NULL; - unsigned int iface; - - handle = findProxmark(verbose, &iface); - if (!handle) - return NULL; - -#ifdef __linux__ - /* detach kernel driver first */ - ret = usb_detach_kernel_driver_np(handle, iface); - /* don't complain if no driver attached */ - if (ret<0 && ret != -61 && verbose) - fprintf(stderr, "detach kernel driver failed: (%d) %s!\n", ret, usb_strerror()); -#endif - - // Needed for Windows. Optional for Mac OS and Linux - ret = usb_set_configuration(handle, 1); - if (ret < 0) { - if (verbose) - fprintf(stderr, "configuration set failed: %s!\n", usb_strerror()); - return NULL; - } - - ret = usb_claim_interface(handle, iface); - if (ret < 0) { - if (verbose) - fprintf(stderr, "claim failed: %s!\n", usb_strerror()); - return NULL; - } - claimed_iface = iface; - devh = handle; - return handle; -} - -void CloseProxmark(void) -{ - usb_release_interface(devh, claimed_iface); - usb_close(devh); - devh = NULL; -} diff --git a/client/proxusb.h b/client/proxusb.h deleted file mode 100644 index cc34fd48..00000000 --- a/client/proxusb.h +++ /dev/null @@ -1,34 +0,0 @@ -//----------------------------------------------------------------------------- -// Copyright (C) 2010 iZsh -// -// 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. -//----------------------------------------------------------------------------- -// USB utilities -//----------------------------------------------------------------------------- - -#ifndef PROXUSB_H__ -#define PROXUSB_H__ - -#include -#include -#include -#include "usb_cmd.h" - -extern unsigned char return_on_error; -extern unsigned char error_occured; - -void SendCommand_(HidCommand *c); -bool ReceiveCommandPoll(HidCommand *c); -void ReceiveCommand(HidCommand *c); -struct usb_dev_handle* FindProxmark(int verbose, unsigned int *iface); -struct usb_dev_handle* OpenProxmark(int verbose); -void CloseProxmark(void); - -struct prox_unit { - usb_dev_handle *handle; - char serial_number[256]; -}; - -#endif diff --git a/common/Makefile.common b/common/Makefile.common index 9ff05c50..2befd456 100644 --- a/common/Makefile.common +++ b/common/Makefile.common @@ -65,7 +65,7 @@ VPATH = . ../common/ ../fpga/ INCLUDES = ../include/proxmark3.h ../include/at91sam7s512.h ../include/config_gpio.h ../include/usb_cmd.h $(APP_INCLUDES) -CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) +CFLAGS = -c $(INCLUDE) -Wall -Werror -pedantic -std=c99 $(APP_CFLAGS) -Os LDFLAGS = -nostartfiles -nodefaultlibs -Wl,-gc-sections -n LIBS = -lgcc diff --git a/common/cmd.c b/common/cmd.c new file mode 100644 index 00000000..49d9d942 --- /dev/null +++ b/common/cmd.c @@ -0,0 +1,81 @@ +/* + * Proxmark send and receive commands + * + * Copyright (c) 2012, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @file cmd.c + * @brief + */ + +#include "cmd.h" +#include "string.h" +#include "proxmark3.h" + +//static UsbCommand txcmd; + +bool cmd_receive(UsbCommand* cmd) { + + // Check if there is a usb packet available + if (!usb_poll()) return false; + + // Try to retrieve the available command frame + size_t rxlen = usb_read((byte_t*)cmd,sizeof(UsbCommand)); + + // Check if the transfer was complete + if (rxlen != sizeof(UsbCommand)) return false; + + // Received command successfully + return true; +} + +bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) { + UsbCommand txcmd; + + for (size_t i=0; i +#include +#include "usb_cdc.h" + +bool cmd_receive(UsbCommand* cmd); +bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len); + +#endif // _PROXMARK_CMD_H_ + diff --git a/common/usb_cdc.c b/common/usb_cdc.c new file mode 100644 index 00000000..e2787fb6 --- /dev/null +++ b/common/usb_cdc.c @@ -0,0 +1,567 @@ +/* + * at91sam7s USB CDC device implementation + * + * Copyright (c) 2012, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * based on the "Basic USB Example" from ATMEL (doc6123.pdf) + * + * @file usb_cdc.c + * @brief + */ + +#include "usb_cdc.h" +#include "config_gpio.h" + +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#define AT91C_EP_IN_SIZE 0x40 +#define AT91C_EP_OUT 1 +#define AT91C_EP_OUT_SIZE 0x40 +#define AT91C_EP_IN 2 + +const char devDescriptor[] = { + /* Device descriptor */ + 0x12, // bLength + 0x01, // bDescriptorType + 0x10,0x01, // Complies with USB Spec. Release (0110h = release 1.10) + 0x02, // bDeviceClass: CDC class code + 0x00, // bDeviceSubclass: CDC class sub code + 0x00, // bDeviceProtocol: CDC Device protocol + 0x08, // bMaxPacketSize0 + 0x2d,0x2d, // Vendor ID (--) + 0x4d,0x50, // Product ID (PM), transmitted in reverse + 0x01,0x00, // Device release number (0001) + 0x01, // iManufacturer // 0x01 + 0x00, // iProduct + 0x00, // SerialNumber + 0x01 // bNumConfigs +}; + +const char cfgDescriptor[] = { + /* ============== CONFIGURATION 1 =========== */ + /* Configuration 1 descriptor */ + 0x09, // CbLength + 0x02, // CbDescriptorType + 0x43, // CwTotalLength 2 EP + Control + 0x00, + 0x02, // CbNumInterfaces + 0x01, // CbConfigurationValue + 0x00, // CiConfiguration + 0xC0, // CbmAttributes 0xA0 + 0x00, // CMaxPower + + /* Communication Class Interface Descriptor Requirement */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x00, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x01, // bNumEndpoints + 0x02, // bInterfaceClass + 0x02, // bInterfaceSubclass + 0x00, // bInterfaceProtocol + 0x00, // iInterface + + /* Header Functional Descriptor */ + 0x05, // bFunction Length + 0x24, // bDescriptor type: CS_INTERFACE + 0x00, // bDescriptor subtype: Header Func Desc + 0x10, // bcdCDC:1.1 + 0x01, + + /* ACM Functional Descriptor */ + 0x04, // bFunctionLength + 0x24, // bDescriptor Type: CS_INTERFACE + 0x02, // bDescriptor Subtype: ACM Func Desc + 0x00, // bmCapabilities + + /* Union Functional Descriptor */ + 0x05, // bFunctionLength + 0x24, // bDescriptorType: CS_INTERFACE + 0x06, // bDescriptor Subtype: Union Func Desc + 0x00, // bMasterInterface: Communication Class Interface + 0x01, // bSlaveInterface0: Data Class Interface + + /* Call Management Functional Descriptor */ + 0x05, // bFunctionLength + 0x24, // bDescriptor Type: CS_INTERFACE + 0x01, // bDescriptor Subtype: Call Management Func Desc + 0x00, // bmCapabilities: D1 + D0 + 0x01, // bDataInterface: Data Class Interface 1 + + /* Endpoint 1 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x83, // bEndpointAddress, Endpoint 03 - IN + 0x03, // bmAttributes INT + 0x08, // wMaxPacketSize + 0x00, + 0xFF, // bInterval + + /* Data Class Interface Descriptor Requirement */ + 0x09, // bLength + 0x04, // bDescriptorType + 0x01, // bInterfaceNumber + 0x00, // bAlternateSetting + 0x02, // bNumEndpoints + 0x0A, // bInterfaceClass + 0x00, // bInterfaceSubclass + 0x00, // bInterfaceProtocol + 0x00, // iInterface + + /* First alternate setting */ + /* Endpoint 1 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x01, // bEndpointAddress, Endpoint 01 - OUT + 0x02, // bmAttributes BULK + AT91C_EP_OUT_SIZE, // wMaxPacketSize + 0x00, + 0x00, // bInterval + + /* Endpoint 2 descriptor */ + 0x07, // bLength + 0x05, // bDescriptorType + 0x82, // bEndpointAddress, Endpoint 02 - IN + 0x02, // bmAttributes BULK + AT91C_EP_IN_SIZE, // wMaxPacketSize + 0x00, + 0x00 // bInterval +}; + +const char strDescriptor[] = { + 26, // Length + 0x03, // Type is string + 'p', 0x00, + 'r', 0x00, + 'o', 0x00, + 'x', 0x00, + 'm', 0x00, + 'a', 0x00, + 'r', 0x00, + 'k', 0x00, + '.', 0x00, + 'o', 0x00, + 'r', 0x00, + 'g', 0x00, +}; + + +/* 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 { + unsigned int dwDTERRate; + char bCharFormat; + char bParityType; + char bDataBits; +} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING; + +AT91S_CDC_LINE_CODING line = { + 115200, // baudrate + 0, // 1 Stop Bit + 0, // None Parity + 8}; // 8 Data bits + +void AT91F_CDC_Enumerate(); + +AT91PS_UDP pUdp = AT91C_BASE_UDP; +byte_t btConfiguration = 0; +byte_t btConnection = 0; +byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; + +//*---------------------------------------------------------------------------- +//* \fn usb_disable +//* \brief This function deactivates the USB device +//*---------------------------------------------------------------------------- +void usb_disable() { + // Disconnect the USB device + AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU; +// SpinDelay(100); + + // Clear all lingering interrupts + if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) { + pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES; + } +} + +//*---------------------------------------------------------------------------- +//* \fn usb_enable +//* \brief This function Activates the USB device +//*---------------------------------------------------------------------------- +void usb_enable() { + // Set the PLL USB Divider + AT91C_BASE_CKGR->CKGR_PLLR |= AT91C_CKGR_USBDIV_1 ; + + // Specific Chip USB Initialisation + // 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); + + // Enable UDP PullUp (USB_DP_PUP) : enable & Clear of the corresponding PIO + // Set in PIO mode and Configure in Output + AT91C_BASE_PIOA->PIO_PER = GPIO_USB_PU; // Set in PIO mode + AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; // Configure as Output + + // Clear for set the Pullup resistor + AT91C_BASE_PIOA->PIO_CODR = GPIO_USB_PU; + + // Disconnect and reconnect USB controller for 100ms + usb_disable(); + + // Wait for a short while + for (volatile size_t i=0; i<0x100000; i++); +// SpinDelay(100); + + // Reconnect USB reconnect + AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU; + AT91C_BASE_PIOA->PIO_OER = GPIO_USB_PU; +} + +//*---------------------------------------------------------------------------- +//* \fn usb_check +//* \brief Test if the device is configured and handle enumeration +//*---------------------------------------------------------------------------- +bool usb_check() { + AT91_REG isr = pUdp->UDP_ISR; + + if (isr & AT91C_UDP_ENDBUSRES) { + pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES; + // reset all endpoints + pUdp->UDP_RSTEP = (unsigned int)-1; + pUdp->UDP_RSTEP = 0; + // Enable the function + pUdp->UDP_FADDR = AT91C_UDP_FEN; + // Configure endpoint 0 + pUdp->UDP_CSR[0] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_CTRL); + } + else if (isr & AT91C_UDP_EPINT0) { + pUdp->UDP_ICR = AT91C_UDP_EPINT0; + AT91F_CDC_Enumerate(); + } + return (btConfiguration) ? true : false; +} + + +bool usb_poll() +{ + if (!usb_check()) return false; + return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank); +} + +//*---------------------------------------------------------------------------- +//* \fn usb_read +//* \brief Read available data from Endpoint OUT +//*---------------------------------------------------------------------------- +uint32_t usb_read(byte_t* data, size_t len) { + byte_t bank = btReceiveBank; + uint32_t packetSize, nbBytesRcv = 0; + uint32_t time_out = 0; + + while (len) + { + if (!usb_check()) break; + + if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) { + packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len); + len -= packetSize; + while(packetSize--) + data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT]; + pUdp->UDP_CSR[AT91C_EP_OUT] &= ~(bank); + if (bank == AT91C_UDP_RX_DATA_BK0) + { + bank = AT91C_UDP_RX_DATA_BK1; + } else { + bank = AT91C_UDP_RX_DATA_BK0; + } + } + if (time_out++ == 0x1fff) break; + } + + btReceiveBank = bank; + return nbBytesRcv; +} + +//*---------------------------------------------------------------------------- +//* \fn usb_write +//* \brief Send through endpoint 2 +//*---------------------------------------------------------------------------- +uint32_t usb_write(const byte_t* data, const size_t len) { + size_t length = len; + uint32_t cpt = 0; + + if (!length) return 0; + if (!usb_check()) return 0; + + // Send the first packet + cpt = MIN(length, AT91C_EP_IN_SIZE-1); + length -= cpt; + while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++; + pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; + + while (length) { + // Fill the second bank + cpt = MIN(length, AT91C_EP_IN_SIZE-1); + length -= cpt; + while (cpt--) pUdp->UDP_FDR[AT91C_EP_IN] = *data++; + // Wait for the the first bank to be sent + while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) { + if (!usb_check()) return length; + } + pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); + while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); + pUdp->UDP_CSR[AT91C_EP_IN] |= AT91C_UDP_TXPKTRDY; + } + + // Wait for the end of transfer + while (!(pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)) { + if (!usb_check()) return length; + } + + pUdp->UDP_CSR[AT91C_EP_IN] &= ~(AT91C_UDP_TXCOMP); + while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); + + return length; +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_USB_SendData +//* \brief Send Data through the control endpoint +//*---------------------------------------------------------------------------- +unsigned int csrTab[100]; +unsigned char csrIdx = 0; + +static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t length) { + uint32_t cpt = 0; + AT91_REG csr; + + do { + cpt = MIN(length, 8); + length -= cpt; + + while (cpt--) + pUdp->UDP_FDR[0] = *pData++; + + if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) { + pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP); + while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP); + } + + pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; + do { + csr = pUdp->UDP_CSR[0]; + + // Data IN stage has been stopped by a status OUT + if (csr & AT91C_UDP_RX_DATA_BK0) { + pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0); + return; + } + } while ( !(csr & AT91C_UDP_TXCOMP) ); + + } while (length); + + if (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) { + pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP); + while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP); + } +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_USB_SendZlp +//* \brief Send zero length packet through the control endpoint +//*---------------------------------------------------------------------------- +void AT91F_USB_SendZlp(AT91PS_UDP pUdp) { + pUdp->UDP_CSR[0] |= AT91C_UDP_TXPKTRDY; + while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP) ); + pUdp->UDP_CSR[0] &= ~(AT91C_UDP_TXCOMP); + while (pUdp->UDP_CSR[0] & AT91C_UDP_TXCOMP); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_USB_SendStall +//* \brief Stall the control endpoint +//*---------------------------------------------------------------------------- +void AT91F_USB_SendStall(AT91PS_UDP pUdp) { + pUdp->UDP_CSR[0] |= AT91C_UDP_FORCESTALL; + while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_ISOERROR) ); + pUdp->UDP_CSR[0] &= ~(AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR); + while (pUdp->UDP_CSR[0] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); +} + +//*---------------------------------------------------------------------------- +//* \fn AT91F_CDC_Enumerate +//* \brief This function is a callback invoked when a SETUP packet is received +//*---------------------------------------------------------------------------- +void AT91F_CDC_Enumerate() { + byte_t bmRequestType, bRequest; + uint16_t wValue, wIndex, wLength, wStatus; + + if ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) ) + return; + + bmRequestType = pUdp->UDP_FDR[0]; + bRequest = pUdp->UDP_FDR[0]; + wValue = (pUdp->UDP_FDR[0] & 0xFF); + wValue |= (pUdp->UDP_FDR[0] << 8); + wIndex = (pUdp->UDP_FDR[0] & 0xFF); + wIndex |= (pUdp->UDP_FDR[0] << 8); + wLength = (pUdp->UDP_FDR[0] & 0xFF); + wLength |= (pUdp->UDP_FDR[0] << 8); + + if (bmRequestType & 0x80) { + pUdp->UDP_CSR[0] |= AT91C_UDP_DIR; + while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_DIR) ); + } + pUdp->UDP_CSR[0] &= ~AT91C_UDP_RXSETUP; + while ( (pUdp->UDP_CSR[0] & AT91C_UDP_RXSETUP) ); + + // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 + switch ((bRequest << 8) | bmRequestType) { + case STD_GET_DESCRIPTOR: + if (wValue == 0x100) // Return Device Descriptor + AT91F_USB_SendData(pUdp, devDescriptor, MIN(sizeof(devDescriptor), wLength)); + else if (wValue == 0x200) // Return Configuration Descriptor + AT91F_USB_SendData(pUdp, cfgDescriptor, MIN(sizeof(cfgDescriptor), wLength)); + else if ((wValue & 0x300) == 0x300) // Return String Descriptor + AT91F_USB_SendData(pUdp, strDescriptor, MIN(sizeof(strDescriptor), wLength)); + else + AT91F_USB_SendStall(pUdp); + break; + case STD_SET_ADDRESS: + AT91F_USB_SendZlp(pUdp); + pUdp->UDP_FADDR = (AT91C_UDP_FEN | wValue); + pUdp->UDP_GLBSTATE = (wValue) ? AT91C_UDP_FADDEN : 0; + break; + case STD_SET_CONFIGURATION: + btConfiguration = wValue; + AT91F_USB_SendZlp(pUdp); + 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; + pUdp->UDP_CSR[3] = (wValue) ? (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_INT_IN) : 0; + break; + case STD_GET_CONFIGURATION: + AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration)); + break; + case STD_GET_STATUS_ZERO: + wStatus = 0; + AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); + break; + case STD_GET_STATUS_INTERFACE: + wStatus = 0; + AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); + break; + case STD_GET_STATUS_ENDPOINT: + wStatus = 0; + wIndex &= 0x0F; + if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= 3)) { + wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; + AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); + } + else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == 0)) { + wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; + AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); + } + else + AT91F_USB_SendStall(pUdp); + break; + case STD_SET_FEATURE_ZERO: + AT91F_USB_SendStall(pUdp); + break; + case STD_SET_FEATURE_INTERFACE: + AT91F_USB_SendZlp(pUdp); + break; + case STD_SET_FEATURE_ENDPOINT: + wIndex &= 0x0F; + if ((wValue == 0) && wIndex && (wIndex <= 3)) { + pUdp->UDP_CSR[wIndex] = 0; + AT91F_USB_SendZlp(pUdp); + } + else + AT91F_USB_SendStall(pUdp); + break; + case STD_CLEAR_FEATURE_ZERO: + AT91F_USB_SendStall(pUdp); + break; + case STD_CLEAR_FEATURE_INTERFACE: + AT91F_USB_SendZlp(pUdp); + break; + case STD_CLEAR_FEATURE_ENDPOINT: + wIndex &= 0x0F; + if ((wValue == 0) && wIndex && (wIndex <= 3)) { + if (wIndex == 1) + pUdp->UDP_CSR[1] = (AT91C_UDP_EPEDS | AT91C_UDP_EPTYPE_BULK_OUT); + else if (wIndex == 2) + pUdp->UDP_CSR[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); + AT91F_USB_SendZlp(pUdp); + } + else + AT91F_USB_SendStall(pUdp); + break; + + // handle CDC class requests + case SET_LINE_CODING: + while ( !(pUdp->UDP_CSR[0] & AT91C_UDP_RX_DATA_BK0) ); + pUdp->UDP_CSR[0] &= ~(AT91C_UDP_RX_DATA_BK0); + AT91F_USB_SendZlp(pUdp); + break; + case GET_LINE_CODING: + AT91F_USB_SendData(pUdp, (char *) &line, MIN(sizeof(line), wLength)); + break; + case SET_CONTROL_LINE_STATE: + btConnection = wValue; + AT91F_USB_SendZlp(pUdp); + break; + default: + AT91F_USB_SendStall(pUdp); + break; + } +} diff --git a/common/usb_cdc.h b/common/usb_cdc.h new file mode 100644 index 00000000..d7b9c2e5 --- /dev/null +++ b/common/usb_cdc.h @@ -0,0 +1,48 @@ +/* + * at91sam7s USB CDC device implementation + * + * Copyright (c) 2012, Roel Verdult + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holders nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * based on the "Basic USB Example" from ATMEL (doc6123.pdf) + * + * @file usb_cdc.c + * @brief + */ + +#ifndef _USB_CDC_H_ +#define _USB_CDC_H_ + +#include + +void usb_disable(); +void usb_enable(); +bool usb_check(); +bool usb_poll(); +uint32_t usb_read(byte_t* data, size_t len); +uint32_t usb_write(const byte_t* data, const size_t len); + +#endif // _USB_CDC_H_ + diff --git a/include/common.h b/include/common.h index 13daa86e..ba286377 100644 --- a/include/common.h +++ b/include/common.h @@ -18,4 +18,7 @@ #include typedef unsigned char byte_t; +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) + #endif diff --git a/include/usb_cmd.h b/include/usb_cmd.h index 62c0acd7..349496b7 100644 --- a/include/usb_cmd.h +++ b/include/usb_cmd.h @@ -23,15 +23,6 @@ typedef BYTE uint8_t; #define PACKED __attribute__((packed)) #endif -typedef struct { - uint32_t cmd; - uint32_t arg[3]; - union { - uint8_t asBytes[48]; - uint32_t asDwords[12]; - } d; -} PACKED HidCommand; - #define USB_CMD_DATA_SIZE 512 typedef struct {