usb communication (device side) housekeeping

* move cmd.[ch] and usb_cdc.[ch] to armsrc
* sorting out #includes
* replace byte_t by uint8_t
* some reformatting
* whitespace fixes
* (no functional changes)
This commit is contained in:
pwpiwi 2020-01-11 17:11:19 +01:00
parent d00a30d56f
commit 72622d6429
17 changed files with 230 additions and 197 deletions

View file

@ -112,8 +112,4 @@ void ReaderMifareDES(uint32_t param, uint32_t param2, uint8_t * datain);
int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout); int DesfireAPDU(uint8_t *cmd, size_t cmd_len, uint8_t *dataout);
size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout); size_t CreateAPDU( uint8_t *datain, size_t len, uint8_t *dataout);
// cmd.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 #endif

View file

@ -31,49 +31,56 @@
*/ */
#include "cmd.h" #include "cmd.h"
#include "string.h"
#include "proxmark3.h" #include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "common.h"
#include "usb_cmd.h"
#include "usb_cdc.h"
bool cmd_receive(UsbCommand* cmd) { 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 // Check if there is a usb packet available
if (rxlen != sizeof(UsbCommand)) return false; if (!usb_poll())
return false;
// Received command successfully
return true; // Try to retrieve the available command frame
size_t rxlen = usb_read((uint8_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) { bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len) {
UsbCommand txcmd; UsbCommand txcmd;
for (size_t i=0; i<sizeof(UsbCommand); i++) { for (size_t i = 0; i < sizeof(UsbCommand); i++) {
((byte_t*)&txcmd)[i] = 0x00; ((uint8_t*)&txcmd)[i] = 0x00;
} }
// 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 // Compose the outgoing command frame
if (data && len) { txcmd.cmd = cmd;
len = MIN(len,USB_CMD_DATA_SIZE); txcmd.arg[0] = arg0;
for (size_t i=0; i<len; i++) { txcmd.arg[1] = arg1;
txcmd.d.asBytes[i] = ((byte_t*)data)[i]; txcmd.arg[2] = arg2;
}
} // Add the (optional) content to the frame, with a maximum size of USB_CMD_DATA_SIZE
if (data && len) {
// Send frame and make sure all bytes are transmitted len = MIN(len, USB_CMD_DATA_SIZE);
if (usb_write((byte_t*)&txcmd,sizeof(UsbCommand)) != 0) return false; for (size_t i = 0; i < len; i++) {
txcmd.d.asBytes[i] = ((uint8_t*)data)[i];
return true; }
}
// Send frame and make sure all bytes are transmitted
if (usb_write((uint8_t*)&txcmd, sizeof(UsbCommand)) != 0) return false;
return true;
} }

View file

@ -30,15 +30,15 @@
* @brief * @brief
*/ */
#ifndef _PROXMARK_CMD_H_ #ifndef PROXMARK_CMD_H__
#define _PROXMARK_CMD_H_ #define PROXMARK_CMD_H__
#include "common.h" #include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "usb_cmd.h" #include "usb_cmd.h"
#include "usb_cdc.h"
bool cmd_receive(UsbCommand* cmd); extern 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); extern bool cmd_send(uint32_t cmd, uint32_t arg0, uint32_t arg1, uint32_t arg2, void* data, size_t len);
#endif // _PROXMARK_CMD_H_
#endif // PROXMARK_CMD_H__

View file

@ -14,6 +14,7 @@
#include "BigBuf.h" #include "BigBuf.h"
#include "util.h" #include "util.h"
#include "apps.h" #include "apps.h"
#include "cmd.h"
#include "usb_cdc.h" // for usb_poll_validate_length #include "usb_cdc.h" // for usb_poll_validate_length
#include "fpga.h" #include "fpga.h"
#include "fpgaloader.h" #include "fpgaloader.h"

View file

@ -17,6 +17,7 @@
#include <stdlib.h> #include <stdlib.h>
#include "proxmark3.h" #include "proxmark3.h"
#include "apps.h" #include "apps.h"
#include "cmd.h"
#include "util.h" #include "util.h"
#include "hitag.h" #include "hitag.h"
#include "string.h" #include "string.h"

View file

@ -18,6 +18,7 @@
#include "mifareutil.h" // for MF_DBGLEVEL #include "mifareutil.h" // for MF_DBGLEVEL
#include "BigBuf.h" #include "BigBuf.h"
#include "apps.h" #include "apps.h"
#include "cmd.h"
#ifdef WITH_SMARTCARD #ifdef WITH_SMARTCARD
#include "smartcard.h" #include "smartcard.h"

View file

@ -942,7 +942,7 @@ bool prepare_allocated_tag_modulation(tag_response_info_t* response_info, uint8_
// Main loop of simulated tag: receive commands from reader, decide what // Main loop of simulated tag: receive commands from reader, decide what
// response to send, and send it. // response to send, and send it.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data) { void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, uint8_t* data) {
uint8_t sak; uint8_t sak;
@ -1701,13 +1701,13 @@ static int GetATQA(uint8_t *resp, uint8_t *resp_par) {
// if anticollision is false, then the UID must be provided in uid_ptr[] // if anticollision is false, then the UID must be provided in uid_ptr[]
// and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID) // and num_cascades must be set (1: 4 Byte UID, 2: 7 Byte UID, 3: 10 Byte UID)
// requests ATS unless no_rats is true // requests ATS unless no_rats is true
int iso14443a_select_card(byte_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) { int iso14443a_select_card(uint8_t *uid_ptr, iso14a_card_select_t *p_hi14a_card, uint32_t *cuid_ptr, bool anticollision, uint8_t num_cascades, bool no_rats) {
uint8_t sel_all[] = { 0x93,0x20 }; uint8_t sel_all[] = { 0x93,0x20 };
uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; uint8_t sel_uid[] = { 0x93,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0 uint8_t rats[] = { 0xE0,0x80,0x00,0x00 }; // FSD=256, FSDI=8, CID=0
uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller uint8_t resp[MAX_FRAME_SIZE]; // theoretically. A usual RATS will be much smaller
uint8_t resp_par[MAX_PARITY_SIZE]; uint8_t resp_par[MAX_PARITY_SIZE];
byte_t uid_resp[4]; uint8_t uid_resp[4];
size_t uid_resp_len; size_t uid_resp_len;
uint8_t sak = 0x04; // cascade uid uint8_t sak = 0x04; // cascade uid
@ -2020,7 +2020,7 @@ void ReaderIso14443a(UsbCommand *c) {
size_t lenbits = c->arg[1] >> 16; size_t lenbits = c->arg[1] >> 16;
uint32_t timeout = c->arg[2]; uint32_t timeout = c->arg[2];
uint32_t arg0 = 0; uint32_t arg0 = 0;
byte_t buf[USB_CMD_DATA_SIZE] = {0}; uint8_t buf[USB_CMD_DATA_SIZE] = {0};
uint8_t par[MAX_PARITY_SIZE]; uint8_t par[MAX_PARITY_SIZE];
bool cantSELECT = false; bool cantSELECT = false;

View file

@ -13,6 +13,7 @@
#ifndef __ISO14443A_H #ifndef __ISO14443A_H
#define __ISO14443A_H #define __ISO14443A_H
#include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "usb_cmd.h" #include "usb_cmd.h"
@ -31,7 +32,7 @@ extern void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *par);
extern void AppendCrc14443a(uint8_t *data, int len); extern void AppendCrc14443a(uint8_t *data, int len);
extern void RAMFUNC SnoopIso14443a(uint8_t param); extern void RAMFUNC SnoopIso14443a(uint8_t param);
extern void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t *data); extern void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, uint8_t *data);
extern void ReaderIso14443a(UsbCommand *c); extern void ReaderIso14443a(UsbCommand *c);
extern void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing); extern void ReaderTransmit(uint8_t *frame, uint16_t len, uint32_t *timing);
extern void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing); extern void ReaderTransmitBitsPar(uint8_t *frame, uint16_t bits, uint8_t *par, uint32_t *timing);

View file

@ -14,6 +14,7 @@
#include "proxmark3.h" #include "proxmark3.h"
#include "apps.h" #include "apps.h"
#include "cmd.h"
#include "util.h" #include "util.h"
#include "string.h" #include "string.h"
#include "iso14443crc.h" #include "iso14443crc.h"

View file

@ -14,6 +14,7 @@
#include "proxmark3.h" #include "proxmark3.h"
#include "apps.h" #include "apps.h"
#include "cmd.h"
#include "util.h" #include "util.h"
#include "string.h" #include "string.h"
#include "legic_prng.h" #include "legic_prng.h"

View file

@ -17,6 +17,7 @@
#include "lfdemod.h" #include "lfdemod.h"
#include "lfsampling.h" #include "lfsampling.h"
#include "protocols.h" #include "protocols.h"
#include "cmd.h"
#include "usb_cdc.h" // for usb_poll_validate_length #include "usb_cdc.h" // for usb_poll_validate_length
#include "fpgaloader.h" #include "fpgaloader.h"

View file

@ -1,5 +1,6 @@
#include "proxmark3.h" #include "proxmark3.h"
#include "apps.h" #include "apps.h"
#include "cmd.h"
#include "lfsampling.h" #include "lfsampling.h"
#include "pcf7931.h" #include "pcf7931.h"
#include "util.h" #include "util.h"

View file

@ -33,10 +33,15 @@
*/ */
#include "usb_cdc.h" #include "usb_cdc.h"
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include "common.h"
#include "at91sam7s512.h" #include "at91sam7s512.h"
#include "config_gpio.h" #include "config_gpio.h"
#define AT91C_EP_CONTROL 0 #define AT91C_EP_CONTROL 0
#define AT91C_EP_OUT 1 #define AT91C_EP_OUT 1
#define AT91C_EP_IN 2 #define AT91C_EP_IN 2
@ -49,6 +54,7 @@
#define STR_MANUFACTURER 0x01 #define STR_MANUFACTURER 0x01
#define STR_PRODUCT 0x02 #define STR_PRODUCT 0x02
static const char devDescriptor[] = { static const char devDescriptor[] = {
/* Device descriptor */ /* Device descriptor */
0x12, // bLength 0x12, // bLength
@ -67,6 +73,7 @@ static const char devDescriptor[] = {
0x01 // bNumConfigs 0x01 // bNumConfigs
}; };
static const char cfgDescriptor[] = { static const char cfgDescriptor[] = {
/* ============== CONFIGURATION 1 =========== */ /* ============== CONFIGURATION 1 =========== */
/* Configuration 1 descriptor */ /* Configuration 1 descriptor */
@ -157,47 +164,50 @@ static const char cfgDescriptor[] = {
0x00 // bInterval 0x00 // bInterval
}; };
static const char StrDescLanguageCodes[] = { static const char StrDescLanguageCodes[] = {
4, // Length 4, // Length
0x03, // Type is string 0x03, // Type is string
0x09, 0x04 // supported language Code 0 = 0x0409 (English) 0x09, 0x04 // supported language Code 0 = 0x0409 (English)
}; };
// Note: ModemManager (Linux) ignores Proxmark3 devices by matching the // Note: ModemManager (Linux) ignores Proxmark3 devices by matching the
// manufacturer string "proxmark.org". Don't change this. // manufacturer string "proxmark.org". Don't change this.
static const char StrDescManufacturer[] = { static const char StrDescManufacturer[] = {
26, // Length 26, // Length
0x03, // Type is string 0x03, // Type is string
'p', 0x00, 'p', 0x00,
'r', 0x00, 'r', 0x00,
'o', 0x00, 'o', 0x00,
'x', 0x00, 'x', 0x00,
'm', 0x00, 'm', 0x00,
'a', 0x00, 'a', 0x00,
'r', 0x00, 'r', 0x00,
'k', 0x00, 'k', 0x00,
'.', 0x00, '.', 0x00,
'o', 0x00, 'o', 0x00,
'r', 0x00, 'r', 0x00,
'g', 0x00 'g', 0x00
}; };
static const char StrDescProduct[] = { static const char StrDescProduct[] = {
20, // Length 20, // Length
0x03, // Type is string 0x03, // Type is string
'p', 0x00, 'p', 0x00,
'r', 0x00, 'r', 0x00,
'o', 0x00, 'o', 0x00,
'x', 0x00, 'x', 0x00,
'm', 0x00, 'm', 0x00,
'a', 0x00, 'a', 0x00,
'r', 0x00, 'r', 0x00,
'k', 0x00, 'k', 0x00,
'3', 0x00 '3', 0x00
}; };
const char* getStringDescriptor(uint8_t idx)
{ const char* getStringDescriptor(uint8_t idx) {
switch (idx) { switch (idx) {
case STR_LANGUAGE_CODES: case STR_LANGUAGE_CODES:
return StrDescLanguageCodes; return StrDescLanguageCodes;
@ -210,10 +220,12 @@ const char* getStringDescriptor(uint8_t idx)
} }
} }
// Bitmap for all status bits in CSR which must be written as 1 to cause no effect // Bitmap for all status bits in CSR which must be written as 1 to cause no effect
#define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \ #define REG_NO_EFFECT_1_ALL AT91C_UDP_RX_DATA_BK0 | AT91C_UDP_RX_DATA_BK1 \
|AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \ |AT91C_UDP_STALLSENT | AT91C_UDP_RXSETUP \
|AT91C_UDP_TXCOMP |AT91C_UDP_TXCOMP
// Clear flags in the UDP_CSR register // Clear flags in the UDP_CSR register
#define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \ #define UDP_CLEAR_EP_FLAGS(endpoint, flags) { \
@ -222,7 +234,8 @@ const char* getStringDescriptor(uint8_t idx)
reg |= REG_NO_EFFECT_1_ALL; \ reg |= REG_NO_EFFECT_1_ALL; \
reg &= ~(flags); \ reg &= ~(flags); \
pUdp->UDP_CSR[(endpoint)] = reg; \ pUdp->UDP_CSR[(endpoint)] = reg; \
} }
// Set flags in the UDP_CSR register // Set flags in the UDP_CSR register
#define UDP_SET_EP_FLAGS(endpoint, flags) { \ #define UDP_SET_EP_FLAGS(endpoint, flags) { \
@ -233,6 +246,7 @@ const char* getStringDescriptor(uint8_t idx)
pUdp->UDP_CSR[(endpoint)] = reg; \ pUdp->UDP_CSR[(endpoint)] = reg; \
} }
/* USB standard request codes */ /* USB standard request codes */
#define STD_GET_STATUS_ZERO 0x0080 #define STD_GET_STATUS_ZERO 0x0080
#define STD_GET_STATUS_INTERFACE 0x0081 #define STD_GET_STATUS_INTERFACE 0x0081
@ -260,6 +274,7 @@ const char* getStringDescriptor(uint8_t idx)
#define SET_LINE_CODING 0x2021 #define SET_LINE_CODING 0x2021
#define SET_CONTROL_LINE_STATE 0x2221 #define SET_CONTROL_LINE_STATE 0x2221
typedef struct { typedef struct {
unsigned int dwDTERRate; unsigned int dwDTERRate;
char bCharFormat; char bCharFormat;
@ -267,6 +282,7 @@ typedef struct {
char bDataBits; char bDataBits;
} AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING; } AT91S_CDC_LINE_CODING, *AT91PS_CDC_LINE_CODING;
AT91S_CDC_LINE_CODING line = { AT91S_CDC_LINE_CODING line = {
115200, // baudrate 115200, // baudrate
0, // 1 Stop Bit 0, // 1 Stop Bit
@ -277,9 +293,9 @@ AT91S_CDC_LINE_CODING line = {
void AT91F_CDC_Enumerate(); void AT91F_CDC_Enumerate();
AT91PS_UDP pUdp = AT91C_BASE_UDP; AT91PS_UDP pUdp = AT91C_BASE_UDP;
byte_t btConfiguration = 0; uint8_t btConfiguration = 0;
byte_t btConnection = 0; uint8_t btConnection = 0;
byte_t btReceiveBank = AT91C_UDP_RX_DATA_BK0; uint8_t btReceiveBank = AT91C_UDP_RX_DATA_BK0;
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
@ -291,7 +307,7 @@ void usb_disable() {
AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU; AT91C_BASE_PIOA->PIO_ODR = GPIO_USB_PU;
// Clear all lingering interrupts // Clear all lingering interrupts
if(pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) { if (pUdp->UDP_ISR & AT91C_UDP_ENDBUSRES) {
pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES; pUdp->UDP_ICR = AT91C_UDP_ENDBUSRES;
} }
} }
@ -322,7 +338,7 @@ void usb_enable() {
usb_disable(); usb_disable();
// Wait for a short while // Wait for a short while
for (volatile size_t i=0; i<0x100000; i++); for (volatile size_t i = 0; i < 0x100000; i++);
// Reconnect USB reconnect // Reconnect USB reconnect
AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU; AT91C_BASE_PIOA->PIO_SODR = GPIO_USB_PU;
@ -354,8 +370,7 @@ bool usb_check() {
} }
bool usb_poll() bool usb_poll() {
{
if (!usb_check()) return false; if (!usb_check()) return false;
return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank); return (pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank);
} }
@ -369,29 +384,29 @@ bool usb_poll()
that the length available to read is non-zero, thus hopefully fixes the that the length available to read is non-zero, thus hopefully fixes the
bug. bug.
**/ **/
bool usb_poll_validate_length() bool usb_poll_validate_length() {
{
if (!usb_check()) return false; if (!usb_check()) return false;
if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false; if (!(pUdp->UDP_CSR[AT91C_EP_OUT] & btReceiveBank)) return false;
return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0; return (pUdp->UDP_CSR[AT91C_EP_OUT] >> 16) > 0;
} }
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
//* \fn usb_read //* \fn usb_read
//* \brief Read available data from Endpoint OUT //* \brief Read available data from Endpoint OUT
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
uint32_t usb_read(byte_t* data, size_t len) { uint32_t usb_read(uint8_t* data, size_t len) {
byte_t bank = btReceiveBank; uint8_t bank = btReceiveBank;
uint32_t packetSize, nbBytesRcv = 0; uint32_t packetSize, nbBytesRcv = 0;
uint32_t time_out = 0; uint32_t time_out = 0;
while (len) { while (len) {
if (!usb_check()) break; if (!usb_check()) break;
if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) { if ( pUdp->UDP_CSR[AT91C_EP_OUT] & bank ) {
packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len); packetSize = MIN(pUdp->UDP_CSR[AT91C_EP_OUT] >> 16, len);
len -= packetSize; len -= packetSize;
while(packetSize--) while (packetSize--)
data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT]; data[nbBytesRcv++] = pUdp->UDP_FDR[AT91C_EP_OUT];
UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank); UDP_CLEAR_EP_FLAGS(AT91C_EP_OUT, bank);
if (bank == AT91C_UDP_RX_DATA_BK0) { if (bank == AT91C_UDP_RX_DATA_BK0) {
@ -412,7 +427,7 @@ uint32_t usb_read(byte_t* data, size_t len) {
//* \fn usb_write //* \fn usb_write
//* \brief Send through endpoint 2 //* \brief Send through endpoint 2
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
uint32_t usb_write(const byte_t* data, const size_t len) { uint32_t usb_write(const uint8_t* data, const size_t len) {
size_t length = len; size_t length = len;
uint32_t cpt = 0; uint32_t cpt = 0;
@ -439,7 +454,8 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
if (!usb_check()) return length; if (!usb_check()) return length;
} }
UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP); UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
/* wait */;
UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY); UDP_SET_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXPKTRDY);
} }
@ -449,7 +465,8 @@ uint32_t usb_write(const byte_t* data, const size_t len) {
} }
UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP); UDP_CLEAR_EP_FLAGS(AT91C_EP_IN, AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_IN] & AT91C_UDP_TXCOMP)
/* wait */;
return length; return length;
} }
@ -475,7 +492,8 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) { if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)
/* wait */;
} }
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY); UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
@ -487,13 +505,14 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
return; return;
} }
} while ( !(csr & AT91C_UDP_TXCOMP) ); } while (!(csr & AT91C_UDP_TXCOMP));
} while (length); } while (length);
if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) { if (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) {
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)
/* wait */;
} }
} }
@ -504,9 +523,11 @@ static void AT91F_USB_SendData(AT91PS_UDP pUdp, const char *pData, uint32_t leng
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
void AT91F_USB_SendZlp(AT91PS_UDP pUdp) { void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY); UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXPKTRDY);
while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP) ); while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP))
/* wait */;
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_TXCOMP);
while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP); while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_TXCOMP)
/* wait */;
} }
@ -516,9 +537,11 @@ void AT91F_USB_SendZlp(AT91PS_UDP pUdp) {
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
void AT91F_USB_SendStall(AT91PS_UDP pUdp) { void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL); UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL);
while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR) ); while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_ISOERROR))
/* wait */;
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR);
while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR)); while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & (AT91C_UDP_FORCESTALL | AT91C_UDP_ISOERROR))
/* wait */;
} }
@ -527,10 +550,10 @@ void AT91F_USB_SendStall(AT91PS_UDP pUdp) {
//* \brief This function is a callback invoked when a SETUP packet is received //* \brief This function is a callback invoked when a SETUP packet is received
//*---------------------------------------------------------------------------- //*----------------------------------------------------------------------------
void AT91F_CDC_Enumerate() { void AT91F_CDC_Enumerate() {
byte_t bmRequestType, bRequest; uint8_t bmRequestType, bRequest;
uint16_t wValue, wIndex, wLength, wStatus; uint16_t wValue, wIndex, wLength, wStatus;
if ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) ) if (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP))
return; return;
bmRequestType = pUdp->UDP_FDR[AT91C_EP_CONTROL]; bmRequestType = pUdp->UDP_FDR[AT91C_EP_CONTROL];
@ -542,12 +565,14 @@ void AT91F_CDC_Enumerate() {
wLength = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF); wLength = (pUdp->UDP_FDR[AT91C_EP_CONTROL] & 0xFF);
wLength |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8); wLength |= (pUdp->UDP_FDR[AT91C_EP_CONTROL] << 8);
if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host if (bmRequestType & 0x80) { // Data Phase Transfer Direction Device to Host
UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR); UDP_SET_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_DIR);
while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR) ); while (!(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_DIR))
/* wait */;
} }
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RXSETUP);
while ( (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP) ); while (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RXSETUP)
/* wait */;
// Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1 // Handle supported standard device request Cf Table 9-3 in USB specification Rev 1.1
switch ((bRequest << 8) | bmRequestType) { switch ((bRequest << 8) | bmRequestType) {
@ -584,11 +609,11 @@ void AT91F_CDC_Enumerate() {
AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration)); AT91F_USB_SendData(pUdp, (char *) &(btConfiguration), sizeof(btConfiguration));
break; break;
case STD_GET_STATUS_ZERO: case STD_GET_STATUS_ZERO:
wStatus = 0; // Device is Bus powered, remote wakeup disabled wStatus = 0; // Device is Bus powered, remote wakeup disabled
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
break; break;
case STD_GET_STATUS_INTERFACE: case STD_GET_STATUS_INTERFACE:
wStatus = 0; // reserved for future use wStatus = 0; // reserved for future use
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
break; break;
case STD_GET_STATUS_ENDPOINT: case STD_GET_STATUS_ENDPOINT:
@ -597,17 +622,15 @@ void AT91F_CDC_Enumerate() {
if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) { if ((pUdp->UDP_GLBSTATE & AT91C_UDP_CONFG) && (wIndex <= AT91C_EP_NOTIFY)) {
wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
} } else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {
else if ((pUdp->UDP_GLBSTATE & AT91C_UDP_FADDEN) && (wIndex == AT91C_EP_CONTROL)) {
wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1; wStatus = (pUdp->UDP_CSR[wIndex] & AT91C_UDP_EPEDS) ? 0 : 1;
AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus)); AT91F_USB_SendData(pUdp, (char *) &wStatus, sizeof(wStatus));
} } else
else
AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
break; break;
case STD_SET_FEATURE_ZERO: case STD_SET_FEATURE_ZERO:
AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
break; break;
case STD_SET_FEATURE_INTERFACE: case STD_SET_FEATURE_INTERFACE:
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);
break; break;
@ -616,13 +639,12 @@ void AT91F_CDC_Enumerate() {
if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) { if ((wValue == 0) && (wIndex >= AT91C_EP_OUT) && (wIndex <= AT91C_EP_NOTIFY)) {
pUdp->UDP_CSR[wIndex] = 0; pUdp->UDP_CSR[wIndex] = 0;
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);
} } else
else
AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
break; break;
case STD_CLEAR_FEATURE_ZERO: case STD_CLEAR_FEATURE_ZERO:
AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
break; break;
case STD_CLEAR_FEATURE_INTERFACE: case STD_CLEAR_FEATURE_INTERFACE:
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);
break; break;
@ -643,7 +665,8 @@ void AT91F_CDC_Enumerate() {
// handle CDC class requests // handle CDC class requests
case SET_LINE_CODING: case SET_LINE_CODING:
while ( !(pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0) ); while ( (pUdp->UDP_CSR[AT91C_EP_CONTROL] & AT91C_UDP_RX_DATA_BK0))
/* wait */;
UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0); UDP_CLEAR_EP_FLAGS(AT91C_EP_CONTROL, AT91C_UDP_RX_DATA_BK0);
AT91F_USB_SendZlp(pUdp); AT91F_USB_SendZlp(pUdp);
break; break;
@ -656,6 +679,6 @@ void AT91F_CDC_Enumerate() {
break; break;
default: default:
AT91F_USB_SendStall(pUdp); AT91F_USB_SendStall(pUdp);
break; break;
} }
} }

View file

@ -32,18 +32,19 @@
* @brief * @brief
*/ */
#ifndef _USB_CDC_H_ #ifndef USB_CDC_H__
#define _USB_CDC_H_ #define USB_CDC_H__
#include "common.h" #include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
void usb_disable(); extern void usb_disable();
void usb_enable(); extern void usb_enable();
bool usb_check(); extern bool usb_check();
bool usb_poll(); extern bool usb_poll();
bool usb_poll_validate_length(); extern bool usb_poll_validate_length();
uint32_t usb_read(byte_t* data, size_t len); extern uint32_t usb_read(uint8_t* data, size_t len);
uint32_t usb_write(const byte_t* data, const size_t len); extern uint32_t usb_write(const uint8_t* data, const size_t len);
#endif // _USB_CDC_H_
#endif // _USB_CDC_H__

View file

@ -8,12 +8,13 @@
// Utility functions used in many places, not specific to any piece of code. // Utility functions used in many places, not specific to any piece of code.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __UTIL_H #ifndef UTIL_H__
#define __UTIL_H #define UTIL_H__
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "common.h" #include "common.h"
#include "at91sam7s512.h"
#define BYTEx(x, n) (((x) >> (n * 8)) & 0xff ) #define BYTEx(x, n) (((x) >> (n * 8)) & 0xff )
@ -33,40 +34,40 @@
#define REV32(x) (REV16(x) | (REV16(x >> 16) << 16)) #define REV32(x) (REV16(x) | (REV16(x >> 16) << 16))
#define REV64(x) (REV32(x) | (REV32(x >> 32) << 32)) #define REV64(x) (REV32(x) | (REV32(x >> 32) << 32))
void print_result(char *name, uint8_t *buf, size_t len); extern void print_result(char *name, uint8_t *buf, size_t len);
size_t nbytes(size_t nbits); extern size_t nbytes(size_t nbits);
uint32_t SwapBits(uint32_t value, int nrbits); extern uint32_t SwapBits(uint32_t value, int nrbits);
void num_to_bytes(uint64_t n, size_t len, uint8_t* dest); extern void num_to_bytes(uint64_t n, size_t len, uint8_t* dest);
uint64_t bytes_to_num(uint8_t* src, size_t len); extern uint64_t bytes_to_num(uint8_t* src, size_t len);
void rol(uint8_t *data, const size_t len); extern void rol(uint8_t *data, const size_t len);
void lsl (uint8_t *data, size_t len); extern void lsl (uint8_t *data, size_t len);
void LED(int led, int ms); extern void LED(int led, int ms);
void LEDsoff(); extern void LEDsoff();
void LEDson(); extern void LEDson();
void LEDsinvert(); extern void LEDsinvert();
int BUTTON_CLICKED(int ms); extern int BUTTON_CLICKED(int ms);
int BUTTON_HELD(int ms); extern int BUTTON_HELD(int ms);
void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information); extern void FormatVersionInformation(char *dst, int len, const char *prefix, void *version_information);
//iceman's ticks.h //iceman's ticks.h
#ifndef GET_TICKS #ifndef GET_TICKS
# define GET_TICKS GetTicks() # define GET_TICKS GetTicks()
#endif #endif
void SpinDelay(int ms); extern void SpinDelay(int ms);
void SpinDelayUs(int us); extern void SpinDelayUs(int us);
void StartTickCount(); extern void StartTickCount();
uint32_t RAMFUNC GetTickCount(); extern uint32_t RAMFUNC GetTickCount();
void StartCountUS(); extern void StartCountUS();
uint32_t RAMFUNC GetCountUS(); extern uint32_t RAMFUNC GetCountUS();
uint32_t RAMFUNC GetDeltaCountUS(); extern uint32_t RAMFUNC GetDeltaCountUS();
void StartCountSspClk(); extern void StartCountSspClk();
void ResetSspClk(void); extern void ResetSspClk(void);
uint32_t GetCountSspClk(); extern uint32_t GetCountSspClk();
extern void StartTicks(void); extern void StartTicks(void);
extern uint32_t GetTicks(void); extern uint32_t GetTicks(void);
@ -78,6 +79,6 @@ extern void ResetTimer(AT91PS_TC timer);
extern void StopTicks(void); extern void StopTicks(void);
// end iceman's ticks.h // end iceman's ticks.h
uint32_t prand(); extern uint32_t prand();
#endif #endif

