mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
First pass rewrite of flashmem driver for optimization. Lot of changes here. Provides PoC of saving and recalling a tag in Standalone mode. Added some printing passthrough to client to azccomodate for vt100 eye-candyness. FastREAD mode implemented for flashmem, testable from client. Beta but functionnal. Reading the whole flash with 1Kb to 32kb buffers was ~730ms, now 380ms Max (even at 24Mhz spi baudrate)
This commit is contained in:
parent
41ca388edc
commit
8d673fa1bf
8 changed files with 865 additions and 292 deletions
|
@ -24,7 +24,7 @@ APP_CFLAGS = -DWITH_CRC \
|
||||||
-DWITH_FLASH \
|
-DWITH_FLASH \
|
||||||
-DWITH_SMARTCARD \
|
-DWITH_SMARTCARD \
|
||||||
-DWITH_HFSNOOP \
|
-DWITH_HFSNOOP \
|
||||||
-DWITH_LF_SAMYRUN \
|
-DWITH_HF_COLIN \
|
||||||
-fno-strict-aliasing -ffunction-sections -fdata-sections
|
-fno-strict-aliasing -ffunction-sections -fdata-sections
|
||||||
|
|
||||||
### IMPORTANT - move the commented variable below this line
|
### IMPORTANT - move the commented variable below this line
|
||||||
|
@ -106,12 +106,9 @@ ARMSRC = fpgaloader.c \
|
||||||
parity.c \
|
parity.c \
|
||||||
usb_cdc.c \
|
usb_cdc.c \
|
||||||
cmd.c \
|
cmd.c \
|
||||||
lf_samyrun.c \
|
vtsend.c \
|
||||||
vtsend.c
|
hf_colin.c \
|
||||||
# lf_samyrun.c \
|
lib_AT91SAM7.c
|
||||||
# lf_hidbrute.c \
|
|
||||||
# lf_proxbrute.c \
|
|
||||||
# hf_mattyrun.c \
|
|
||||||
|
|
||||||
VERSIONSRC = version.c \
|
VERSIONSRC = version.c \
|
||||||
fpga_version_info.c
|
fpga_version_info.c
|
||||||
|
@ -120,7 +117,6 @@ VERSIONSRC = version.c \
|
||||||
include ../common/Makefile.common
|
include ../common/Makefile.common
|
||||||
|
|
||||||
COMMON_FLAGS = -Os
|
COMMON_FLAGS = -Os
|
||||||
|
|
||||||
OBJS = $(OBJDIR)/fullimage.s19
|
OBJS = $(OBJDIR)/fullimage.s19
|
||||||
FPGA_COMPRESSOR = ../client/fpga_compress
|
FPGA_COMPRESSOR = ../client/fpga_compress
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -16,18 +16,21 @@
|
||||||
#ifndef __HF_COLIN_H
|
#ifndef __HF_COLIN_H
|
||||||
#define __HF_COLIN_H
|
#define __HF_COLIN_H
|
||||||
|
|
||||||
#include <stdbool.h> // for bool
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "standalone.h" // standalone definitions
|
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
#include "iso14443a.h"
|
#include "iso14443a.h"
|
||||||
|
//#include "printf.h"
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "standalone.h" // standalone definitions
|
||||||
|
#include <stdbool.h> // for bool
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
//#include <stdio.h>
|
||||||
#include "vtsend.h"
|
#include "vtsend.h"
|
||||||
#include "apps.h"
|
#include "apps.h"
|
||||||
#include "usb_cmd.h" // mifare1ksim flags
|
#include "printf.h"
|
||||||
|
|
||||||
#define _RED_ "\x1b[31m"
|
#define _RED_ "\x1b[31m"
|
||||||
#define _GREEN_ "\x1b[32m"
|
#define _GREEN_ "\x1b[32m"
|
||||||
|
@ -38,14 +41,19 @@
|
||||||
#define _WHITE_ "\x1b[0m"
|
#define _WHITE_ "\x1b[0m"
|
||||||
#define _ORANGE_ _YELLOW_
|
#define _ORANGE_ _YELLOW_
|
||||||
|
|
||||||
|
#define NTIME(n) for (int _index = 0; _index < n; _index++)
|
||||||
|
|
||||||
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key);
|
int cjat91_saMifareChkKeys(uint8_t blockNo, uint8_t keyType, bool clearTrace, uint8_t keyCount, uint8_t *datain, uint64_t *key);
|
||||||
void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void e_MifareECardLoad(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
void saMifareMakeTag(void);
|
void saMifareMakeTag(void);
|
||||||
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
int saMifareCSetBlock(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug);
|
void cjPrintBigArray(const char *bigar, int len, uint8_t newlines, uint8_t debug);
|
||||||
|
void WriteTagToFlash(uint8_t index, size_t size);
|
||||||
|
|
||||||
const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'};
|
const char clearTerm[8] = {0x1b, 0x5b, 0x48, 0x1b, 0x5b, 0x32, 0x4a, '\0'};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define LOGO logo_kigiv
|
#define LOGO logo_kigiv
|
||||||
|
|
||||||
const char sub_banner[] = " From Vigik : \"20 years of (un)security without a single update\"";
|
const char sub_banner[] = " From Vigik : \"20 years of (un)security without a single update\"";
|
||||||
|
@ -410,7 +418,7 @@ const char logo_kigiv[] = {
|
||||||
0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x0d, 0x0a};
|
0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x35, 0x3b, 0x35, 0x39, 0x6d, 0x31, 0x0d, 0x0a};
|
||||||
unsigned int logo_kigiv_len = 9303;
|
unsigned int logo_kigiv_len = 9303;
|
||||||
|
|
||||||
const char logo_kigiv_nocolor[] = {
|
/*const char logo_kigiv_nocolor[] = {
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x30, 0x30, 0x30, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
|
@ -494,6 +502,6 @@ const char logo_kigiv_nocolor[] = {
|
||||||
0x30, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x31,
|
0x30, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x30, 0x31, 0x31,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x30, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x30, 0x31, 0x31, 0x0d, 0x0a};
|
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x31, 0x31, 0x30, 0x31, 0x31, 0x0d, 0x0a};
|
||||||
unsigned int logo_kigiv_nocolor_len = 2153;
|
unsigned int logo_kigiv_nocolor_len = 2153;*/
|
||||||
|
|
||||||
#endif /* __HF_COLIN_H */
|
#endif /* __HF_COLIN_H */
|
||||||
|
|
|
@ -33,10 +33,6 @@
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_FPC
|
|
||||||
#include "usart.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// A buffer where we can queue things up to be sent through the FPGA, for
|
// A buffer where we can queue things up to be sent through the FPGA, for
|
||||||
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
|
// any purpose (fake tag, as reader, whatever). We go MSB first, since that
|
||||||
|
@ -78,26 +74,24 @@ void PrintToSendBuffer(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_result(char *name, uint8_t *buf, size_t len) {
|
void print_result(char *name, uint8_t *buf, size_t len) {
|
||||||
|
|
||||||
uint8_t *p = buf;
|
uint8_t *p = buf;
|
||||||
uint16_t tmp = len & 0xFFF0;
|
|
||||||
|
|
||||||
for(; p-buf < tmp; p += 16) {
|
if ( len % 16 == 0 ) {
|
||||||
Dbprintf("[%s: %02d/%02d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
for(; p-buf < len; p += 16)
|
||||||
|
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
name,
|
name,
|
||||||
p-buf,
|
p-buf,
|
||||||
len,
|
len,
|
||||||
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
|
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7],p[8], p[9], p[10], p[11], p[12], p[13], p[14], p[15]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (len % 16 != 0) {
|
else {
|
||||||
char s[46] = {0};
|
for(; p-buf < len; p += 8)
|
||||||
char *sp = s;
|
Dbprintf("[%s:%d/%d] %02x %02x %02x %02x %02x %02x %02x %02x",
|
||||||
for (; p-buf < len; p++ ) {
|
name,
|
||||||
sprintf(sp, "%02x ", p[0] );
|
p-buf,
|
||||||
sp += 3;
|
len,
|
||||||
}
|
p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]);
|
||||||
Dbprintf("[%s: %02d/%02d] %s", name, p-buf, len, s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +101,7 @@ void print_result(char *name, uint8_t *buf, size_t len) {
|
||||||
|
|
||||||
void DbpStringEx(char *str, uint32_t cmd) {
|
void DbpStringEx(char *str, uint32_t cmd) {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
uint8_t len = strlen(str);
|
byte_t len = strlen(str);
|
||||||
cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (byte_t*)str, len);
|
cmd_send(CMD_DEBUG_PRINT_STRING, len, cmd, 0, (byte_t*)str, len);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -119,7 +113,7 @@ void DbpString(char *str) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
void DbpIntegers(int x1, int x2, int x3) {
|
void DbpIntegers(inst x1, int x2, int x3) {
|
||||||
cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
|
cmd_send(CMD_DEBUG_PRINT_INTEGERS,x1,x2,x3,0,0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -440,7 +434,7 @@ void printStandAloneModes(void) {
|
||||||
DbpString(" LF HID corporate 1000 bruteforce - (Federico dotta & Maurizio Agazzini)");
|
DbpString(" LF HID corporate 1000 bruteforce - (Federico dotta & Maurizio Agazzini)");
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_HF_MATTYRUN)
|
#if defined(WITH_HF_MATTYRUN)
|
||||||
DbpString(" HF Mifare sniff/clone - aka MattyRun (Matías A. Ré Medina)");
|
DbpString(" HF Mifare sniff/clone - aka MattyRun (Mat<EFBFBD>as A. R<> Medina)");
|
||||||
#endif
|
#endif
|
||||||
#if defined(WITH_HF_COLIN)
|
#if defined(WITH_HF_COLIN)
|
||||||
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
DbpString(" HF Mifare ultra fast sniff/sim/clone - aka VIGIKPWN (Colin Brigato)");
|
||||||
|
@ -448,7 +442,6 @@ void printStandAloneModes(void) {
|
||||||
|
|
||||||
//DbpString("Running ");
|
//DbpString("Running ");
|
||||||
//Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No");
|
//Dbprintf(" Is Device attached to USB| %s", USB_ATTACHED() ? "Yes" : "No");
|
||||||
//Dbprintf(" Is Device attached to FPC| %s", 0 ? "Yes" : "No");
|
|
||||||
//Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() );
|
//Dbprintf(" Is USB_reconnect value | %d", GetUSBreconnect() );
|
||||||
//Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() );
|
//Dbprintf(" Is USB_configured value | %d", GetUSBconfigured() );
|
||||||
|
|
||||||
|
@ -1077,7 +1070,6 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
#endif
|
#endif
|
||||||
case CMD_BUFF_CLEAR:
|
case CMD_BUFF_CLEAR:
|
||||||
BigBuf_Clear();
|
BigBuf_Clear();
|
||||||
BigBuf_free();
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_MEASURE_ANTENNA_TUNING:
|
case CMD_MEASURE_ANTENNA_TUNING:
|
||||||
|
@ -1114,7 +1106,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE);
|
len = MIN( (numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len);
|
isok = cmd_send(CMD_DOWNLOADED_RAW_ADC_SAMPLES_125K, i, len, BigBuf_get_traceLen(), mem + startidx + i, len);
|
||||||
if (!isok)
|
if (!isok)
|
||||||
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
// iceman, when did sending samplingconfig array got attached here?!?
|
// iceman, when did sending samplingconfig array got attached here?!?
|
||||||
|
@ -1160,7 +1152,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
|
isok = cmd_send(CMD_DOWNLOADED_EML_BIGBUF, i, len, 0, mem + startidx + i, len);
|
||||||
if (!isok)
|
if (!isok)
|
||||||
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||||
}
|
}
|
||||||
// Trigger a finish downloading signal with an ACK frame
|
// Trigger a finish downloading signal with an ACK frame
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
|
@ -1177,6 +1169,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
uint16_t isok = 0;
|
uint16_t isok = 0;
|
||||||
uint32_t startidx = c->arg[0];
|
uint32_t startidx = c->arg[0];
|
||||||
uint16_t len = c->arg[1];
|
uint16_t len = c->arg[1];
|
||||||
|
uint8_t fast = c->arg[2];
|
||||||
|
|
||||||
Dbprintf("FlashMem read | %d - %d", startidx, len);
|
Dbprintf("FlashMem read | %d - %d", startidx, len);
|
||||||
|
|
||||||
|
@ -1184,14 +1177,23 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
|
|
||||||
uint8_t *mem = BigBuf_malloc(size);
|
uint8_t *mem = BigBuf_malloc(size);
|
||||||
|
|
||||||
|
|
||||||
|
if (fast) {
|
||||||
|
FlashInit(1);
|
||||||
|
//FlashInit();
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
}
|
||||||
for(size_t i = 0; i < len; i += size) {
|
for(size_t i = 0; i < len; i += size) {
|
||||||
len = MIN((len - i), size);
|
len = MIN((len - i), size);
|
||||||
|
|
||||||
memset(mem, 0, len);
|
|
||||||
|
|
||||||
Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len);
|
Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len);
|
||||||
|
|
||||||
|
if (!fast){
|
||||||
isok = Flash_ReadData(startidx + i, mem, len);
|
isok = Flash_ReadData(startidx + i, mem, len);
|
||||||
|
}
|
||||||
|
if (fast){
|
||||||
|
isok = Flash_FastReadDataCont(startidx + i, mem, len);
|
||||||
|
}
|
||||||
if ( isok == len ) {
|
if ( isok == len ) {
|
||||||
print_result("Chunk: ", mem, len);
|
print_result("Chunk: ", mem, len);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1199,6 +1201,9 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (fast){
|
||||||
|
FlashStop();
|
||||||
|
}
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1271,21 +1276,36 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
uint32_t startidx = c->arg[0];
|
uint32_t startidx = c->arg[0];
|
||||||
uint32_t numofbytes = c->arg[1];
|
uint32_t numofbytes = c->arg[1];
|
||||||
|
uint8_t fast = c->arg[2];
|
||||||
|
|
||||||
// arg0 = startindex
|
// arg0 = startindex
|
||||||
// arg1 = length bytes to transfer
|
// arg1 = length bytes to transfer
|
||||||
// arg2 = RFU
|
// arg2 = RFU
|
||||||
|
|
||||||
|
|
||||||
|
if (fast) {
|
||||||
|
FlashInit(1);
|
||||||
|
//FlashInit();
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
}
|
||||||
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
for (size_t i = 0; i < numofbytes; i += USB_CMD_DATA_SIZE) {
|
||||||
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
len = MIN((numofbytes - i), USB_CMD_DATA_SIZE);
|
||||||
|
if (!fast){
|
||||||
isok = Flash_ReadData(startidx + i, mem, len);
|
isok = Flash_ReadData(startidx + i, mem, len);
|
||||||
|
}
|
||||||
|
if (fast){
|
||||||
|
isok = Flash_FastReadDataCont(startidx + i, mem, len);
|
||||||
|
}
|
||||||
if (!isok )
|
if (!isok )
|
||||||
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
|
Dbprintf("reading flash memory failed :: | bytes between %d - %d", i, len);
|
||||||
|
|
||||||
isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len);
|
isok = cmd_send(CMD_DOWNLOADED_FLASHMEM, i, len, 0, mem, len);
|
||||||
if (!isok)
|
if (!isok)
|
||||||
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
|
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
|
||||||
|
}
|
||||||
|
if (fast){
|
||||||
|
FlashStop();
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
cmd_send(CMD_ACK, 1, 0, 0, 0, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
|
@ -1297,7 +1317,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
|
||||||
|
|
||||||
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN);
|
bool isok = Flash_ReadData(FLASH_MEM_SIGNATURE_OFFSET, info->signature, FLASH_MEM_SIGNATURE_LEN);
|
||||||
|
|
||||||
if (FlashInit()) {
|
if (FlashInit(0)) {
|
||||||
Flash_UniqueID( info->flashid);
|
Flash_UniqueID( info->flashid);
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
||||||
|
@ -1392,8 +1412,6 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
|
|
||||||
LEDsoff();
|
LEDsoff();
|
||||||
|
|
||||||
usb_enable();
|
|
||||||
|
|
||||||
// The FPGA gets its clock from us from PCK0 output, so set that up.
|
// The FPGA gets its clock from us from PCK0 output, so set that up.
|
||||||
AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
|
AT91C_BASE_PIOA->PIO_BSR = GPIO_PCK0;
|
||||||
AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
|
AT91C_BASE_PIOA->PIO_PDR = GPIO_PCK0;
|
||||||
|
@ -1419,16 +1437,22 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
StartTickCount();
|
StartTickCount();
|
||||||
|
|
||||||
#ifdef WITH_LCD
|
#ifdef WITH_LCD
|
||||||
LCDInit();
|
// LCDInit();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_SMARTCARD
|
#ifdef WITH_SMARTCARD
|
||||||
I2C_init();
|
// I2C_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef WITH_FPC
|
#ifdef WITH_FPC
|
||||||
usart_init();
|
// usart_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// This is made as late as possible to ensure enumeration without timeout
|
||||||
|
// against device such as http://www.hobbytronics.co.uk/usb-host-board-v2
|
||||||
|
usb_disable();
|
||||||
|
usb_enable();
|
||||||
|
|
||||||
uint8_t rx[sizeof(UsbCommand)];
|
uint8_t rx[sizeof(UsbCommand)];
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
@ -1464,6 +1488,10 @@ void __attribute__((noreturn)) AppMain(void) {
|
||||||
RunMod();
|
RunMod();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// when here, we are no longer in standalone mode.
|
||||||
|
// reseting the variables which keeps track of usb re-attached/configured
|
||||||
|
//SetUSBreconnect(0);
|
||||||
|
//SetUSBconfigured(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,39 +1,43 @@
|
||||||
#include "flashmem.h"
|
#include "flashmem.h"
|
||||||
|
|
||||||
|
|
||||||
|
#define MCK 48000000
|
||||||
|
//#define FLASH_BAUD 24000000
|
||||||
|
//define FLASH_BAUD 33000000
|
||||||
|
#define FLASH_BAUD MCK/2
|
||||||
|
#define FLASH_FASTBAUD MCK
|
||||||
|
|
||||||
/* here: use NCPS2 @ PA10: */
|
/* here: use NCPS2 @ PA10: */
|
||||||
#define SPI_CSR_NUM 2 // Chip Select register[] 0,1,2,3 (at91samv512 has 4)
|
#define SPI_CSR_NUM 2
|
||||||
|
#define SPI_PCS(npcs) ((~(1 << (npcs)) & 0xF) << 16)
|
||||||
/* PCS_0 for NPCS0, PCS_1 for NPCS1 ... */
|
/// Calculates the value of the CSR SCBR field given the baudrate and MCK.
|
||||||
#define PCS_0 ((0<<0)|(1<<1)|(1<<2)|(1<<3)) // 0xE - 1110
|
#define SPI_SCBR(baudrate, masterClock) ((uint32_t) ((masterClock) / (baudrate)) << 8)
|
||||||
#define PCS_1 ((1<<0)|(0<<1)|(1<<2)|(1<<3)) // 0xD - 1101
|
/// Calculates the value of the CSR DLYBS field given the desired delay (in ns)
|
||||||
#define PCS_2 ((1<<0)|(1<<1)|(0<<2)|(1<<3)) // 0xB - 1011
|
#define SPI_DLYBS(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 1000) << 16)
|
||||||
#define PCS_3 ((1<<0)|(1<<1)|(1<<2)|(0<<3)) // 0x7 - 0111
|
/// Calculates the value of the CSR DLYBCT field given the desired delay (in ns)
|
||||||
|
#define SPI_DLYBCT(delay, masterClock) ((uint32_t) ((((masterClock) / 1000000) * (delay)) / 32000) << 24)
|
||||||
// TODO
|
|
||||||
#if (SPI_CSR_NUM == 0)
|
|
||||||
#define SPI_MR_PCS PCS_0
|
|
||||||
#elif (SPI_CSR_NUM == 1)
|
|
||||||
#define SPI_MR_PCS PCS_1
|
|
||||||
#elif (SPI_CSR_NUM == 2)
|
|
||||||
#define SPI_MR_PCS PCS_2
|
|
||||||
#elif (SPI_CSR_NUM == 3)
|
|
||||||
#define SPI_MR_PCS PCS_3
|
|
||||||
#else
|
|
||||||
#error "SPI_CSR_NUM invalid"
|
|
||||||
// not realy - when using an external address decoder...
|
|
||||||
// but this code takes over the complete SPI-interace anyway
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
读取指令,可以从一个位置开始持续的读,最多能将整块芯片读取完
|
|
||||||
页写指令,每次写入为1-256字节,但是不能跨越256字节边界
|
|
||||||
擦除指令,擦除指令后必须将CS拉高,否则不会执行
|
|
||||||
*/
|
|
||||||
|
|
||||||
void FlashSetup(void) {
|
// initialize
|
||||||
// PA1 -> SPI_NCS3 chip select (MEM)
|
bool FlashInit(bool fast) {
|
||||||
// PA10 -> SPI_NCS2 chip select (LCD)
|
FlashSetup(fast);
|
||||||
|
|
||||||
|
StartTicks();
|
||||||
|
|
||||||
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) {
|
||||||
|
StopTicks();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlashSetup(bool fast){
|
||||||
|
//WDT_DISABLE
|
||||||
|
AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS;
|
||||||
|
|
||||||
|
// PA10 -> SPI_NCS2 chip select (FLASHMEM)
|
||||||
// PA11 -> SPI_NCS0 chip select (FPGA)
|
// PA11 -> SPI_NCS0 chip select (FPGA)
|
||||||
// PA12 -> SPI_MISO Master-In Slave-Out
|
// PA12 -> SPI_MISO Master-In Slave-Out
|
||||||
// PA13 -> SPI_MOSI Master-Out Slave-In
|
// PA13 -> SPI_MOSI Master-Out Slave-In
|
||||||
|
@ -54,27 +58,71 @@ void FlashSetup(void) {
|
||||||
//enable the SPI Peripheral clock
|
//enable the SPI Peripheral clock
|
||||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_SPI);
|
||||||
|
|
||||||
|
|
||||||
|
//reset spi needs double SWRST, see atmel's errata on this case
|
||||||
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||||
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
|
||||||
|
|
||||||
// Enable SPI
|
// Enable SPI
|
||||||
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
|
||||||
|
|
||||||
// NPCS2 Mode 0
|
// NPCS2 Mode 0
|
||||||
AT91C_BASE_SPI->SPI_MR =
|
AT91C_BASE_SPI->SPI_MR =
|
||||||
( 0 << 24) | // Delay between chip selects (take default: 6 MCK periods)
|
(0 << 24) | // Delay between chip selects = DYLBCS/MCK BUT:
|
||||||
(0xB << 16) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
|
// If DLYBCS is less than or equal to six, six MCK periods
|
||||||
( 0 << 7) | // Local Loopback Disabled
|
// will be inserted by default.
|
||||||
( 1 << 4) | // Mode Fault Detection disabled
|
SPI_PCS(SPI_CSR_NUM) | // Peripheral Chip Select (selects SPI_NCS2 or PA10)
|
||||||
( 0 << 2) | // Chip selects connected directly to peripheral
|
( 0 << 7) | // Disable LLB (1=MOSI2MISO test mode)
|
||||||
( 0 << 1) | // Fixed Peripheral Select
|
( 1 << 4) | // Disable ModeFault Protection
|
||||||
( 1 << 0); // Master Mode
|
( 0 << 3) | // makes spi operate at MCK (1 is MCK/2)
|
||||||
|
( 0 << 2) | // Chip selects connected directly to peripheral
|
||||||
|
AT91C_SPI_PS_FIXED | // Fixed Peripheral Select
|
||||||
|
AT91C_SPI_MSTR; // Master Mode
|
||||||
|
|
||||||
|
int baudrate = FLASH_BAUD;
|
||||||
|
uint8_t csaat = 1;
|
||||||
|
int dlybct = 0;
|
||||||
|
if (fast) {
|
||||||
|
baudrate = FLASH_FASTBAUD;
|
||||||
|
//csaat = 0;
|
||||||
|
dlybct = MCK/32;
|
||||||
|
}
|
||||||
|
|
||||||
// 8 bit
|
|
||||||
AT91C_BASE_SPI->SPI_CSR[2] =
|
AT91C_BASE_SPI->SPI_CSR[2] =
|
||||||
( 0 << 24) | // Delay between Consecutive Transfers (32 MCK periods)
|
SPI_DLYBCT(dlybct,MCK) | // Delay between Consecutive Transfers (32 MCK periods)
|
||||||
( 0 << 16) | // Delay Before SPCK (1 MCK period)
|
SPI_DLYBS(0,MCK) | // Delay Beforce SPCK CLock
|
||||||
( 6 << 8) | // Serial Clock Baud Rate (baudrate = MCK/6 = 24Mhz/6 = 4M baud
|
SPI_SCBR(baudrate,MCK) | // SPI Baudrate Selection
|
||||||
( 0 << 4) | // Bits per Transfer (8 bits)
|
AT91C_SPI_BITS_8 | // Bits per Transfer (8 bits)
|
||||||
( 1 << 3) | // Chip Select inactive after transfer
|
//AT91C_SPI_CSAAT | // Chip Select inactive after transfer
|
||||||
( 1 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
// 40.4.6.2 SPI: Bad tx_ready Behavior when CSAAT = 1 and SCBR = 1
|
||||||
|
// If the SPI is programmed with CSAAT = 1, SCBR(baudrate) = 1 and two transfers are performed consecutively on
|
||||||
|
// the same slave with an IDLE state between them, the tx_ready signal does not rise after the second data has been
|
||||||
|
// transferred in the shifter. This can imply for example, that the second data is sent twice.
|
||||||
|
// COLIN :: For now we STILL use CSAAT=1 to avoid having to (de)assert NPCS manually via PIO lines and we deal with delay
|
||||||
|
( csaat << 3) |
|
||||||
|
/* Spi modes:
|
||||||
|
Mode CPOL CPHA NCPHA
|
||||||
|
0 0 0 1 clock normally low read on rising edge
|
||||||
|
1 0 1 0 clock normally low read on falling edge
|
||||||
|
2 1 0 1 clock normally high read on falling edge
|
||||||
|
3 1 1 0 clock normally high read on rising edge
|
||||||
|
However, page 512 of the AT91SAM7Sx datasheet say "Note that in SPI
|
||||||
|
master mode the ATSAM7S512/256/128/64/321/32 does not sample the data
|
||||||
|
(MISO) on the opposite edge where data clocks out (MOSI) but the same
|
||||||
|
edge is used as shown in Figure 36-3 and Figure 36-4." Figure 36-3
|
||||||
|
shows that CPOL=NCPHA=0 or CPOL=NCPHA=1 samples on the rising edge and
|
||||||
|
that the data changes sometime after the rising edge (about 2 ns). To
|
||||||
|
be consistent with normal SPI operation, it is probably safe to say
|
||||||
|
that the data changes on the falling edge and should be sampled on the
|
||||||
|
rising edge. Therefore, it appears that NCPHA should be treated the
|
||||||
|
same as CPHA. Thus:
|
||||||
|
Mode CPOL CPHA NCPHA
|
||||||
|
0 0 0 0 clock normally low read on rising edge
|
||||||
|
1 0 1 1 clock normally low read on falling edge
|
||||||
|
2 1 0 0 clock normally high read on falling edge
|
||||||
|
3 1 1 1 clock normally high read on rising edge
|
||||||
|
*/
|
||||||
|
( 0 << 1) | // Clock Phase data captured on leading edge, changes on following edge
|
||||||
( 0 << 0); // Clock Polarity inactive state is logic 0
|
( 0 << 0); // Clock Polarity inactive state is logic 0
|
||||||
|
|
||||||
// read first, empty buffer
|
// read first, empty buffer
|
||||||
|
@ -82,6 +130,7 @@ void FlashSetup(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlashStop(void) {
|
void FlashStop(void) {
|
||||||
|
//Bof
|
||||||
//* Reset all the Chip Select register
|
//* Reset all the Chip Select register
|
||||||
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
AT91C_BASE_SPI->SPI_CSR[0] = 0;
|
||||||
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
AT91C_BASE_SPI->SPI_CSR[1] = 0;
|
||||||
|
@ -104,24 +153,21 @@ void FlashStop(void) {
|
||||||
|
|
||||||
// send one byte over SPI
|
// send one byte over SPI
|
||||||
uint16_t FlashSendByte(uint32_t data) {
|
uint16_t FlashSendByte(uint32_t data) {
|
||||||
uint16_t incoming = 0;
|
|
||||||
|
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
// wait until SPI is ready for transfer
|
// wait until SPI is ready for transfer
|
||||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
|
//if you are checking for incoming data returned then the TXEMPTY flag is redundant
|
||||||
|
//while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TXEMPTY) == 0) {};
|
||||||
|
|
||||||
// send the data
|
// send the data
|
||||||
AT91C_BASE_SPI->SPI_TDR = data;
|
AT91C_BASE_SPI->SPI_TDR = data;
|
||||||
|
|
||||||
|
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_TDRE) == 0){};
|
||||||
|
|
||||||
// wait recive transfer is complete
|
// wait recive transfer is complete
|
||||||
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0)
|
while ((AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RDRF) == 0);
|
||||||
WDT_HIT();
|
|
||||||
|
|
||||||
// reading incoming data
|
// reading incoming data
|
||||||
incoming = ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
return ((AT91C_BASE_SPI->SPI_RDR) & 0xFFFF);
|
||||||
|
|
||||||
return incoming;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// send last byte over SPI
|
// send last byte over SPI
|
||||||
|
@ -132,41 +178,35 @@ uint16_t FlashSendLastByte(uint32_t data) {
|
||||||
// read state register 1
|
// read state register 1
|
||||||
uint8_t Flash_ReadStat1(void) {
|
uint8_t Flash_ReadStat1(void) {
|
||||||
FlashSendByte(READSTAT1);
|
FlashSendByte(READSTAT1);
|
||||||
uint8_t stat1 = FlashSendLastByte(0xFF);
|
return FlashSendLastByte(0xFF);
|
||||||
// if ( MF_DBGLEVEL > 3 ) Dbprintf("stat1 [%02x]", stat1);
|
|
||||||
return stat1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// read state register 2
|
bool Flash_CheckBusy(uint32_t timeout)
|
||||||
uint8_t Flash_ReadStat2(void) {
|
{
|
||||||
FlashSendByte(READSTAT2);
|
WaitUS(WINBOND_WRITE_DELAY);
|
||||||
uint8_t stat2 = FlashSendLastByte(0xFF);
|
StartCountUS();
|
||||||
// if ( MF_DBGLEVEL > 3 ) Dbprintf("stat2 [%02x]", stat2);
|
uint32_t _time = GetCountUS();
|
||||||
return stat2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// determine whether FLASHMEM is busy
|
do
|
||||||
bool Flash_CheckBusy(uint16_t times) {
|
{
|
||||||
bool ret = (Flash_ReadStat1() & BUSY);
|
if (!(Flash_ReadStat1() & BUSY))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} while ((GetCountUS() - _time) < timeout);
|
||||||
|
|
||||||
if (!ret || !times || !(times--))
|
if (timeout <= (GetCountUS() - _time))
|
||||||
return ret;
|
{
|
||||||
|
return true;
|
||||||
while (times) {
|
|
||||||
WDT_HIT();
|
|
||||||
SpinDelay(1);
|
|
||||||
ret = (Flash_ReadStat1() & BUSY);
|
|
||||||
if (!ret)
|
|
||||||
break;
|
|
||||||
times--;
|
|
||||||
}
|
}
|
||||||
return ret;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// read ID out
|
// read ID out
|
||||||
uint8_t Flash_ReadID(void) {
|
uint8_t Flash_ReadID(void) {
|
||||||
|
|
||||||
if (Flash_CheckBusy(100)) return 0;
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||||
|
|
||||||
// Manufacture ID / device ID
|
// Manufacture ID / device ID
|
||||||
FlashSendByte(ID);
|
FlashSendByte(ID);
|
||||||
|
@ -188,7 +228,7 @@ uint8_t Flash_ReadID(void) {
|
||||||
// read unique id for chip.
|
// read unique id for chip.
|
||||||
void Flash_UniqueID(uint8_t *uid) {
|
void Flash_UniqueID(uint8_t *uid) {
|
||||||
|
|
||||||
if (Flash_CheckBusy(100)) return;
|
if (Flash_CheckBusy(BUSY_TIMEOUT)) return;
|
||||||
|
|
||||||
// reading unique serial number
|
// reading unique serial number
|
||||||
FlashSendByte(UNIQUE_ID);
|
FlashSendByte(UNIQUE_ID);
|
||||||
|
@ -209,12 +249,10 @@ void Flash_UniqueID(uint8_t *uid) {
|
||||||
|
|
||||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
if (!FlashInit()) return 0;
|
if (!FlashInit(0)) return 0;
|
||||||
|
|
||||||
Flash_ReadStat1();
|
|
||||||
|
|
||||||
// length should never be zero
|
// length should never be zero
|
||||||
if (!len || Flash_CheckBusy(100)) return 0;
|
if (!len || Flash_CheckBusy(BUSY_TIMEOUT)) return 0;
|
||||||
|
|
||||||
FlashSendByte(READDATA);
|
FlashSendByte(READDATA);
|
||||||
FlashSendByte((address >> 16) & 0xFF);
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
@ -231,6 +269,55 @@ uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This ensure we can ReadData without having to cycle through initialization everytime */
|
||||||
|
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
if (!len) return 0;
|
||||||
|
|
||||||
|
FlashSendByte(READDATA);
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Flash_FastReadDataCont(uint32_t address, uint8_t *out, uint16_t len) {
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
if (!len) return 0;
|
||||||
|
|
||||||
|
//if (Flash_CheckBusy(BUSY_TIMEOUT))
|
||||||
|
//{return 0;}
|
||||||
|
|
||||||
|
FlashSendByte(FASTREAD);
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
FlashSendByte(0xFF);
|
||||||
|
//Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
out[i] = FlashSendByte(0xFF);
|
||||||
|
|
||||||
|
out[i] = FlashSendLastByte(0xFF);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
|
||||||
// Write data can only program one page. A page has 256 bytes.
|
// Write data can only program one page. A page has 256 bytes.
|
||||||
// if len > 256, it might wrap around and overwrite pos 0.
|
// if len > 256, it might wrap around and overwrite pos 0.
|
||||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
@ -251,12 +338,13 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!FlashInit()) {
|
if (!FlashInit(0)) {
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Flash_ReadStat1();
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
//Flash_ReadStat1();
|
||||||
|
|
||||||
Flash_WriteEnable();
|
Flash_WriteEnable();
|
||||||
|
|
||||||
|
@ -275,22 +363,61 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len) {
|
||||||
|
|
||||||
|
// length should never be zero
|
||||||
|
if (!len)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// Max 256 bytes write
|
||||||
|
if (((address & 0xFF) + len) > 256) {
|
||||||
|
Dbprintf("Flash_WriteData 256 fail [ 0x%02x ] [ %u ]", (address & 0xFF)+len, len );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// out-of-range
|
||||||
|
if ( (( address >> 16 ) & 0xFF ) > MAX_BLOCKS) {
|
||||||
|
Dbprintf("Flash_WriteData, block out-of-range");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Flash_CheckBusy(100);
|
||||||
|
//SpinDelay(1);
|
||||||
|
Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
//Flash_ReadStat1();
|
||||||
|
Flash_WriteEnable();
|
||||||
|
|
||||||
|
FlashSendByte(PAGEPROG);
|
||||||
|
FlashSendByte((address >> 16) & 0xFF);
|
||||||
|
FlashSendByte((address >> 8) & 0xFF);
|
||||||
|
FlashSendByte((address >> 0) & 0xFF);
|
||||||
|
|
||||||
|
uint16_t i = 0;
|
||||||
|
for (; i < (len - 1); i++)
|
||||||
|
FlashSendByte(in[i]);
|
||||||
|
|
||||||
|
FlashSendLastByte(in[i]);
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
bool Flash_WipeMemoryPage(uint8_t page) {
|
bool Flash_WipeMemoryPage(uint8_t page) {
|
||||||
if (!FlashInit()) {
|
if (!FlashInit(0)) {
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Flash_ReadStat1();
|
Flash_ReadStat1();
|
||||||
|
|
||||||
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
// Each block is 64Kb. One block erase takes 1s ( 1000ms )
|
||||||
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(1000);
|
Flash_WriteEnable(); Flash_Erase64k(page); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Wipes flash memory completely, fills with 0xFF
|
// Wipes flash memory completely, fills with 0xFF
|
||||||
bool Flash_WipeMemory() {
|
bool Flash_WipeMemory() {
|
||||||
if (!FlashInit()) {
|
if (!FlashInit(0)) {
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -298,10 +425,10 @@ bool Flash_WipeMemory() {
|
||||||
|
|
||||||
// Each block is 64Kb. Four blocks
|
// Each block is 64Kb. Four blocks
|
||||||
// one block erase takes 1s ( 1000ms )
|
// one block erase takes 1s ( 1000ms )
|
||||||
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(1000);
|
Flash_WriteEnable(); Flash_Erase64k(0); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(1000);
|
Flash_WriteEnable(); Flash_Erase64k(1); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(1000);
|
Flash_WriteEnable(); Flash_Erase64k(2); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(1000);
|
Flash_WriteEnable(); Flash_Erase64k(3); Flash_CheckBusy(BUSY_TIMEOUT);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
return true;
|
return true;
|
||||||
|
@ -366,25 +493,13 @@ void Flash_EraseChip(void) {
|
||||||
FlashSendLastByte(CHIPERASE);
|
FlashSendLastByte(CHIPERASE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// initialize
|
|
||||||
bool FlashInit(void) {
|
|
||||||
FlashSetup();
|
|
||||||
|
|
||||||
StartTicks();
|
|
||||||
|
|
||||||
if (Flash_CheckBusy(100)) {
|
|
||||||
StopTicks();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( MF_DBGLEVEL > 3 ) Dbprintf("FlashInit OK");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Flashmem_print_status(void) {
|
void Flashmem_print_status(void) {
|
||||||
DbpString("Flash memory");
|
DbpString("Flash memory");
|
||||||
|
|
||||||
if (!FlashInit()) {
|
if (!FlashInit(0)) {
|
||||||
DbpString(" init....................FAIL");
|
DbpString(" init....................FAIL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -414,4 +529,4 @@ void Flashmem_print_status(void) {
|
||||||
);
|
);
|
||||||
|
|
||||||
FlashStop();
|
FlashStop();
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#define WRITEENABLE 0x06
|
#define WRITEENABLE 0x06
|
||||||
|
|
||||||
#define READDATA 0x03
|
#define READDATA 0x03
|
||||||
|
#define FASTREAD 0x0B
|
||||||
#define PAGEPROG 0x02
|
#define PAGEPROG 0x02
|
||||||
|
|
||||||
#define SECTORERASE 0x20
|
#define SECTORERASE 0x20
|
||||||
|
@ -57,27 +58,17 @@
|
||||||
// Not used or not support command
|
// Not used or not support command
|
||||||
#define RELEASE 0xAB
|
#define RELEASE 0xAB
|
||||||
#define POWERDOWN 0xB9
|
#define POWERDOWN 0xB9
|
||||||
#define FASTREAD 0x0B
|
|
||||||
#define SUSPEND 0x75
|
#define SUSPEND 0x75
|
||||||
#define RESUME 0x7A
|
#define RESUME 0x7A
|
||||||
|
|
||||||
|
#define BUSY_TIMEOUT 1000000000L
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
||||||
// Chip specific instructions //
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~ Winbond ~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
||||||
#define WINBOND_MANID 0xEF
|
#define WINBOND_MANID 0xEF
|
||||||
#define WINBOND_DEVID 0x11
|
#define WINBOND_DEVID 0x11
|
||||||
#define PAGESIZE 0x100
|
#define PAGESIZE 0x100
|
||||||
|
#define WINBOND_WRITE_DELAY 0x02
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~ Microchip ~~~~~~~~~~~~~~~~~~~~~~~~//
|
#define SPI_CLK 48000000
|
||||||
#define MICROCHIP_MANID 0xBF
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
||||||
// Definitions //
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
|
||||||
|
|
||||||
#define SPI_CLK 75000000 //Hex equivalent of 75MHz
|
|
||||||
|
|
||||||
#define BUSY 0x01
|
#define BUSY 0x01
|
||||||
#define WRTEN 0x02
|
#define WRTEN 0x02
|
||||||
|
@ -113,14 +104,17 @@
|
||||||
|
|
||||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
|
||||||
extern void Dbprintf(const char *fmt, ...);
|
extern void Dbprintf(const char *fmt, ...);
|
||||||
|
bool FlashInit(bool fast);
|
||||||
void FlashSetup(void);
|
void FlashSetup(bool fast);
|
||||||
void FlashStop(void);
|
void FlashStop(void);
|
||||||
bool Flash_WaitIdle(void);
|
bool Flash_WaitIdle(void);
|
||||||
uint8_t Flash_ReadStat1(void);
|
uint8_t Flash_ReadStat1(void);
|
||||||
uint8_t Flash_ReadStat2(void);
|
uint8_t Flash_ReadStat2(void);
|
||||||
uint16_t FlashSendByte(uint32_t data);
|
uint16_t FlashSendByte(uint32_t data);
|
||||||
|
|
||||||
|
bool Flash_CheckBusy(uint32_t timeout);
|
||||||
|
|
||||||
|
|
||||||
void Flash_WriteEnable();
|
void Flash_WriteEnable();
|
||||||
bool Flash_WipeMemoryPage(uint8_t page);
|
bool Flash_WipeMemoryPage(uint8_t page);
|
||||||
bool Flash_WipeMemory();
|
bool Flash_WipeMemory();
|
||||||
|
@ -128,12 +122,16 @@ bool Flash_Erase4k(uint8_t block, uint8_t sector);
|
||||||
//bool Flash_Erase32k(uint32_t address);
|
//bool Flash_Erase32k(uint32_t address);
|
||||||
bool Flash_Erase64k(uint8_t block);
|
bool Flash_Erase64k(uint8_t block);
|
||||||
|
|
||||||
bool FlashInit();
|
|
||||||
|
|
||||||
void Flash_UniqueID(uint8_t *uid);
|
void Flash_UniqueID(uint8_t *uid);
|
||||||
uint8_t Flash_ReadID(void);
|
uint8_t Flash_ReadID(void);
|
||||||
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
uint16_t Flash_ReadData(uint32_t address, uint8_t *out, uint16_t len);
|
||||||
|
|
||||||
|
uint16_t Flash_ReadDataCont(uint32_t address, uint8_t *out, uint16_t len);
|
||||||
|
uint16_t Flash_FastReadDataCont(uint32_t address, uint8_t *out, uint16_t len);
|
||||||
|
|
||||||
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
|
uint16_t Flash_WriteDataCont(uint32_t address, uint8_t *in, uint16_t len);
|
||||||
void Flashmem_print_status(void);
|
void Flashmem_print_status(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -15,9 +15,10 @@
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
int usage_flashmem_read(void){
|
int usage_flashmem_read(void){
|
||||||
PrintAndLogEx(NORMAL, "Read flash memory on device");
|
PrintAndLogEx(NORMAL, "Read flash memory on device");
|
||||||
PrintAndLogEx(NORMAL, "Usage: mem read o <offset> l <len>");
|
PrintAndLogEx(NORMAL, "Usage: mem read o <offset> l <len> [f]");
|
||||||
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
|
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
|
||||||
PrintAndLogEx(NORMAL, " l <len> : length");
|
PrintAndLogEx(NORMAL, " l <len> : length");
|
||||||
|
PrintAndLogEx(NORMAL, " f : fastRead mode");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " mem read o 0 l 32"); // read 32 bytes starting at offset 0
|
PrintAndLogEx(NORMAL, " mem read o 0 l 32"); // read 32 bytes starting at offset 0
|
||||||
|
@ -41,6 +42,7 @@ int usage_flashmem_save(void){
|
||||||
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
|
PrintAndLogEx(NORMAL, " o <offset> : offset in memory");
|
||||||
PrintAndLogEx(NORMAL, " l <length> : length");
|
PrintAndLogEx(NORMAL, " l <length> : length");
|
||||||
PrintAndLogEx(NORMAL, " f <filename> : file name");
|
PrintAndLogEx(NORMAL, " f <filename> : file name");
|
||||||
|
PrintAndLogEx(NORMAL, " + : fast read mode");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, " mem save f myfile"); // download whole flashmem to file myfile
|
PrintAndLogEx(NORMAL, " mem save f myfile"); // download whole flashmem to file myfile
|
||||||
|
@ -79,9 +81,14 @@ int CmdFlashMemRead(const char *Cmd) {
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint32_t start_index = 0, len = 0;
|
uint32_t start_index = 0, len = 0;
|
||||||
|
uint8_t fast = 0;
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
case 'f':
|
||||||
|
fast = 1;
|
||||||
|
cmdp += 1;
|
||||||
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
start_index = param_get32ex(Cmd, cmdp+1, 0, 10);
|
start_index = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
|
@ -107,7 +114,7 @@ int CmdFlashMemRead(const char *Cmd) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
UsbCommand c = {CMD_READ_FLASH_MEM, {start_index, len, 0}};
|
UsbCommand c = {CMD_READ_FLASH_MEM, {start_index, len, fast}};
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -221,6 +228,7 @@ int CmdFlashMemSave(const char *Cmd){
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
bool errors = false;
|
bool errors = false;
|
||||||
uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE;
|
uint32_t start_index = 0, len = FLASH_MEM_MAX_SIZE;
|
||||||
|
uint8_t fast = 0;
|
||||||
|
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||||
|
@ -233,6 +241,10 @@ int CmdFlashMemSave(const char *Cmd){
|
||||||
start_index = param_get32ex(Cmd, cmdp+1, 0, 10);
|
start_index = param_get32ex(Cmd, cmdp+1, 0, 10);
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case '+':
|
||||||
|
fast = 1;
|
||||||
|
cmdp += 1;
|
||||||
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
//File handling
|
//File handling
|
||||||
if ( param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) {
|
if ( param_getstr(Cmd, cmdp+1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE ) {
|
||||||
|
|
|
@ -199,7 +199,31 @@ void UsbCommandReceived(UsbCommand* _ch) {
|
||||||
memset(s, 0x00, sizeof(s));
|
memset(s, 0x00, sizeof(s));
|
||||||
size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE);
|
size_t len = MIN(c->arg[0], USB_CMD_DATA_SIZE);
|
||||||
memcpy(s, c->d.asBytes, len);
|
memcpy(s, c->d.asBytes, len);
|
||||||
|
|
||||||
|
//#define FLAG_RAWPRINT 0x0111
|
||||||
|
//#define FLAG_NOOPT 0x0000
|
||||||
|
//#define FLAG_NOLOG 0x0001
|
||||||
|
//#define FLAG_NONEWLINE 0x0010
|
||||||
|
//#define FLAG_NOPROMPT 0x0100
|
||||||
|
uint64_t flag = c->arg[1];
|
||||||
|
if (flag > 0) { // FLAG_RAWPRINT) {
|
||||||
|
switch (flag) {
|
||||||
|
case FLAG_RAWPRINT: {
|
||||||
|
printf("%s", s);
|
||||||
|
} return; break;
|
||||||
|
case FLAG_NONEWLINE: {
|
||||||
|
printf("%s\r", s);
|
||||||
|
} return; break;
|
||||||
|
case FLAG_NOLOG: {
|
||||||
|
printf("%s\r\n", s);
|
||||||
|
} return; break;
|
||||||
|
// printf("%s", s);
|
||||||
|
fflush(stdout);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// print debug line on same row. escape seq \r
|
// print debug line on same row. escape seq \r
|
||||||
if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) {
|
if ( c->arg[1] == CMD_MEASURE_ANTENNA_TUNING_HF) {
|
||||||
PrintAndLogEx(NORMAL, "\r#db# %s", s);
|
PrintAndLogEx(NORMAL, "\r#db# %s", s);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue