Merge pull request #21 from cjbrigato/master

[Updated] Flashmem optimization, pass 1 + 2
This commit is contained in:
RFID Research Group 2018-09-06 17:27:26 +02:00 committed by GitHub
commit 5019f847a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 1111 additions and 298 deletions

View file

@ -1,4 +1,4 @@
#-----------------------------------------------------------------------------
# This code is licensed to you under the terms of the GNU GPL, version 2 or, # 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 # at your option, any later version. See the LICENSE.txt file for the text of
# the license. # the license.

183
armsrc/Makefile.colin Normal file
View file

@ -0,0 +1,183 @@
#-----------------------------------------------------------------------------
# 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.
#-----------------------------------------------------------------------------
# Makefile for armsrc, see ../common/Makefile.common for common settings
#-----------------------------------------------------------------------------
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.
# NO space,TABs after the "\" sign.
APP_CFLAGS = -DWITH_CRC \
-DON_DEVICE \
-DWITH_LF \
-DWITH_HITAG \
-DWITH_ISO15693 \
-DWITH_LEGICRF \
-DWITH_ISO14443b \
-DWITH_ISO14443a \
-DWITH_ICLASS \
-DWITH_FELICA \
-DWITH_FLASH \
-DWITH_SMARTCARD \
-DWITH_HFSNOOP \
-DWITH_HF_COLIN \
-fno-strict-aliasing -ffunction-sections -fdata-sections
### IMPORTANT - move the commented variable below this line
# -DWITH_LCD \
# -DWITH_EMV \
# -DWITH_FPC \
#
# Standalone Mods
#-------------------------------------------------------
# -DWITH_LF_ICERUN
# -DWITH_LF_SAMYRUN
# -DWITH_LF_PROXBRUTE
# -DWITH_LF_HIDBRUTE
# -DWITH_HF_YOUNG
# -DWITH_HF_MATTYRUN
# -DWITH_HF_COLIN
SRC_LCD = fonts.c LCD.c
SRC_LF = lfops.c hitag2.c hitagS.c lfsampling.c pcf7931.c lfdemod.c
SRC_ISO15693 = iso15693.c iso15693tools.c
#SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c mifaresim.c
SRC_ISO14443a = iso14443a.c mifareutil.c mifarecmd.c epa.c
SRC_ISO14443b = iso14443b.c
SRC_FELICA = felica.c
SRC_CRAPTO1 = crypto1.c des.c aes.c desfire_key.c desfire_crypto.c mifaredesfire.c
SRC_CRC = crc.c crc16.c crc32.c
SRC_ICLASS = iclass.c optimized_cipher.c
SRC_LEGIC = legicrf.c legic_prng.c
SRC_FLASH = flashmem.c
SRC_SMARTCARD = i2c.c
#SRC_FPC = usart.c
SRC_BEE = bee.c
#the FPGA bitstream files. Note: order matters!
FPGA_BITSTREAMS = fpga_lf.bit fpga_hf.bit
#the zlib source files required for decompressing the fpga config at run time
SRC_ZLIB = inflate.c inffast.c inftrees.c adler32.c zutil.c
#additional defines required to compile zlib
ZLIB_CFLAGS = -DZ_SOLO -DZ_PREFIX -DNO_GZIP -DZLIB_PM3_TUNED
APP_CFLAGS += $(ZLIB_CFLAGS)
# zlib includes:
APP_CFLAGS += -I../zlib
# stdint.h provided locally until GCC 4.5 becomes C99 compliant
APP_CFLAGS += -I.
# Compile these in thumb mode (small size)
THUMBSRC = start.c \
protocols.c \
$(SRC_LCD) \
$(SRC_ISO15693) \
$(SRC_LF) \
$(SRC_ZLIB) \
$(SRC_LEGIC) \
$(SRC_FLASH) \
$(SRC_SMARTCARD) \
$(SRC_FPC) \
appmain.c \
printf.c \
util.c \
string.c \
BigBuf.c \
ticks.c \
random.c \
hfsnoop.c
# These are to be compiled in ARM mode
ARMSRC = fpgaloader.c \
$(SRC_ISO14443a) \
$(SRC_ISO14443b) \
$(SRC_CRAPTO1) \
$(SRC_ICLASS) \
$(SRC_EMV) \
$(SRC_CRC) \
$(SRC_FELICA) \
parity.c \
usb_cdc.c \
cmd.c \
vtsend.c \
hf_colin.c \
lib_AT91SAM7.c
VERSIONSRC = version.c \
fpga_version_info.c
# Do not move this inclusion before the definition of {THUMB,ASM,ARM}SRC
include ../common/Makefile.common
COMMON_FLAGS = -Os
OBJS = $(OBJDIR)/fullimage.s19
FPGA_COMPRESSOR = ../client/fpga_compress
all: $(OBJS)
.DELETE_ON_ERROR:
# version.c should be remade on every compilation
.PHONY: version.c
version.c: default_version.c
perl ../tools/mkversion.pl .. > $@ || $(COPY) $^ $@
fpga_version_info.c: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(FPGA_COMPRESSOR) -v $(filter %.bit,$^) $@
$(OBJDIR)/fpga_all.o: $(OBJDIR)/fpga_all.bit.z
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --prefix-sections=fpga_all_bit $^ $@
$(OBJDIR)/fpga_all.bit.z: $(FPGA_BITSTREAMS) $(FPGA_COMPRESSOR)
$(FPGA_COMPRESSOR) $(filter %.bit,$^) $@
$(FPGA_COMPRESSOR):
make -C ../client $(notdir $(FPGA_COMPRESSOR))
$(OBJDIR)/fullimage.stage1.elf: $(VERSIONOBJ) $(OBJDIR)/fpga_all.o $(THUMBOBJ) $(ARMOBJ)
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^ $(LIBS)
$(OBJDIR)/fullimage.nodata.bin: $(OBJDIR)/fullimage.stage1.elf
$(OBJCOPY) -O binary -I elf32-littlearm --remove-section .data $^ $@
$(OBJDIR)/fullimage.nodata.o: $(OBJDIR)/fullimage.nodata.bin
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --rename-section .data=stage1_image $^ $@
$(OBJDIR)/fullimage.data.bin: $(OBJDIR)/fullimage.stage1.elf
$(OBJCOPY) -O binary -I elf32-littlearm --only-section .data $^ $@
$(OBJDIR)/fullimage.data.bin.z: $(OBJDIR)/fullimage.data.bin $(FPGA_COMPRESSOR)
$(FPGA_COMPRESSOR) $(filter %.bin,$^) $@
$(OBJDIR)/fullimage.data.o: $(OBJDIR)/fullimage.data.bin.z
$(OBJCOPY) -O elf32-littlearm -I binary -B arm --rename-section .data=compressed_data $^ $@
$(OBJDIR)/fullimage.elf: $(OBJDIR)/fullimage.nodata.o $(OBJDIR)/fullimage.data.o
$(CC) $(LDFLAGS) -Wl,-T,ldscript,-e,_osimage_entry,-Map,$(patsubst %.elf,%.map,$@) -o $@ $^
tarbin: $(OBJS)
$(TAR) $(TARFLAGS) ../proxmark3-$(platform)-bin.tar $(OBJS:%=armsrc/%) $(OBJS:%.s19=armsrc/%.elf)
clean:
$(DELETE) $(OBJDIR)$(PATHSEP)*.o
$(DELETE) $(OBJDIR)$(PATHSEP)*.elf
$(DELETE) $(OBJDIR)$(PATHSEP)*.s19
$(DELETE) $(OBJDIR)$(PATHSEP)*.map
$(DELETE) $(OBJDIR)$(PATHSEP)*.d
$(DELETE) $(OBJDIR)$(PATHSEP)*.z
$(DELETE) $(OBJDIR)$(PATHSEP)*.bin
$(DELETE) version.c
.PHONY: all clean help
help:
@echo Multi-OS Makefile, you are running on $(DETECTED_OS)
@echo Possible targets:
@echo + all - Build the full image $(OBJDIR)/fullimage.s19
@echo + clean - Clean $(OBJDIR)