View file

@ -9,13 +9,9 @@
// Interlib Definitions // Interlib Definitions
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __COMMON_H #ifndef COMMON_H__
#define __COMMON_H #define COMMON_H__
#include <stddef.h>
#include <stdint.h>
#include <stdbool.h>
#include <at91sam7s512.h>
typedef unsigned char byte_t; typedef unsigned char byte_t;
#ifndef MIN #ifndef MIN
@ -25,10 +21,9 @@ typedef unsigned char byte_t;
# define MAX(a, b) (((a) > (b)) ? (a) : (b)) # define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif #endif
#ifndef ABS #ifndef ABS
# define ABS(a) ( ((a)<0) ? -(a) : (a) ) # define ABS(a) (((a) < 0) ? -(a) : (a))
#endif #endif
#define RAMFUNC __attribute((long_call, section(".ramfunc"))) #define RAMFUNC __attribute((long_call, section(".ramfunc")))
#endif #endif

View file

@ -10,13 +10,13 @@
// own protocol. // own protocol.
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
#ifndef __USB_CMD_H #ifndef USB_CMD_H__
#define __USB_CMD_H #define USB_CMD_H__
#ifdef _MSC_VER #ifdef _MSC_VER
typedef DWORD uint32_t; typedef DWORD uint32_t;
typedef BYTE uint8_t; typedef BYTE uint8_t;
#define PACKED #define PACKED
// stuff
#else #else
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@ -26,16 +26,17 @@ typedef BYTE uint8_t;
#define USB_CMD_DATA_SIZE 512 #define USB_CMD_DATA_SIZE 512
typedef struct { typedef struct {
uint64_t cmd; uint64_t cmd;
uint64_t arg[3]; uint64_t arg[3];
union { union {
uint8_t asBytes[USB_CMD_DATA_SIZE]; uint8_t asBytes[USB_CMD_DATA_SIZE];
uint32_t asDwords[USB_CMD_DATA_SIZE/4]; uint32_t asDwords[USB_CMD_DATA_SIZE/4];
} d; } d;
} PACKED UsbCommand; } PACKED UsbCommand;
// A struct used to send sample-configs over USB // A struct used to send sample-configs over USB
typedef struct{ typedef struct {
uint8_t decimation; uint8_t decimation;
uint8_t bits_per_sample; uint8_t bits_per_sample;
bool averaging; bool averaging;
@ -44,6 +45,7 @@ typedef struct{
int samples_to_skip; int samples_to_skip;
} sample_config; } sample_config;
// For the bootloader // For the bootloader
#define CMD_DEVICE_INFO 0x0000 #define CMD_DEVICE_INFO 0x0000
#define CMD_SETUP_WRITE 0x0001 #define CMD_SETUP_WRITE 0x0001
@ -165,7 +167,7 @@ typedef struct{
#define CMD_ICLASS_WRITEBLOCK 0x0397 #define CMD_ICLASS_WRITEBLOCK 0x0397
#define CMD_ICLASS_EML_MEMSET 0x0398 #define CMD_ICLASS_EML_MEMSET 0x0398
#define CMD_ICLASS_CHECK 0x0399 #define CMD_ICLASS_CHECK 0x0399
#define CMD_ICLASS_READCHECK 0x039A #define CMD_ICLASS_READCHECK 0x039A
// For measurements of the antenna tuning // For measurements of the antenna tuning
#define CMD_MEASURE_ANTENNA_TUNING 0x0400 #define CMD_MEASURE_ANTENNA_TUNING 0x0400
@ -208,7 +210,7 @@ typedef struct{
#define CMD_MIFAREU_WRITEBL 0x0722 #define CMD_MIFAREU_WRITEBL 0x0722
#define CMD_MIFAREU_WRITEBL_COMPAT 0x0723 #define CMD_MIFAREU_WRITEBL_COMPAT 0x0723
#define CMD_MIFAREUC_AUTH 0x0724 #define CMD_MIFAREUC_AUTH 0x0724
//0x0725 and 0x0726 no longer used //0x0725 and 0x0726 no longer used
#define CMD_MIFAREUC_SETPWD 0x0727 #define CMD_MIFAREUC_SETPWD 0x0727
@ -228,11 +230,11 @@ typedef struct{
// Mifare simulation flags // Mifare simulation flags
#define FLAG_INTERACTIVE (1<<0) #define FLAG_INTERACTIVE (1<<0)
#define FLAG_4B_UID_IN_DATA (1<<1) #define FLAG_4B_UID_IN_DATA (1<<1)
#define FLAG_7B_UID_IN_DATA (1<<2) #define FLAG_7B_UID_IN_DATA (1<<2)
#define FLAG_NR_AR_ATTACK (1<<4) #define FLAG_NR_AR_ATTACK (1<<4)
#define FLAG_RANDOM_NONCE (1<<5) #define FLAG_RANDOM_NONCE (1<<5)
// iCLASS reader flags // iCLASS reader flags
@ -266,19 +268,19 @@ typedef struct{
// CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions: // CMD_DEVICE_INFO response packet has flags in arg[0], flag definitions:
/* Whether a bootloader that understands the common_area is present */ /* Whether a bootloader that understands the common_area is present */
#define DEVICE_INFO_FLAG_BOOTROM_PRESENT (1<<0) #define DEVICE_INFO_FLAG_BOOTROM_PRESENT (1<<0)
/* Whether a osimage that understands the common_area is present */ /* Whether a osimage that understands the common_area is present */
#define DEVICE_INFO_FLAG_OSIMAGE_PRESENT (1<<1) #define DEVICE_INFO_FLAG_OSIMAGE_PRESENT (1<<1)
/* Set if the bootloader is currently executing */ /* Set if the bootloader is currently executing */
#define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM (1<<2) #define DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM (1<<2)
/* Set if the OS is currently executing */ /* Set if the OS is currently executing */
#define DEVICE_INFO_FLAG_CURRENT_MODE_OS (1<<3) #define DEVICE_INFO_FLAG_CURRENT_MODE_OS (1<<3)
/* Set if this device understands the extend start flash command */ /* Set if this device understands the extend start flash command */
#define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4) #define DEVICE_INFO_FLAG_UNDERSTANDS_START_FLASH (1<<4)
/* CMD_START_FLASH may have three arguments: start of area to flash, /* CMD_START_FLASH may have three arguments: start of area to flash,
end of area to flash, optional magic. end of area to flash, optional magic.