File diff suppressed because it is too large Load diff

View file

@ -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,20 @@
#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'};
void TestFlashmemSpeed(size_t buffersize, uint32_t spibaudrate);
#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 +419,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 +503,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 */

View file

@ -440,7 +440,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)");
@ -1160,7 +1160,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);
@ -1171,27 +1171,30 @@ void UsbPacketReceived(uint8_t *packet, int len) {
ReadMem(c->arg[0]); ReadMem(c->arg[0]);
break; break;
#ifdef WITH_FLASH #ifdef WITH_FLASH
case CMD_READ_FLASH_MEM: { case CMD_FLASHMEM_SET_SPIBAUDRATE:
FlashmemSetSpiBaudrate(c->arg[0]);
break;
case CMD_FLASHMEM_READ: {
LED_B_ON(); LED_B_ON();
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);
size_t size = MIN(USB_CMD_DATA_SIZE, len); size_t size = MIN(USB_CMD_DATA_SIZE, len);
uint8_t *mem = BigBuf_malloc(size); uint8_t *mem = BigBuf_malloc(size);
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);
isok = Flash_ReadDataCont(startidx + i, mem, len);
Dbprintf("FlashMem reading | %d | %d | %d", startidx + i, i, len);
isok = Flash_ReadData(startidx + i, mem, len);
if ( isok == len ) { if ( isok == len ) {
print_result("Chunk: ", mem, len); print_result("Chunk: ", mem, len);
} else { } else {
@ -1199,10 +1202,11 @@ void UsbPacketReceived(uint8_t *packet, int len) {
break; break;
} }
} }
FlashStop();
LED_B_OFF(); LED_B_OFF();
break; break;
} }
case CMD_WRITE_FLASH_MEM: { case CMD_FLASHMEM_WRITE: {
LED_B_ON(); LED_B_ON();
uint8_t isok = 0; uint8_t isok = 0;
uint16_t res = 0; uint16_t res = 0;
@ -1212,6 +1216,14 @@ void UsbPacketReceived(uint8_t *packet, int len) {
uint32_t tmp = startidx + len; uint32_t tmp = startidx + len;
if (!FlashInit())
{
break;
}
Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable();
// inside 256b page? // inside 256b page?
if ( (tmp & 0xFF) != 0) { if ( (tmp & 0xFF) != 0) {
@ -1225,27 +1237,28 @@ void UsbPacketReceived(uint8_t *packet, int len) {
uint8_t first_len = (~startidx & 0xFF)+1; uint8_t first_len = (~startidx & 0xFF)+1;
// first mem page // first mem page
res = Flash_WriteData(startidx, data, first_len); res = Flash_WriteDataCont(startidx, data, first_len);
// second mem page // second mem page
res = Flash_WriteData(startidx + first_len, data + first_len, len - first_len); res = Flash_WriteDataCont(startidx + first_len, data + first_len, len - first_len);
isok = (res == (len - first_len)) ? 1 : 0; isok = (res == (len - first_len)) ? 1 : 0;
} else { } else {
res = Flash_WriteData(startidx, data, len); res = Flash_WriteDataCont(startidx, data, len);
isok = (res == len) ? 1 : 0; isok = (res == len) ? 1 : 0;
} }
} else { } else {
res = Flash_WriteData(startidx, data, len); res = Flash_WriteDataCont(startidx, data, len);
isok = (res == len) ? 1 : 0; isok = (res == len) ? 1 : 0;
} }
FlashStop();
cmd_send(CMD_ACK, isok, 0, 0, 0, 0); cmd_send(CMD_ACK, isok, 0, 0, 0, 0);
LED_B_OFF(); LED_B_OFF();
break; break;
} }
case CMD_WIPE_FLASH_MEM: { case CMD_FLASHMEM_WIPE: {
LED_B_ON(); LED_B_ON();
uint8_t page = c->arg[0]; uint8_t page = c->arg[0];
uint8_t initalwipe = c->arg[1]; uint8_t initalwipe = c->arg[1];
@ -1263,7 +1276,7 @@ void UsbPacketReceived(uint8_t *packet, int len) {
LED_B_OFF(); LED_B_OFF();
break; break;
} }
case CMD_DOWNLOAND_FLASH_MEM: { case CMD_FLASHMEM_DOWNLOAD: {
LED_B_ON(); LED_B_ON();
uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE); uint8_t *mem = BigBuf_malloc(USB_CMD_DATA_SIZE);
@ -1271,26 +1284,32 @@ 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
FlashInit();
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);
isok = Flash_ReadData(startidx + i, mem, len); isok = Flash_ReadDataCont(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);
if (!isok)
Dbprintf("transfer to client failed :: | bytes between %d - %d (%d)", i, i+len, len);
}
isok = cmd_send(CMD_FLASHMEM_DOWNLOADED, i, len, 0, mem, len);
if (!isok)
Dbprintf("transfer to client failed :: | bytes between %d - %d", i, len);
}
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;
} }
case CMD_INFO_FLASH_MEM: { case CMD_FLASHMEM_INFO: {
LED_B_ON(); LED_B_ON();
rdv40_validation_t *info = (rdv40_validation_t*)BigBuf_malloc( sizeof(rdv40_validation_t) ); rdv40_validation_t *info = (rdv40_validation_t*)BigBuf_malloc( sizeof(rdv40_validation_t) );
@ -1392,8 +1411,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;
@ -1429,6 +1446,12 @@ void __attribute__((noreturn)) AppMain(void) {
#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(;;) {
@ -1463,7 +1486,6 @@ void __attribute__((noreturn)) AppMain(void) {
#if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) ) #if defined (WITH_ISO14443a) && ( defined (WITH_HF_YOUNG) || defined(WITH_HF_COLIN) || defined(WITH_HF_MATTYRUN) )
RunMod(); RunMod();
#endif #endif
} }
} }
} }

View file

@ -1,39 +1,45 @@
#include "flashmem.h" #include "flashmem.h"
/* 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
/* uint32_t FLASHMEM_SPIBAUDRATE = FLASH_BAUD;
1-256256
CS拉高
*/
void FlashSetup(void) {
// PA1 -> SPI_NCS3 chip select (MEM) void FlashmemSetSpiBaudrate(uint32_t baudrate){
// PA10 -> SPI_NCS2 chip select (LCD) FLASHMEM_SPIBAUDRATE = baudrate;
Dbprintf("Spi Baudrate : %dMhz", FLASHMEM_SPIBAUDRATE/1000000);
}
// initialize
bool FlashInit() {
FlashSetup(FLASHMEM_SPIBAUDRATE);
StartTicks();
if (Flash_CheckBusy(BUSY_TIMEOUT)) {
StopTicks();
return false;
}
return true;
}
void FlashSetup(uint32_t baudrate){
//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 +60,70 @@ 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
uint8_t csaat = 1;
uint32_t dlybct = 0;
if (baudrate > FLASH_MINFAST) {
baudrate = FLASH_FASTBAUD;
//csaat = 0;
dlybct = 1500;
}
// 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 +131,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 +154,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 +179,37 @@ 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 if ( MF_DBGLEVEL > 3 ) Dbprintf("Checkbusy in...");
bool Flash_CheckBusy(uint16_t times) {
bool ret = (Flash_ReadStat1() & BUSY);
if (!ret || !times || !(times--)) do
return ret; {
if (!(Flash_ReadStat1() & BUSY))
{
return false;
}
} while ((GetCountUS() - _time) < timeout);
while (times) { if (timeout <= (GetCountUS() - _time))
WDT_HIT(); {
SpinDelay(1); return true;
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 +231,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);
@ -210,27 +253,72 @@ 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()) 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((address >> 16) & 0xFF); uint8_t cmd = READDATA;
FlashSendByte((address >> 8) & 0xFF);
FlashSendByte((address >> 0) & 0xFF); if(FASTFLASH) {
cmd = FASTREAD;
}
FlashSendByte(cmd);
Flash_TransferAdresse(address);
if (FASTFLASH){
FlashSendByte(DUMMYBYTE);
}
uint16_t i = 0; uint16_t i = 0;
for (; i < (len - 1); i++) for (; i < (len - 1); i++)
out[i] = FlashSendByte(0xFF); out[i] = FlashSendByte(0xFF);
out[i] = FlashSendLastByte(0xFF); out[i] = FlashSendLastByte(0xFF);
FlashStop(); FlashStop();
return len; return len;
} }
void Flash_TransferAdresse(uint32_t address){
FlashSendByte((address >> 16) & 0xFF);
FlashSendByte((address >> 8) & 0xFF);
FlashSendByte((address >> 0) & 0xFF);
}
/* 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;
uint8_t cmd = READDATA;
if(FASTFLASH) {
cmd = FASTREAD;
}
FlashSendByte(cmd);
Flash_TransferAdresse(address);
if (FASTFLASH){
FlashSendByte(DUMMYBYTE);
}
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) {
@ -256,7 +344,7 @@ uint16_t Flash_WriteData(uint32_t address, uint8_t *in, uint16_t len) {
return 0; return 0;
} }
Flash_ReadStat1(); Flash_CheckBusy(BUSY_TIMEOUT);
Flash_WriteEnable(); Flash_WriteEnable();
@ -275,6 +363,39 @@ 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;
}
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()) {
if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail"); if ( MF_DBGLEVEL > 3 ) Dbprintf("Flash_WriteData init fail");
@ -283,7 +404,7 @@ bool Flash_WipeMemoryPage(uint8_t page) {
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;
@ -298,10 +419,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,29 +487,18 @@ 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");
Dbprintf(" Baudrate................%dMHz",FLASHMEM_SPIBAUDRATE/1000000);
if (!FlashInit()) { if (!FlashInit()) {
DbpString(" init....................FAIL"); DbpString(" Init....................FAIL");
return; return;
} }
DbpString(" init....................OK"); DbpString(" Init....................OK");
uint8_t dev_id = Flash_ReadID(); uint8_t dev_id = Flash_ReadID();
switch (dev_id) { switch (dev_id) {
@ -414,4 +524,4 @@ void Flashmem_print_status(void) {
); );
FlashStop(); FlashStop();
} }

View file

@ -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
@ -111,15 +102,33 @@
#define MAX_SECTORS 16 #define MAX_SECTORS 16
#define MCK 48000000
//#define FLASH_BAUD 24000000
#define FLASH_MINFAST 24000000 //33000000
#define FLASH_BAUD MCK/2
#define FLASH_FASTBAUD MCK
#define FLASH_MINBAUD FLASH_FASTBAUD
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
extern void Dbprintf(const char *fmt, ...); extern void Dbprintf(const char *fmt, ...);
void FlashSetup(void); void FlashmemSetSpiBaudrate(uint32_t baudrate);
bool FlashInit();
void FlashSetup(uint32_t baudrate);
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);
void Flash_TransferAdresse(uint32_t address);
bool Flash_CheckBusy(uint32_t timeout);
void Flash_WriteEnable(); void Flash_WriteEnable();
bool Flash_WipeMemoryPage(uint8_t page); bool Flash_WipeMemoryPage(uint8_t page);
@ -128,12 +137,17 @@ 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_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

View file

@ -12,7 +12,31 @@
#include "rsa.h" #include "rsa.h"
#include "sha1.h" #include "sha1.h"
#define MCK 48000000
//#define FLASH_BAUD 24000000
#define FLASH_MINFAST 24000000 //33000000
#define FLASH_BAUD MCK/2
#define FLASH_FASTBAUD MCK
#define FLASH_MINBAUD FLASH_FASTBAUD
#define FASTFLASH (FLASHMEM_SPIBAUDRATE > FLASH_MINFAST)
static int CmdHelp(const char *Cmd); static int CmdHelp(const char *Cmd);
int usage_flashmem_spibaud(void){
PrintAndLogEx(NORMAL, "Usage: mem spibaud [h] <baudrate>");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h this help");
PrintAndLogEx(NORMAL, " <baudrate> SPI baudrate in MHz [24|48]");
PrintAndLogEx(NORMAL, " ");
PrintAndLogEx(NORMAL, " If >= 24Mhz, FASTREADS instead of READS instruction will be used.");
PrintAndLogEx(NORMAL, " Reading Flash ID will virtually always fail under 48Mhz setting");
PrintAndLogEx(NORMAL, " Unless you know what you are doing, please stay at 24Mhz");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " mem spibaud 48");
return 0;
}
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>");
@ -107,11 +131,24 @@ int CmdFlashMemRead(const char *Cmd) {
return 1; return 1;
} }
UsbCommand c = {CMD_READ_FLASH_MEM, {start_index, len, 0}}; UsbCommand c = {CMD_FLASHMEM_READ, {start_index, len, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
return 0; return 0;
} }
int CmdFlashmemSpiBaudrate(const char *Cmd) {
char ctmp = param_getchar(Cmd, 0);
if (strlen(Cmd) < 1 || ctmp == 'h' || ctmp == 'H') return usage_flashmem_spibaud();
uint32_t baudrate = param_get32ex(Cmd, 0, 0, 10);
baudrate = baudrate*1000000;
if (baudrate != FLASH_BAUD && baudrate != FLASH_MINBAUD ) return usage_flashmem_spibaud();
UsbCommand c = {CMD_FLASHMEM_SET_SPIBAUDRATE, {baudrate, 0, 0}};
SendCommand(&c);
return 0;
}
int CmdFlashMemLoad(const char *Cmd){ int CmdFlashMemLoad(const char *Cmd){
FILE *f; FILE *f;
@ -189,7 +226,7 @@ int CmdFlashMemLoad(const char *Cmd){
while (bytes_remaining > 0){ while (bytes_remaining > 0){
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining); uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
UsbCommand c = {CMD_WRITE_FLASH_MEM, {start_index + bytes_sent, bytes_in_packet, 0}}; UsbCommand c = {CMD_FLASHMEM_WRITE, {start_index + bytes_sent, bytes_in_packet, 0}};
memcpy(c.d.asBytes, dump + bytes_sent, bytes_in_packet); memcpy(c.d.asBytes, dump + bytes_sent, bytes_in_packet);
clearCommandBuffer(); clearCommandBuffer();
@ -302,7 +339,7 @@ int CmdFlashMemWipe(const char *Cmd){
//Validations //Validations
if (errors || cmdp == 0 ) return usage_flashmem_wipe(); if (errors || cmdp == 0 ) return usage_flashmem_wipe();
UsbCommand c = {CMD_WIPE_FLASH_MEM, {page, initalwipe, 0}}; UsbCommand c = {CMD_FLASHMEM_WIPE, {page, initalwipe, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
@ -347,7 +384,7 @@ int CmdFlashMemInfo(const char *Cmd){
//Validations //Validations
if (errors ) return usage_flashmem_info(); if (errors ) return usage_flashmem_info();
UsbCommand c = {CMD_INFO_FLASH_MEM, {0, 0, 0}}; UsbCommand c = {CMD_FLASHMEM_INFO, {0, 0, 0}};
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
UsbCommand resp; UsbCommand resp;
@ -476,7 +513,7 @@ int CmdFlashMemInfo(const char *Cmd){
if (shall_write) { if (shall_write) {
// save to mem // save to mem
c = (UsbCommand){CMD_WRITE_FLASH_MEM, {FLASH_MEM_SIGNATURE_OFFSET, FLASH_MEM_SIGNATURE_LEN, 0}}; c = (UsbCommand){CMD_FLASHMEM_WRITE, {FLASH_MEM_SIGNATURE_OFFSET, FLASH_MEM_SIGNATURE_LEN, 0}};
memcpy(c.d.asBytes, sign, sizeof(sign)); memcpy(c.d.asBytes, sign, sizeof(sign));
clearCommandBuffer(); clearCommandBuffer();
SendCommand(&c); SendCommand(&c);
@ -508,6 +545,7 @@ int CmdFlashMemInfo(const char *Cmd){
static command_t CommandTable[] = { static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"}, {"help", CmdHelp, 1, "This help"},
{"spibaud", CmdFlashmemSpiBaudrate, 1, "Set Flash memory Spi baudrate [rdv40]"},
{"read", CmdFlashMemRead, 1, "Read Flash memory [rdv40]"}, {"read", CmdFlashMemRead, 1, "Read Flash memory [rdv40]"},
{"info", CmdFlashMemInfo, 1, "Flash memory information [rdv40]"}, {"info", CmdFlashMemInfo, 1, "Flash memory information [rdv40]"},
{"load", CmdFlashMemLoad, 1, "Load data into flash memory [rdv40]"}, {"load", CmdFlashMemLoad, 1, "Load data into flash memory [rdv40]"},

View file

@ -213,7 +213,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);
@ -274,9 +298,9 @@ bool GetFromDevice(DeviceMemType_t memtype, uint8_t *dest, uint32_t bytes, uint3
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF); return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_EML_BIGBUF);
} }
case FLASH_MEM: { case FLASH_MEM: {
UsbCommand c = {CMD_DOWNLOAND_FLASH_MEM, {start_index, bytes, 0}}; UsbCommand c = {CMD_FLASHMEM_DOWNLOAD, {start_index, bytes, 0}};
SendCommand(&c); SendCommand(&c);
return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_DOWNLOADED_FLASHMEM); return dl_it(dest, bytes, start_index, response, ms_timeout, show_warning, CMD_FLASHMEM_DOWNLOADED);
} }
case SIM_MEM: { case SIM_MEM: {
//UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}}; //UsbCommand c = {CMD_DOWNLOAND_SIM_MEM, {start_index, bytes, 0}};

View file

@ -57,12 +57,12 @@ typedef struct {
#define CMD_DOWNLOADED_EML_BIGBUF 0x0111 #define CMD_DOWNLOADED_EML_BIGBUF 0x0111
// RDV40, Flash memory operations // RDV40, Flash memory operations
#define CMD_READ_FLASH_MEM 0x0120 #define CMD_FLASHMEM_READ 0x0120
#define CMD_WRITE_FLASH_MEM 0x0121 #define CMD_FLASHMEM_WRITE 0x0121
#define CMD_WIPE_FLASH_MEM 0x0122 #define CMD_FLASHMEM_WIPE 0x0122
#define CMD_DOWNLOAND_FLASH_MEM 0x0123 #define CMD_FLASHMEM_DOWNLOAD 0x0123
#define CMD_DOWNLOADED_FLASHMEM 0x0124 #define CMD_FLASHMEM_DOWNLOADED 0x0124
#define CMD_INFO_FLASH_MEM 0x0125 #define CMD_FLASHMEM_INFO 0x0125
// For low-frequency tags // For low-frequency tags
#define CMD_READ_TI_TYPE 0x0202 #define CMD_READ_TI_TYPE 0x0202

View file

@ -30,6 +30,9 @@ typedef unsigned char byte_t;
#define MF_DBG_EXTENDED 4 #define MF_DBG_EXTENDED 4
extern int MF_DBGLEVEL; extern int MF_DBGLEVEL;
// Flashmem spi baudrate
extern uint32_t FLASHMEM_SPIBAUDRATE;
// reader voltage field detector // reader voltage field detector
#define MF_MINFIELDV 4000 #define MF_MINFIELDV 4000

View file

@ -67,13 +67,17 @@ typedef struct{
#define CMD_DOWNLOAD_EML_BIGBUF 0x0110 #define CMD_DOWNLOAD_EML_BIGBUF 0x0110
#define CMD_DOWNLOADED_EML_BIGBUF 0x0111 #define CMD_DOWNLOADED_EML_BIGBUF 0x0111
// RDV40, Flash memory operations // RDV40, Flash memory operations
#define CMD_READ_FLASH_MEM 0x0120 #define CMD_FLASHMEM_READ 0x0120
#define CMD_WRITE_FLASH_MEM 0x0121 #define CMD_FLASHMEM_WRITE 0x0121
#define CMD_WIPE_FLASH_MEM 0x0122 #define CMD_FLASHMEM_WIPE 0x0122
#define CMD_DOWNLOAND_FLASH_MEM 0x0123 #define CMD_FLASHMEM_DOWNLOAD 0x0123
#define CMD_DOWNLOADED_FLASHMEM 0x0124 #define CMD_FLASHMEM_DOWNLOADED 0x0124
#define CMD_INFO_FLASH_MEM 0x0125 #define CMD_FLASHMEM_INFO 0x0125
#define CMD_FLASHMEM_SET_SPIBAUDRATE 0x0126
// RDV40, Smart card operations // RDV40, Smart card operations
#define CMD_SMART_RAW 0x0140 #define CMD_SMART_RAW 0x0140

View file

@ -18,13 +18,23 @@ my $fullgitinfo = 'iceman';
my $ctime; my $ctime;
# GIT status 0 = dirty, 1 = clean , 2 = undecided # GIT status 0 = dirty, 1 = clean , 2 = undecided
my $clean = 2; my $clean = 2;
# Do we have acces to git command? # Do we have acces to git command?
my $commandGIT = `bash which git`; #######
# solves some bug on macos i.e:
##
# perl ../tools/mkversion.pl .. > version.c || cp ../common/default_version.c version.c
# /usr/bin/which: /usr/bin/which: cannot execute binary file
# fatal: No names found, cannot describe anything.
##
# anyway forcing any kind of shell is at least useless, at worst fatal.
my $commandGIT = "env -S which git";
if ( defined($commandGIT) ) { if ( defined($commandGIT) ) {
my $githistory = `git fetch --all`; my $githistory = `git fetch --all`;
my $gitversion = `git describe --dirty`; # now avoiding the "fatal: No names found, cannot describe anything." error by fallbacking to abbrev hash in such case
my $gitversion = `git describe --dirty --always`;
my $gitbranch = `git rev-parse --abbrev-ref HEAD`; my $gitbranch = `git rev-parse --abbrev-ref HEAD`;
$clean = $gitversion =~ '-dirty' ? 0 : 1; $clean = $gitversion =~ '-dirty' ? 0 : 1;